David here again!
In Thimbleweed Park 1, there was large puddle the actors walked through, and we saw splashing around their feet, and heard splashing for each step. I’m going to talk about how we did that by setting up room triggers and turning on a special animation layer in the actor’s animation file.
Triggers
In the Dinky engine, triggers are quadrilaterals on the screen, usually placed somewhere in the area where the actors are going to walk. When an actor enters a trigger, the triggerEnter() function is called, and when they exit the trigger, the triggerLeave() function is called.
Triggers are added using our room setup tool, Wimpy. We add a generic object, indicate it’s a trigger, and adjust the four corners of the quadrilateral to match the desired trigger area. More on this below.
Animation Layers
In my last blog post on animation, I mentioned we could have multiple layers for things like hats, heads, nose glasses. We also used layers for splashes.
In the above screenshot you can see all the layers that make up the basic Agent Ray animation, including one for eye blinks (the blink is made up of a few pixels which cover her eyes), eyes looking left or right, a collection of six heads that each have a different mouth shape (maybe we’ll go into lipsync in another blog), and near the bottom, you see the splash layer.
There’s also a layer near the bottom called _trigger. This has nothing to do with room triggers, but is a flag we can set to trigger a sound effect (footstep), or some other event we need synchronized with the animation.
The _floor layer is for reference only, and helps us align the actor to where the floor will be. I have it turned off in the above screen capture.
The splash animation is made up of three frames. We position the frames over the actor’s feet, timed to the moment the foot hits the ground (or water).
Here’s the splash animation of Agent Ray.
Trigger Code
Now that we have the animation working, here’s the code to turn on and off the splash layers on Agent Ray. splashTrigger is what I named the room trigger in Wimpy:
splashTrigger = {
function triggerEnter(actor) {
footstepsWater(actor)
}
function triggerLeave(actor) {
footstepsNormal(actor)
}
}
and elsewhere we have the actual footstep functions:
function footstepsNormal(actor) {
actor.footstep_sound = actor.footstep_save
actorShowLayer(actor, "splash", false)
}
function footstepsWater(actor) {
actor.footstep_sound = SOUNDID(footstep_water)
actorShowLayer(actor, "splash", true)
}
function footstepsGrass(actor) {
actor.footstep_sound = SOUNDID(footstep_grass)
actorShowLayer(actor, "splash", false)
}
Each actor has a default footstep, and we save that off in the footstep_save variable for each actor.
The actorShowLayer command turns on and off the specified layer.
I threw in another function above, footstepsGrass(), where I was testing out the sound of walking on grass and added another room trigger area over the grass outside the Nickel News.
Finally, we have a system function that is called when there’s a _trigger in the animation, as I described above. Again, this is a different kind of trigger from a room-defined trigger quadrilateral. For animation events, the _triggerEvent() function is called.
function _triggerEvent(actor, event) {
if (event == "@step") {
local sid = actor?.footstep_sound
if (sid) {
playSoundAt(sid, actor)
}
} else {
if (is_function(actor?.triggerEvent, 1)) {
actor.triggerEvent(event)
}
}
}
The event name in Aseprite for footstep _triggers is “@step”. If there are other event names in the animation, the else portion of the code is run, but only if the specified actor has its own triggerEvent code. For example, the Sheriff from Thimbleweed Park 1 had an animation of flipping a coin, and this is the code that’s triggered when that event is detected in his animation:
function triggerEvent(sound) {
if (sound == "@coinFlip") playSoundAt(SOUNDID(coin_flip), sheriff)
}
Here’s what the splash animation looks and sounds like in the game. I don’t have a puddle here, but I’ve made the trigger quadrilaterals visible for you to see.
– David Fox

Comments:
Twice the work, but double the pride :-)
Add comment: