Pasting a copy of my dev log from my project here https://baronvonzoomie.itch.io/circuitmind/devlog/1528195/dev-diary-3-simple-com...
Dev Diary #3: Closing the Loop — The Combat Foundation
Introduction
This sprint we focused heavily on the core combat feel of the game. It is the foundation of everything combat related that we will implement later on, this include affix system, chassis system, socketing and skill. It is critical that we get this right so that we have a good base combat that player can rely on while they are looking for a good loot.
Binary Flash
The first thing I worked on was getting the player's attack to feel good. The skill is called **Binary Flash** — a two-hit melee combo, the Operative's primary damage tool.
The damage is split 40% on the first hit and 60% on the second. This was a deliberate choice from looking at reference games — a combo that rewards committing to the full sequence rather than hitting once and retreating. You get more out of it if you see it through.
Under the hood, each swing has an active window defined in the animation data itself. When the animator marks a frame as the attack frame, the engine reads it and fires the hit logic at that exact moment. This means the artist controls when the damage happens, not the programmer hardcoding frame numbers. If a swing feels too early or too late, you fix it in the animation file, not the code.

Contact Stasis
As an engineer newly turned game dev, it is a little difficult to convey the feel of a good combat to the player. We know the feeling of holding a sword, and we know the feeling of striking something with the sword, and that is because our senses directly connects with the instrument. As engineers, we don't reinvent the wheel, we look for references, and we look for the right problems to solve. In this case, the problem is, how do we convey the impact of a sword swing hitting something when holding a controller? Luckily this is a solved problem in the game industry, as there are many games such as Devil May Cry 5 and Breath of the Wild that have excellent combat and can serve as reference material. The common factor I found in those games is that when the hits land, the player and the enemy will freeze for few frames, and that is one of the magical ingredient in conveying the weight behind a hit.
In CircuitMind, both the player and the enemy pause for 0.12 seconds when Binary Flash connects. This value comes from our config file so it can be tuned without touching code. It's also limited to melee only — our Arc Blast ranged skill fires continuously, and applying this pause on every tick there would make it unplayable.

Knockback
The other piece of the hit response is knockback — the scout gets pushed back when it takes a hit. This sounds simple but had a tricky engineering problem behind it.
The scout's movement is controlled by a state machine that runs every frame. My first instinct was to add the knockback force directly to the enemy's velocity. But the state machine would overwrite that velocity on the very next frame — the enemy would visually not move at all.
The fix was to add a dedicated knockback method to our motor system. When a hit lands, the motor locks out the AI's movement control for the duration of the stagger. The AI literally cannot override its own stagger while the timer is running. Ground friction then decelerates it naturally so it doesn't slide indefinitely. The force and duration both come from `skills.json`, so dialing it in is just editing a number.

The Scout: The Other Side of the Fight
Building a combat system in isolation is one thing. But for it to feel like a real fight, the enemy also has to threaten the player — not just absorb damage.
The Scout is our first ranged enemy. It doesn't wake up when the player enters the room — it patrols, dormant. When you get close enough, it enters an alert state, then broadcasts a signal to nearby scouts. Those wake up too. Your first engagement can escalate into a multi-enemy situation very quickly if you're not paying attention.
I found this pattern in a lot of games I admire — enemies that communicate, that don't just react individually. It makes the world feel like it's actually coordinating against you rather than waiting in line.

Once in range, the scout fires a projectile. The muzzle flash and bullet both spawn from the gun itself — there's an anchor point on the attack animation that tells the engine exactly where the barrel is on that frame. Small detail, but it reads much more clearly than spawning everything from the enemy's center.
When the projectile hits the player, it drains poise. If poise drops to zero, the player's hurt animation triggers. That closes the loop — the player is now the one reacting instead of the enemy.
Audio
Two sound effects anchor the combat feel this sprint.
The sword swoosh fires on each swing's active frame — the same frame that triggers the hit logic. I originally had it playing when the skill executes, which meant the sound played before the blade even moved. Tying it to the active frame made it feel immediate and physical.
The hit sound fires when damage lands. To avoid the same sound repeating identically every hit, we apply a small random pitch shift each time. The range is narrow enough that it doesn't sound strange, but wide enough that repeated hits feel like separate events rather than a loop.
Both sit inside the vertical audio layering system from Dev Diary #2. When combat starts, the action layer comes to full volume and the calmer layers pull back.
The Full Loop
What's Next
With the combat foundation in place, the next two things on the list are the Inventory UI and Skill Ranks.
The loot system already generates items when enemies die — but there's no screen to put them in yet. That showcase is saved for when the inventory UI is ready, because seeing an item land in a slot is the actual payoff, not just the drop.
Binary Flash also currently runs at Rank 1. Rank 2 unlocks attack-to-dash and dash-to-attack canceling, which opens up a much richer combat expression. That's waiting on the rank system to be built first.
Thanks for following along.
— BaronVonZoomie