Remove AGENTS.md file

This commit is contained in:
2026-04-11 03:13:59 +02:00
parent 8e5240a950
commit 3d66f7ec5c

562
AGENTS.md
View File

@@ -1,562 +0,0 @@
# AGENTS.md
## Project identity
This repository contains a browser-based engine/editor for creating interactive 3D environments, with a built-in browser runner for immediate playtesting.
The product goal is:
- intuitive whiteboxing and scene assembly for interactive 3D spaces
- modern browser delivery
- glTF asset import, with optional later interchange export
- fast edit -> run iteration
- lightweight interactive runtime with spatial audio, navigation modes, and simple entity-driven logic
This is not a general-purpose DCC.
This is not an unlimited AAA engine platform.
This is a focused engine/editor for browser-delivered interactive 3D environments.
---
## Product pillars
1. **Interactive environments come first**
- The tool exists to build playable interactive 3D spaces for the web.
- The editor and runner are one product, not separate concerns.
- One-click edit -> run must remain central.
2. **Whiteboxing is sacred**
- Layout authoring must remain faster and more direct than using a general DCC for the same task.
- Whiteboxing is a first-class workflow, not a temporary preproduction mode.
- The editor must feel immediate and precise, with snapping available as a helper rather than a hard restriction.
3. **Imported assets are first-class**
- glTF / GLB import must feel native.
- Imported meshes, materials, textures, and animations must coexist cleanly with whitebox-authored worlds.
- Imported assets complement whiteboxing; they do not replace it.
4. **The runner is built in**
- Every meaningful authoring step should be testable in-browser.
- Switching from edit mode to play mode should be nearly instant.
- The runner is part of the product, not a demo app.
5. **Web-native sharing matters**
- Scenes should be easy to load, embed, preview, and eventually share by URL.
- The browser is a target platform, not a secondary export target.
---
## Architectural stance
When making design decisions, prefer:
- plain three.js over unnecessary abstraction
- explicit data models over implicit scene graph state
- deterministic rebuilds over hidden mutations
- command-based editing over ad hoc state changes
- typed scene entities over free-form JSON blobs
- vertical slices over speculative infrastructure
- boring, maintainable code over cleverness
The project uses:
- React for application shell and editor UI
- three.js for viewport and runtime rendering
- a canonical editor document model independent of three.js
- command pattern for undo/redo
- runtime entity systems for navigation, triggers, audio, and interaction
- glTF / GLB as the main imported 3D asset format
- JSON as the canonical authoring format
Do not collapse editor state into raw three.js objects.
Do not make the three.js scene the source of truth.
Do not make glTF the canonical editor save format.
---
## Early binding decisions
These defaults are intentionally fixed for the early slices unless a later slice explicitly changes them.
### Coordinate system
- world space is right-handed and **Y-up**
- `+X` is right, `+Y` is up
- scene units are meter-like and should be used consistently for movement, collision, and audio distances
### Early repo shape
- start as a single Vite app
- keep domain folders under `src/`
- do not introduce `/apps` + `/packages` or a monorepo split until the current code actually needs it
### State ownership
- do not use the React tree as the canonical state container
- keep canonical editor state in a thin external editor store/service
- React renders and dispatches commands; it does not own the document
### Persistence
- the canonical scene document is versioned from day one
- M0-M2 may use local draft persistence plus explicit JSON import/export
- once binary assets matter, user-facing save/load must become a portable project package containing canonical scene JSON plus referenced assets
- canonical scene JSON remains the source document format, but by itself is no longer a portable project once external assets exist
- runner/deployment output is a separate downstream package, not the editable project format
- when binary assets arrive, they must survive reloads via embedded data or project-scoped packaged storage
- never rely on ephemeral Blob URLs as the only persisted asset reference
### Current box-solid defaults
- early slices began with axis-aligned box brushes
- canonical box face IDs are fixed and stable:
- `posX`
- `negX`
- `posY`
- `negY`
- `posZ`
- `negZ`
- `posY` is the top face and `negY` is the bottom face
- future geometry slices may evolve these box-authored solids into freely transformable whitebox solids while preserving stable face identity where practical
### Whitebox geometry direction
- the product is moving from grid-bound brush thinking toward intuitive whitebox solids for level blocking
- floating point position, rotation, and scale are allowed
- the grid is a snap/reference aid, not a hard authoring law
- whitebox boxes should support object, face, edge, and vertex interaction modes
- non-planar quads are acceptable; rendering/build should triangulate them deterministically
- whitebox solids do not need to stay convex
- derived collision for whitebox solids should come from the solid-collider path, not from an assumption that all geometry is convex or axis-aligned
### Model placement
- placed imported models are **model instances**, not typed entities
- keep model instances in a document collection separate from `entities`
### Imported model collision scope
- collision authoring for imported models belongs on `modelInstances`, not on asset records
- the canonical source of truth is authored collision settings, not cooked collider bytes
- generated collider data may be cached or rebuilt, but it is derived from:
- imported model asset geometry
- model instance transform
- authored collision settings
- for imported-model collider support beyond simple boxes, prefer integrating a real collision/query library such as Rapier over inventing custom broad-phase/narrow-phase code in-house
- let the collision/query layer own broad-phase and narrow-phase pruning instead of re-implementing that manually in app code
- do not turn this slice into a full physics sandbox or general rigidbody architecture rewrite unless the roadmap explicitly asks for that
- near-term slices may adapt or replace the current handcrafted runner collision path where necessary so brush and imported-model colliders can participate in one coherent collision/query system
### Runtime interaction scope
- keep trigger/action/target links explicit and typed
- do not activate actions for systems that do not exist yet
- add sound and animation actions only when those runtime systems are implemented
### Whitebox editing scope
- object, face, edge, and vertex editing should converge on one coherent transform-driven interaction model
- `G / R / S` style modal transforms with axis constraints are a good fit for whiteboxing
- clipping/extrusion/other topology tools should come after the whitebox-solid interaction model is coherent
- unsupported geometry edits must fail clearly instead of inventing hidden topology rules
---
## Non-goals
Unless explicitly added to the roadmap, do not turn this project into:
- a general CAD package
- a Blender replacement
- a multiplayer MMO editor
- a full node-based visual scripting environment
- a full physics sandbox
- a photoreal AAA renderer
- a React Three Fiber showcase
- an ECS research project
We may add optional scripting, plugins, collaboration, or advanced baking later.
They are not v1 priorities.
---
## Core product vocabulary
Use these terms consistently:
- **Document**: canonical editor state
- **Whitebox Solid**: author-authored blockout/level-shaping solid used for layout and gameplay space
- **Box Solid**: the first whitebox solid shape; current code may still refer to this historically as a box brush
- **Face**: one editable surface of a whitebox solid
- **Edge**: one editable edge of a whitebox solid
- **Vertex**: one editable point of a whitebox solid
- **Material**: logical authoring material definition
- **Texture**: image resource backing material channels
- **Asset**: imported external resource, usually GLB/GLTF or audio and related media
- **Model Instance**: placed scene instance of an imported asset
- **Collider**: runtime collision representation derived from brushes or imported models
- **Prefab**: reusable asset/entity package placeable in scenes
- **Entity**: typed scene object with runtime/editor semantics
- **Project Package**: portable editable bundle containing canonical scene JSON plus referenced assets
- **Runner Package**: deployable playable output for the built-in runner
- **Runner**: browser runtime that loads and plays scenes
- **Viewport**: editor rendering surface
- **Command**: undoable state transition
- **Tool**: editor interaction mode such as select, create, transform, or face-edit
- **Build**: deterministic transformation from document -> runtime scene data
- **Export**: downstream transformation to deployable or interchange deliverables such as runner packages or optional later GLB
Avoid vague terms like “object”, “thing”, “item”, or “component” when a more precise domain term exists.
---
## Repo expectations for agents
When working in this repo:
1. Read:
- `AGENTS.md`
- `CHAT_CONTEXT.md`
- then inspect the relevant sections of `architecture.md`, `roadmap.md`, and `testing.md` for the active slice
- if a slice touches persistence, runtime, or testing boundaries in a non-obvious way, read the relevant full doc sections before changing code
2. Respect the current vertical slice.
- Do not “prepare for future flexibility” by adding unnecessary systems.
- Implement the smallest coherent version that preserves the architecture.
3. Preserve layering.
- `document` owns canonical state.
- `commands` apply valid state changes.
- `geometry` owns derived solid and collider generation.
- `viewport-three` renders editor state.
- `runtime-three` plays runtime state.
- `entities` owns typed non-brush scene objects.
- `assets` adapts external asset/audio/media formats.
- `serialization` persists canonical state.
4. Do not bypass command infrastructure for editor mutations.
- If the user can do it in the editor, it should usually be represented as a command.
5. If persisted schema changes, update compatibility explicitly.
- bump the document schema version when required
- add or update migrations
- add at least one migration or compatibility test
6. Prefer explicit typing and explicit invariants.
- Avoid permissive `any`, loose maps, or magic strings when a discriminated union or typed schema is appropriate.
7. Keep systems testable.
- Geometry generation should be testable outside the browser UI.
- Serialization should be round-trip tested.
- Runtime interactions should be testable through deterministic fixtures where possible.
8. Keep browser concerns in mind.
- Gracefully handle pointer lock failure, audio unlock requirements, missing gamepads, and asset load failures.
- Avoid architecture that assumes native desktop privileges.
---
## Code quality rules
### General
- TypeScript only
- strict typing enabled
- prefer pure functions for transforms/build steps
- isolate impure browser/three.js side effects
- no silent catch-and-ignore
- no dead feature flags without roadmap justification
- no hidden singleton globals unless explicitly part of infrastructure
### Naming
- use descriptive names
- prefer domain names over generic utility names
- avoid abbreviations unless they are standard and obvious
- function names should describe intent, not implementation detail
Good:
- `buildRuntimeSceneFromDocument`
- `applyMaterialToSelectedFaces`
- `createBoxBrushCommand`
Bad:
- `handleThing`
- `updateData`
- `doBuild`
### File organization
- small files where it helps clarity
- split by domain, not by arbitrary technical categories
- avoid giant “misc” or “utils” dumping grounds
- every folder should have a clear reason to exist
### Comments
- explain *why*, not what the code obviously does
- use comments to document invariants, constraints, and tricky browser behavior
- remove stale comments promptly
### Error handling
- fail loudly in development
- surface usable diagnostics in the editor UI
- never corrupt the document silently
- preserve previous valid state on failed builds where possible
---
## Data model rules
The canonical authoring state must remain independent from three.js scene graph objects.
### Required separation
Maintain these layers:
1. **Authoring model**
- JSON-serializable
- versioned
- typed
- stable across runtime/editor rebuilds
2. **Editor view model**
- three.js meshes, helpers, overlays, gizmos
- disposable and rebuildable
3. **Runtime model**
- play-mode scene graph
- controllers, triggers, emitters, colliders, animation mixers
Do not let editor-only helpers leak into the canonical document.
Do not store raw three.js objects inside canonical document state.
### Whitebox geometry rules
- whitebox solids are canonical authoring objects, not raw renderer state
- face material assignments are per-face
- UV transforms are canonical editor data
- render triangulation is derived data
- collision generation is derived data
- non-planar quad faces are acceptable if the derived mesh triangulates them deterministically
- whitebox solids do not need to remain convex
- current box solids still use stable face IDs, even if later slices relax earlier axis-aligned constraints
### Entity rules
- entities must be typed
- entity schemas must be explicit
- entity defaults must be centralized
- entity validation must happen at document/build boundaries
- model instances remain separate from entities
### Imported model collision rules
- collision settings for imported models live on `modelInstances`
- supported collision modes must be explicit and typed
- generated collision geometry is derived data, not the canonical source document
- collision debug visibility is editor/runtime UI state driven by authored settings, not a hidden renderer-only toggle
- avoid implicit “always collide with render mesh” behavior
- if broad-phase/narrow-phase pruning or non-box collider support is needed, prefer Rapier over ad hoc custom collision math
- collision modes mean:
- `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
---
## Performance rules
Performance matters, but premature micro-optimization does not.
Priorities:
1. editor responsiveness during common operations
2. deterministic rebuild behavior
3. predictable memory usage
4. runtime smoothness for modest scenes
5. export/build correctness
When optimizing:
- measure first
- optimize hotspots, not aesthetics
- document assumptions
- prefer algorithmic improvements over clever hacks
Expected hotspots:
- picking/raycasting
- whitebox mesh rebuilds / solid triangulation
- face highlighting
- large texture browser lists
- imported asset previews
- runtime trigger scanning if implemented naively
---
## UX rules
The editor should feel like a real authoring tool, not a tech demo.
Prioritize:
- fast selection
- trustworthy snapping when enabled
- visible grid and transform feedback
- obvious active tool state
- low-friction material application
- quick play testing
- understandable errors
Every new feature should answer:
- What does the user see?
- What does the user click/drag/type?
- How is failure communicated?
- How is the action undone?
- How is the result tested?
---
## Vertical slice policy
We build in vertical slices.
Each slice must deliver a complete, usable capability across all relevant layers.
A good slice includes:
- document changes
- commands
- viewport behavior
- UI panel updates
- runner behavior if relevant
- persistence
- tests
- manual QA notes
A bad slice is “just backend structure” or “just a partial UI”.
Do not land architectural scaffolding that has no immediate use in the current slice.
If a roadmap item is too large for one pass, split it into smaller end-to-end sub-slices instead of landing half-systems.
---
## Typical slice shape
For each slice, agents should aim to deliver:
1. domain model changes
2. command(s)
3. viewport interaction/tooling
4. UI affordance
5. serialization support
6. runtime/build support if needed
7. tests
8. docs update if behavior changed materially
---
## Decision heuristics
When uncertain:
### Prefer plain three.js over extra abstraction
Unless abstraction clearly simplifies repeated patterns.
### Prefer canonical JSON over reusing runtime/export data structures
The editors needs are different from export/runtime needs.
### Prefer typed entity schemas over generic script bags
Especially in early versions.
### Prefer constrained capabilities that feel good over flexible capabilities that feel vague
Example:
- better to have one excellent whitebox-solid editing flow than five half-working primitive tools
### Prefer immediate usability over speculative extensibility
But preserve clean seams for future extensions.
---
## What agents must not do
Do not:
- rewrite broad project structure without a strong reason
- introduce new framework dependencies casually
- add R3F because “we might want it later”
- introduce ECS because “games use ECS”
- over-generalize the entity system
- replace canonical whitebox data with hidden renderer-only mesh mutations
- implement hidden magic behaviors without schema support
- remove tests to get green CI
- make visual changes without noting them in the slice summary
- ignore browser restrictions around input/audio
---
## Required deliverables in implementation responses
When making meaningful changes, include:
1. what changed
2. why it changed
3. which files were added/updated
4. how to run/test it
5. known limitations
6. follow-up suggestions only if directly relevant
If the environment prevents verification, state exactly what was and was not verified.
---
## Definition of done for a slice
A slice is done when:
- the feature can be used end-to-end
- the feature is represented in canonical document data
- the feature can be saved and loaded
- the feature is test-covered appropriately
- the feature has manual verification notes
- the feature does not violate the architecture
- obvious failures produce usable diagnostics
- undo/redo works if the feature is editor-authored
---
## Preferred stack unless changed deliberately
- TypeScript
- React
- Vite
- three.js
- Vitest
- Playwright
- ESLint
- Prettier
- a small state store if needed
- minimal dependencies overall
Add dependencies only when they clearly save time and complexity over building in-house.
---
## Final instruction to agents
Build the smallest coherent thing that feels real.
The product should always trend toward:
- spatial immediacy
- authoring clarity
- browser-native practicality
- fast iteration
- strong foundations for whiteboxing, assets, entities, and runner behavior
If forced to choose, preserve the integrity of:
1. the canonical document model
2. the whiteboxing workflow
3. the edit -> run loop