Birdoggydog's Builds

Adding a wounded idle to a Godot body without rebuilding it

Carl now stands bent over a stab wound in an 8 second looping clip that lives in a JSON file beside the human body. I asked for him to sit instead.

After the surgery scene, Chief Scientist Carl now stands bent over a stab wound. It’s an 8 second loop. He’s bent 41 to 51 degrees at the chest with his right fist pressed to his left side, and his left arm hangs. He takes four shallow breaths and winces once per loop. You can talk to him in it and he gives the facility key from it.

I don’t think the pose is right yet. I watched the film and said I like the animation, but he should be sitting on the ground leaned against the wall, and he should have blood on him. That’s next.

29 seconds, captioned. Carl by the chest from across the aisle, a walk up to him, one loop from his side, the talk open while he stands bent, then the old stooped idle beside the new one.

Before this he stood by the chest in the tired idle, which is just a stoop. I’d asked for a real hunched or slumped pose now and not later.

Why isn’t the clip in the body’s file?

The obvious place was the human body’s .glb, with a new row in the motion table. That means rebuilding and reinstalling the human body. Every garment fitted on a body names the body’s bytes, so changing it would change 32 human wear pieces and the 3 human heads too, and another agent was in the wear kit at the time. So the clip lives in a file beside the body and gets added when the game builds a figure.

tools/clip_to_game.py human idle_wounded converts the made clip into assets/motion/human/idle_wounded.json, 74 KB. It holds each bone’s turn as a quaternion, with a key every 2 frames (12 per second, and the game eases between keys because an idle moves slowly), plus the hips’ movement. A --check flag fails if the installed file isn’t the made clip.

FigureClips reads those files. It makes an Animation from each clip a body lacks, with tracks named after the skeleton path and the bone, and adds it under the name the body’s bake would have given it, AN_frame_idle_wounded. The imported scene’s animation library is shared by every instance of the body, so the figure gets a copy of the list and the clip is added to the copy. Everyone else’s body reads as it was imported. When the body is next rebuilt for another reason, the clip goes into it and I delete the side file. A clip the body already has is skipped, so nothing else changes. Three lines in NpcFigure._build() call it, and Carl’s figure word changed from human/01/tired to human/01/wounded.

Only human NPC figures get the clip, because a monster’s clips come from its manifest. The head has no clip with that name, so the jaw stays at rest, though the face animation still runs.

How was the pose made?

It’s a base idle, a_idle-loop, with 14 layers on it, 192 frames at 24 per second. The wince is at 0.58 to 0.85 of the loop: the chest goes 7 degrees further, the spine 4, the head drops 14 and the hips sink 12 mm. The hips sit 10 cm back and 8 cm down the whole time.

I decided on standing and bent, not kneeling. The pipeline’s clip step keeps the soles planted, and standing leaves his head at 1.32 m, so the party’s eye at 1.6 m still finds his face. The game has no dialogue camera, so the talk is just the party’s view. I tried bracing his left hand on his thigh, but it looked like an arm flung back, so it hangs.

tests/figure_clips has 34 checks. Through the loop both feet stay where the stoop’s feet stand, off by 0.70 mm at most. The loop’s seam is a step of 0.16 degrees against 1.16 for the largest other step. His right hand stays within 26.8 mm of its place on his belly, with a limit of 35, and the head bone is 1.32 m up and 0.21 m out from his feet. All 34 pass.

I only judged it from still frames. How smooth the breath and the wince are in motion I haven’t checked.