Procedural pressure plates
This week's focus was traps, graphics and animations. Most important being the ubiquitous pressure plate. Pressure plates are normal looking tiles, which when pressed, do something: trigger traps, open doors, being elements of puzzles, etc. Now here's the tricky point: "normal looking tiles". How do we represent that?
- If tiles were rendered individually, I could push these tiles a bit further back, to simulate a recess or dent. But the current render process is fully 2D, plus if I pushed the tiles back, there would be some minor void to fill
- Make regular sprites. A regular sprite fits nicely in the pipeline, but given that plates are placed procedurally pretty much anywhere, then the sprite has to look good and also work well with any terrain underneath.
- Make it a shader effect. I was tempted, but it would complicate and slow down the rest 99% of the sprite rendering.
- Make sprites dynamically based on the tile(s) underneath. Let's see how that works.
I've recently added support for dynamic texture atlases (sprites can be dynamically added and removed from there), for use with composable sprites, in order to cache the compositions (e.g. player with beard, a sword and a shield). So, it wasn't a huge jump to add another atlas for miscellaneous dynamically created sprites, such as pressure plates.
When a pressure plate entity is created, we look to see if there are explicit sprites for it, for its 2 states: unpressed and pressed. If there are not, we generate them automatically. How?
- Get the underlying floor sprite, and if there is one, the floor overlap sprite (exists where zones connect, for nice transitions)
- Create a name parameterised on the sprites, e.g. "pressure_plateunpressed{floorsprite}{floor_overlap_sprite}"
- Look up in the dynamic texture atlas if it already exists. If it does, get it, otherwise create it
- Create it by pushing pixels diagonally (1 pixel away for unpressed, 2 pixels away for pressed) to simulate the recess
- Fill the void with a common dark grey color
This seems to work fine! Sprites might need to be regenerated every time we reload the current level or change to a different level. Because this is a per-level process, the number of sprites to be generated would be pretty low, e.g. I foresee a max of 10, so there's no performance issue looming.
Hazardous intelligence
A little bit of work went to make the pathfinding and AI code a bit more granular in terms of hazard avoidance. Hazards are split into environmental and man-made (sort of) and avoidance depends on intelligence. A mindless creature does not avoid hazard. A dumb beast avoids environmental hazards but doesn't avoid pressure plate traps, whereas a sapient creature does. So, this part of AI is driven purely by the intelligence attribute score.