Skip to content

Commit 6942519

Browse files
lanmowerclaude
andcommitted
docs: clean up CLAUDE.md — remove duplicate and stale sections
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 8c01191 commit 6942519

1 file changed

Lines changed: 1 addition & 4 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ SKILL.md and CLAUDE.md MUST be updated whenever code changes. SKILL.md is the ag
2727
- **gh-pages deployment**: the Worker needs the full server-side `src/` tree at runtime. The gh-pages workflow must copy ALL `src/` subdirs (sdk, connection, debug, netcode, physics, apps, stage, storage, transport, spatial) plus `src/math.js` and `jolt-physics` npm package — not just `src/client`, `src/protocol`, `src/shared`. The importmap sed uses a generic `s|"/node_modules/|"/spoint/node_modules/|` to patch all packages at once.
2828
- **App sources**: `WorkerEntry` receives `{ name, source }` pairs and calls `appLoader.loadFromString()` — no filesystem access needed
2929
- **`AppLoader.loadFromString` (browser Worker path)**: uses `URL.createObjectURL + import()` instead of `new Function` — handles full ES module syntax (`export default`, top-level `await`). Apps loaded via this path **cannot use relative `import` statements** (blob URL has no base path for resolution); all inter-app dependencies must be inlined or passed via `engineCtx`. **`AppLoader.BLOCKED_PATTERNS` applies to ALL app sources** — both `loadApp()` (Node.js file path) and `loadFromString()` (browser Worker): any app containing `import(` (dynamic import), `eval(`, `require(`, `process.exit`, `child_process`, `__proto__`, `Object.prototype`, or `globalThis` is rejected silently. The environment app must NOT use dynamic `import()` inside its exported `setup()` — use top-level module initialization (guarded by `process.versions?.node`) for any Node.js-only features. The `"app"` field on entities in `singleplayer-world.json` must be set for `BrowserServer.connect()` to fetch and send the app source to the Worker — missing `"app"` means `setup()` never runs and no collider is created.
30-
- **`singleplayer-world.json` entities**: each entity must have `"app"` set — without it, the app source is not fetched, `setup()` never runs, and no collider is created. The map entity (`env-sillos`) must have `"app": "environment"`.
3130
- **Editor in singleplayer**: all editor handlers work via `AppRuntime` in-memory state; `LIST_APPS` reads `appRuntime._appDefs`, `SAVE_SOURCE` calls `loadFromString()` and broadcasts `APP_MODULE`
3231
- **Inspector message intercept range**: `Inspector.handleMessage` in `src/debug/Inspector.js` intercepts messages by type range as debug/inspector messages, silently returning before `ServerHandlers` can process them. `TRIMESH_DATA (0x92)` must NOT fall in the intercepted range — if it does, trimesh bodies are never created in singleplayer and players fall through the floor with no error logged. Check the exclusion range covers all non-inspector message types when adding new message type constants.
3332

@@ -79,8 +78,6 @@ All three client modes extend `BaseClient` (`src/client/BaseClient.js`) and expo
7978

8079
`TransformLerp.js` — SceneGraph imports only `lerpEntityTransform` and `applyPlayerTransform` (the lerp/apply half). `setEntityTarget` and `setPlayerTarget` exist in TransformLerp but expect a **Map** as first arg — SceneGraph does NOT use them (uses inline writes instead). Passing `node.target` plain object to these Map-based setters causes `targets.get is not a function`.
8180

82-
**Why**: previously `EntityLoader` owned `entityTargets`, `PlayerManager` owned `playerTargets`, and `app.js` had `_dirty` Set plus two separate update functions (`updatePlayerPositions`, `updateEntityPositions`). SceneGraph centralizes all of this — one `tick()` call handles both, nodes own their own target state.
83-
8481
## Renderer
8582

8683
`createRenderer(isMobile)` in `client/SceneSetup.js` returns a `THREE.WebGLRenderer` (synchronous). No WebGPU — it was removed due to persistent GPU OOM crashes across browsers.
@@ -233,8 +230,8 @@ Set `entity.model = null` and populate `entity.custom`:
233230

234231
**LOD index cache** (`getLodIndex` / `storeLodIndex`): After MeshoptSimplifier produces a simplified index buffer in `_simplifyObject`, it is stored keyed by `url:lod0` or `url:lod1`. On next load, `_scheduleLodUpgrades` checks for cached indices before calling `MeshoptSimplifier.simplify`. `url` is carried via `model.userData.url` set at parse time and passed through `_generateLODEager``_lodUpgradeQueue` entries.
235232

236-
237233
**`_generateLODEager` scale inheritance**: `_generateLODEager` copies `model.position/quaternion/scale` to the LOD wrapper, then resets the model to identity before `lod.addLevel(model, 0)`. This is required — if model retains its scale when added as a child of the LOD, THREE.js compounds parent and child scales (e.g. [3,3,3] × [3,3,3] = 9× visual size). The LOD wrapper owns the transform; the model child must be at identity.
234+
238235
### Shader Warmup Persistence
239236

240237
`warmupShaders` in `client/SceneSetup.js` stores `lastShaderWarmupKey` in `localStorage`. The scene key includes entity count and ID hash — same world across browser sessions skips re-compilation.

0 commit comments

Comments
 (0)