Hey guys, Let's talk about animation systems. Animation Trees and AI Interaction Last time we concluded the AI refactor portion of this upcoming update, this month we took a pass at the animation system that's interconn
In this update2
Full notes
Full Ascent of Ashes update
Read the full published notes in a cleaner layout. The original post stays linked below.
Repeated intro
Hey guys,
What changed
0 fixes3 additions4 changes0 removals
Events
Performance
Gameplay
changedAnimation Trees and AI InteractionLast time we concluded the AI refactor portion of this upcoming update, this month we took a pass at the animation system that's interconnected with the AI. Until now we've been using Godot's built-in animation tree to handle transitions and playback. You can think of an animation tree as a series of branching animation nodes, transitions and blend values that are combined together to calculate a final animation. This allows for easy layering of different animations for upper and lower body, smoothing cross-fades, etc. To control this tree structure, AI systems would send transition requests to the animation system to trigger animation changes, then listen for callback events that happened at certain frames in the animation to trigger gameplay behavior (for example picking up an item for hauling midway through a pickup animation). The transitions themselves were processed internally by the animation tree based on its node setup.
addedAnimation Trees and AI InteractionWhile such a basic implementation works for most games, our case is a bit more complicated. For one, due to the mechanical complexity of our game, there's a lot of different animations that our AI agents need to play. This is further amplified by the fact that agents can be in one of multiple stances, which need their own layer of animations, transitions and so on. The combat system adds several major challenges, needing to layer its own internal state on top of other AI behaviors. With multiple systems vying for control over the animator, keeping track of all the different transitions, reset points and parameters was becoming increasingly difficult, rendering the entire setup prone to bugs. And since other systems were relying on animations to send callbacks before triggering gameplay events, every time a bug occurred it would leave the AI permanently stuck, waiting for signals that would never come.
changedAnimation Trees and AI InteractionImprove fallback behaviors in case of internal errors so a few missed frames or a misconfigured event don't result in permanently stuck AI.
addedAnimation Trees and AI InteractionPrepare the system to support more complex gameplay states involving upcoming new features too complex to implement under the current framework.
changedAnimation Trees and AI InteractionThe first big change we made was to completely decouple gameplay state and rendering. Rather than gameplay systems requesting transitions and waiting for callbacks from animations, the AI, combat and stance controller calculate their own internal state with no regard as to how it is visually represented. This means that each of these systems can be completely encapsulated and isolated, and so long as that section of code works there's no risk of external factors messing things up. Suffice to say this makes development and bug hunting significantly easier.
changedAnimation Trees and AI InteractionSimilar to our AI refactor we've decided the AI agent should act as a central conduit for gathering up all rendering-related information and sending it down the pipe. It collects all relevant data about its own state, from current AI behaviors, stances, equipped items, special override states like stun/unconsciousness and puts it into a format that can be easily passed to the renderer. The renderer in turn takes these gameplay parameters and translates them to the animation tree, setting animation parameters and blend values as needed. Here we treat game state as authoritative, meaning if for some reason visuals are out of sync with game state we simply override them and force the animation directly to where it ought to be. That means incorrectly configured code can result in skipped frames and transitions, but that's significantly better than survivors getting stuck in infinite loops trying to pick items off the ground.
Ascent of Ashes changes
changedLast time we concluded the AI refactor portion of this upcoming update, this month we took a pass at the animation system that's interconnected with the AI. Until now we've been using Godot's built-in animation tree to handle transitions and playback. You can think of an animation tree as a series of branching animation nodes, transitions and blend values that are combined together to calculate a final animation. This allows for easy layering of different animations for upper and lower body, smoothing cross-fades, etc. To control this tree structure, AI systems would send transition requests to the animation system to trigger animation changes, then listen for callback events that happened at certain frames in the animation to trigger gameplay behavior (for example picking up an item for hauling midway through a pickup animation). The transitions themselves were processed internally by the animation tree based on its node setup.
addedWhile such a basic implementation works for most games, our case is a bit more complicated. For one, due to the mechanical complexity of our game, there's a lot of different animations that our AI agents need to play. This is further amplified by the fact that agents can be in one of multiple stances, which need their own layer of animations, transitions and so on. The combat system adds several major challenges, needing to layer its own internal state on top of other AI behaviors. With multiple systems vying for control over the animator, keeping track of all the different transitions, reset points and parameters was becoming increasingly difficult, rendering the entire setup prone to bugs. And since other systems were relying on animations to send callbacks before triggering gameplay events, every time a bug occurred it would leave the AI permanently stuck, waiting for signals that would never come.
changedImprove fallback behaviors in case of internal errors so a few missed frames or a misconfigured event don't result in permanently stuck AI.
addedPrepare the system to support more complex gameplay states involving upcoming new features too complex to implement under the current framework.
changedThe first big change we made was to completely decouple gameplay state and rendering. Rather than gameplay systems requesting transitions and waiting for callbacks from animations, the AI, combat and stance controller calculate their own internal state with no regard as to how it is visually represented. This means that each of these systems can be completely encapsulated and isolated, and so long as that section of code works there's no risk of external factors messing things up. Suffice to say this makes development and bug hunting significantly easier.
Let's talk about animation systems.
Animation Trees and AI Interaction
Last time we concluded the AI refactor portion of this upcoming update, this month we took a pass at the animation system that's interconnected with the AI. Until now we've been using Godot's built-in animation tree to handle transitions and playback. You can think of an animation tree as a series of branching animation nodes, transitions and blend values that are combined together to calculate a final animation. This allows for easy layering of different animations for upper and lower body, smoothing cross-fades, etc. To control this tree structure, AI systems would send transition requests to the animation system to trigger animation changes, then listen for callback events that happened at certain frames in the animation to trigger gameplay behavior (for example picking up an item for hauling midway through a pickup animation). The transitions themselves were processed internally by the animation tree based on its node setup.
While such a basic implementation works for most games, our case is a bit more complicated. For one, due to the mechanical complexity of our game, there's a lot of different animations that our AI agents need to play. This is further amplified by the fact that agents can be in one of multiple stances, which need their own layer of animations, transitions and so on. The combat system adds several major challenges, needing to layer its own internal state on top of other AI behaviors. With multiple systems vying for control over the animator, keeping track of all the different transitions, reset points and parameters was becoming increasingly difficult, rendering the entire setup prone to bugs. And since other systems were relying on animations to send callbacks before triggering gameplay events, every time a bug occurred it would leave the AI permanently stuck, waiting for signals that would never come.
Having reached the limit of what our current setup can do, and with more involved combat behaviors on the way, it became clear that just like the AI, animations needed an overhaul. We had three main goals here:
Simplify control flow to make debugging and future development easier.
Improve fallback behaviors in case of internal errors so a few missed frames or a misconfigured event don't result in permanently stuck AI.
Prepare the system to support more complex gameplay states involving upcoming new features too complex to implement under the current framework.
The first big change we made was to completely decouple gameplay state and rendering. Rather than gameplay systems requesting transitions and waiting for callbacks from animations, the AI, combat and stance controller calculate their own internal state with no regard as to how it is visually represented. This means that each of these systems can be completely encapsulated and isolated, and so long as that section of code works there's no risk of external factors messing things up. Suffice to say this makes development and bug hunting significantly easier.
Similar to our AI refactor we've decided the AI agent should act as a central conduit for gathering up all rendering-related information and sending it down the pipe. It collects all relevant data about its own state, from current AI behaviors, stances, equipped items, special override states like stun/unconsciousness and puts it into a format that can be easily passed to the renderer. The renderer in turn takes these gameplay parameters and translates them to the animation tree, setting animation parameters and blend values as needed. Here we treat game state as authoritative, meaning if for some reason visuals are out of sync with game state we simply override them and force the animation directly to where it ought to be. That means incorrectly configured code can result in skipped frames and transitions, but that's significantly better than survivors getting stuck in infinite loops trying to pick items off the ground.
What's Next
So far most of our work on this update has focused on technical aspects, under-the-hood improvements and software architecture, but our ultimate goal is to prepare these systems for actual gameplay features. With the animation refactor done, we can finally get to work on just that. One of the main things we're adding is the ability for survivors to shoot while moving, along with facing controls to let you set a particular direction you want them to watch. Corner leans are another planned addition enabled by the updated animation system, as are weapon draw/holster animations and a new prone state. Once we've ironed out the last remaining visual issues introduced by the overhaul we should be able to showcase some of the new gameplay in a future video log.
That’s it for today. Until next time, stay safe and keep surviving!