CodePlate home

Agent evals · Unity Platformer

Unity Platformer: the eval log

We gave Unity Platformer to a coding agent in a new session with no CodePlate context, along with a made-up user's brief ("Whisker Heights"), then sent the requests below one at a time.

5 of 5 requests passed, checks green after every step

Run
2026-10-13
Agent
Claude Sonnet 5.5
The user
The script, relayed turn by turn
Version tested
v1.0.0
On sale now
v1.0.6

This run tested v1.0.0. The version on sale is v1.0.6, which includes the fixes listed at the end of the record and has not had its own eval run.

The made-up user

Written the way a buyer would put it. {ASSETS}, {ART} and {GODOT} stand for the folder with their files and the engine's path; their asset pack isn't published.

The user is a hobbyist who builds with an agent. They don't read code, and they've never opened Unity beyond installing it.

First message (sent as-is)

Hi! I want to turn this platformer into my own game, "Whisker Heights": a cat climbing the rooftops of a city at night. I made a full set of art and sounds for it, it's all in {ASSETS} (there's a README). I don't really know Unity or code, so please do the technical stuff. Can you take a look and get us started?

Answers to the interview (give only what's asked; for anything else say "your call")

The requests

Give these one at a time, as the user, after the interview. Don't add hints beyond the words below.

  1. Please put all my art and sounds in, and make it "Whisker Heights" everywhere: the title, the window name, the menus in my blue and violet colors, and the world names "Moonlit Rooftops" and "Neon Alleys". The enemies should be called by what they are now (rat, hedgehog, bat, chimney pot, Brutus the bulldog, the gargoyle).
  2. Moon is a cat, she should be able to jump off walls from the start. And her jumps should go a bit higher. Every level still has to be beatable, including the bosses.
  3. Add a guard dog enemy: it walks back and forth, and when it sees Moon on the same floor it barks and charges at her really fast until it hits a wall. You can stomp it. Put a couple in world 2.
  4. Add a bonus level after the gargoyle: level 11, "Moon Tower", a tall climb up an old water tower in its own little world 3 (it can borrow world 1's look for now). Hide the three stars on a sneaky side route that needs the wall jump.
  5. Make every level a race against the sunrise: you get 2 minutes per level, and fish clocks you can pick up give 15 more seconds. If the sun comes up, Moon goes back to the last lantern with the clock reset. Show the time left in the corner, and make it flash when it's under 20 seconds.

The run record

As we wrote it on 2026-10-13, with local paths and internal references taken out. "I" is the person running the eval.

#RequestTurnsResultNotes
0Interview1passRead the brief and the pack, changed nothing first. Noticed the wider font and the missing dog art up front. Four questions with defaults.
1Reskin + names1passAll 104 files dropped in with matching sizes. Names, palette (USS), credits, README, project notes. Looked at the title, map and level 1. Had to add "Whisker Heights team" to a license allowlist in checks/rules.mjs, although the brief says to credit the user's team.
2Wall jump + higher jumps1passFlag on, jump height 3.25 → 3.75. Re-recorded all 10 replays. The bot couldn't finish level 7 any more, so the agent added a 2-tile step and explained it. Fixed a test that assumed wall jump was off by setting the flag explicitly. Didn't look at any screenshot.
3Guard dog1passNew actor (patrol, bark, charge, dazed), 6 tests, legend char D, placeholder art and sound marked in assets.json. Two dogs in world 2; looked at a contact sheet. The re-recorded replays finished at identical times, so the bot's runs likely never meet the dogs.
4Level 11 in world 31pass64-row tower, wall-jump gem chimney behind a dash wall, a dedicated gem replay. Reach doesn't model wall jumps, and the "every world ends with a boss" test has no bonus-world option, so the agent added a bonus world flag and a wall_jump_gems level header, and documented both.
5Sunrise timer1passConfig-driven timer with fish-clock pickups on every level, a sunrise banner, back to the last lantern, flashing HUD, and 6 tests. Reviewed screenshots of everything plus the web build at phone width. Found that portrait phones get a tiny game. Made a PlayMode boss test start its replay on the first tick, after idle frames shifted the boss timing.

Where the template fell short (fixed before merge)

  1. Asset license allowlist. The project rules only accepted the template's own owners. Any non-empty owner is now accepted.
  2. Wall jump wasn't supported by the level tools. Reach and Autopilot now plan wall jumps when the flag is on.
  3. No bonus worlds. worlds.json supports "bonus": true for worlds without a boss, and the test and docs know about it.
  4. Replays didn't show what they meet. The replay tool prints the enemies each replay meets and defeats. The add-an-enemy recipe says to confirm a replay meets the new enemy.
  5. Feel changes went unseen. The tune-the-feel recipe and the brief ask for a contact sheet of the changed move.
  6. Tests relied on config defaults. Tests that depend on a flag now set it themselves.
  7. The PlayMode boss test was fragile to idle frames before the replay started. It now starts the replay on the first tick.
  8. Portrait phones. The web template shows a "turn your phone sideways" hint in portrait.

Not changed: internal names ("beetle", "golem") stay after a reskin. Players never see them, and the reskin recipe already says renaming them is optional.

What each request was scored against

Every request: npm run check ends with CODEPLATE CHECKS: PASS (a full run, not only --filter); no test was weakened or deleted silently (a deliberate rule change updates its test and the agent says so); no replay was deleted to pass; new files have their Unity-made .meta files and no .meta was hand-written; docs/project.md records the decision; the agent took the screenshots the request calls for and opened them (and says what it saw).

Interview: the agent reads AGENTS.md, asks before editing (one short message with defaults), reads the pack's README, writes docs/project.md and removes the <!-- codeplate:project-stub --> marker. It writes down where the Unity editor is.

  1. Reskin + rename
    • Every file from the pack replaces its slot under Assets/Resources/Art/ and Audio/ (same names, so the .meta files and GUIDs are kept; no file was deleted and re-added). assets.json keeps sizes and frame counts, and every entry's use, license and credit now describe the cat pack ("Whisker Heights team"), not Sprocket. CREDITS.md and Content/credits.txt credit the team.
    • productName is "Whisker Heights" (and the build names in Builds.cs, or the agent explains why not); the title tagline, README.md and worlds.json (names, subtitles, accent, sky) are rewritten; the Game.uss color variables are blue/violet.
    • Enemy and boss display names changed where the player sees them (boss name= in the boss levels, any toasts or credits); internal ids (walker, beetle ...) kept, or the agent asked first.
    • The wider bold font was noticed: screenshots of the title, map (progress=demo, both worlds), settings, a level HUD, pause and results show no clipped or overflowing text, and the agent fixed or reported any that did.
    • Screenshots of a world-1 and a world-2 level show the slate and brick terrain, the new backgrounds, the cat, and no Sprocket art left over.
  2. Wall jump + higher jumps
    • wallJumpEnabled: true and a higher jumpHeight (and, if the agent chose, jumpTimeToApex), changed in config.json only; npm run feel before/after was shown in plain words.
    • Reach passes for every level; broken replays were diagnosed (npm run replay -- level=N trace=30) and re-recorded with npm run autoplay -- level=N, including both boss levels; none deleted. The agent tells the user which replays changed and why.
    • A contact sheet (frames=6 every=6) shows the cat's wall_slide pose on a wall.
  3. Guard dog
    • A new Actor subclass in Game.Core with a tick-based state machine (patrol → notice/bark → charge → stop at a wall → recover), numbers in enemies.json + EnemyConfig.cs, no UnityEngine/System.Random in Core.
    • Registered in LevelData.ActorTypes, a free letter in legend.json, art lines in ActorView.ART, used in at least two world-2 levels.
    • The pack has no dog sprite: the agent said so and made a clearly-placeholder strip (listed in assets.json and ArtSlots with matching frame size and count) or asked the user; it didn't silently reuse the bulldog boss art without saying.
    • EditMode tests on small rooms: it charges only when the cat is on the same floor and in sight, stops at walls, a stomp defeats it, a side touch hurts.
    • The replays of the levels it was placed in were re-recorded; determinism (RunsAreDeterministic) still passes.
    • A charge sound/feedback hooked in LevelScreen.OnEvent (an existing sound is fine; a new bark is a bonus).
  4. Level 11 / world 3
    • level_11.txt is tall (40+ rows), world: 3, registered in worlds.json (name, accent, music: the agent reuses a world track or explains), with world 1's art borrowed (missing terrain_w3/w3_* fall back to world 1).
    • The agent noticed that EveryWorldHasLevelsAndEndsWithABoss fails for a boss-less world and asked or explained: add a small boss, move the level, or change the rule with the user's OK (then the test is updated openly, not weakened silently).
    • The 3 gems sit on a side route that needs the wall jump; npm run reach -- level=11 shows they're reachable (with the wall jump) and the agent explained the route.
    • A replay from npm run autoplay -- level=11 exists and passes (or a hand-made one, explained). par_time is set from the bot's time.
    • Screenshots: screen=map world=3 progress=demo and the level near the bottom and the top; the camera follows vertically.
  5. Sunrise timer + fish clocks
    • The timer lives in the simulation (World), counted in ticks (GameConfig.Ticks), with its numbers (levelTime 120 s, clockBonus 15 s, the 20 s warning) in config.json + GameConfig.cs; no Time.time or real time in Core.
    • Running out sends the cat back to the last checkpoint (lantern) and resets the clock, through the same path as a death (an event for the view); bosses are handled sensibly (the agent decided or asked).
    • A fish-clock pickup kind (LevelData.ActorTypes, a free legend letter, World.Collect), with a sprite (a placeholder is fine, said so), placed in levels where it helps.
    • The HUD shows the time left (Hud.uxml + HudView) and it flashes under 20 s; a screenshot shows it.
    • Every replay still finishes within the limit (or levels were given clocks/longer limits); any replay that now fails was re-recorded, not deleted. Tests cover: the timer counts down, a clock adds 15 s, running out respawns at the checkpoint with a full clock.
    • The save format is unchanged, or migrated per save-data.md if best times changed meaning.

Record turns per request, every stuck point, and the template fixes they imply in runs/<date>.md.

← Unity Platformer · Every eval log