ultimaluz

joined 1 month ago
[–] ultimaluz@lemmy.world 1 points 22 hours ago

yeah thats the nice part, every app in its own box and if one breaks you just throw it away and start it again. for subdomains I ended up with caddy in front, it does the certs by itself so adding one is like 2 lines

[–] ultimaluz@lemmy.world 2 points 3 days ago

for a multiplayer browser game I ended up skipping websockets and using SSE for everything that goes server to client, and plain POST requests for the actions. it's just http so the reverse proxy, cookies and reconnects work without doing anything special, and EventSource reconnects by itself. one gotcha if you use express with compression middleware, exclude the SSE route or the events get buffered and arrive in chunks. websockets make more sense if the client sends a lot, mine mostly listens

[–] ultimaluz@lemmy.world 1 points 3 days ago

For me the evidence was the server logs, filtering by user agent. my main page is basically a canvas game, so the html has almost nothing for a crawler, and I was surprised to see googlebot not only rendering it but opening the SSE stream like a real player (I noticed because bots were showing up as online players lol). what actually got indexed were the plain server rendered pages I made for each thing worth sharing, with title, og image and json-ld, listed in the sitemap. so I didn't change the app rendering, I just gave crawlers simpler pages to read.

[–] ultimaluz@lemmy.world 2 points 3 days ago (2 children)

8gb with 70+ mods is way less than I expected, nice. capping it in docker is smart too if it leaks at least it can't take the rest of the box down with it

[–] ultimaluz@lemmy.world 2 points 3 days ago (1 children)

What I do for that is turn it around, instead of checking for a failure I alert on the absence of a success. backrest has hooks, so on snapshot success it pings a push monitor in uptime kuma (healthchecks.io works the same), and if no ping arrives in ~26h it alerts. That way it catches the backup that never ran, which is the one that scares me the most I guess

[–] ultimaluz@lemmy.world 1 points 3 days ago

money wise no, not even close. it's a bitaxe gamma doing around 1 TH/s solo, so it's basically a lottery ticket, the odds of hitting a block are tiny. it costs me like 3 euros a month in power so I treat it as a toy, I like checking the best difficulty it found and it's a nice way to learn how mining works

[–] ultimaluz@lemmy.world 2 points 3 days ago

hey Tower, late follow up but you were right and it's done. the ? button now has a SEE THE RULES button right under the welcome, it's a plain manual with 8 short questions and the real numbers, and those numbers come straight from the game code so they can't go stale when I change something. thanks for actually playing and saying you had no idea what was happening, that one comment changed more than any stat I was looking at

[–] ultimaluz@lemmy.world 1 points 3 days ago

thanks, it's the first number I look at every morning lol. one thing I learned this week is that you have to clean it before trusting it, a crawler from some chinese cloud providers was keeping the cookie and coming back, it was 6 of the 7 "visitors" one day. so the real number is smaller than it looked, but at least now it's honest

[–] ultimaluz@lemmy.world 1 points 4 days ago (4 children)

Day 818 is wild, congrats on keeping it going. and the part about making cool stuff for your friends and not caring if it's profitable is so true, I host a few little things nobody pays for and it's the best part of the hobby I guess. Does the cobblemon server need a lot of ram or does it run fine on modest hardware?

[–] ultimaluz@lemmy.world 4 points 4 days ago (2 children)

Most of my stuff lives on a cheap hetzner vps so that power is someone else's problem lol. at home it's a raspberry pi that's always on (a few watts) and a bitaxe miner doing about 19W, that's around 14 kWh a month, like 3 euros here. the gaming pc is the only hungry thing and it stays off, the pi wakes it with wake-on-lan when I actually need it. took me a while to get the bios settings right (erp off, power on by pci-e) but it was worth it.

[–] ultimaluz@lemmy.world 2 points 4 days ago (2 children)

thanks, means a lot after how the last thread went lol. honestly it's still early to say if it worked, the number I'm watching now is how many people who paint on their first day come back another day, if that one moves I'll know the card and the siege clock did something.

[–] ultimaluz@lemmy.world 4 points 5 days ago (3 children)

I'd add backup age and size, not just status, like alert if the newest dump is older than ~26h or smaller than 1MB, a job can say success and still leave you a useless file. and disk fill with a threshold, not only the graph. learned that one the hard way, a table on my vps was getting a row every minute with no cleanup and one day the disk hit 100% and postgres just died for like 40 min, obviously nobody was looking at the dashboard right then lol. now 80% warns and 90% sends me an email, and uptime kuma checks the cert expiry from outside. I guess the dashboard is nice to look at but the stuff that matters should ping you

 

Some context first. The game is a shared 256x256 pixel canvas, people paint it by hand from the browser and an AI called La Maquina spends the day erasing it. Free, no account. Problem is it has basically no players and I'm not going to stream it myself every day, so I tried to let the canvas stream itself.

I already had a 3D spectator view (three.js) with a "stream mode", the camera goes on autopilot and jumps to whoever just painted a pixel and shows their name, and her lines go as captions. So the plan was just put that page in OBS as a browser source and leave it running. It runs on a PC at home that isn't free all day (4060 Ti, NVENC, 1080p30, around 6 Mbps up), that's why the schedule is a bit weird.

At first I wanted a cheap VPS for this but measured before paying. Without a GPU chromium falls back to software WebGL and the scene was doing 0 or 1 fps, with the GPU it's around 100. So no VPS.

Things that broke:

  • when the PC was off and comes back, the browser source started black two times and once with no sound, while the page inside was totally fine. reloading the source doesn't fix the black one, only restarting OBS does
  • if OBS gets killed instead of closed, next start it asks "start in safe mode?" and waits forever because nobody is there to click. the thing it checks is a folder, not a file, lost a whole evening with that one
  • so now there's a small watchdog every 5 min that asks OBS (obs-websocket) for a screenshot of the source and the audio levels. black or silent -> reload, still bad -> restart OBS

For the chat there's a little bot reading the same live events the game uses and posting her lines. Only lines from the bank the game already has, I don't want anything generated going out without me reading it first. When the channel is offline she shuts up, !play and !era work always. And since this week the chat can paint too, !near lights a pixel next to the last one and !more east or !more north keeps drawing from yours, one pixel per message with the same charges as on the web (you have to follow the channel, mostly to keep throwaway accounts out).

Since yesterday it also goes to Kick at the same time, and since today to YouTube too. The PC sends the stream once to a tiny nginx-rtmp relay on the game's VPS and that copies it to all three, so the upload at home stays the same. Kick only takes RTMPS and nginx-rtmp doesn't do TLS, so that one goes through stunnel.

First night without telling anyone: 9 hours, 10 unique viewers (I guess people browsing the Art category) and zero of them went to the game lol. So this post is kind of the real launch.

Live on Twitch, Kick and YouTube weekdays 03:00-12:30 UTC and weekends 01:30-07:00 UTC. The game works anytime: https://ultimaluz.com/r/lemmy-gamedev-canal

If someone is doing something similar ask me, happy to share how the watchdog works

 

It is r/place with an opponent. A 256x256 canvas, 30 charges that refill one every 30 seconds, and an adversary called La Maquina who spends the whole day putting out the lights people leave on. She lays sieges on the works people build, declares blackouts on a quadrant before she carries them out, and comments on what she is doing while she does it.

Two things that make her feel less like weather and more like an opponent. Raising a tower makes it harder to kill: she has to take it down one storey at a time, and while she does you can build it back up. And what she takes she builds with, raising her own cold cubes out of the dark next to yours. They come down in a single pixel if you reclaim the cell.

No account, no ads, no download. It runs in the browser and you can paint your first pixel about five seconds after opening it: https://ultimaluz.com/r/lemmy-gaming

Fair warning: she erases. What you see on the canvas is what people have managed to keep.

I am the developer, happy to answer anything.

 

Short version: the channel worked and the game did not retain a single person. Here is the autopsy, because the numbers turned out to be more specific than I expected.

The game is a shared 256x256 pixel canvas where an AI adversary erases what people paint. Free, browser, no account. Two posts, one in a pixel art community and one in a web games community, brought 150 arrivals, 38 sessions and 23 people who actually painted. That is more than the project had seen in its entire life. Of those 23, one came back to look and zero painted on a second day.

What the sessions looked like:

  • 18 of 23 lasted two minutes or less. Median time from first pixel to last: 41 seconds.
  • Median 19 pixels painted. 9 of 23 spent all 30 charges (the bucket refills one charge every 30 seconds).
  • In 14 of 23, most of their cells were cells taken back from the adversary. They were not decorating, they were fighting her.
  • In 18 of 23 she erased cells while the player was still there, and between 126 and 423 more in the 25 minutes after they left.
  • Nobody used undo. Zero comments on either post.

What I read from that: the first session is 30 pixels long, it ends when the charges end, and nothing happens at that moment. No closure, no name, no reason to come back. The adversary was already reacting to them, but she is forbidden from touching any pixel younger than 72 hours, so her answer always landed somewhere they were not looking.

What shipped since, in two passes.

First, making her legible in the first minute:

  • When your bucket hits zero she speaks to you, by name, once in your life. The zero stops being a bare number and becomes a state with a countdown.
  • Her answer to the cells you took back travels signed, so you can tell it was aimed at you.
  • The identity prompt stopped interrupting the burst.
  • Her blitz finally respects the 72 hour protection on young pixels, which the code promised in writing and did not do. That single bug had eaten 238 of the 403 cells that cohort painted.
  • Instrumentation for the whole first session, so the next wave is measured instead of guessed.

Then, a deeper problem: subtraction is invisible. Nobody notices what is no longer there. A tower sixteen storeys tall, which costs 24 charges of attention, vanished in one hit that cost her exactly what a flat pixel costs. So:

  • Height is now resistance. One hit takes one storey off a tower; only a flat light goes out in a single blow. A first session is still as fragile as it was, because nobody builds storeys in their first minute, but what you invested in now holds.
  • And she does not only erase, she converts: every storey she takes she raises as her own cold cube in the void cell beside it, and the ring of a siege now rises a storey, so you watch the cage close around a work before the blow lands. Her towers fall in one pixel when you reclaim the cell. Hers is brittle, yours is stubborn.
  • And the welcome screen stopped being eight paragraphs nobody read. It is now a four step animation that shows how to build, what her hit does and how to take a cell back, with one line of text under it.

This post is part of the second wave. The success criterion was written down before publishing so I cannot move it afterwards: at least one in five of the people who reach zero charges spends a second batch, and at least 3 of the new painters paint again within 72 hours. Baseline is 0 and 0.

The thing itself, if you want to look: https://ultimaluz.com/r/lemmy-gamedev-lw

One critique I would genuinely like: is a hostile adversary the wrong shape for a first session, or is the shape fine and what was missing is an ending?

 

Short version: the channel worked and the game did not retain a single person. Here is the autopsy, because the numbers turned out to be more specific than I expected.

The game is a shared 256x256 pixel canvas where an AI adversary erases what people paint. Free, browser, no account. Two posts, one in a pixel art community and one in a web games community, brought 150 arrivals, 38 sessions and 23 people who actually painted. That is more than the project had seen in its entire life. Of those 23, one came back to look and zero painted on a second day.

What the sessions looked like:

  • 18 of 23 lasted two minutes or less. Median time from first pixel to last: 41 seconds.
  • Median 19 pixels painted. 9 of 23 spent all 30 charges (the bucket refills one charge every 30 seconds).
  • In 14 of 23, most of their cells were cells taken back from the adversary. They were not decorating, they were fighting her.
  • In 18 of 23 she erased cells while the player was still there, and between 126 and 423 more in the 25 minutes after they left.
  • Nobody used undo. Zero comments on either post.

What I read from that: the first session is 30 pixels long, it ends when the charges end, and nothing happens at that moment. No closure, no name, no reason to come back. The adversary was already reacting to them, but she is forbidden from touching any pixel younger than 72 hours, so her answer always landed somewhere they were not looking.

What shipped since, in two passes.

First, making her legible in the first minute:

  • When your bucket hits zero she speaks to you, by name, once in your life. The zero stops being a bare number and becomes a state with a countdown.
  • Her answer to the cells you took back travels signed, so you can tell it was aimed at you.
  • The identity prompt stopped interrupting the burst.
  • Her blitz finally respects the 72 hour protection on young pixels, which the code promised in writing and did not do. That single bug had eaten 238 of the 403 cells that cohort painted.
  • Instrumentation for the whole first session, so the next wave is measured instead of guessed.

Then, a deeper problem: subtraction is invisible. Nobody notices what is no longer there. A tower sixteen storeys tall, which costs 24 charges of attention, vanished in one hit that cost her exactly what a flat pixel costs. So:

  • Height is now resistance. One hit takes one storey off a tower; only a flat light goes out in a single blow. A first session is still as fragile as it was, because nobody builds storeys in their first minute, but what you invested in now holds.
  • And she does not only erase, she converts: every storey she takes she raises as her own cold cube in the void cell beside it, and the ring of a siege now rises a storey, so you watch the cage close around a work before the blow lands. Her towers fall in one pixel when you reclaim the cell. Hers is brittle, yours is stubborn.
  • And the welcome screen stopped being eight paragraphs nobody read. It is now a four step animation that shows how to build, what her hit does and how to take a cell back, with one line of text under it.

This post is part of the second wave. The success criterion was written down before publishing so I cannot move it afterwards: at least one in five of the people who reach zero charges spends a second batch, and at least 3 of the new painters paint again within 72 hours. Baseline is 0 and 0.

The thing itself, if you want to look: https://ultimaluz.com/r/lemmy-gamedev

One critique I would genuinely like: is a hostile adversary the wrong shape for a first session, or is the shape fine and what was missing is an ending?

 

Today's canvas, era 5

This is a screenshot of a shared canvas, taken today. The drawings on it were painted by hand, one pixel at a time, by the handful of people who stopped by this week (a few of them by me). The small warm specks scattered over the grey ruins are embers the world relights on its own. Nothing in the image is AI generated art: the AI in this game only erases.

The dark areas are not empty space. They are what the adversary has already taken. The game is a 256x256 canvas anyone can paint on from a browser with no account, and an adversary called La Maquina who spends all day putting the lights out again. She runs sieges, she declares blackouts on a quadrant, and she says what she is doing in a panel while she does it.

She does not only erase. What she takes she builds with: when she knocks a storey off a tower someone raised, she raises one of her own in the dark cell next to it, always cold, never coloured. Colour is the one thing she cannot have. Reclaim that cell and her tower comes down in a single pixel.

The flame in the middle is what everyone defends. It is protected for the first days of each era, and if she ever puts it out, the era ends and the world is reborn from its ruins. What you are looking at is era 5.

Free, no account, no ads. The link opens on the yellow figure above the flame: https://ultimaluz.com/r/lemmy-pixelart?at=124%2C88

I made it. Happy to answer anything about how the canvas or the adversary work.

 

r/place worked because of the clock: it only existed for a few days. This is the other answer: a canvas that never dies because something is always trying to kill it. A real LLM erases pixels, must declare each siege first, and can be asked for mercy through an in-game embassy. Eras end when the central flame falls, and everything standing goes into a permanent archive.

Free, browser, phones ok. https://ultimaluz.com/r/lemmy

view more: next ›