{
  "name": "3d-engine",
  "title": "3D Engine - Minimal Three.js + Rapier + Colyseus Template",
  "description": "Minimal 3D multiplayer template - Three.js rendering, Rapier physics, Colyseus multiplayer, player controller, voxel primitives. No gameplay; start here to build something new.",
  "guid": "sk_plat_3deng",
  "category": "Templates",
  "requiredTools": [
    "add",
    "realtime_room",
    "file_write",
    "project_deploy"
  ],
  "content": "# 3D Engine - Minimal 3D Multiplayer Template\n\n**3D Engine** is the blank-slate 3D multiplayer template on Gipity. It boots a Three.js scene, a Rapier physics world, a Colyseus multiplayer client, and exposes the engine API - with no gameplay. Use it when the user wants to build a fresh 3D app without inheriting a demo's logic.\n\n**When to use this:** When the user describes a new 3D or multiplayer app (e.g. \"3D Boggle\", \"voxel painting\", \"3D chat room\") and you want a clean starting point. If they want a playable reference with rockets, camera orbit, and spawn logic already wired, add the `3d-world` starter instead.\n\n## Quick Start\n\n```\nadd name=3d-engine title=\"<App Name>\"\n```\n\nAfter adding the template, the player sees a lit ground plane with multiplayer connected. There's no character yet - you decide the control model.\n\n**Naming:** Use the user's name verbatim if given. If they didn't specify, blend \"Gip\" or \"Gipity\" into the name.\n\n## Project Structure\n\nAfter adding the template, all files are in `src/` and fully editable. Two-layer split:\n\n**Your code (edit these):**\n- `game.js` - entry point. Calls `setConfig`, `onInit`, `onUpdate`. Start here.\n- `config.js` - project metadata and feature flags.\n- `settings.js` - tunable values (world size, colors). Add your own.\n- `strings.js` - user-facing text. Localized via `translations.js`.\n- `scene.js` - scene builder. Currently creates one ground plane. Replace with your world.\n- `css/game.css` - game-specific styles. Empty stub.\n\n**Engine (leave as-is unless you know what you're doing):**\n- `core.js` - boot sequence and render loop. Re-exports every engine module.\n- `world.js` - Three.js scene, camera, renderer, lighting.\n- `physics.js` - Rapier physics world, raycasting, triggers.\n- `network.js` - thin 3D facade over the `@gipity/realtime` kit (presence + world-state channels).\n- `network/adapter-3d.js` - the only 3D-aware networking code: bridges `@gipity/realtime` to Three.js / Rapier.\n- `packages/realtime/` - the engine-agnostic `@gipity/realtime` kit (transport, channels, host election, sync). Self-describing: see its `README.md`, `contracts/`, and `examples/`. Reusable by any app, not just games.\n- `player.js` - optional character controller (call `player.initPlayer(...)` when you want one).\n- `primitives.js` - Part system and workspace.\n- `constraints.js` - joint/constraint system.\n- `assets.js` - geometry builders, material presets.\n- `shapes.js` - voxel shape library (cubes, spheres, arches, towers).\n- `utils.js` - helpers (randInt, onCircle, placeVoxels).\n- `features.js` - opt-in feature registry. Empty by default.\n- `ui.js` - HUD, loading screen, message overlay.\n- `css/engine.css` - engine styles.\n\nRead the files before making changes - the comments explain what each one does.\n\n## Engine API\n\nAll engine modules are available via a single import:\n\n```js\nimport { world, assets, physics, player, network, ui, THREE, onInit, onUpdate, setConfig, primitives, constraints, workspace, features } from './core.js';\n```\n\n### Lifecycle\n\n```js\nsetConfig(config);               // set once at import time\nonInit(async () => { ... });     // runs after engine boots\nonUpdate((dt) => { ... });       // runs every frame\n```\n\nThe starter `game.js` already wires these up - edit its bodies.\n\n### Adding a player\n\nThe template ships without a character. To add one, import `player` and call `initPlayer` in `onInit`:\n\n```js\nimport { player } from './core.js';\n\nonInit(async () => {\n  player.initPlayer({\n    speed: 12,\n    jumpForce: 18,\n    gravity: -40,\n    color: 0xf26522,\n    camera: { distance: 20, sensitivity: 0.003 },\n  });\n});\n```\n\nSee the `3d-world` starter for a full player configuration (camera orbit, aim mode, crosshair).\n\n### Building a scene\n\n`primitives.createPart(...)` is the workhorse. Anchored parts don't move; dynamic parts fall under gravity and collide.\n\n```js\nimport { primitives } from './core.js';\n\nprimitives.createPart({\n  position: { x: 0, y: 5, z: 0 },\n  size: { x: 3, y: 3, z: 3 },\n  color: 0x2196F3,\n  material: 'wood',\n});\n```\n\nFor voxel structures, use the shapes library:\n\n```js\nimport { placeVoxels } from './utils.js';\nimport { solidCube, voxelSphere, arch } from './shapes.js';\n\nplaceVoxels(arch(5, 6), { x: 0, y: 0, z: 10 }, 0x9C27B0);\n```\n\n### Multiplayer\n\nMultiplayer runs on the engine-agnostic `@gipity/realtime` kit (`packages/realtime/`); `network.js` is a thin 3D facade over it. The `multiplayer` feature connects to the Colyseus room named in `config.js`, broadcasts the local player on the `avatars` presence channel, and renders remote peers. The room itself is declared in the template's `gipity.yaml` (a `realtime` deploy phase), so `gipity deploy` provisions it automatically. For game events, open a channel: `network.channel('events', { sync: 'messages' })` → `.send(type, data)` / `.on(type, cb)`. For host-authoritative shared world state, enable `sync.worldState`. See the `3d-world` skill's \"Multiplayer in Depth\" for the full API.\n\n### Features\n\n`features.js` ships empty. To add a feature module:\n\n1. Create `js/features/my-feature.js` exporting `DEFAULTS` and `create({...settings}, deps)`.\n2. Register it in `featureLoaders` in `features.js`.\n3. Enable it in `config.js`: `features: { 'my-feature': true }`.\n\nEach feature receives the full engine deps: `world, scene, camera, renderer, physics, player, network, ui, assets, primitives, constraints, THREE`.\n\n## Reference: the 3d-world starter\n\nThe `3d-world` starter uses this same engine, plus:\n- A player controller wired with orbit + aim camera\n- A demo scene with voxel structures in two rings\n- A `rocket-launcher` feature with projectile + explosion + audio\n- Block-collision tick sounds\n\nAdd one in a throwaway project if you want to see a fully-wired implementation:\n\n```\nadd name=3d-world title=\"Rocket Demo\"\n```\n\n## Deploy\n\nSame flow as every Gipity app:\n\n```\nproject_deploy target=dev\n```\n\n{{DEPLOY_VERIFICATION}}\n"
}
