From a6cff8b3b150221f9915b057fb0c5e7de1a8d278 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Sat, 11 Apr 2026 03:14:45 +0200 Subject: [PATCH] Add AGENTS.md and update CHAT_CONTEXT.md, architecture.md --- AGENTS.md | 247 ++++++++++++++++++++++++++++++++++++++++++++++ CHAT_CONTEXT.md | 255 +++++++++++++++++++----------------------------- architecture.md | 7 ++ 3 files changed, 352 insertions(+), 157 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..193bb06d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,247 @@ +# AGENTS.md + +## Purpose + +This is the mandatory high-signal brief for agents working in this repo. + +Read this file first. +Then read `CHAT_CONTEXT.md`. +After that, inspect the code and open only the relevant sections of `architecture.md`, `roadmap.md`, and `testing.md`. + +Do not read the large docs end-to-end by default. + +When docs and code disagree: + +1. trust the code for current behavior +2. trust `AGENTS.md` + `CHAT_CONTEXT.md` for current intent +3. use the larger docs as selective reference +4. update stale docs if your slice materially changes behavior + +--- + +## Product + +This repo is a browser-based engine/editor for interactive 3D environments with a built-in runner. + +Core loop: + +1. author +2. save/load +3. run immediately in-browser + +Primary product priorities: + +- intuitive whiteboxing / level blocking +- imported assets as first-class content +- typed entities and simple interactions +- very fast edit -> run iteration +- web-native delivery and sharing + +This is not: + +- a Blender replacement +- a general CAD tool +- an unlimited engine platform +- a full physics sandbox unless the roadmap explicitly says so + +--- + +## Hard Rules + +### Canonical state + +- The canonical `SceneDocument` / project state is the source of truth. +- Do not store three.js objects in canonical document state. +- Do not make the three.js scene graph the source of truth. +- Editor-authored mutations should go through commands. + +### Layering + +- `document` owns canonical state +- `commands` own undoable mutations +- `geometry` owns derived solid/mesh/collider generation +- `viewport-three` owns editor rendering and interaction helpers +- `runtime-three` owns play-mode runtime behavior +- `entities` own typed non-model scene objects +- `assets` own imported external resources and adapters +- `serialization` owns save/load/versioning/migrations + +### Persistence + +- The document is versioned from day one. +- If persisted schema changes, update version/migration/validation and add at least one compatibility test. +- Canonical save format is project JSON. +- Once binary assets matter, user-facing save/load must be a portable project package containing canonical JSON plus referenced assets. +- Runner/deployment output is separate from editable save/load. +- Never rely on Blob URLs as the only persisted asset reference. + +### Models, entities, world + +- Imported assets live in the asset registry. +- Placed imported models live in `modelInstances`. +- `modelInstances` are not `entities`. +- Typed runtime/editor objects such as `PlayerStart`, `TriggerVolume`, and lights live in `entities`. +- Global ambient/sun/background/fog belong in `world` settings. +- Local authored lights belong in typed entity schemas. + +### Imported model collision + +- Collision authoring for imported models belongs on `modelInstances`, not assets. +- Supported imported-model collision modes must stay explicit and typed. +- Generated collision data is derived data, not canonical source data. +- If broad-phase/narrow-phase pruning or non-box collider support is needed, prefer Rapier over custom collision math. +- Collision mode meanings are fixed unless deliberately changed: + - `none` = no collider + - `terrain` = heightfield collider, static only + - `static` = triangle mesh collider, fixed only + - `dynamic` = convex decomposition into compound collider, dynamic/kinematic capable + - `simple` = one cheap primitive or one convex hull + +### Whiteboxing direction + +- The product is moving away from grid-bound brush thinking toward whitebox solids. +- Floating point position/rotation/scale are allowed. +- The grid is a snap/reference helper, not a hard law. +- Whiteboxing should converge on one coherent transform-driven interaction model. +- Object / face / edge / vertex editing are valid goals. +- Non-planar quads are acceptable if derived triangulation is deterministic. +- Whitebox solids do not have to remain convex. +- Collision should come from the solid collider path, not old axis-aligned assumptions. + +--- + +## Implementation Strategy + +### Default workflow + +1. Inspect the current repo first. +2. Extend the existing implementation. +3. Keep the slice as small and vertical as possible. +4. Reuse existing paths instead of adding parallel architecture. +5. Verify with the narrowest relevant checks. + +### Vertical slices + +Good slice: + +- document changes +- commands +- viewport/editor behavior +- UI +- persistence +- runner behavior if relevant +- tests +- brief manual QA notes + +Bad slice: + +- scaffolding with no user-facing payoff +- duplicate systems +- speculative abstractions + +### Read selectively + +Only open full reference sections when needed: + +- `architecture.md` for non-trivial runtime/editor/data-model boundaries +- `roadmap.md` for future direction and accepted scope +- `testing.md` for which test layers to add + +If the slice is local and obvious, do not reload half the repo’s docs. + +--- + +## Code Rules + +### Do + +- use TypeScript only +- keep types explicit +- prefer pure functions for transforms/build steps +- isolate browser/three.js side effects +- fail loudly in development +- surface useful diagnostics instead of silently ignoring errors +- keep geometry/collision generation testable outside the browser where practical + +### Don’t + +- add R3F casually +- add ECS casually +- over-generalize the entity system +- replace canonical whitebox data with hidden renderer-only mutations +- invent hidden magic behavior without schema support +- remove tests to get green CI +- silently corrupt state on failure + +--- + +## UX Rules + +Prioritize: + +- fast selection +- direct transforms +- understandable tool state +- visible feedback +- quick play testing +- clear failure modes + +Every meaningful feature should answer: + +- what the user sees +- what the user clicks/drags/types +- how it is undone +- how failure is shown +- how it is tested + +--- + +## Testing Rules + +At minimum, match the slice: + +- pure/domain tests for deterministic logic +- serialization tests for persisted features +- runtime/build tests where runtime behavior changes +- browser/e2e only when real browser behavior matters + +If schema changes: + +- add round-trip coverage +- add migration/compatibility coverage + +Prefer small explicit fixtures over giant snapshots. + +--- + +## Vocabulary + +Use precise terms: + +- `Document`: canonical editor state +- `Whitebox Solid`: author-authored blockout / gameplay-space solid +- `Box Solid`: the first whitebox solid shape; old code may still say “box brush” +- `Face` / `Edge` / `Vertex`: editable parts of a whitebox solid +- `Asset`: imported external resource +- `Model Instance`: placed instance of an imported asset +- `Entity`: typed scene object with editor/runtime semantics +- `Collider`: derived runtime collision representation +- `Project Package`: portable editable bundle +- `Runner Package`: deployable playable output +- `Build`: deterministic document -> runtime transformation + +Avoid vague terms like “thing” or “object” when a domain term exists. + +--- + +## Required Closeout + +For meaningful changes, report briefly: + +1. what changed +2. why +3. files touched +4. how you verified it +5. known limitations + +If you could not verify something, say so plainly. diff --git a/CHAT_CONTEXT.md b/CHAT_CONTEXT.md index b53e80fa..883e7588 100644 --- a/CHAT_CONTEXT.md +++ b/CHAT_CONTEXT.md @@ -1,198 +1,139 @@ # CHAT_CONTEXT.md -This file is the lightweight startup context for new Codex chats. +This file is the small startup brief for new implementation chats. Read this after `AGENTS.md`. -Then inspect only the relevant sections of `architecture.md`, `roadmap.md`, and `testing.md` for the active slice. +Then inspect the code. +Then open only the relevant sections of `architecture.md`, `roadmap.md`, and `testing.md`. -This file does not replace the full docs. -It exists to keep new chats focused and to reduce repeated context load. +The large docs are reference docs, not mandatory full reads. --- -## Product summary +## Current Status -This repo is a browser-based 3D scene authoring tool with a built-in runner. +As of now, the repo is no longer in the very early “empty skeleton” phase. -Core loop: +Broadly implemented already: -1. author a scene -2. save/load it reliably -3. run it in-browser immediately +- foundational document/command/persistence/test setup +- box-based room authoring and per-face materials / UVs +- built-in runner with edit -> run loop +- world settings / lighting / environment basics +- typed entities and trigger/action/target interaction flow +- GLB/GLTF model import and model instances +- local lights, animation playback, spatial audio +- advanced rendering +- better material-library workflow +- runner package / embeddable runner work +- multi-viewport editor foundations +- unified creation/placement foundations +- transform foundations -The product prioritizes: +Important consequence: -- intuitive whiteboxing / level blocking for interactive 3D environments -- imported assets as first-class additions -- typed entities and simple interactions -- browser-native delivery +- many roadmap sections are now historical context, not literal todo items +- do not assume Milestone 0-3 are untouched just because they are still documented -It is not: - -- an unlimited general-purpose engine platform -- a Blender replacement -- a general CAD tool -- an R3F showcase +When in doubt, inspect the current code before trusting old milestone wording. --- -## Hard architectural rules +## Current Product Direction -- The canonical `SceneDocument` is the source of truth. -- The document must stay independent from three.js objects. -- Editor-authored mutations should flow through commands. -- The editor viewport is derived from the document. -- The runner is a sibling system, not an editor hack. -- Canonical document format is project JSON, not glTF/GLB. -- Portable save/load for asset-bearing scenes should use a project package built around that JSON. -- Runner/deployment output is downstream from the document/runtime build and is separate from editable project save/load. -- Model instances are separate from typed entities. +The product is a browser-native engine/editor for interactive 3D environments. + +Key direction: + +- intuitive whiteboxing / level blocking +- imported assets as first-class content +- typed entities and runtime interactions +- fast built-in runner workflow + +The geometry direction is shifting from old grid-bound “brush” thinking toward whitebox solids: + +- floating point transforms allowed +- free object rotation allowed +- grid is optional snap/reference help +- object / face / edge / vertex editing should converge on one transform-driven model +- non-planar quads are acceptable if triangulated deterministically +- non-convex whitebox solids are acceptable if the solid mesh/collider path supports them + +Old code and docs may still say “brush” in places. +Treat current box-brush structures as the starting point for whitebox solids unless the slice deliberately changes that. --- -## Early binding decisions +## Hard Current Assumptions -These are fixed for the early milestones unless a later slice explicitly changes them. +- world is right-handed and Y-up +- canonical state lives outside the React tree +- document/project state remains source of truth +- editor changes should flow through commands +- model instances remain separate from entities +- world settings own global background / ambient / sun / fog +- local authored lights stay in typed entities +- project save/load and runner export are separate concerns -### Coordinates and units +Imported model collision: -- world is right-handed and **Y-up** -- `+X` is right -- `+Y` is up -- units are meter-like - -### Repo shape - -- keep the repo as a single Vite app -- keep domain folders under `src/` -- do not split into a monorepo early - -### State ownership - -- do not use the React tree as the canonical state container -- keep canonical state in a thin external editor store/service - -### Persistence - -- version the document from day one -- keep migrations explicit -- early project persistence can be local draft storage plus JSON import/export -- once binary assets exist, portable save/load should use a project package such as `scene.json` plus bundled assets -- canonical JSON stays the source document format underneath that project package -- runner package output is a separate deployable artifact -- binary assets must survive reload via embedded or project-scoped persistent storage -- never rely on Blob URLs as the only persisted asset reference - -### Current box-solid foundation - -- early slices began with an axis-aligned box shape and stable face IDs -- stable box face IDs are: - - `posX` - - `negX` - - `posY` - - `negY` - - `posZ` - - `negZ` -- `posY` is top and `negY` is bottom - -### Whitebox direction - -- move away from grid-bound brush thinking toward whitebox solids -- allow floating point transforms -- allow free object rotation -- use the grid as optional snap/reference help, not as a hard restriction -- unify object / face / edge / vertex editing around one transform-driven interaction model -- non-planar quads are acceptable if triangulated deterministically in derived geometry -- non-convex whitebox solids are acceptable if the solid mesh/collider pipeline can support them - -### Early UV data - -Per face, keep explicit UV transform values such as: - -- `offset` -- `scale` -- `rotationQuarterTurns` -- `flipU` -- `flipV` - -“Fit to face” should rewrite explicit values, not add a magical persistent flag. - -### Model placement - -- imported assets live in the asset registry -- placed imported models live in `modelInstances` -- typed scene objects like `PlayerStart`, `TriggerVolume`, or lights live in `entities` -- collision authoring for imported models belongs on `modelInstances`, not asset records -- generated imported-model collider data should be derived from asset geometry + instance transform + authored settings -- for imported-model collider types beyond simple boxes, prefer a Rapier-backed collision/query layer over extending the handcrafted collision code indefinitely -- broad-phase and narrow-phase pruning should come from that collision/query layer, not custom app code - -### Interaction scope - -- keep `Trigger -> Action -> Target` typed and explicit -- do not add actions for systems that do not exist yet - -### World environment vs local lights - -- global background / ambient / sun / fog belong in `world` settings -- local authored lights belong in typed entity schemas -- true skyboxes or environment textures belong after persistent asset storage exists +- authored collision settings belong on `modelInstances` +- generated collider data is derived, not canonical +- if non-box collider support needs broad-phase/narrow-phase pruning, prefer Rapier over custom app-side collision math --- -## What a good slice looks like +## Reading Strategy -Each slice should land the smallest coherent end-to-end version of the feature across the layers it touches: +Default: -- document data -- commands -- viewport behavior -- runner behavior if relevant -- persistence -- UI -- tests +1. read `AGENTS.md` +2. read this file +3. inspect the code paths touched by the slice +4. open only the relevant sections of: + - `architecture.md` + - `roadmap.md` + - `testing.md` -Do not land speculative scaffolding with no immediate slice use. +Open the larger docs only when needed: -If a roadmap item is too large, split it into smaller vertical slices. +- `architecture.md` + - data-model boundaries + - runtime/editor integration + - geometry/collision semantics + - persistence/export/package architecture + +- `roadmap.md` + - whether a direction is already chosen + - whether something is intentionally deferred + - how a large topic should be split into slices + +- `testing.md` + - what test layers to add + - schema/migration expectations + - browser/e2e guidance + +If the slice is small and local, do not reread unrelated doc sections. --- -## Required habits for implementation +## What To Be Careful About -- Inspect the current repo first. -- Extend the current implementation instead of restarting architecture. -- If persisted schema changes, update versioning/migrations and add a compatibility test. -- Run the narrowest relevant checks you can. -- Report what was actually verified. +- do not restart architecture just because the original docs were written earlier +- extend existing paths instead of introducing parallel systems +- if docs and code disagree on current behavior, trust the code and update docs if your slice changes direction materially +- keep responses brief and verification scoped to the actual slice --- -## Early slice ordering to keep in mind +## Likely Near-Term Themes -- M0: foundation, document, commands, persistence, test setup -- M1: axis-aligned box brushes, face materials/UVs, runner, first-room polish, world lighting basics -- M2: typed entities, simple trigger/action/target interactions, click interactions -- M3: GLB/GLTF import, local lights + skyboxes, animation, spatial audio -- M4+: whitebox-solid interaction model, component editing, derived solid triangulation/collision +The next large topics are more likely to be things like: -That ordering matters because: +- whitebox-solid editing model +- multi-scene / project structure +- richer runtime systems +- remaining packaging / portability work +- future primitives and topology tools after the whitebox direction is coherent -- world settings do not need entity or asset pipelines -- local lights need the entity system -- skyboxes need persistent asset storage -- animation and audio actions should land only with those runtime systems - ---- - -## When to open the full docs - -Open the relevant full sections when: - -- persistence schema changes -- runtime/editor boundaries are being touched -- a slice adds new tests or new failure modes -- geometry semantics are non-trivial -- import/export behavior changes - -Otherwise, stay focused on the active slice and keep the implementation small. +Do not assume the old prompt list is still the whole plan. diff --git a/architecture.md b/architecture.md index 3f9d571f..2deeff1b 100644 --- a/architecture.md +++ b/architecture.md @@ -1,5 +1,12 @@ # architecture.md +Use this as a selective reference doc. + +Do not read this file end-to-end by default. +Read only the headings relevant to the active slice after reading `AGENTS.md`, `CHAT_CONTEXT.md`, and inspecting the current code. + +If examples in this file lag behind the code, trust the code for current behavior and update the docs when your slice materially changes direction. + ## Overview This project is a browser-based 3D scene authoring tool with a built-in runtime runner.