Skip to content

EN Contribute Import Boundaries

wanoo edited this page Oct 23, 2026 · 2 revisions

Import boundaries

Français · Type: reference · Audience: contributor · Context: engine repository · Status: ready · Applies from: 4.1.14

What each folder of src/engine/ may import, where each responsibility of the engine, the player and the solver lives, and what is public. The source is src/engine/BOUNDARIES.md; tests/boundaries.test.ts checks the rules on every run of the unit suite.

The layers and what they may import

feature since 3.9.0

Values

Layer Folder May import Never
Core core/ itself, plain packages (zod/mini) the DOM, tools, dev, minigames, the Studio
Player dom/, minigames/, ending/, boot.ts core, each other; tools/i18n (locales at boot); tools/replay and dev/ only through import() the solver, the validator, the linter, any other tool, the Studio, tweakpane
Scene scene/ (4.1.11) core (the painter's specs as types only) the DOM, tools, dev, the Studio, a painter
Reality reality/ (4.1.1) core, plain packages (zod/mini); WebCrypto the DOM, tools, dev, the Studio, the Bridge (bridge/)
Tools tools/ core the DOM (they run in Node, workers and tests)
Dev dev/ anything being imported statically by the player

Outside src/engine/, the test also holds two rules of 4.1.1: the engine never imports the Bridge (Biscuit, keys and the server stay out of every game), and the Bridge reaches neither the Studio, the tools, nor a game: only the protocol it shares with the player.

Guarantee · core-imports-no-dom · referenced · scope self-checked by the author (AI), not reviewed The core imports none of the engine's other layers: no DOM layer (dom/), no tools, no dev code, no minigames, no ending/, no Studio. A static import that breaks this fails the unit suite. The check reads the import statements of the files; it cannot see a module reached through a global or an eval.

The check does not sort packages: keeping the core's packages plain is left to review.

Constraints

  • The player's first visit is held to assetBudgets.initialJsKB (npm run verify:dist): the minigames load when one starts (minigames/meta.ts keeps what the tools read of them), the dev panel and the Studio on demand.
  • A painter (dom/render-*.ts, dom/renderer.ts, dom/frame-renderer.ts) never imports the engine, its ports or its runtime modules, not even as a type (4.1.11, D21): it is given frames and specs, and answers with intentions.
  • No cycle of static imports anywhere in src/engine (4.1.0): a module never imports itself back. Types (import type) are erased and do not count.

Behaviour on an unknown folder

A new folder under src/engine/ belongs to no layer of the test until one is written for it: add it to BOUNDARIES.md and to tests/boundaries.test.ts together.

Inside the core (4.1.0 "Clarity")

feature since 4.1.0

Engine (core/engine.ts) is the facade: its state, its lifecycle (new game, load, checkpoint) and one forwarding method per operation, in the same order of effects as before the split. What each operation does lives in a module of its own, a function taking the engine as its first argument:

Module What it does
core/session-runtime.ts the session: entries opened and closed, the answers recorded, digests, replay's feed
core/event-runtime.ts emit: scripts waiting for the event, then the room's listeners, then the game's
core/script-runtime.ts scripts: their state, one step, loops, the scheduler
core/interactions.ts the rule, kind or fallback that answers an action; lines, hints, the talk loop
core/command-runtime.ts exec and step: running Cmds, each through its handler in core/command-handlers.ts (4.1.5); where a command points in the room
core/world-queries.ts names, kinds, visibility, prop states, targets, approach points
core/players.ts several playable characters: who is where, switch, swap, transfer
core/movement.ts walking, entering a room, the map and its travel, a teleport (4.1.1)
core/reality-runtime.ts a signal from outside: applied at most once, the cursor, the session entry (4.1.1)
core/engine-shared.ts the context of a command, the journal's entry, small helpers
core/journal.ts the semantic journal (4.1.11): what happened, in ids, numbered; emitted by the core alone
core/busy.ts the busy owner (4.1.11): runs in progress, the tutorial step waited for, a skip
core/run-clock.ts the run clock (4.1.14, ADR 0016): logical steps and time, told by the session and the commands; it never writes the state
core/prng.ts the seeded generator (4.1.14): xoshiro128**, a stream per purpose; engine.random draws from logic
core/run-tape.ts a run's links (4.1.14): each entry with its events and the clock after it, the same live and replayed
core/journal-chunks.ts the run's chunks chained by SHA-256 (4.1.14), written to a ChunkStore, read back checked
core/types/*.ts the content format by subject; core/types.ts re-exports every name

The modules import Engine as a type only; tests/core-runtime.test.ts calls each directly.

Inside the player (4.1.0 "Clarity")

feature since 4.1.0

App (dom/app.ts) is the orchestration (4.1.11): its state, the constructor, and the composition of the engine, a Presenter (dom/presenter.ts) and the room view's renderer. The rest lives in modules called through forwarding methods, as in the core:

Module What it does
dom/presenter.ts the Presenter the engine talks to (4.1.11): the scene's calls, lines, overlays, minigames, the ending; intent(), the one door of the player's input
dom/room.ts the scene model: entities, walking, the camera; it makes the SceneFrame (scene/frame.ts) and paints it
dom/room-stage.ts a room's stage for the painter: conditions evaluated, images placed on the backdrop (4.1.11)
dom/frame-renderer.ts a painter (DOM or Canvas) as a Renderer: whole frames, an unchanged one skipped, a changed one by its differences
dom/shell.ts the shell's elements, their layout for the screen, the accessible targets (from the frame's targets)
dom/side-fit.ts the phone column's fit (pure): verb and slot heights that keep the tools row on a short screen
dom/input.ts verbs, the inventory bar, taps and double taps (verbFor, nearMiss), the keyboard, the action line
dom/speech.ts lines with their voice, the transcript, phone calls, the choice of responses
dom/map-view.ts the map and the travel animation
dom/menus.ts title, pause (and the session export, through import()), save slots, restart, credits
dom/settings.ts the player's preferences, their defaults and menu
dom/update.ts the offline warm-ups and status, the update offered after a verified save
dom/storage.ts the localStorage autosave and slots (when IndexedDB is missing)
dom/app-shared.ts small helpers (element factory, tap timings, the FPS meter)
dom/reality-ui.ts the world link (4.1.1): pairing, status, the client; loaded by import() only for a game with reality
dom/run-store.ts the runs' IndexedDB store (4.1.14, web-scumm-runs): chunks and heads in one transaction, local records
dom/speedrun-ui.ts the speedrun mode (4.1.14): the recorder on the app's engine, its timer, records, ghost, export; loaded by import() (it reaches tools/speedrun/ the same way)

Inside the solver (4.1.0 "Clarity")

feature since 4.1.0

tools/solve.ts re-exports what it exported before; the solver lives in tools/solve/:

Module What it does
src/engine/tools/solve/search.ts solve(): the frontier, the proof workers, termination and the verdict
src/engine/tools/solve/expansion.ts makeExpander: every action worth trying from a state, run on the real engine; the no-op memo
src/engine/tools/solve/abstractions.ts what a state is made of (dimensions), the canonical forms (players, mobility, ownership), dominance
src/engine/tools/solve/model.ts options, SearchNode, Expansion and a transition (TryRecord), with their invariants
src/engine/tools/solve/scenarios.ts signals from outside in a search: closed, a scenario, adversarial (4.1.1)
src/engine/tools/solve/report.ts the result, its profile, the profile as text
src/engine/tools/solve/drive.ts an engine promise awaited, the guided tutorial's steps played meanwhile
src/engine/tools/solve/explosion.ts the explosion profile (4.1.13): the states attributed to positions, inventories, flags, dialogues, scripts
src/engine/tools/solve/search/compact.ts the store of the states seen (4.1.13, ADR 0015): by index, interned keys, parents, paths and session entries
src/engine/tools/solve/search/checkpoint.ts a search written down and taken up again (4.1.13): snapshot, header, fingerprint
src/engine/tools/solve/search/classify.ts the verdict of a proof over the stored states: reverse reachability, softlocks and their causes
src/engine/tools/solve/search/dominance.ts dominance, symmetric items, independent sub-puzzles (4.1.13)
src/engine/tools/solve/search/partition.ts the workers' shared visited table, the partition of a batch and work stealing (4.1.13)

The path of a proof reads solve() → solveOnce() (search) → makeExpander() (expansion) → the engine's act() → a TryRecord merged into the store and the frontier → the verdict.

File size

No file of src/ is over 800 lines but the exceptions tests/file-size.test.ts lists with their reason, each capped at its size: an exception never grows, and leaves the list once under the limit.

Public and internal

Public, and held to semantic versioning: the five entries of src/engine/api/, published as quest-n-click/content (the types and defineGame), quest-n-click/player (boot), quest-n-click/minigames, quest-n-click/testing (Engine, the fakes, the save envelope, solve) and quest-n-click/reality (since 4.1.1); the content format, the save envelope and the MCP tools. They are held by tests/api-surface.json and the support policy (Stability and support, Public API).

Internal: the modules behind the Engine and App facades (their members marked @internal), the solver's modules, the tools' code. They may move between minor versions.

Related identifiers

  • npm run verify:dist (the first visit's budget), tests/boundaries.test.ts, tests/file-size.test.ts, tests/api-surface.json.
  • Architecture, Code tour.

Edit the source of this page · Report an error

Home

Index (6)
Start (6)
Play (9)
Install (17)
Create a game (55)
Engine (4)
Local Studio (24)
Team Studio (21)
Clever Cloud (23)
Reality Bridge and connectors (16)
Contribute (25)
Reference (7)

Clone this wiki locally