REC  CAM 00 · POST-MORTEM OCT.13 – OCT.21 2026 · MAIN 87992cd

First passreviewed

A beat-synced gun-fu prototype set in a Kowloon tower. Nine days, one player, six agent sessions and one orchestrator. What got built, what broke, and what to fix first next time.

The AI orchestrator that ran the coding sessions wrote this review for Josh at the end of the art and look pass, which is why it says "you". It is posted as written, with CAM 11 brought up to date. The project page has the game.

The game's wet market floor seen through a CCTV camera: the player in a long coat with a cyan beat ring under him, grunts approaching, OSD text in the corners reading REC CAM 18-A, FLOOR 02, and THREAT: GUNNER, DODGE, SHOOT OR EXECUTE.
CAM 18-A · Floor 02, the wet market, as Josh plays it: ?look=cctv&anim=1
652
commits on main
9
days
310
browser checks
220
unit tests
83
merges
$21
spent in total

CAM 01Summary

The short version

There is now a playable slice. You start at a CCTV monitor wall, calibrate, and fight up five floors of a tower: a courtyard, a wet market, tenements, a plant room and a rooftop. Every press is judged against the beat on the audio clock. Light, heavy, gun strike and shot make three-press figures. Kills open film cuts with a kill-cam replay. Eight generated characters share one 66-joint rig, and each floor has its own room sound.

"I think in terms of difficulty it's pretty fun right now."

Josh · Oct 20, after a 175-press run

"That feels way better with your anti-mash fixes."

Josh · Oct 20

"That facing fix looks good to me! Plays well now."

Josh · Oct 21

The one lesson

The 310 browser checks proved that the code did what the agents meant. They did not prove that the game looked, sounded or felt right. In the last two days your play found the three biggest problems: the model turned 90° to 180° off its target, mashing worked as a strategy, and finisher cuts looked disjointed. No gate caught any of them. Five of the six sessions named this same gap in their wrap-ups, without seeing each other's.

On October 20 we changed the method because of it. Background sessions finished what they had in flight. New work ran one piece at a time: you play and point at the problem, a fix goes on its own port, you confirm it there, then it merges. The anti-mash rule was built and confirmed that way in one sitting.

CAM 02TimelineCommits per day

Nine days

Commits on main per day, October 13 to 21: 21, 61, 77, 29, 24, 75, 233, 114, 16. 21OCT 13 6114 7715 2916 2417 7518 23319 11420 1621
  1. Oct 13
    Setup and the vision spec. The action map for keyboard and DualSense. Game time comes from the audio clock. Slices 1 to 6: combat, the diegetic beat ring, waves and floors.
  2. Oct 14
    Enemy types, onboarding, the difficulty ramp, music per floor, the save schema. Timing research sets the ring to travel linearly and stop dead on the line.
  3. Oct 15
    Lock-on, the half-beat grid, execute aimed by flick, formation rows, enemy polish, pacing and director passes. The animation prototype passes.
  4. Oct 16–17
    The pistol on R2 and execute on R1. A mannequin in the game behind ?anim=1. The animation design log: escalation by judgment, gun strikes in figures, beat-locked locomotion.
  5. Oct 18
    Animation stages 2 to 9 in one day: the move editor, stances, locomotion with foot locks, retargeting, content and presentation. The CCTV look is planned. The decision log starts.
  6. Oct 19
    Parallel sessions start, and the busiest day by far. The gate lock goes in. Slice flow A to D, blood, the OSD and post pass, the environment kit, the first generated cast, the sound feed. You turn the setting grounded: "less on the cyber element".
  7. Oct 20
    The grounded pass. The Rodin cast for $19. Your timing spec and the follow table. Anti-mash. You ask whether supervising agents is still worth it, and the foreground loop starts.
  8. Oct 21
    The facing fix, the stance fix, the reach warp, the pistol-whip grip, the spawn overlap fix, lens blood order. You call the first pass complete.

CAM 03What shippedBy area

What you play now

AreaWhat you see in playCommitsChecks added
Combat and feel
orchestrator, first coder
Beat judgment on the audio clock, your follow-table timing (light 1, heavy 2, gun 0.5), 3-press figures over L, H, G and S, parry, counter, dodge, execute. An early press now costs the combo and half a beat.—smoke 1–74
Animation
session 54
The 66-joint rig with a move editor, stances and foot-locked locomotion, kill-cam replays. This pass: correct facing after replays, the stance turned 37° back to the target, strikes that reach the body (warp up to 0.5 m), smoother chains, no enemy spawning inside you.11anim-smoke 51–54, look-smoke 142–144, smoke 74
Characters
session a4
A cast of eight from Rodin with normal and AO maps, real hands, a 202 mm pistol, coat tails that trail 0.77 m on a run, fists on every pistol strike.53model-smoke 1–20, look-smoke hall and 39
Environment
session a5
A 72-piece Blender kit, five floor themes with three arena variants each, a lobby with baked contact shadows, tenement rooms dressed by role, floor wear with puddles that reflect.34look-smoke 101–102, 124–125, 137–138
VFX and HUD
session e2
The CCTV on-screen display, the post pass (grain, halation, tracking band), readability rims, hit sparks and flashes, one beat envelope for neons and lamps, the grounded switch, lens blood on top.66look-smoke grew from 16 to 145
Sound
session 38
Feed static and ambience, the 80s action palette, hits fitted to 13 CC0 recordings, a beat scheduler that loses no beat on 250 ms frames, rooms fitted to published reverb times, a −1 dBFS ceiling.42look-smoke 71–80, 98–105, 132–133, 139–141
Slice flow and evidence
session 92
Power-on, the monitor wall, the LAST RECORDING report, the combo offer, calibration in three blocks. Behind the scenes: a QA bot, the play log you export, a lock-facing watch and a facing soak.35smoke 71–72, look-smoke flow, 84, 115–117, 127

Commit counts are each session's own trailer from Oct 19 on. Spend: $21.40 of fal credit for the cast, $0 everywhere else.

A film cut in the wet market: the player aims the pistol under yellow neon shop signs.
Film cut · the wet market
A kill-cam replay frame: a blown-out pale victim struck by the player in a corridor.
Kill-cam replay
The rooftop at night in the rain, the player seen from behind among water tanks.
Rooftop · rain
The lift lobby with grimy tiles, a bicycle and metal doors, the player aiming.
Lift lobby · baked AO
A top-down CCTV view of a tenement balcony hall with unit doors, the player inside the cyan beat ring.
Tenement · balcony hall
The eight generated characters in a T-pose line-up: the player in a long coat and seven enemy types.
The cast · Rodin Gen-2.5 on one 66-joint rig

CAM 04Fig 1The beat gate

The rule at the centre

Every press is stamped with the raw audio-clock time and judged against the nearest half-beat tick. At 120 BPM a beat is 500 ms. On normal difficulty the PERFECT window narrows from ±85 ms to ±60 ms as you climb, and GOOD is twice that, capped at 0.4 of a half beat (±100 ms at 120 BPM). Each move also has a gate: the first tick your follow-table timing allows after the last one. A press whose tick lands before its gate is EARLY. Before October 20 an EARLY press cost nothing, so mashing through floor 3 worked. Now it counts as a miss and pushes the gate half a beat later. That happens once per gate, so mashing costs one lockout per gate, not a pile-up.

Code: src/game/combat.ts:200–218 punishEarly · tunables beat.earlyMiss true, beat.earlyLock 0.5 · windows src/core/ramp.ts:25

CAM 05Fig 2The bug no check saw

Facing the wrong way

"My attacks still move and go in the right direction, and the hitbox seems to play in the right direction. My character model is just rotated incorrectly."

Josh · Oct 20

The gameplay heading was always right. The drawn model was not. A kill-cam replay writes each rig's whole rotation as a quaternion. three.js reads a yaw past ±90° back as the Euler angles (π, π − yaw, π). The avatar code then set only the yaw and left the two flipped axes in place, so the model drew at π − yaw. The error swept from 0° to 180° as you turned. At a heading past ±90°, each replay frame toggled the flip, so a room ended flipped or straight by the parity of its replay frames.

The "stacking" you felt was a second, separate problem. Fighting Idle in the right-lead stance is authored with the hips 45° and the chest 30° off the target, and nothing returned you to neutral after a heavy.

MeasureBeforeAfter
Rooms flipped in the 9-room soak3 of 90 of 9
Floor 2 room 1, samples flipped13 of 180
Right-lead idle: hips off target45.0°8.0°
Right-lead idle: chest off target29.6°−7.4°
Heavies pinned in a row, extra turn per heavy0° (108 heavies)0°

The fix writes the whole rotation, rotation.set(0, yaw, 0), plus a stance return and a −37° clip yaw on Fighting Idle. Every smoke and look-smoke check was green the whole time this bug was live, because no check compared the drawn rig with the gameplay heading. Session 92's facing soak now does.

CAM 06Fig 3How we worked

Six sessions, one machine

From October 19 the work ran as parallel Claude Code sessions, one per area, each in its own git worktree with its own Vite port. One orchestrator session made calls for you, logged them, and fast-forward merged one branch at a time. Every browser gate went through one lock, because timing checks failed when several gates loaded the CPU at once.

Decision logRows
All decisions and checkpoints, Oct 18–21335
Merges to main83
Your own calls34
Calls the orchestrator made for you31
Gate queue: time spent waiting against time spent running (92's last four runs)1.9×

The lock did not keep the machine quiet. Across the 35 logged acquires, the 1-minute load read 5.1 to 21.8 at the moment a gate started, often 12 to 16. The lock serialized the gates, but builds, renders, Metal probes and a dozen running Vite servers sat outside it. That is why "load flakes" never went away, and why some of them hid real bugs (CAM 07, pattern 03).

The parallel setup produced volume: 233 commits on October 19 alone. It also produced work you never looked at. Every environment change after your "every floor's look is a yes" merged on blind subagent judges and stills, and nearly all sound was tuned by meters.

CAM 07What went wrong7 patterns

What went wrong

Each session listed its own mistakes. The same few patterns came up across areas.

01 · all areas

The gates tested the logic, not the picture

What
Wrong facing lived for days under green gates. Floor transitions hitch on Metal, but the gates run on SwiftShader, which cannot see it. Hand poses were judged on close-up stills, yet a hand is 10–20 px at play distance.
Cost
Your play time is the only detector of the biggest bugs.
Now
The facing soak exists. A position watcher exists as a script. Neither is a standing gate yet.
02 · e2, 38, a4, a5

Measuring before checking the meter

What
The bystander lift reported 0.092 on an unfrozen frame, and the real figure was below 0.0585. The rim's signal (0.010–0.016) sat under render drift (0.003–0.010) for five tries. The sound fit measured a Chrome limiter that starts cold at 21 dB of reduction. A bake read sRGB bytes as linear, so the grunt sat at luma 50 against a target of 122. One clean run was taken as proof that a stall was cured.
Cost
One merge on wrong defaults, three bake fix cycles, about 2 h of gate waits, and decay figures that were wrong until the next merge.
Rule
Measure the noise floor and the meter's own state first. Take three runs, not one.
03 · e2, 54, a4

"Load flake" used as a verdict

What
anim-smoke 43 was written off as load, and it was a frame-order bug. Check 120 was "load" for a day before the ring-stamp fix. A light hit whiffing at 5 cm turned out to be an enemy spawned outside the room and snapped onto you. A merged commit message (401b15a) still says that snap happened "in play". It came from a test setup.
Rule
Force slow frames (70–100 ms) before calling a failure load. Every real frame bug this pass showed up that way.
04 · a4

Choosing before testing in the game

What
The first cast (TRELLIS.2) was picked on price and licence research. You called the faces "Project Zomboid level", and it was replaced a day later. Judged raw, the generators ranked one way. Under the game's grade and in film cuts, the ranking flipped, and Rodin came first.
Cost
$2.40 and about a day of pipeline work.
05 · e2, 92, a5, 38, 54

One global list of check numbers

What
Checks were numbered by position in shared suites, and main moved under every branch. At least eight commits only renumbered checks. Doc rows were lost in rebases twice. One check was renumbered three times before it merged.
Rule
Name checks by section and id. People already run them by name (--only facing).
06 · 54

Branches waited while main moved

What
The stance fix and the warp waited for your verdict. Meanwhile they were rebased three times and fully gated each time, then cherry-picked onto main when you asked for everything at once.
Cost
About six full gate sets, over 2 h of lock time.
07 · orchestrator

My own wrong calls

What
I ruled custom clips exempt from pose match, then withdrew it once 54 showed the failure was check state. I briefed rooftop footsteps as metal grating, but the art had plant as grating and roof as gravel. I sent 54 after a "wave spawn" path that turned out to be a test setup. I ran six sessions in parallel, more than one person can review, so work merged that you never saw.
Rule
Read the art or code before briefing. Keep the number of open threads to what you can confirm.

CAM 08What went well

What to keep

  • Every new check had a bounce. Each one was run against the old code or a zeroed value and had to fail before it counted. Smoke 74 read 0.35 m without the fix and 1.20 m with it. Look-smoke 145 read a cover median of 0 without the fix and 1.03 with it.
  • Forced slow frames found real bugs. The beat scheduler missed 4 of 8 beats at 250 ms frames, and the fix misses 0. The ring stamped arrivals at the frame, not the tick. The spawn snap showed only at 100 ms frames.
  • Outside data over taste. Room reverb from published RT60s, within 20% on every band. Tenement rooms from the Mark I block's real layout: no lifts, corridor cooking, cocklofts. Hits fitted to 13 CC0 recordings.
  • The play log turned your play into data. Your 175-press export settled the difficulty question. The lock watch now records facing problems as numbers instead of screenshots.
  • Judging in the engine. Same-room A/B stills (--seed 7) and the in-game bake-off decided the lobby and the cast.
  • The foreground loop. Anti-mash was built and confirmed in one sitting. The facing fix went from your report to your OK on its own port.
  • Cheap. $21.40 in total. Cached meshes made four fix rounds free.
The lift lobby before the tracer pass: flat walls and no contact shadows.
Lobby · before
The same lobby after: tile dado, grime decals, glossy terrazzo and baked contact shadows.
Lobby · after · 3 of 3 judges
Two pairs of hit frames, main on the left with the fingers splayed off the pistol, the fix on the right with a closed fist on the grip.
Pistol whip · 33 of 36 votes

CAM 09Field notesWhat a fresh agent gets wrong

Field notes

  • three.jsA quaternion with yaw past ±90° reads back as Euler (π, π − yaw, π). Write the whole Euler.
  • three.jsTransparent objects sort by renderOrder before depth. The player is at 200, so any later effect without depth write needs more than 200.
  • three.jsA material reuses its cached program by key, and a second onBeforeCompile never runs. Dispose before you restyle (87992cd).
  • Chrome audioThe DynamicsCompressor starts cold, 21 dB into reduction, for about 2 s. Its reduction under-reads transients.
  • Chrome audioChrome can run two long frames back to back with no timer between them, up to 510 ms. The frame loop must pump the beat scheduler too.
  • BlenderThe bake's use_clear is on by default, and byte images hold sRGB values, not linear ones.
  • SwiftShaderA new floor's first render can stall 5–7 s while the main thread sits idle. No WebGL call shows it.
  • ViteWorktrees that share node_modules also shared a dep cache and threw 504s. Each checkout now has its own .scratch/vite.
  • The gameA hitstop never stops the audio clock. To freeze a film cut, suspend the AudioContext.
  • The gameNothing separates the player from enemies. Six systems write body position, and none runs a final resolve.
  • The gameModels load only under ?look=cctv. Without it, a probe measures the mannequin and a box for a gun.
  • JudgingGenerator rankings flip between raw close-ups and frames under the game's grade. Judge under the grade.

CAM 10OpenAnd least confident

Still open

ItemOwnerStatus
The plain page is still the default. Stage F has all 9 answers and has not been switched on.orchestratorReady to do
Metal first-frame measurement for floor transitions. The probe is ready.a5Waits for you to stop playing
Hand targets 2–4: support hand, trigger reach, open handsa4Waits on your grip verdict
The sauna floor (floor 4). Names agreed between environment and sound.a5, 38Not started
Check 21 failed twice on full runs under load. It may be a frame bug.e2Not run under slow frames
The reach warp's 0.5 m gap between rig and capsule: which systems read which (sparks, blood origin, film framing)54Not checked
Finisher animation quality, which makes film cuts look disjointedyou, 54Known limit. Shot list ready for a friend's video capture.
Wrist candy-wrap (no forearm twist bones), coat hem tears in kicksa4Known limit
Footsteps follow the beat grid, not the feet38Known limit
Frame time on a base M1. Only the M4 Pro is measured.a4, a5Not measured

Least confident about

  • Whether the faint beat ring, now the default, costs you perfects. There is no play data per ring mode yet.
  • Whether floor wear causes the transition hitch you feel. It is unmeasured on Metal.
  • The stance at −37° on real hardware. It was judged on SwiftShader stills, then by your play on 5173.
  • The lock watch's thresholds (30° for 0.5 s). They have never seen one of your real exports.
  • Every sound value has a meter verdict. Only three have an ear verdict: the rain, SIGNAL LOST and the market.

CAM 11The front doorUpdated Oct 22

Capsules at the front door, on purpose

This is a portfolio piece for the 3 Cs. When this review was written, anyone who opened the game's address without flags got the plain test page: capsules, a fixed 3/4 camera, no CCTV look, no cast. Everything in this review lived behind ?look=cctv&anim=1, and the test suites ran on the plain page, so the gates did not test the look you would show.

On October 21 you chose to keep the capsules as the default. They show the character, the camera and the controls without the art in the way. Both modes now open on a welcome screen that says the game is a work in progress, says the art is temporary and AI-assisted, and explains the toggle: G, or Create on the pad, reloads the page in the CCTV look.

Behind that sits the lesson from CAM 01: the picture and the sound have exactly one real check, and it is you. Five of the six sessions said so on their own.

CAM 12Next passRanked

Next pass

  1. Flip Stage F, and test what you playMake ?look=cctv&anim=1 the default and keep ?look=off as the test page. Move smoke and anim-smoke onto the real page where it matters.92 · orchestrator
  2. Gate the picture, not just the logicRun the facing soak and the position watcher as standing 5-minute gates on animation changes. Add one final position resolve per frame, after every writer.54 · 92
  3. Four short review sessions with youA 20-minute listening pass with a keep, louder, quieter or wrong form. The ring test in full, faint and off. Sign-off on the tenement roles and floor wear. The characters judged at play distance and in film cuts.38 · e2 · a5 · a4
  4. Floor transitions on MetalMeasure the first frame after a floor build, then precompile every program variant and upload the wear masks before the floor shows.a5
  5. Named check idsKey every check by section and name, and give each one its own page or an explicit reset, so suite state never hides a bug again.e2 · 92
  6. Finisher animationThe film cuts look disjointed because the paired moves lack synced animation. Use the shot list for a friend's video capture, then frame-level pose matching.you · 54
  7. Detail that reads at game distanceForearm twist bones for the wrist wrap, footsteps on real foot contacts, coat flow. Skip finger detail unless a close camera puts hands in frame.a4 · 38

CAM 13Wrap-upChecklist

Closed out

  • Git
    Main is clean at 87992cd. Each session committed on its own branch. Nothing is pushed: you have not asked for a push.
  • Tests
    tsc is clean and npm test passes 220 of 220. On the combined main, anim-smoke passed 54 of 54. Last full runs: look-smoke 145/145 (plus 146 under --only art), smoke 74/74, editor-smoke 16/16, model-smoke 20/20.
  • Review
    Six self-reviews found no Critical issues. Two real bugs came out of them. The pose-match cache now clears on a graph swap (4f830fd). A look-variant toggle left floor plates with a stale wear mask, now fixed with look-smoke 146 (87992cd, 5 of 5 plates stale without it).
  • Docs
    AGENTS.md said "capsule placeholders, no animation yet". It now describes the page you play, the plain test page, and the portfolio purpose (2cadd08).
  • Memory
    Saved: the non-commercial portfolio purpose, the foreground loop, and kill vites by PID.
  • Cleanup
    About 60 branches and 20 worktrees are already patch-equal with main and can go. Two branches hold commits main does not have: vfx-beatring (4, pre-rebase copies by e2's account) and anim-match (5, unreviewed). Nothing has been deleted yet.