September: The Swing Finally Played, and I Stopped
The short version
I found the second fault hiding under the first, and the sword swing finally played. A few days later I put that game down and started a different one.
August ended with a fix that changed nothing. I had filled the empty list that was swallowing every sword swing in my game, measured it filled, and the swing still didn't play. September started there.
ONE FRAME OF THE GAME
part 1 (swinging) writes swing = ON
part 2 (idle) writes swing = off
part 3 (idle) writes swing = off
|
v
the animation reads the switch
after all three have written
it reads: offThe second fault
Veronica's weapon is a three hit combo, which in the engine means three separate weapon parts sitting on one object. My guess was that my fix had repaired a part that was resting while a different one did the swinging. That was wrong.
Every frame, the engine asks all three parts to update the animation, not just the one that's firing. Each one writes the same swing switch: on if it's swinging right now, off if it isn't. So on the one frame the first part swings, it writes on, and then the two idle parts write off in the same pass. By the time the animation reads the switch, the last word on it is off.
I proved it by switching the two idle parts off while the game was running. The same button press swung. The engine's demo weapon never hits this because each of its parts gets its own switch. I had made mine share one switch the week before, to fix something else.
The fix was one file. When the combo moves to the next hit, the parts that aren't holding the weapon get switched off, so only one part writes at a time. I measured it twice and the swing clip played all the way through, then the second hit played its own.
Fixing the first of two stacked faults looks exactly like fixing nothing.
The honest gap
Everything above was measured by a recorder inside the game printing one line a frame. I never sat down and played it. After a month of work aimed at seeing a swing land, I had still not watched one with my own eyes.
The wall
On 11 September I said I had hit a wall and was thinking about a pivot. I'm not going to dress that up. A month of the work had been finding out that things I thought worked didn't, and the part I actually wanted to judge, how the fighting feels, kept moving further away.
So I stopped, and I did one useful thing before I left. I cleaned the project up so that it could be picked up again: every loose branch merged or listed, the main line brought up to date, and one document that explains the whole project in one place, written from the logs rather than from memory.
What I started instead
Five days later I started a new game called Crawler Manager. It's a satirical manager game set in a televised death dungeon. You don't fight. You are the agent for one crawler who fights for herself, and the network pays more when she almost dies.
The way I'm building it is the lesson from Ginger turned into a rule. All the game's numbers live in a plain code layer with no game engine in it at all, and it has its own tests. The engine only draws what that layer says. In Ginger I kept judging the result through parts that were silently broken. Here, a fight can be run a hundred times and counted before anything is drawn.
By the end of September I had moved the drawing side from Unity to Godot, for a reason that comes down to which version of C# each one can run, and the game layer had 577 tests passing. None of it was fun to look at yet. That was the point of building it in that order.
Brian Franke
brian@coasterlogic.com