Working on actors being able to trigger scene transitions. In the case of these doors: when no scene trigger is defined, they change their animation to reveal only a brick wall behind them when opened.
Work Since Last Devlog
Platfomer Movement, Collision Detection
Okay, so I caught most of the remaining actor-to-tilemap collision and placement problems, and I have a good idea of which layouts to avoid. I ended up returning to the “fan out from middle” collision check that excludes solid floors if they’re 100% covered by slope tiles. There are only a few remaining issues:
- Some very short-and-wide hitboxes can phase through walls that are at the top of a steep incline. In this diagram, the two leftmost hitboxes on the bottom row will pass through the wall when they travel up the slope to the right:
- Slope tiles that don’t connect to solids at the seams of the tilemap behave poorly in general, but they can cause short-and-wide hitboxes to completely fall through the ground.
I can live with these. The main thing that was absolutely driving me up the wall, and which is now fixed, was hitboxes snapping to slopes when they terminated at seams one row below, like this:
I have these small spherical characters that I’m using to test the slopes. I made them bounce against orthogonal walls by inverting their velocity on a given axis, but I wasn’t able to make the bounces against sloped tiles look correct. I found this Allegro forum post really helpful, as it steps through the entire process from a 2D game programming perspective. I uploaded a snippet of Lua code here.
Besides actor-to-tile collision checks, I also started working on actor-to-actor checks. In the scene tick function, I added a separate collision detection loop which happens before actors are processed. This removes the drudgery of explicitly checking for collisions within the actor behavior scripts. I started working on a spatial partition to limit collision checks by location, but things are running OK with about 100 actors in a scene, so it’s probably not worth pursuing unless it’s truly needed for performance.
Scene Management, Maps
Added support for the horizontal and vertical flipping flags for objects in Tiled. These parameters are stored in the high bits of the object’s GID value, and need to be separated out from the GID when importing. This is pretty straightforward in C/C++, but Lua doesn’t have built-in bitwise operators. Thankfully, LuaJIT includes a nifty library which implements them.
I revisited actor creation and destruction, and added a simple table-pooling system so that actors don’t generate and discard sub-tables every time they’re instantiated and removed. Each scene gets its own set of data pools:
- The sprite animation instance
- A general-purpose “data” table
- A “stack” table, not in use now, but would be used for reading incoming messages from other actors
- An “overlap” table, which tells the actor which other actors were intersecting it at tick start
- A “services” table, which contains a list of cleanup functions for automatically releasing external pooled tables when destroying a given actor. This table is populated as different services or toolkit files are installed into an actor which require additional state.
I added an option to pre-allocate tables in a pool upon creation, but I’m not sure if it’s doing much.
Fixed a long-standing issue with sprite placement. Sprites in older versions of the engine contained XY offset values, which were applied to the upper-left corner of the host actor’s hitbox. Now, both the actor and the sprite / animation have XY coordinates that are used to anchor the graphic to the hitbox exactly where it is needed.
I don’t have much to comment on this week, other than that I’m so glad I’m finally over that collision detection hump. Although there’s still a lot more to get done, I think I’m ending September in a pretty good state.
Plans For Next Post
- Uncomment that unused messaging system and get inter-scene actor communication working.
- Improve UI and widget system. Make a title screen and title menu.
- Fill out October section of planning page