[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7B3268KYZXFS1ERVC31FCWN":3,"skill-same:01M7B3268KYZXFS1ERVC31FCWN":45},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":20,"frontMatter":21,"refName":22,"commitSha":23,"skillDirectory":24,"forksCount":25,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":28,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M7B3268KYZXFS1ERVC31FCWN","engine-package",null,"xirtus\u002F3JSE","xirtus","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F8495145?v=4","01M7B2YY3Y4XFSV4WSG3DQ7DYQ","Andreas Xirtus","01M7B2YY539A2AR3N5MM0ZR93M",2,"GPL-3.0","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fengine-package\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"# Engine Package\n\nUse when the task is to build or change a `@3jse\u002F*` **engine** package (or the editor app) in this monorepo — as opposed to building a game *with* Three.js, which is what `3jse-director` and the provider skills cover. Load on demand; do not keep in always-on context.\n\n`docs\u002FROADMAP.md` is the sequencing contract; `docs\u002FARCHITECTURE.md` + `docs\u002FGAMEPLAY_IR.md` + `docs\u002FENTITY_COMPONENT_MODEL.md` are read before writing engine code. This skill is the *repo conventions* those docs assume but don't spell out.\n\n## Reuse ladder, engine edition\n\n0. **An existing `@3jse\u002F*` package already covers the capability.** Search `packages\u002F*\u002Fsrc` first. Current map (keep updated as packages land):\n\n   | Capability | Package |\n   |---|---|\n   | World \u002F Level \u002F Entity \u002F Component \u002F Scheduler \u002F Prefab \u002F Input | `@3jse\u002Fruntime` |\n   | Gameplay IR (frontend + interpreter + JS emitter + source map) | `@3jse\u002Fir` |\n   | Node canvas over the IR | `@3jse\u002Fgraph` |\n   | glTF\u002FGLB import, thumbnails, metadata, character detection | `@3jse\u002Fassets` |\n   | Project save\u002Fload in the `PROJECT_FORMAT.md` tree | `@3jse\u002Fproject` |\n   | Character controller + camera rig | `@3jse\u002Fcharacter` |\n   | Animation state machine + blend tree + TwoBoneIK | `@3jse\u002Fanimation` |\n   | Rapier physics integration | `@3jse\u002Fphysics-rapier` |\n   | Save games (tagged-component snapshots) | `@3jse\u002Fsave` |\n   | Spawn points + object pooling | `@3jse\u002Fspawning` |\n   | Starter templates (Third Person, …) | `@3jse\u002Ftemplates` |\n   | Netcode: replication, authority, prediction, RPC, priority\u002Fbandwidth, lag comp, WebSocket transport | `@3jse\u002Fnetworking` |\n   | Timeline \u002F sequencer runtime | `@3jse\u002Fcinematics` |\n   | Shareable-URL snippet sandbox | `@3jse\u002Fplayground` |\n   | Input recording + deterministic replay | `@3jse\u002Freplay` |\n   | MCP-shaped agent tool server | `@3jse\u002Fagent` |\n   | Semantic system model \u002F FeelSpec \u002F Atlas graph compiler \u002F agent-scoping | `@3jse\u002Fatlas` |\n   | Plugin manifest \u002F host \u002F extension-point versioning \u002F package catalog | `@3jse\u002Fplugins` |\n   | Publish pipeline: tree-shake, asset finalize, manifest, notices, static-host files | `@3jse\u002Fpackaging` |\n   | Audio: bus mixer, AudioSource\u002FListener\u002FReverbZone, event router, musical grid + MIDI\u002FOSC | `@3jse\u002Faudio` |\n   | UI\u002FHUD: retained widget tree, flexbox-subset layout, data binding, hit-test, renderer seam | `@3jse\u002Fui` |\n   | Material Graph -> TSL codegen + CPU reference evaluator + validation | `@3jse\u002Fmaterials` |\n   | Terrain: heightfield sampling, chunk mesher, LOD, bounded-residency streamer | `@3jse\u002Fterrain` |\n   | Foliage: deterministic field scatter -> InstancedMesh instance data | `@3jse\u002Ffoliage` |\n   | Navigation: grid bake \u002F A* + string-pull \u002F flow field \u002F NavAgent \u002F PolyNavMesh seam | `@3jse\u002Fnav` |\n   | Polygon navmesh bake from THREE geometry via recast-navigation-js -> PolyNavMesh | `@3jse\u002Fnav-recast` |\n   | Provider-agnostic LLM chat client (OpenAI \u002F Anthropic \u002F DeepSeek \u002F Gemini \u002F OpenRouter \u002F Groq \u002F Ollama \u002F any OpenAI-compatible) | `@3jse\u002Fllm` |\n   | Particles\u002FVFX: CPU SoA sim, curves\u002Fgradients over life, ParticleEmitter component\u002Fsystem | `@3jse\u002Fvfx` |\n   | THREE-side render bridges: terrain chunks \u002F foliage InstancedMesh \u002F particle Points from the headless cores | `@3jse\u002Frender` |\n   | `3jse` CLI: publish (runs @3jse\u002Fpackaging + esbuild) \u002F info | `@3jse\u002Fcli` |\n   | Vendored MIT ecosystem libs (mesh-bvh, troika text, postprocessing, …) | `@3jse\u002Fextras` |\n   | Vendor registry + fetcher; Tier A wraps (poseidon\u002Fgaia\u002Fdryad\u002Fdemiurge) | `@3jse\u002Fvendor`, `@3jse\u002Fwater-poseidon` etc. |\n\n1. A sibling package's pattern (copy the shape, not a dependency edge you don't need).\n2. A reference game in `docs\u002FREFERENCE_GAMES.md` (dambeavers ECS core, 3jsurf headless tools, …).\n3. Custom — last resort, with a one-line justification in the package's index\u002Fheader comment.\n\n## Non-negotiable conventions (proven by the packages that already pass)\n\n- **Headless-first.** Gameplay\u002Flogic code runs with **no renderer, no canvas, no DOM**. `World.step(dt)` is caller-driven, never `requestAnimationFrame`-owned. A package that can't be exercised in a plain vitest `node` test is wrong. Physics is the only async seam (Rapier WASM init) — isolate it.\n- **Components are plain JSON data.** Primitives, arrays, plain objects, entity-id strings. No functions, Maps, or class instances in component data. Behaviour lives in **Systems**, not component methods.\n- **Register components as an import side effect.** Every package with components does `import \".\u002Fcomponents.js\"` (or `.\u002Fsystems.js`) from its `index.ts`, and that module calls `registerComponent(...)` at module scope. Matches `@3jse\u002Fruntime`'s own builtins. Consumers get a working component set just by importing the package.\n- **`Object3D` *is* the Transform.** Spatial entities store position\u002Frotation\u002Fscale on `entity.object3D` directly — never a parallel copy. Non-spatial entities (`{ spatial: false }`) have `object3D === null` and are not in the render scene.\n- **Import from `three\u002Fwebgpu`**, never bare `three`, in any package that touches the scene graph — they are non-identical builds and mixing specifiers creates two `Object3D` classes.\n- **`.js` extensions in relative TS imports** (`.\u002Ffoo.js` even though the file is `foo.ts`) — the repo's `moduleResolution: \"Bundler\"` + `isolatedModules` setup requires it. Copy an existing package's `import` lines.\n- **Scheduler stage + registration order is load-bearing.** Stages run `fixed → variable → late`; within a stage, systems run in registration order. Kinematic movement (`@3jse\u002Fcharacter`) registers *before* `@3jse\u002Fphysics-rapier`'s system so the move is queued before `physics.step()` commits it. Document any ordering dependency in the system factory's doc comment.\n- **Determinism.** Seed RNG; route time-scaling through one `worldDt = dt * scale` clock; make structural results reproducible. Replay\u002Fghost\u002Fnetcode all assume it.\n- **Stable ids on load.** `createEntity`\u002F`createLevel` accept an optional `id` so a loader (`@3jse\u002Fproject`) rehydrates persisted ids instead of session-local counters. Don't reintroduce a hidden global counter as the only id source.\n- **Testability via a virtual filesystem.** Anything that reads\u002Fwrites project files works over a `Record\u003Cpath, string>` map (see `@3jse\u002Fproject`), so it's testable with no disk and is \"recoverable without the editor\" (`PROJECT_FORMAT.md`).\n\n## Package scaffold\n\n`packages\u002F\u003Cname>\u002F`:\n- `package.json` — `\"name\": \"@3jse\u002F\u003Cname>\"`, `\"type\": \"module\"`, `\"main\"`\u002F`\"types\": \".\u002Fsrc\u002Findex.ts\"`, `exports: { \".\": \".\u002Fsrc\u002Findex.ts\" }`, scripts `typecheck` (`tsc --noEmit -p tsconfig.json`) + `test` (`vitest run`), deps on `workspace:*` siblings, dev-deps `typescript` + `vitest` (+ `@types\u002Fthree` if it imports three).\n- `tsconfig.json` — `{ \"extends\": \"..\u002F..\u002Ftsconfig.base.json\", \"compilerOptions\": { \"outDir\": \"dist\", \"rootDir\": \"src\" }, \"include\": [\"src\"] }`.\n- `src\u002Findex.ts` — the public barrel; explicit re-exports; the component-registration side-effect import last.\n- `src\u002F*.test.ts` — at least a smoke\u002Fround-trip test per module so `pnpm -r test` stays a real gate.\n- After scaffolding: `pnpm install` (links the workspace), then `pnpm --filter @3jse\u002F\u003Cname> typecheck && pnpm --filter @3jse\u002F\u003Cname> test`.\n\n## Evidence for engine work (not the game evidence report)\n\nA game task uses `templates\u002FEVIDENCE_REPORT.example.md` (core loop, screenshots, draw calls). Engine-package \u002F roadmap-spike work uses instead:\n\n- **The phase\u002Fdeliverable's exit criterion, quoted**, then met \u002F partially met \u002F not met with specifics.\n- **A round-trip or invariant proof** where the claim is structural (serialize→load→serialize byte-identical; parse→emit→re-parse behaviourally identical; N-frame headless sim settles \u002F stays within bounds).\n- **A benchmark table** where the claim is performance (min\u002Favg\u002Fp95\u002Fmax, % of frame budget, hardware named).\n- **A routing ledger** (rung-0 search result · chosen approach · why · fallback).\n- Written to `evidence\u002Fphase\u003CN>-\u003Cslug>.md` and one line in `BUILD_TASKS.md` (phase · task · status · evidence file · commit).\n\n## Verify before claiming done\n\n- `pnpm -r typecheck` clean (includes `apps\u002Feditor`).\n- `pnpm -r test` green — if it's red for an infrastructural reason (a package's vitest globbing vendored files), fix that first; a red workspace gate hides real regressions.\n- `pnpm --filter @3jse\u002Feditor build` still succeeds if runtime\u002Fany editor dep changed.\n- `node 3JSE_Harness_v0.2\u002Fscripts\u002Fverify-harness.mjs` PASS.\n- New package added to this skill's rung-0 table and to `docs\u002FFILE_INDEX.txt` if it's a harness file (engine packages under `packages\u002F` are not).\n",{},"main","6e2d3a6a3ae00965b2e0dac39fc7d082a68d8b39","3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fengine-package",0,"https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE","https:\u002F\u002Fgithub.com\u002Fxirtus","metaspace.xirtus.com","https:\u002F\u002FAndreas.me\r\n","2026-10-20 07:07:06",{"source":7,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add xirtus\u002F3JSE --skill engine-package",{"tool":37,"command":38},"bunx","bunx skills add xirtus\u002F3JSE --skill engine-package",{"tool":40,"command":41},"pnpm","pnpm dlx skills add xirtus\u002F3JSE --skill engine-package","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fengine-package\u002FSKILL.md",true,[],[46,52,58,64,70,76],{"skillNo":47,"name":48,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":49,"categories":50,"keywords":51,"publishedAt":18},"01M7B33DN3BBGB63JJGB9DFBBN","webgpu","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fwebgpu\u002FSKILL.md",[],[],{"skillNo":53,"name":54,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":18},"01M7B33APJ9BYZXX0068A1ZB8T","visual-qa","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fvisual-qa\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":18},"01M7B339H7H5JW80G1WHX3R9MV","vendor-router","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fvendor-router\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":18},"01M7B336MK7S7A3RSBMG8EMAEG","threejs-runtime","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fthreejs-runtime\u002FSKILL.md",[],[],{"skillNo":71,"name":72,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":75,"publishedAt":18},"01M7B335CXS2ZGJY6949KP08Y4","safe-repo-inspector","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Fsafe-repo-inspector\u002FSKILL.md",[],[],{"skillNo":77,"name":78,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":18},"01M7B33498PEQ1WR79TS0PFX1M","reference-broker","https:\u002F\u002Fgithub.com\u002Fxirtus\u002F3JSE\u002Fblob\u002Fmain\u002F3JSE_Harness_v0.2\u002F.claude\u002Fskills\u002Freference-broker\u002FSKILL.md",[],[]]