I kept paying for the same silent failure twice, so I wrote the traps down
This game is built almost entirely by an AI agent driving a live Unreal editor through a couple of MCP servers. That works far better than I expected, with one structural problem: every session starts from nothing. The agent has no memory of the afternoon it spent last week working out why a write that returned true had changed nothing.
And in this project, that is the normal failure. The tooling here does not usually crash. It succeeds and does nothing. Writes that report success and no-op. Meshes that import at one hundredth scale with no warning. Casts that compile clean and fail every tick. A vector written in the wrong text format that stores exactly as typed and evaluates to zero. Each of those cost hours to find the first time. Paying for them a second time is the real cost of working this way, and it is much larger than it sounds.
So on this date I started keeping a skill file for the project — a document that loads automatically in any session, holding the verified recipe for each subsystem and, more importantly, the traps. It began as one page and about six references. It is now a router plus roughly thirty reference files, and it is the single change that has made the most difference to how fast this project moves.
What goes in it, and what does not
Two stores, with a hard line between them.
The skill holds durable know-how: how to do a thing correctly, and every way this project has found of doing it incorrectly while being told it worked. It is written for the next session, not for me.
The memory corpus — a few hundred single-subject notes — holds project state and history: what is built, what is placed, what was decided and rejected, what has never been tested. That distinction matters because state rots and recipes do not. Mixing them produces a document that is simultaneously the manual and the changelog, and it will lie to you about both.
The trap, written the way you would search for it
The most useful thing I learned was not what to write down but how to index it. Early on the skill was organised by subsystem — navigation, materials, characters. That is the wrong index, because at the moment you need it you do not know which subsystem you are in. You know what you saw.
So the front page now carries a symptom table. Real rows, in plain words:
- "We already changed that, but the game still shows the old thing."
- "The write returned true and nothing changed."
- "Distant buildings look broken, grey or hollow."
- "The NPC won't move, or walks through walls."
- "The capture is black."
Take the third one. A playtest report said the houses in the middle distance looked low detail, with the windows broken and distorted. Every instinct — mine and the agent's — says level of detail, so you go and change LOD distances. That is a wasted afternoon, because the medium houses involved have exactly one LOD and no LOD setting on earth can affect them.
The real mechanism: the distant world is drawn by an instancing proxy layer, and the engine silently substitutes a flat grey default material for any material not flagged as usable with instanced meshes. Near buildings are ordinary actors, skip that check entirely, and look fine. It is a material-flag bug wearing a LOD bug's clothes, and it never self-heals within a session, because the proxy is built once with the fallback already baked in. The fix was to set the flag on base materials — 360 misbehaving material instances resolved to only 119 bases — and then read every one of them back, because that flag write is exactly the sort that reports nothing.
None of that is findable under "materials". It is findable under "distant buildings look grey". The symptom is the only key you actually have when it happens.
Why writing it down compounds
Each entry is paid for once and then pays out forever. Some concrete ones:
Positional arguments bind to a hidden pin. In the graph-authoring language used here, passing an argument by position rather than by name binds it to the invisible self pin. Hiding an actor by passing the boolean positionally writes cleanly, compiles, and does nothing at all — the boolean lands on the actor pin and the real parameter keeps its default of false. That one presented as neighbours standing visibly in the street when they were supposed to be indoors.
The navmesh must stay on static runtime generation. Switching it to dynamic empties the runtime navmesh and freezes every pedestrian. The cruel part is the false evidence: the cars kept moving, because they are moved directly and never touch navigation at all. "The cars still work" feels like proof that navigation is fine. It is proof of nothing.
Instruments lie more often than assets fail. Roughly half the long investigations here turned out to be a measurement tool reporting nothing rather than a thing being absent — previews that render black, captures that miss particles, an editor world that does not tick, and once a graphics driver setting suppressing the draw entirely. The rule that came out of that is now a prime rule: before believing a null result, measure something known to work.
Where the practice falls down
Honesty is the point of this format, so:
A written rule is not a guard. The hidden-pin rule above is rule four on the front page of the skill, in bold, and it was walked into again months later — because a proximity check was copied out of a readback, and the readback renders named arguments as positional. Every gate written that way measured a distance to null, got zero back, and was permanently open. It broke eight functions in a single day, compiled clean and passed validation, because the graph was complete — just wrong. Writing the rule down did not prevent it. What prevents it is mechanical: inspect the pins directly rather than trusting a readback, or use a form that has no second pin to forget.
Big references stop being read. The editor-operations reference reached 218 KB across 93 flat sections, which is more context than a task can afford to load. It has been split into six task-scoped files, moved verbatim, with the old document left in place as a router so existing links still resolve. The graph-authoring reference got the same treatment.
The index has a byte cap, and overflow is silent. The memory index quietly exceeded it, and one session received only part of the file — about ninety pointers below a certain heading simply were not there, with no error. Worse, the header's own rule at the time told sessions to merge entries onto shared lines to stay under a line limit, which saves no bytes whatsoever. It was optimising the wrong axis and driving the file straight through the real cap.
Chronological notes contradict themselves. Append-only build notes are the hazard, not long ones. One file had six live self-contradictions: a conclusion and its own reversal both standing, measurements sitting below a claim that no measurement existed. A later sweep found nine summary lines describing a state their own body disproved, and several stale "still to do" lists — which are the expensive kind, because a dead to-do does not merely mislead, it commissions work that is already done or was deliberately abandoned.
And I have never measured any of this. Eval prompts for the skill were drafted and never run, because running them would mutate the live editor. The claim that it helps is my own impression, plus the observation that documented traps get walked into less often than they used to. That is not a number, and I am not going to dress it up as one.
What to take from it
- **Write the trap the moment you pay for it, in the words you would type into a search
box.** The symptom is the key; the subsystem is not.
- Separate durable know-how from project state. One rots and the other does not, and a
document trying to be both will lie about both.
- A reference nobody can afford to load is not a reference. Split by task, leave a router
behind, and move the text verbatim so nothing is quietly reworded away.
- Rules do not enforce themselves. Every expensive trap deserves a mechanical check as
well as a paragraph.
- Watch the recall surface. The one-line summary someone uses to decide whether to open a
document is where staleness does the most damage, because it gets acted on without the body ever being read.
- Retire rules as loudly as you add them. Three "the human must hand-author this" rules
here were true and then were not; leaving them standing cost hand-work that no longer needed doing.