Skip to content

AGI IS HERE 1.2.3

Choose a tag to compare

@joakimriedel joakimriedel released this 12 Oct 18:45
· 2 commits to main since this release
cc32d3b

1.2.3: applied changes show at once

Since 1.2.1, an Agent change in Create reported Applied but nothing changed on screen. Returning to
Play showed the old room. This patch brings back the 1.1 behavior for the unified conversation and
extends it to Play. It also adds a check that fails any browser test leaving the page and the game
disagreeing about the pause.

What changes for players

  • A change shows at once. When an applied change touches what the current room uses (its LOGIC,
    a loaded LOGIC or VIEW, the picture on screen, or a VIEW stamped into that picture), the room
    starts fresh so its entry code runs the new version. Score, inventory, flags and variables carry
    over as on any room entry; the room's own entry code runs again and may change them. The hero
    keeps walking in the same direction, as in the original interpreters. Changes to anything else
    apply when the game next uses them.
  • Quick edits all land. Undo and Redo can send several edits before the game runs a cycle. A
    picture or VIEW edit the screen cannot take while a room restart is still to run waits for it,
    and the page retries it; each edit then reaches the running game.
  • A change that entering the room cannot show asks for a restart. A room can keep the previous
    room's picture, draw only once under a flag or on a later cycle, or lose its drawing code to an
    edit. When a change needs a room entry to show, a detached copy of the game enters the room on
    the new files first; the change is admitted only if that entry draws a whole picture. Otherwise
    it asks for a restart and the game keeps its bytes, instead of reporting Applied over the old
    screen.
  • Play catches up. Returning from Create starts Play's room fresh when Create changed what that
    room uses, with a note: "Room 1 started fresh with your changes." This holds when the old picture
    cannot be rebuilt on the edited files, such as a stamped VIEW that lost the frame it showed: Play
    keeps the player's progress instead of asking for a restart from the beginning.
  • Play saves the edited game. Play saves its progress as soon as the edited game has drawn. A
    periodic save no longer waits behind the cycle report when a busy browser runs the timer late.
  • The page owns the pause. Play, Back, From my game, Restart, a project restart and Take control
    follow the pause the page shows. The worker keeps the page's last pause message across run
    replacements; a replay keeps its recorded pause separately.
  • The Agent pauses Play, never Create. An Agent panel opened in Create and kept open into Play
    now pauses the game, as opening it in Play does. In 1.2.2 the game ran on while the panel held its
    keyboard: Play looked frozen, the switch still said "Keys go to the game", and clicking the game
    did nothing. Back in Create the game runs beside the panel again, so applied changes show.
  • A fresh room runs under a pause. A room that starts fresh for a change does so even while
    the game is paused, then waits. The change shows, and Play's progress is saved, with the Agent
    still open.
  • The play bar tells the truth with the Agent open. While the Agent holds Play, the bar offers
    Resume, which closes the Agent and plays on, instead of a Pause that did nothing. However the
    Agent closes, the game takes the keyboard back.
  • Reviews show only what changed. An Agent edit to an imported game's LOGIC was diffed against
    an empty file, so every line looked new; both sides now read as the LOGIC editor shows them.
  • One action, not one button per item. In a VIEW review a cel opens itself in the editor;
    each changed part has one Open icon; a suggested command is itself the button that types it;
    named checkpoints and figure rows use icon buttons named for their item.
  • Notices close by themselves. "Saved as your own copy" and "Room N started fresh" close after six
    seconds, and stay up while the pointer or focus rests on them.
  • The Agent sits beside the game in Create. The drawer floated over the workspace's right side,
    hiding about a third of the game and the editor at 1063 to 1920 px wide. The workspace now keeps
    the drawer's width free; on a phone the drawer still covers the sheet.
  • Show Room N. An applied change to another room's LOGIC gets a button on the result card that
    takes the hero there. Back now sits beside the room name, out from under the drawer. A Show that
    finishes saving after the player left Create, or after another run took over, does nothing.
  • Plain mode name. The Agent tells players to switch to Create to apply a change.
  • Release names. An installed older release of a catalog game is named by its release, such as
    "Adventure Department 1.0", and keeps its own card. Older releases are never folded into the
    current one.
  • Less repetition. The SOUND and Launches editors no longer repeat their tab's name as a heading.

Decisions to confirm

These change what existing tests expected or how the app behaves (AGENTS.md, Tests and evals). The
owner approved all eight.

  1. An applied change the running room cannot take in place (a loaded VIEW's new loop layout, a VIEW
    stamped into the picture) re-enters the room at once, instead of offering Re-enter room
    (worker-project-restart, project-restart.spec.ts).
  2. The checkpoint after an applied change that re-enters the room is taken at the first boundary
    after its entry pass, not in the same call (worker-project-session, worker-project-restart).
  3. Play, Back, From my game and Restart follow the page's pause, not the pause captured when Create
    opened (worker-create-return).
  4. Returning to Play after a change to its room shows that room's entry message again, as entering
    a room does (agent-game.spec.ts).
  5. Approving an Agent change shows the room's new entry message before the player types anything.
    The room restarts as on any normal room entry, and the message comes from the room's own entry
    code; the engine adds nothing. The export test now closes that message, then checks that look
    answers from the changed room (game-zip.spec.ts).
  6. An open Agent pauses Play, never Create, however it opened. A panel opened in Play and kept open
    into Create no longer keeps Create paused, which held back an applied change's room restart.
    With the Agent still open, Play's restarted room enters and saves, then waits paused until the
    Agent closes (agent-conversation.spec.ts, workspace-agent.spec.ts).
  7. In Create, the Agent drawer takes its own width beside the workspace instead of floating over it.
    This replaces a deliberate overlay meant to keep the editor's width, which hid the editor's right
    side as well as the game (agent-drawer.spec.ts, workspace-layout.spec.ts,
    workspace-agent.spec.ts).
  8. Returning to Play after Create changed the room's own LOGIC, which had resumed from scan.start,
    starts the room fresh on the new code and keeps the player's place. Before, Play refused and
    offered Restart from the beginning (run-owner.spec.ts). A LOGIC changed while a message waited
    still refuses (run-integrity.spec.ts).

Holistic review (Fable lane)

A separate reviewer on another model read the whole change and drove Chrome journeys as a beginner
and an expert, with real Agent turns ($0.59): tutorial edits, Agent changes in Create and Play, the
King's Quest I alligator, Show Room and Back, quick Undo/Redo, compact and wide windows. Verdict:
merge-ready. It found the interpreter still takes its own new.room path for every re-entry and the
trial engine detached, and asked for one fix (the play bar while the Agent holds Play, done above)
plus plain restart copy and a stale "Updated · … restarted" note, also done. Its code-shape
suggestions (one re-entry path, a reactive mode for the Agent hold) are 1.2.4 follow-ups.

What was wrong before this candidate

An outside review of the first candidate and a browser trace found the causes of its three browser
failures:

  • workspace.spec.ts (two tests). Three quick redos each restarted the room. An edit that
    arrived before the previous restart's entry pass found no drawing record for the screen, so the
    engine refused the picture or VIEW change. The game stayed on the older version, Play resumed on
    it, and the page correctly refused to save it as the edited project. The engine now accepts a
    swap while a host room entry is pending, because that entry draws the room from the new files,
    and a pending entry is not restarted again.
  • game-zip.spec.ts. The change now shows at once, so "Remixed room one." was already on screen
    when the test typed look; Enter closed that message, and look was never sent. The extra pause
    report after each run replacement only changed the timing. It is removed: the pause check now
    asks the worker in its state query instead.

The first CI run of this candidate failed two browser tests:

  • agent-game.spec.ts, in-game ZIP export. Returning to Play restarted room 2, whose entry
    message parks the game. Play saved at that cycle, and no later cycle came. The test helper
    savePlayProgress waited for a save after the frame's cycle, which it read after the Play reply;
    on CI the entry pass had already run. The helper now waits for any save stored after Play
    resumes. A one-second delay before the frame read reproduced the CI failure with the old helper
    and passes with the new one.
  • ai-settings.spec.ts on WebKit. The trace shows the page making no requests for four seconds
    while WebKit parsed the 3D renderer module on a cold dev server, so room 1 missed the 5-second
    poll; the game kept running and the pause check agreed. The 30 catalog boots that polled for room
    1 now use the existing cold-boot wait, waitForRoom(page, 1, { coldBoot: true }).

A third outside review, of head 95966a50, found that R1 and R3 were only partly fixed and two
new problems in the paused room entry, plus an Agent hold leak and a pause-check gap. Each is
reproduced in a test watched failing first, and fixed:

  • R1 (again), earlier drawing is not proof. Round 2 trusted a room's earlier complete picture to
    predict its next entry. Four cases showed otherwise: a draw once under a flag, a draw only on a
    later cycle, an edit that removed the drawing code, and a VIEW stamped once. A visual change now
    waits while a room entry is still to run (the real entry decides), and a re-entry may admit a
    visual change only when a detached copy, entering the room on the staged files, draws a whole
    picture. All four cases now ask for a restart and keep the old bytes.
  • R3a and R3b, fresh-entry ordering. Round 2 replaced Create's run on the captured files, then
    committed the room entry. Admission, sources and boot files stayed on the captured image, so the
    next Create edit was refused, and an attached debugger armed in between could defer the entry
    after Create was gone. The detached candidate now takes the edited files and owes its entry before
    anything is replaced. Tests cover the next Create edit landing, against the page's expected
    identity, and the return with the debugger attached and armed.
  • R5a, released tapes. The paused entry ignored a recorded "no cycle" poll. A tape recorded by
    the 1.2.2 worker itself (app/test/formats/history-1.2.2-paused-reenter.json) now replays to its
    recorded state; it diverged at cycle 17/16 before.
  • R5b, controlled passes. With the debugger's execution control armed, the paused entry counted
    a completed pass twice and a breakpoint or yield once. It now follows the cycle poll's accounting,
    and a yielded remainder finishes on later paused polls, once.
  • R6, Agent hold leak. A map build started in Create keeps the Agent open into Play; its success
    closed the Agent directly and left Play paused. The Agent's hold now follows its open state too.
    A browser test holds the build at the worker boundary to reach that order.
  • R4, fixture page closed. The fixture page was marked checked before it was, so a test that
    closed it skipped the pause check. A planted disagreement now fails page.close, context.close and
    an open page.

A second outside review of the whole change found four issues, each reproduced and fixed with a
test watched failing first (R1 and R3 were completed in the third round, above):

  • R1, picture shown stale. The automatic re-entry and the pending-entry bypass both assumed that
    entering a room redraws it. A room keeping the previous room's picture does not, so a picture
    edit there reported Applied over the old screen. A host entry now counts as redrawing only when
    the room drew a complete picture since it was entered, recorded when the entry is scheduled;
    otherwise the change is a truthful restartRequired and the game keeps its bytes. Covered for a
    single edit and for a LOGIC edit followed by a picture edit before the entry runs.
  • R2, late Show Room. Show waited for the workspace save, then launched on whatever run was
    current; switching to Play meanwhile moved Play's own progress. Show now captures the Create
    visit, session and run token before the save and does nothing if any changed. Browser tests hold
    the save with a controlled promise for Play, and for Create → Play → Create, and keep one normal
    Show → Back.
  • R3, Play after a stamped VIEW lost a frame. returnToPlay replayed the old picture on the
    edited files and threw on the missing frame. When the room's own parts changed, Play now restores
    the moment on the captured files and enters the room on the edited ones through the same validated
    room entry an applied change uses, on the detached candidate before the run is replaced, so a
    refusal leaves Create as it was. The existing refusals (removed VIEW or SOUND, profile, OBJECT,
    scan.start in a LOGIC other than the room's own, changed LOGIC behind a waiting message) still
    hold. The test checks the new pixel, the progress variables, the pause, the save's revision, and
    that the resumed timeline replays to the live state.
  • R4, pause check coverage. 43 spec files imported Playwright's own test, so the pause check
    skipped them. All now use app/e2e/test.ts; app/test/e2e-shared-test.test.ts fails a spec that
    does not. The check now also covers other pages in the default context and pages closed before
    their context, each checked just before it closes. A planted disagreement failed all three page
    cases. Five specs about the profile picker opt out of the fixture that dismisses it.
  • The review's optional point is taken too: a picture the room drew and then discarded counts among
    what the room uses.

The first review also found smaller gaps, fixed here with a test each:

  • A refused forced save was forgotten unless a room entry was pending. It now stays owed until the
    game reaches a boundary that can be saved.
  • A cycle report took every poll that arrived 250 ms or more after the last, starving periodic
    saves. This was already in 1.2.2.
  • Returning to Play from a Create opened before the game ran compared rooms anyway and reported a
    room 0 restart.
  • The automatic VIEW-layout re-entry left an active test recording marked clean.

How it works

  • Engine.roomResources() names what the current room has in use, including VIEWs stamped into
    the picture. roomResourcesChanged in app/src/worker/roomChange.ts compares two game images on
    exactly those resources.
  • Project admission swaps the files in, then records a room re-entry in the same timeline segment.
    A change the engine says needs a re-entry enters the room with it, in a new segment as before.
  • While a host room entry is still to run, a visual change the screen cannot rebuild returns
    deferred, and the page's project session retries it. A re-entry admits such a change only when
    Engine.entryRedraws (a detached copy entering the room on the staged files) draws a whole
    picture.
  • A paused host poll runs a room entry the host began, honouring a recorded cycle: false and the
    armed-pass accounting, so a change shows and is saved while the game waits.
  • A forced checkpoint that cannot be taken yet is retried on each host poll. The cycle report and
    the checkpoint no longer share one branch.
  • returnToPlay re-enters the captured room when Create changed what it uses, skips that for a
    cold return point, and reports the room in projectPlayed.restartedRoom. When the moment cannot
    restore on the edited files, adoptResumePoint(..., { freshEntry: true }) restores it on the
    captured files and commits a room entry on the edited ones, on the detached candidate, before the
    run is replaced.
  • WorkerContext.livePause holds the page's last pause message; live replacements use it.
  • The state query reply carries runtime: { paused, cycle } from the worker. app/e2e/test.ts
    compares it with the page's pause for every page a test opens, just before that page closes.

Limits

  • A return point captured while a message from LOGIC N was open cannot resume after LOGIC N
    changes. Play asks the player to choose Restart, as in 1.2.2.
  • Show Room N appears for edited room LOGICs. A PICTURE or VIEW change in another room gets no
    button.
  • The original report of Play frozen while the bar showed it running matches an Agent panel carried
    from Create into Play, found in a walkthrough on the owner's setup and fixed here. It reproduces
    the same way on 1.2.2.
  • While a room restart is still to run, a picture or VIEW edit the screen cannot take waits for it,
    usually one game cycle, then lands or asks for a restart.
  • Opening Create on a catalog game saves a copy at once, so opening it twice leaves two cards with
    the same name. This is 1.2.2 behavior.
  • Approving a change before the review's code diff finishes computing logs an unhandled
    "no diff result available" from the diff editor. Nothing shows on screen.
  • The phone layout was checked in code, not on a device.

Process

  • docs/hosting.md: a release pull request dates its CHANGELOG.md entry on the day it opens.
    1.2.2 is now dated 2026-10-10, and 1.2.3 is dated for its merge day. test/docs.test.ts fails on an undated entry.
  • AGENTS.md: a test protects a product decision. It names the player-visible rule and asserts what
    the player sees. A rewritten expectation goes to the owner as a decision to confirm.

Tests

  • Every new worker, engine, home-shelf and browser test was watched failing first.
  • The pause check fails a test that leaves the page and game disagreeing. Its first full run found
    Restart and Back/From my game setting the pause on their own, and two spec helpers that paused the
    worker behind the page; all are fixed here.
  • tutorial-continuity.spec.ts now checks its own cards, so it passes with or without contributors'
    local game fixtures.

Also in this release

  • #83: the browser test's pixel probe waits for the canvas to paint before it hashes it, and a worker test checks that a resumed autosave shows the frame it was saved from. The CHANGELOG headings link to their releases.

🤖 Generated with Claude Code

https://claude.ai/code/session_011oMJZaRGYfxBZ4LEnu9hPD