26 July 2024
The last update was all about entities, this one is all about the rooms they run around in.
Last time I said next time I'd change the floor level to Z=16 to fix a few problems. That went just fine and now the player walks on top of the lowest layer of blocks, which will make falling into holes in the floor easier to handle too. I also fixed (finally?) the isometric sorting problems. I didn't look at conveyors yet though.
I had hoped to take the game to Kickstart 02 in a semi-playable state, but various life things prevented me from working on it much for much of May and June (and July) so it was not to be. I tried getting it running on my Retroid Pocket 3+ but it refused to boot from floppy and I didn't have enough time in the airport on the way to Kickstart to figure out what was wrong. I still haven't, but at some point I will have to make the game more OS-compatible. It's likely to outgrow a floppy and will need a savegame feature so hard disk compatiblity will be important.
In that airport hacking session I also tried playing in the very tall and very long test rooms, which, naturally, immediately crashed. The engine supports up to 4096 blocks per room and rooms can be any power-of-two sized cuboid shape that comes in under that total, so I had set up two extreme rooms as 8x8x64 (tall) and 16x128x2 (long). Silly me, assuming there would always be blocks at screen x=0 and that the player couldn't jump out of the blockmap.
Getting these rooms working standalone led, almost by accident, to what turned out to be the main push of this update - doors and moving between rooms.
It took a while to figure out how best to add rooms to the map in Tiled. Visually, doors take up multiple blocks, and I didn't want to have to manually tag every block in every door with various identical parameters. I couldn't create a single object that was as large as the door aperture without things getting weird, and neither could I link doors to destination doors in other rooms. Thanks, Tiled.
After some experimentation, I settled on drawing doors with regular blocks, then placing a block-sized door object in one corner with the appropriate parameters (direction, target etc.) set on it. The build scripts and runtime massage this object so it's collider centres in and extends a couple of points beyond the visual blocks that comprise the door, and default all of the other parameters to save a lot of manual setup. Defaults can of course be overridden for special cases like multiple potential target doors, or specific positions I want the player to enter at, and so on. It works very nicely. Even for secret doors to secret rooms containing secret things. Ssh!
One trick I pulled is to fake the door recesses. The engine supports them, of course, but it would require tagging the surrounding blocks for isometric sorting. Super tedious and a performance hit. Instead, the door blocks fill the entire space and only look recessed. The door triggers when the player enters its collider which - remember - extends a little beyond the blocks, so the player never actually enters the recess. It looks fine in play and I think I can get away with it!
=> [IMG: Do Not Cross The Eastern Red Line]
A final wrinkle was handling "south" and "east" doors. They appear as little steps at the edge of the room to indicate there is an exit. Rather than creating a wall of invsible blocks or whatever to stop the player walking off the floor beside these steps, I simply clipped the player movement bounds for these rooms instead. The door collider extends a couple of points into the room so it activates just before the player reaches the boundary, consistent with the other door directions.
The transitions between rooms were a challenge. Every room unpacks its assorted map and graphical assets on entry which, depending on the room, can take several seconds on a 7Mhz machine. Fully rendering the room takes a number of frames on top of that too, and the freeze while this is all happening is quite disruptive to the flow of play.
Initially I tried rewriting the room setup processes in a "coroutine" style to run step by step along with a fade-out to distract from the delay. This worked all right, but the code was complicated and the duration of each step would vary unpredictably making the fade uneven. Not ideal.
Of course, after I'd got this all working and spent some time frobbing to even out the step durations, I realise I could have left it all as it was and simply run the fade at a guaranteed steady speed on the vertical blank interrupt instead. Idiot (in my defence, I think I've had Covid this week!). A couple of quick reverts later that was in place and worked perfectly.
There was one bug that took a while to track down where the background restore process would fire a stray blit into the new room's bitplanes as they were being rendered. I think it was racing with the room rendering so it didn't manifest every time. Parallelism bugs are always tricky, even on retro machines.
=> [VID: Room By Room] | [VID: Room By Room (YouTube)]
Putting it all together, the player can now freely move around the map. It's looking more like a game now!
I think this is a real milestone point. Perhaps the end of the initial engine development? It feels like it might be time to start building out the first actual rooms and implementing entities and features as they crop up. Once that starts, it probably won't be too long before it's obvious what the game actually is...
I'm sure I'll find new and exciting bugs as well.
=> amiga This content has been proxied by September (3851b).
=> devlog
=> gamedev
=> isometric
=> retroProxy Information
text/gemini;lang=en