{
 "note": "Technology decisions (ADR-003 servers and protocol, ADR-004 monorepo, ADR-024 Unity client accepted 2026-10-04; written up in docs/vision/DECISIONS.md by M0-06) and the machine setup checklist. Exact versions are pinned here when installed (Unity: the 6.3 LTS patch, verified on unity.com).",
 "decided": "2026-10-04",
 "stack": [
  {
   "layer": "Game client",
   "choice": "Unity 6 LTS + URP, C# — one project for Windows, Android, iOS and Web",
   "version": "Unity 6.3 LTS, pinned at 6000.3.25f1 (changeset e1dba0a9aba4, installed 2026-10-07 in ~/Unity/Hub/Editor; M0-04). Upgrade the patch only through the toolchain gate. Checked on unity.com 2026-10-06: 6.3 LTS is supported until December 2027; 6.0 LTS support ends in October 2026.",
   "license": "Unity Personal (free under US$200k revenue + funding in the prior 12 months) — verify plan terms before release",
   "cost": "free if eligible",
   "why": "Native High/Ultra on Windows and phones (GPU Resident Drawer, VFX Graph, URP post), a Web build capped at Low–Mid, batchmode builds and Unity Test Framework from the CLI for agents (ADR-024).",
   "alternatives": "Three.js r186 (lower level, assemble your own engine), PlayCanvas (editor-centric), Unity 6 Web (large downloads and memory pressure on mobile browsers; needs the editor GUI)."
  },
  {
   "layer": "Client build",
   "choice": "Unity batchmode builds: Windows (Mono from this Mac; IL2CPP on a Windows runner), Android IL2CPP AAB, iOS via Xcode, Web (WebGL2, Brotli); Addressables content per zone",
   "version": "Unity 6.x LTS",
   "license": "Unity terms",
   "cost": "free",
   "why": "One project, per-platform quality profiles; the Web build ships only Low/Mid content."
  },
  {
   "layer": "In-game UI",
   "choice": "Unity UI Toolkit (UXML/USS) using the same 9-slice sprites as this wiki; world-space TextMeshPro for nameplates and damage numbers",
   "version": "Unity 6.x LTS",
   "license": "Unity terms",
   "cost": "free",
   "why": "USS slicing (-unity-slice-*) reproduces the kit exactly; data binding updates values without per-frame allocations."
  },
  {
   "layer": "Mobile apps",
   "choice": "Native Unity Android (AAB) and iOS builds; the browser plays the Web build",
   "version": "Unity 6.x LTS",
   "license": "store terms",
   "cost": "Apple developer $99/yr and Google $25 once — owner decision (OPEN-5)",
   "why": "Full High/Ultra experience on phones; store accounts are the owner's."
  },
  {
   "layer": "Zone server (authoritative)",
   "choice": "Rust (tokio, custom data-oriented ECS, rayon for cell-parallel systems)",
   "version": "rust stable",
   "license": "MIT/Apache-2.0",
   "cost": "free",
   "why": "1,000 players + ~4,000 monsters + projectiles per map at a fixed 20 Hz tick needs predictable CPU and no GC pauses."
  },
  {
   "layer": "Shared simulation core",
   "choice": "zoen-sim (Rust crate) on servers. Client side decided by spike M0-11 (ADR-029): the same crate as a native plugin if it passes on every target; otherwise the small C# prediction subset of ADR-024. Golden vectors (JSON from the Rust crate) are exported either way.",
   "version": "rust stable",
   "license": "MIT/Apache-2.0",
   "cost": "free",
   "why": "One implementation of every rule if the plugin passes; the vectors catch drift in CI in both cases."
  },
  {
   "layer": "Protocol",
   "choice": "Schema file (packages/protocol/zoen.schema.json, M1-03) → codegen for Rust + C#; bit-packed binary over WebSocket (all targets; WebTransport/UDP later only if measured better)",
   "version": "in-repo",
   "license": "own",
   "cost": "free",
   "why": "Quantised positions, delta snapshots and priority-based AOI to stay within mobile bandwidth."
  },
  {
   "layer": "Gateway / accounts API",
   "choice": "Rust axum + sqlx",
   "version": "latest stable",
   "license": "MIT",
   "cost": "free",
   "why": "Accounts, characters, inventory, economy writes, zone admission tokens."
  },
  {
   "layer": "Database",
   "choice": "PostgreSQL 17 (+ Redis optional for presence/queues later)",
   "version": "postgres 17",
   "license": "PostgreSQL",
   "cost": "free locally (Docker Desktop is installed)",
   "why": "Durable inventory/economy with transactions; one DB is enough until measured otherwise."
  },
  {
   "layer": "3D content",
   "choice": "Blender 4.2 LTS (installed) + Python bpy scripts run headless",
   "version": "Blender 4.2.3 LTS at ~/Applications/Blender.app",
   "license": "GPL (outputs are yours)",
   "cost": "free",
   "why": "Retopology, rigging, animation, LODs, glTF export and VFX flipbooks — scriptable so agents can batch and test."
  },
  {
   "layer": "Animation base",
   "choice": "Mixamo (free Adobe account) for locomotion/reference + hand-keyed signature skills in Blender",
   "version": "web",
   "license": "Mixamo terms (use in games allowed)",
   "cost": "free",
   "why": "Fast, consistent locomotion on a standard humanoid; signature skills are authored for timing/readability."
  },
  {
   "layer": "Image generation",
   "choice": "Owner's Codex/ChatGPT image tool, driven by art-requests/*.md",
   "version": "—",
   "license": "per provider terms",
   "cost": "owner's existing plan",
   "why": "Already available to the owner; prompts reference current accepted art for consistency."
  },
  {
   "layer": "Image → 3D",
   "choice": "Tripo (owner's plan) via its Python SDK/API for raw meshes, then Blender headless polish (docs/production/TRIPO_PIPELINE.md); Tripo Blender/Unity bridge add-ons are optional interactive helpers (loopback WebSocket 127.0.0.1:60600)",
   "version": "tripo3d SDK (pin at M0-08); Tripo Blender Bridge 1.0.34; Unity Bridge 1.0.14",
   "license": "Tripo terms for the owner's plan — verify commercial use and output ownership before shipping",
   "cost": "owner's Tripo plan; API credits may be billed separately (about US$1 per 100 credits) — counts toward the PHP 5,000 cap",
   "why": "Fast monsters/props from approved concept art; Blender fixes topology, UVs, rig, LODs. API key stays in the owner's environment, never in the repo."
  },
  {
   "layer": "Audio",
   "choice": "Unity AudioMixer (buses, snapshots for ducking, pooled AudioSources); SFX and area ambience from the local Stable Audio 3 SFX generator (tools/sfxgen) + CC0 libraries, layered in Audacity/Reaper; town and GM-room music plus engaged boss themes (ADR-026); ordinary outdoors stays environment sound, from the optional local Small Music bundle (tools/sfxgen --model sm-music)",
   "version": "Unity 6.x LTS",
   "license": "per source; log every file in LICENSES.md",
   "cost": "free (local generation)",
   "why": "Layered SFX per hit (swish + impact + material + sweetener), bus mixing, voice limits per tier."
  },
  {
   "layer": "Testing",
   "choice": "Unity Test Framework (EditMode/PlayMode) in batchmode + Unity Performance Testing; node:test (data); Playwright with system Chrome (wiki, Web build smoke, video capture); cargo test + criterion (server)",
   "version": "Unity 6.x LTS, @playwright/test 1.63.0",
   "license": "Unity terms / Apache-2.0 / MIT",
   "cost": "free",
   "why": "Everything runs headless from the CLI; CI later via GameCI (needs a Unity licence secret from the owner)."
  },
  {
   "layer": "Wiki (this site)",
   "choice": "Next.js 16 static export + react-markdown; Canvas2D Atlas",
   "version": "next 16.3.8",
   "license": "MIT",
   "cost": "free",
   "why": "Source of truth for humans and agents; offline-capable static build."
  },
  {
   "layer": "Hosting (later)",
   "choice": "Static client on a CDN (Cloudflare Pages free tier); one dedicated server for alpha (e.g. 8-core VPS)",
   "version": "—",
   "license": "—",
   "cost": "≈ USD 15–40 / month — needs explicit approval; counts toward PHP 5,000",
   "why": "Cheapest real multiplayer test bed; scale only after measurement."
  }
 ],
 "machine": {
  "observed": "Apple M3, 24 GB RAM, macOS 26 (Darwin 25.5), Node 22.23.1, pnpm 10.9, Python 3.9.6 + Pillow 11.3 (WebP), Git, Google Chrome, Docker Desktop, Blender 4.2.3 LTS (~/Applications), Xcode Command Line Tools only (no full Xcode), Unity 6000.3.25f1 in ~/Unity/Hub/Editor (SETUP-20261007-01), Rust 1.99.0 and .NET SDK 10.0.401 installed 2026-10-06 (SETUP-20261006-01), no full Xcode (iOS builds need it). ffmpeg: bundled with the local SFX runtime.",
  "verifiedBy": "T000 discovery + T009 Blender headless smoke test (see Ledger)."
 },
 "setup": [
  {
   "step": 1,
   "title": "Git repository",
   "command": "Done: the repository exists. Work of 2026-10-03 to 2026-10-06 is committed on the branch sync/working-tree-20261006; merging to main and pushing are the owner's call.",
   "check": "git log -1",
   "required": true,
   "owner": "human (agents never commit without being asked)"
  },
  {
   "step": 2,
   "title": "Node 22 + pnpm 10",
   "command": "node -v && corepack enable && pnpm -v",
   "check": "node ≥ 22, pnpm ≥ 10",
   "required": true
  },
  {
   "step": 3,
   "title": "Install workspace",
   "command": "cd zoen && pnpm install",
   "check": "pnpm -r ls --depth 0",
   "required": true
  },
  {
   "step": 4,
   "title": "Rust toolchain",
   "command": "Done 2026-10-06 (owner approved): rustup-init.sh from https://sh.rustup.rs with -y --no-modify-path --profile default; cargo, rustc and rustup are linked in ~/.local/bin",
   "check": "bash tools/setup/toolchain-smoke.sh rust",
   "required": "M1+"
  },
  {
   "step": 5,
   "title": "Blender CLI alias",
   "command": "echo 'alias blender=~/Applications/Blender.app/Contents/MacOS/Blender' >> ~/.zshrc",
   "check": "blender --version → 4.5.x LTS (4.5.9 measured by M0-02); then node tools/task-log.mjs test <ID> 'blender smoke' -- pnpm blender:smoke (runs tools/blender/smoke.py and validates the GLB and render)",
   "required": true
  },
  {
   "step": 6,
   "title": "Blender add-ons",
   "command": "Enable Rigify (bundled). Optional: Blender MCP add-on only after the toolchain gatekeeper review.",
   "check": "Rigify visible in Add > Armature",
   "required": "M3+"
  },
  {
   "step": 7,
   "title": "Playwright with system Chrome",
   "command": "pnpm --filter @zoen/wiki exec playwright --version",
   "check": "tests use channel: 'chrome' (no browser download)",
   "required": true
  },
  {
   "step": 8,
   "title": "PostgreSQL in Docker",
   "command": "docker run -d --name zoen-pg -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres:17",
   "check": "docker ps | grep zoen-pg",
   "required": "M6+"
  },
  {
   "step": 9,
   "title": "ffmpeg (optional)",
   "command": "brew install ffmpeg",
   "check": "ffmpeg -version (videos also work without it via Playwright/Blender)",
   "required": false
  },
  {
   "step": 10,
   "title": "Mixamo account (free)",
   "command": "Create an Adobe account; download clips manually into zoen/art/source/mixamo/ (In Place, FBX, 30 fps, no skin)",
   "check": "list in docs/production/ANIMATION.md",
   "required": "M3+",
   "owner": "human (agents do not create accounts)"
  },
  {
   "step": 11,
   "title": "Test devices",
   "command": "Record Low baseline: Galaxy A07 4G / 4 GB; iPhone SE (2020) / A13; Intel N150 / 8 GB / integrated GPU / Windows 11. See reference-devices.json; keep this M3 as a secondary High reference. Physical probe and benchmarks pending.",
   "check": "recorded in docs/adr/ADR-006",
   "required": "M1+",
   "owner": "human"
  },
  {
   "step": 12,
   "title": "Token + test logging",
   "command": "node tools/task-log.mjs start <ID> \"<title>\" … test … finish",
   "check": "pnpm tasks:report → logs/tasks.json",
   "required": true
  },
  {
   "step": 13,
   "title": "Unity Hub + Unity 6.3 LTS",
   "command": "Install Unity Hub and the newest Unity 6.3 LTS patch with modules: Android Build Support (OpenJDK, SDK & NDK), iOS Build Support, Web Build Support, Windows Build Support (Mono). An agent may run the Hub command line (owner, 2026-10-06); the owner signs in with the Unity ID.",
   "check": "\"/Applications/Unity/Hub/Editor/<version>/Unity.app/Contents/MacOS/Unity\" -batchmode -quit -version",
   "required": "M0",
   "owner": "agent may install by command line; human signs in (agents never create accounts or enter passwords)"
  },
  {
   "step": 14,
   "title": "Full Xcode (iOS builds)",
   "command": "Install Xcode from the App Store, open it once, accept the licence",
   "check": "xcodebuild -version",
   "required": "M4+ (iOS device builds)",
   "owner": "human (Apple ID)"
  },
  {
   "step": 15,
   "title": "Unity toolkit gate",
   "command": "Follow docs/tech/UNITY_TOOLKIT.md: Unity Test Framework 1.6.0 + Performance Testing 3.5.0 pinned (M0-07); no Unity MCP (owner direction, 2026-10-08)",
   "check": "PlayMode performance tests logged under M0-07",
   "required": "M0+"
  },
  {
   "step": 16,
   "title": "Tripo API key + credit check",
   "command": "In the Tripo Console create an API key; export TRIPO_API_KEY in your shell (or ~/.config/zoen/tripo.env). Check whether your plan's credits cover API calls.",
   "check": "python3 -m pip install tripo3d (venv) then a 1-asset dry run with a credit cap",
   "required": "M0-08",
   "owner": "human (key creation; agents never create keys or accounts)"
  },
  {
   "step": 17,
   "title": "Tripo Blender Bridge add-on (optional)",
   "command": "Blender → Edit → Preferences → Add-ons → Install from Disk → tripo ai/Tripo3d_Blender_Bridge-latest.zip",
   "check": "Sidebar → Tripo Bridge appears; server on 127.0.0.1:60600",
   "required": false,
   "owner": "human or agent after the toolchain gate review"
  },
  {
   "step": 18,
   "title": ".NET SDK (LTS)",
   "command": "Done 2026-10-06 (owner approved): dotnet-install.sh from https://dot.net/v1 with --channel LTS into ~/.dotnet; dotnet is linked in ~/.local/bin; set DOTNET_CLI_TELEMETRY_OPTOUT=1",
   "check": "bash tools/setup/toolchain-smoke.sh dotnet",
   "required": "M0-09"
  }
 ]
}
