Testing camera zones with different scrolling rules on a test map.
Work Since Last Devlog
Figured out how to make a Tiled tileset as a “Collection of Images” so that spawnpoints can have proper full graphics representing the actors they spawn. Tiled has a small implementation quirk where the origin of image rectangles is always bottom-left, so if you want the origin to be upper-left or center, you have to adjust the XY values when feeding the data into your game. Not a big deal, just something to look out for.
Scenes and Actors
Added additional test scenes so that I can work on the code to transition between different areas. Early builds of Hibernator had scene-switching functionality, but it wasn’t really a planned feature for that game. When switching from a scene in the middle of processing actors, the loop iterator value is now stored and retrieved upon returning, so that actors don’t go out of sync.
Started adding Lua colon-syntax methods to actors and scenes, so that their per-tick code is easier to think about. Lua has no built-in class system, and ‘my_object:doThis()’ is essentially shorthand for ‘my_object.doThis(my_object)’. Besides being easier to write, it also means I don’t need to require() a dozen core source files within every single actor script.
Rewrote some of the resource initialization code so that actor templates and scenes are instantiated during the call to love.load(), and not whenever actor.addTemplate() or scene.add() are invoked in the project source. I also added an init function to scenes so that they can add actors and set up custom values at love.load().
Added a simple way for actors to get table references to other actors, for the span of one tick, and ensure that it’s fresh by comparing a serial number instead of searching for the actor on every single tick. This would backfire if hundreds of actors constantly attempted to look for another actor that doesn’t exist, but I think this should be OK for now.
Thanks to some of the above changes to scenes and actors, the path is finally clear to work on camera controls! I added another object layer to my Tiled maps to hold a set of rectangles with additional custom properties. When the camera’s target is within a rectangle, the camera behaves according to the rules set up for that zone. I’m pretty much just using them to create scrolling breaks for now, but they could be extended to change how close the camera follows the player, anchor one axis along a line with linear interpolation, etc.
Here’s an example of different scrolling breaks on different planes of the same screen. Both the upper plane and lower plane break scrolling on the left side, and the lower plane blocks scrolling back on the right side:
I dug into the player’s platformer code again this Saturday, but made only modest progress on the diagonal slope problems that have been plaguing the engine for quite a while now. At the very least, I fixed a problem where the player would warp one tile into the air when standing at the foot of a hill, so you can now walk along slopes without it looking too erratic. But… that’s not good enough. There is still a problem where the player can’t stay grounded at the top of hills, and sometimes, you can conspicuously walk on air as you descend slopes, if you hit them a certain way. The assumptions I made in Hibernator don’t work well with use cases more complicated than square walls and ladders.
It needs an overhaul. The solution I’m trying right now is to build up a secondary player actor — a minimalist object that only has the platforming features that are messing me up. No animation junk, no acceleration while walking or falling, no jump arc management, just the barest movement possible, and collision detection and resolution.
Once I got the basics of Player 2 working, I started converting logic blocks from both players into methods in the collision detection module, and importing them back in. So far it’s working really well! I caught an off-by-one issue with hitbox dimensions, which has likely been hiding in the code ever since Hibernator. I’ve converted all of the basic actor-against-square-tiles collision code over, and there’s now a proper separation between detecting and resolving. Next I have to deal with one-point platforms, including the slopes.
Added outline and shadow options for when drawing text onto the screen, using the inefficient “draw it black a bunch of times and then draw it again” method. I wrote a function to modify the imageData before creating the font, but I forgot about those separator lines in the ImageFont format. I’m guessing that ideally this would be done as a shader. Oh well.
I’ve noticed an occasional frame stutter when playing a piece of music in-game for the first time since booting my PC. After the first play, it doesn’t stutter like that again for the remainder of the OS session. Turns out I wasn’t loading all music at init time, but the play function checked and loaded tracks if that hadn’t yet been done. I’ve fixed that, but the fact that the stutters weren’t reoccurring after closing the program and re-opening it suggests that maybe there is some kind of disk caching issue going on. So I’ve also included a function in the init code which sequentially plays every BGM and SFX at volume 0.0 and then immediately stops them. I’ll check if it fixes the issue next time I restart my PC.
I said I would put a roadmap (I guess more accurately, a task list) on my wiki last week, but I got completely caught up in revamping the collision detection code and now the week is over. Getting this fixed ASAP is probably the best thing I can do right now. I’m going to be so pumped when I finally get those little rolling happy-faces sliding downhill, and then back uphill, and then downhill again, over and over, left, right, left, right, left oh no it stopped.
Plans For Next Post
- Finish up this collision detection stuff!
- Do the roadmap thing