Skip to content
SiteEmail

Agent-written code can appear complete before it has been validated.

Validate it with five checks, from cheapest to most expensive, and include a production build in the Player to catch build-time failures.

Code review and a running dev server are not enough to validate agent-written UI. The code may look coherent while still relying on unsupported APIs, invalid CSS, or untested assumptions about layout and interaction.

Use two review habits consistently.

Treat the agent’s summary as a claim, not evidence. If it says a change was verified, check which commands, assertions, or screenshots support that claim.

Ask for artifacts rather than confirmation. Screenshots, console output, and assertion results are more useful than a plain success statement.

This is the cheapest check and requires no running Player. eslint-plugin-gameface flags unsupported patterns and data-binding mistakes across CSS, SCSS, HTML, JSX/TSX and JavaScript. It ships pre-wired in the Gameface UI boilerplate and in every framework template.

Run it in CI, not only in the editor. Editor diagnostics are easy to miss during agent-driven edits.

This is the cheapest check that requires a running Player. Gameface logs unsupported stylesheet properties by name, which identifies exactly what was discarded.

This check is only useful if the console is read. Builds can succeed and dev servers can remain quiet while the Player reports rejected declarations. With the MCP server connected, get_console_logs exposes that output to the agent. After styling work, a prompt like the following is usually enough:

Load the view and show me get_console_logs. Any unsupported-property warnings?

If the console names a property present in the source, treat it as a confirmed bug. The declaration did not survive.

Layer 3: Assert Against the Running Engine

Section titled “Layer 3: Assert Against the Running Engine”

The console reports rejected declarations. Separate checks are still needed to confirm that the remaining layout behaves correctly. Three assertions cover most layout failures.

AssertionCatches
assert_text_fitsClipped labels, overflowing values, text that fits in English and not in German
assert_no_overlapA tooltip covering the number it explains, a badge sitting on a name
assert_within_parentA panel running off the bottom at 21:9, a dropdown escaping its container

perf_lint sits alongside them as a static check for layout patterns the Gameface documentation identifies as expensive. It does no timing, so it does not flake.

The Conductor skill runs these automatically as its validation stage. Without the skill, request them explicitly.

Tooling does not evaluate visual quality. Review these four areas directly.

  • Visual coherence. Check that the screen matches the surrounding interface. See Design First.
  • Hierarchy. Check that the most important element reads as the most important element.
  • Feel. Review transitions, timing, and press feedback directly.
  • Focus order. Check that gamepad navigation follows a sensible path. See Spatial Navigation and Focus.

Request a screenshot at the target resolution and worst-case aspect ratio, then compare it with an existing screen instead of reviewing it in isolation.

This layer is easy to skip, but it is required for catching build-time rewrites.

One common failure mode appears only after the production build step. In one Chart component, an overlay collapsed to 0x0 only in the built page. The source used left: 0; top: 0; right: 0; bottom: 0. The CSS minifier collapsed those declarations into inset, which Gameface does not support, so all four sides became auto and the element disappeared.

Everything upstream still passed. The source was valid. Lint had nothing to flag because inset never appeared in the source, and the dev server served unminified CSS, so the issue did not appear there either.

The missing step was loading the production build in the Player and reading its console. Layer 2 only protects the artifact that is actually tested.

End-to-end coverage caught the issue because it ran against vite preview, not the dev server.

Apply two rules to any UI that will ship.

Verify shipped UI in a production build inside the Player, not only against a dev server. Source linting cannot catch build-time rewrites.

Prefer source patterns that do not encourage unsupported rewrites. Four zero offsets on a stretched element invite the minifier to emit inset. The version below cannot be folded into that shorthand:

overlay.css
/* Four zero offsets invite the minifier to emit `inset: 0`, which Gameface drops. */
.hit-overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}

See UI Testing for the end-to-end setup, and Layout Debugging for diagnosing an unexpected collapse.

perf_lint and perf_measure indicate whether a screen is structurally expensive or unusually slow against a recorded baseline. Neither reports the full runtime cost inside the game under real load.

Treat them as early warnings during development and use the profiler for real measurement. See Performance and Memory Profiling.

Before accepting a screen built by an agent:

  • Lint passes in CI.
  • The Gameface console is clean, with no unsupported-property warnings naming anything in the source.
  • Layout assertions ran, and their output has been read.
  • A screenshot exists at target resolution and at the worst-case aspect ratio.
  • The screen has been compared against an existing one.
  • It has been opened from a production build in the Player.
  • Gamepad or keyboard navigation has been driven by hand rather than declared present.
  • Every color, size and spacing value traces back to a named entry in the design system.