CodePlate home

Agent evals · Unity Platformer Lite

Unity Platformer Lite: the eval log

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

4 of 5 requests passed (1 partial)

Run
2026-10-15
Agent
Claude Sonnet 5.5
The user
The script, relayed turn by turn
Version tested
v1.0.1
On sale now
v1.0.2

This run tested v1.0.1. The version on sale is v1.0.2, 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. They downloaded the free Lite template.

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 name "Moonlit Rooftops". The enemies should be called by what they are now (rat, hedgehog, bat, chimney pot, Brutus the bulldog).
  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 Brutus.
  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 levels 3 and 4.
  4. Add a second world, "Neon Alleys", with three new levels after Brutus. It can borrow the rooftop look for now (I'll draw it later), but give it a purple tint on the map. The last one is a rematch with Brutus, and this time he takes 4 stomps.
  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-15, with local paths and internal references taken out. "I" is the person running the eval.

#RequestTurnsResultNotes
0Interview1passRead the brief and the pack's README, changed nothing first. Noticed that all 93 files match the slots, that the font is 1 px wider, and that the free license needs the credit line. Five questions with defaults. Wrote the editor path in docs/project.md.
1Reskin + names1partialStarted without the request text (see above). Every file from the pack replaced its slot and kept its .meta; every assets.json entry credits "Whisker Heights team"; product name, company, tagline, world name and subtitle, README, credits (the CodePlate line kept) and a blue/violet USS palette. Looked at the title, map, settings and level 1, and noticed the font's squashed lowercase m. The boss still showed "Brass Beetle" until request 4, four level titles kept the robot story ("Wind-Up Walk", "Clockface Climb"), and the web page around the game kept the brass colors. It offered to rename the levels. No pause or results screenshots.
2Wall jump + higher jumps1passWall jump on, jump height 3.25 → 3.75, both in config.json. Replays of levels 3 and 5 broke; it re-recorded all five with the bot, Brutus defeated. Two test rooms that only work with the old jump height became reachable, so it pinned 3.25 in those tests and said why. Its contact sheet shows a running jump, not a wall slide; it asked the user to try the wall jump by hand.
3Guard dog1passNew actor (patrol, bark, charge to a wall, dazed), numbers in enemies.json, letter g, two dogs each in levels 3 and 4. Four tests: patrol, bark then charge until a wall, no charge from another floor, stomp vs side touch. Re-recorded replays meet the dogs (level 4 went from 12.1 to 15.8 s). Said the pack has no dog and listed the strips to draw, but the stand-in is the rat's strips tinted in code, so assets.json has no dog slot to fill later.
4Second world1passWorld 2 "Neon Alleys" with three levels; the last is a Brutus rematch with 4 stomps and a 4-segment health bar, and its replay defeats him. Borrows world 1's art and music and lists the files to draw. The template had no way to tint a world, so the agent added a mapTint field and the code for it and documented it in the add-a-world recipe. Here it also set the boss name to Brutus in level 5 and renamed "Beetle's Den". Screenshots of the world 2 map and its boss fight.
5Sunrise timer1passA config-driven timer counted in ticks (120 s, +15 s per fish clock, warning at 20 s), 32 fish clocks across the 8 levels, back to the last lantern with a full clock, a banner, and a top-right countdown that turns red and blinks; a contact sheet shows both states. Five tests. Every replay still finishes in under 32 s. The fish clock is the coin strip tinted cyan; the agent said so and warned it looks like a coin.

The concept asks for web and phone browsers. At no point did the agent make a web build or look at the game with the touch buttons.

Where the template fell short (fixed in unity-platformer 1.0.7 and unity-platformer-lite 1.0.2)

  1. No world tint. worlds.json had accent (the map title) and sky, which nothing draws, so a world that borrows world 1's art looked exactly like world 1. A new optional tint colors a world's backgrounds on its map page and in its levels. The add-a-world recipe explains it, and a test covers the default and that every world color is valid.
  2. Names left over after a reskin. The reskin recipe covered the product name, tagline and credits, but not world and level titles or the name above a boss's health bar. It now has a "Names players see" list (worlds, level title: lines, the boss's name=, the controls help on the Settings screen), the brief points to it, and the customization map has a row for it. Its checklist also asks for settings, pause and results screenshots after a font change.
  3. The web page kept the old colors. The page around the web build repeats five colors from Game.uss, and the reskin recipe didn't say so. It does now, and a project rule fails when the two palettes differ. Run against this project, the rule names all five.
  4. No recipe for stand-in art. The add-an-enemy recipe said "generate a clearly-placeholder strip" without saying how, and the agent tinted other actors' strips in code twice. The reskin recipe has a "Stand-in art" section: copy a strip of the same size to the new name, list it in assets.json with a use that starts with STAND-IN:, and tell the user. The enemy, boss and collectible recipes point to it.
  5. Web and phones went unchecked. The brief's verify loop now has a step for projects that target the web or phones: a touch screenshot after changes to screens, text, colors or controls, and a web build opened in a browser (also at a phone's landscape size) after each milestone.
  6. Test rooms followed the shipped jump height. The wall-jump and double-jump rooms in ReachTests read the jump height from config.json, so a higher jump made "out of reach without wall jump" reachable. They now pin the heights they were drawn for, as the agent did.

Not changed: the wall-slide contact sheet. The tune-the-feel recipe already says how to shoot a wall jump, and a fixed command can't know where the walls are in someone's levels. Internal ids (beetle, walker) still stay after a reskin; players never see them.

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); the line "Built with CodePlate (codeplate.io)" stays in Content/credits.txt (the free license asks for it, and a check fails without it).

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, and the CodePlate credit line stays.
    • 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 (name, subtitle, accent, sky) are rewritten; the Game.uss color variables are blue/violet.
    • Enemy and boss display names changed where the player sees them (name=Brutus in level 5's boss line, 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), settings, a level HUD, pause and results show no clipped or overflowing text, and the agent fixed or reported any that did.
    • A level screenshot shows the slate 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 the boss level; 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 levels 3 and 4.
    • 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 levels 3 and 4 were re-recorded and the agent checked that they meet the dogs (npm run replay lists the enemies a run meets); determinism (RunsAreDeterministic) still passes.
  4. Second world
    • Followed add-world.md: world 2 in worlds.json (name "Neon Alleys", a purple accent, a sky, music: the agent reuses a track or explains), levels 6–8 with world: 2; the missing terrain_w2/w2_* fall back to world 1's art, and the agent told the user which files to draw later.
    • Level 8 is a boss arena (add-level.md step 3) with boss type=beetle name=Brutus health=4; the boss tests still pass and a replay records Brutus defeated.
    • Each new level has 3 gems, reach passes, and a replay from npm run autoplay exists; par_time is set from the bot's time.
    • Screenshots: screen=map world=2 progress=demo and a level of world 2; the map page buttons move between the two worlds.
  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); the boss fight is 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 (Recipe add-collectible-and-unlock.md).
    • 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 Lite · Every eval log