Skip to content

feat(playback): play execution visualization — taken paths, +N badges, arrival and conversion cues #330

Description

@MerciHanrim

Summary

Playback already animates one round token per connection per step along the connection's real path, in the engine's own order (docs/simulation-playback.md, docs/simulation-playback-ordering.md). This issue keeps that token and adds to it, so a step reads as "what moved where": every path that carried a move, its amount as a +N badge beside the token, a pulse inside the Pool when the token arrives, a mark inside the Converter, and a rule per way of running. It is a presentation layer only. The playback docs are living documents; the engine, the RNG and the PB-INV and PBO-INV invariants are kept.

Current state

Measured read-only on main 6de1852 (dev server) and on production v0.21.0 · build 6de1852 (real UI, throwaway Chrome contexts); both agree.

  • Token: one round dot (r 3.6, the run colour) per connection per step, carrying the step's summed amount; the amount shows as a bare number 8 px above the dot only when it is above 1, and it can sit on top of the connection's own label. It follows the real Bézier or orthogonal path.
  • Order: connections start in up to 6 buckets within the first 30 % of the step; a router's pull-in and push-out share one onset.
  • Gate: no taken-path tell; a branch with no move just has no token.
  • Pool: the arrival disc plays at settle, after the token is gone, for 120 ms.
  • Converter: no conversion cue; inputs and output move together with the generic fired wave.
  • Speed: 120 to 2400 ms per step (default 600, not persisted); every speed draws the same choreography, and at 120 ms the cue keyframes (120 to 500 ms) are cut off at settle.
  • Budget: at most 60 travelling cues per step; the widest bundled step measured (early MMO, 10 steps) peaks at 35.
  • Monte Carlo: nothing on the canvas. Reduced motion: no travel, held static cues. L0: no token, a path pulse.
  • Phone: no speed control (docs/mobile.md §MV4), always 600 ms; a fitted template sits at about 0.45 zoom, on the L0 line.
  • Priority: tokens always use the run colour (FC-4.2); on a connection outside the Focus set they play at full strength, and the connection itself is not dimmed either (a separate bug, fix(canvas): Focus mode does not dim the connections outside the focus set #329).

The round token stays

The round token that travels a connection today is kept wherever it travels today; the one exception is the very fast tier, where it still appears, at the end of the flashed path. +N is a badge that adds the amount to it; it never replaces it.

Way of running What is drawn
Step, Play slow or normal (beat of 400 ms or more) the round token travels its path with the +N badge beside it
Play fast (300 ms) the round token travels; +N shows when it arrives
Play very fast (120 ms) the path flashes briefly, then the round token appears at the end and leads into the arrival pulse with +N
Phone, default 600 ms the round token keeps travelling
Reduced motion no motion; the path highlight, the arrival circle and +N stay, static, for the step
Monte Carlo no round tokens, as today
Many moves in one step at most 24 token-and-badge pairs, chosen in a stable event order; every other move shows as its path highlight and its arrival cue

The desktop slider is continuous (120 to 2400 ms), so the tiers have exact boundaries: 400 ms and above is the full tier (the token and its +N badge travel together), 200 to 399 ms is fast (the token travels, +N shows on arrival), below 200 ms is very fast (the path flashes, then the token and +N appear at the end). Step always draws the full tier, whatever the slider says. The tier is read once when a step starts; a speed change during a step applies from the next step. The phone's 1000, 600, 300 and 120 ms each fall in exactly one tier.

Decisions

  1. Token unit: one summed round token per connection per step, as today. No token per engine transfer.
  2. Amount: always shown as +N, from +1, as a badge beside the token; the pair is drawn on top. The connection's own label never moves; it dims only while its real bounding box overlaps the token or its badge. Only the connection's own label is checked; no other connection's label is tested on any frame.
  3. Gate: for every gate kind, every outgoing path with a move event this step is highlighted and carries its round token; several can be at once. A branch with no event gets no playback cue.
  4. Converter (option A): inputs and output keep the engine's order and their tokens move together; a conversion mark is shown inside the Converter. No consume-then-produce sequence.
  5. Per mode: the table above. Monte Carlo draws no per-move choreography.
  6. Focus mode wins on connections: the path highlight, round token and badge on a connection outside the focus set are drawn at the same low strength as the connection. Inside the nodes, the fired wave, the evaluated mark, the Pool arrival pulse and the conversion mark keep full strength, as §LGR2.3 intends.
  7. Phone (§MV4 reopened narrowly), in the last pull request: a four-step choice under ⋯ → Playback speed: Slow 1000 ms, Normal 600 ms, Fast 300 ms, Very fast 120 ms. No run seed in the bar; the Monte Carlo dialog keeps its base seed. Each step follows the same tier as on the desktop, with fewer moving elements and simpler effects.
  8. Cap: at most 24 token-and-badge pairs per step, the dot and its badge counted together. This replaces the 60 travelling-cue budget. Past 24, every path that moved keeps its highlight and every arrival keeps its cue.
  9. Reduced motion and forced colours: every pull request implements and tests the reduced-motion and forced-colours forms of the cues it adds, in the same pull request.

Visual priority

  • Invalid, selection and keyboard-focus rings stay on top, unchanged.
  • The structure line and flow colours stay.
  • The arrival pulse and the conversion mark are drawn inside the node only.
  • The playback path is drawn on the connection and follows Focus dimming.
  • No animation reaches a file, a digest or an engine result.

Contract changes, in the documents they belong to

Document Change
docs/simulation-playback.md §PB2.1, §PB9 the arrival pulse inside the Pool after the token arrives; the value still changes at settle; the static forms
docs/simulation-playback.md §PB4.5, PB-Q4 +N from +1 as a badge beside the token; 24 token-and-badge pairs per step replace the 60-cue budget; every moved path highlighted past the cap
docs/simulation-playback.md §PB6.1 the three speed tiers and their boundaries
docs/simulation-playback-ordering.md §PBO3 the conversion mark; onsets unchanged
docs/large-graph-readability.md §LGR2.3 playback cues on a dimmed connection follow the dimming; the cues inside a node keep full strength
docs/mobile.md §MV4 the four-step speed under ⋯; no run seed
docs/visual-language.md §VL9 the new motion and its reduced-motion forms

Pull requests

Work scheduled before PR 1

These are not part of the playback work; they are fixes scheduled to ship before PR 1.

Playback pull requests

Each pull request can be reverted on its own, keeps every existing playback test green, and changes a visual baseline only where it draws something new, each reviewed before it is updated.

Out of scope

  • Any engine, RNG, state-semantics, file format, digest or simulation change; Monte Carlo and Predict stay without per-move choreography.
  • Camera moves or auto-pan to the action; recording or exporting the animation; scrub with choreography.
  • feat(graph): color-coded flows and compact nodes #325 and its milestone stay closed.
  • No manual screen-reader check; automated accessibility-tree, focus and live-region tests are the bar.

Done when

  • Every decision above is shipped, with its contract change in the document it belongs to.
  • Wherever a round token travels in v0.21.0, it still travels, except at the very fast tier, where it appears at the end of the flashed path.
  • The committed simulation, the run CSV, files and digests are byte-identical with and without the new cues, at every speed and under reduced motion.
  • Every new cue has a reduced-motion and a forced-colours form, and a test that pins it.

Activity

  1. MerciHanrim commented on Oct 9, 2026

    @MerciHanrim
    OwnerAuthor

    All three playback pull requests have shipped, after the prerequisite Focus-mode fix (#329, PR #331, v0.21.1).

    Pull request Version Merge Release
    #341: the Gate path, +N badges, the own-label rule, 24 pairs a step v0.22.0 c4640bc v0.22.0
    #342: the Pool arrival pulse and the Converter mark (option A) v0.23.0 1a1ce1b v0.23.0
    #343: the speed tiers, Step at full, the phone's Playback speed and its 12-pair profile v0.24.0 10098d6 v0.24.0

    All three released on 2026-10-09, each with its reduced-motion and forced-colours forms and the contract changes in the documents listed above.

    CI:

    Production, through the real UI in fresh browser contexts with no dev bridge:

    • v0.22.0 (c4640bc): 27 of 27 checks.
    • v0.23.0 (1a1ce1b): 13 of 13 checks.
    • v0.24.0 (10098d6): the v0.24.0 checks 18 of 18 (the three tiers, the tier read once a step, Step at full, the phone's four speeds, 12 pairs and no departure ring on the phone, the profile fixed for the step, reduced motion on the phone), and the v0.22.0 and v0.23.0 checks again, 27 of 27 and 13 of 13; no page error.

    Recorded as a current limit, not part of this work: a stress graph with about 300 transfers in one step draws at roughly 70–200 ms a frame on a desktop development build, before these changes as after them (docs/simulation-playback.md §PB6.1). Text containment in nodes stays deferred in #337.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions