@adatechnology/game-test-room 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/index.d.ts +55 -2
- package/dist/index.global.js +861 -123
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +789 -97
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/room.ts","../src/items.ts","../src/build-from-spec.ts","../src/locale.ts","../src/arena.ts","../src/log.ts","../src/narrate.ts","../src/player.ts","../src/scenarios.ts","../src/ui.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport { createDestruction, JOINT_DEFAULTS, resolveStrings as resolveDestructionStrings } from '@adatechnology/game-destruction'\nimport type { DestructibleImpl, DestructibleSpec, DestructionEvent, JointState, Quat, RayHit, ToolKind, Vec3 } from '@adatechnology/game-destruction'\nimport { createDestructionRenderer, specFromObject3D } from '@adatechnology/game-destruction-three'\nimport type { Piece } from '@adatechnology/game-destruction-three'\nimport { createArsenal, DEFAULT_LOADOUT } from '@adatechnology/game-weapons'\nimport type { Shot, Use, WeaponState } from '@adatechnology/game-weapons'\nimport { createFluids, createItemUse, ITEM_USES, resolveStrings as resolveFluidStrings } from '@adatechnology/game-fluids'\nimport type { FluidEvent, ItemUsePlayer, StainState } from '@adatechnology/game-fluids'\nimport { createFluidRenderer } from '@adatechnology/game-fluids-three'\nimport type { FluidRenderer } from '@adatechnology/game-fluids-three'\nimport { checkAnimation, checkDestructible, checkSpec } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, TestableModule } from '@adatechnology/game-contracts'\nimport { createArena } from './arena'\nimport type { Arena } from './arena'\nimport { buildFromSpec } from './build-from-spec'\nimport { DEMO_MATERIALS, demoItems } from './items'\nimport { createLog } from './log'\nimport { createNarrator } from './narrate'\nimport { createPlayer } from './player'\nimport { makeScenarios } from './scenarios'\nimport { resolveStrings } from './locale'\nimport { createUi } from './ui'\nimport type { HudState, InspectInfo, RoomUi } from './ui'\nimport type {\n AnimationInfo,\n ModuleReport,\n ScenarioContext,\n ScenarioReport,\n SpawnedObject,\n TestRoom,\n TestRoomItem,\n TestRoomOptions,\n TestRoomScenario,\n} from './types'\n\ntype Vars = Record<string, string | number>\n\ninterface Entry {\n so: SpawnedObject\n item?: TestRoomItem\n name: string\n arena: boolean\n containerId?: string\n fluidPart?: string\n fluidOffset: Vec3\n uses: string[]\n piece: Piece | null\n last: Vec3\n velocity: Vec3\n}\n\ninterface Projectile {\n mesh: THREE_NS.Object3D\n pos: THREE_NS.Vector3\n vel: THREE_NS.Vector3\n weapon: string\n fuse: number\n burstOnImpact: boolean\n energy: number\n radius: number\n fire?: { temperature: number; radius: number; seconds: number }\n age: number\n}\n\ninterface FireZone {\n point: Vec3\n radius: number\n temperature: number\n remaining: number\n acc: number\n}\n\ninterface BurningStain {\n center: Vec3\n remaining: number\n acc: number\n}\n\nconst FIXED_DT = 1 / 60\n\nconst v3 = (v: THREE_NS.Vector3): Vec3 => [v.x, v.y, v.z]\nconst dist3 = (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\n\n/**\n * Create the test room. See `TestRoomOptions`. The room owns a renderer, scene and camera unless you pass them; with your own renderer you call\n * `room.update(dt)` every frame and render yourself.\n */\nexport function createTestRoom(options: TestRoomOptions): TestRoom {\n const THREE = options.THREE\n const locale = options.locale ?? 'en'\n const S = resolveStrings(locale)\n const dStrings = resolveDestructionStrings(locale)\n const fStrings = resolveFluidStrings(locale)\n const t = (key: string, vars?: Vars): string => {\n let s = S.text[key] ?? key\n if (vars) for (const k of Object.keys(vars)) s = s.split(`{${k}}`).join(String(vars[k]))\n return s\n }\n const num = (n: number, digits = 1): string => {\n const s = (Math.round(n * 10 ** digits) / 10 ** digits).toFixed(digits)\n return locale.toLowerCase().startsWith('pt') ? s.replace('.', ',') : s\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Renderer, scene, camera\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const ownRenderer = !options.renderer\n const gl: THREE_NS.WebGLRenderer = options.renderer ?? new THREE.WebGLRenderer({ antialias: true })\n const container = options.container\n const width = (): number => container.clientWidth || 960\n const height = (): number => container.clientHeight || 600\n if (ownRenderer) {\n const r = gl as THREE_NS.WebGLRenderer\n r.setPixelRatio(Math.min(typeof devicePixelRatio === 'number' ? devicePixelRatio : 1, 2))\n r.shadowMap.enabled = true\n r.shadowMap.type = THREE.PCFSoftShadowMap\n r.toneMapping = THREE.ACESFilmicToneMapping\n r.toneMappingExposure = 1\n r.outputColorSpace = THREE.SRGBColorSpace\n container.appendChild(r.domElement)\n }\n gl.setSize(width(), height())\n const dom = gl.domElement\n if (dom && !dom.hasAttribute?.('tabindex')) dom.setAttribute?.('tabindex', '0')\n const scene = options.scene ?? new THREE.Scene()\n const camera = options.camera ?? new THREE.PerspectiveCamera(72, width() / height(), 0.05, 140)\n if (!options.camera) scene.add(camera)\n const resize = (): void => {\n const w = width()\n const h = height()\n gl.setSize(w, h)\n camera.aspect = w / h\n camera.updateProjectionMatrix()\n }\n const onResize = (): void => resize()\n window.addEventListener('resize', onResize)\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Worlds\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const arenaSize = options.arenaSize ?? 14\n const arena: Arena = createArena(THREE, arenaSize, scene)\n scene.add(arena.group)\n\n const ownWorld = !options.world\n const world = options.world ?? createDestruction({ seed: 1, ...options.worldOptions, materials: [...DEMO_MATERIALS, ...(options.worldOptions?.materials ?? [])] })\n const pristineWorld = ownWorld ? world.serialize() : null\n const tableOk = (): boolean => {\n const p = world.part(arena.table.id, arena.table.topPart)\n return !!p && p.status !== 'broken' && p.status !== 'melted' && p.status !== 'ashes'\n }\n const groundAt = (x: number, z: number): number =>\n x > arena.table.minX && x < arena.table.maxX && z > arena.table.minZ && z < arena.table.maxZ && tableOk() ? arena.table.top : 0\n\n const ownFluids = !options.fluids\n const fluids = options.fluids ?? createFluids({ seed: 1, locale, liquids: options.liquids, groundAt })\n const pristineFluids = ownFluids ? fluids.serialize() : null\n for (const s of [...arena.surfaces, ...(options.surfaces ?? [])]) fluids.addSurface(s)\n const itemUseDefs = [...ITEM_USES, ...(options.itemUses ?? [])]\n\n const quality = options.quality ?? 'medium'\n const pointScale = height() / (2 * Math.tan((camera.fov * Math.PI) / 360))\n const rendererPieces = new Map<string, Piece>()\n const entries = new Map<string, Entry>()\n const splitOf = new Map<string, Entry>()\n let simTime = 0\n const log = createLog({ exportCancelled: () => t('log.export_cancelled') })\n log.setClock(() => simTime)\n\n const renderer = createDestructionRenderer(THREE, {\n scene,\n world,\n quality,\n groundAt,\n pointScale,\n onSound: options.onSound,\n onPiece: (piece) => {\n rendererPieces.set(piece.objectId, piece)\n loose.push(piece)\n // find the entry it came from: the one whose spec holds all its parts and that is nearest\n const st = world.state(piece.objectId)\n if (!st) return\n let best: Entry | null = null\n let bestD = Infinity\n for (const e of entries.values()) {\n const spec = specs.get(e.so.objectId)\n if (!spec) continue\n const ids = new Set(spec.parts.map((p) => p.id))\n if (!st.parts.every((p) => ids.has(p.id))) continue\n const d = e.so.root.position.distanceTo(piece.root.position)\n if (d < bestD) {\n bestD = d\n best = e\n }\n }\n if (best) splitOf.set(piece.objectId, best)\n },\n })\n const fluidView: FluidRenderer = createFluidRenderer(THREE, { scene, fluids, quality, pointScale })\n const specs = new Map<string, DestructibleSpec>()\n const loose: Piece[] = []\n\n const arsenal = options.arsenal ?? createArsenal({ locale, weapons: options.weapons, seed: 1 })\n const loadout = (options.loadout ?? DEFAULT_LOADOUT).filter((id) => arsenal.weapons.has(id))\n const tools = new Map<string, WeaponState>()\n let toolIndex = Math.max(0, loadout.indexOf('hand'))\n let toolId = loadout[toolIndex] ?? 'hand'\n const toolState = (id: string): WeaponState => {\n let s = tools.get(id)\n if (!s) {\n s = arsenal.create(id, { seed: 7, reserve: 999 })\n s.refill()\n tools.set(id, s)\n }\n return s\n }\n let tool = toolState(toolId)\n\n const catalogMap = new Map<string, TestRoomItem>()\n for (const i of demoItems(locale)) catalogMap.set(i.id, i)\n for (const i of options.catalog) catalogMap.set(i.id, i)\n const catalog = [...options.catalog]\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Names and narration\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const entryOf = (objectId: string): Entry | undefined => entries.get(objectId) ?? splitOf.get(objectId)\n const nameOf = (objectId: string): string => {\n const e = entries.get(objectId)\n if (e) return e.name\n const s = splitOf.get(objectId)\n return s ? `${s.name} (${t('piece')})` : objectId\n }\n const narrator = createNarrator({\n world,\n fluids,\n log,\n now: () => simTime,\n t,\n num,\n nameOf,\n itemIdOf: (id) => entryOf(id)?.so.itemId,\n materialName: (id) => S.text[`material.${id}`] ?? dStrings.materialNames[id] ?? id,\n liquidName: (id) => fStrings.liquids[id] ?? id,\n jointKind: (k) => dStrings.jointKinds[k as keyof typeof dStrings.jointKinds] ?? k,\n toolName: (k) => dStrings.toolKinds[k as keyof typeof dStrings.toolKinds] ?? k,\n locatePart: (objectId, partId) => {\n const own = world.part(objectId, partId)\n if (own) return { objectId, part: own }\n for (const [id, owner] of splitOf) {\n if (owner.so.objectId !== objectId) continue\n const p = world.part(id, partId)\n if (p) return { objectId: id, part: p }\n }\n return null\n },\n containerName: (cid) => {\n for (const e of entries.values()) if (e.containerId === cid) return { name: e.name, objectId: e.so.objectId, itemId: e.so.itemId }\n return undefined\n },\n })\n\n let pending: DestructionEvent[] = []\n const eventListeners = new Set<(d: unknown) => void>()\n const listeners: Record<string, Set<(d: unknown) => void>> = { spawn: new Set(), tool: new Set(), grab: new Set(), throw: new Set(), event: eventListeners }\n const fire = (type: string, data: unknown): void => {\n for (const fn of listeners[type] ?? []) fn(data)\n }\n world.on('*', (ev) => {\n pending.push(ev)\n })\n fluids.on('*', (ev: FluidEvent) => {\n narrator.fluid(ev)\n fire('event', ev)\n })\n\n const action = (type: string, text: string, extra: Partial<{ objectId: string; itemId: string; part: string; data: Record<string, unknown>; material: string }> = {}): void => {\n log.add({ channel: 'action', type, text, ...extra })\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Flush: events of the frame -> log, fluids glue, fire glue\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const tmpV = new THREE.Vector3()\n const tmpV2 = new THREE.Vector3()\n const tmpQ = new THREE.Quaternion()\n const tmpM = new THREE.Matrix4()\n\n const hostOf = (e: Entry): { objectId: string; root: THREE_NS.Object3D } => {\n if (e.fluidPart && !e.arena && !world.part(e.so.objectId, e.fluidPart)) {\n for (const [id, owner] of splitOf) {\n if (owner === e && world.part(id, e.fluidPart)) {\n const p = rendererPieces.get(id)\n if (p) return { objectId: id, root: p.root }\n }\n }\n }\n return { objectId: e.so.objectId, root: e.so.root }\n }\n\n const puncture = (ev: Extract<DestructionEvent, { type: 'leak' }>): void => {\n const e = entryOf(ev.object)\n if (!e?.containerId || e.fluidPart !== ev.part) return\n const host = hostOf(e)\n host.root.updateMatrixWorld(true)\n tmpM.copy(host.root.matrixWorld).invert()\n const local = tmpV.set(ev.point[0], ev.point[1], ev.point[2]).applyMatrix4(tmpM)\n local.x -= e.fluidOffset[0]\n local.y -= e.fluidOffset[1]\n local.z -= e.fluidOffset[2]\n host.root.getWorldQuaternion(tmpQ).invert()\n const n = tmpV2.set(ev.direction[0], ev.direction[1], ev.direction[2]).applyQuaternion(tmpQ)\n const part = world.part(host.objectId, ev.part)\n const hole = part?.holes[part.holes.length - 1]\n fluids.puncture(e.containerId, [local.x, local.y, local.z], [n.x, n.y, n.z], hole?.diameter ?? 0.009)\n }\n\n const flush = (): void => {\n if (pending.length === 0) return\n const batch = pending\n pending = []\n narrator.events(batch)\n for (const ev of batch) {\n if (ev.type === 'leak') puncture(ev)\n else if (ev.type === 'ignite') igniteNear(ev.point, 0.9)\n fire('event', ev)\n options.onEvent?.(ev)\n }\n }\n log.setBeforeRead(flush)\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Player\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let useHeld = false\n let useFirst = false\n const player = createPlayer(THREE, {\n camera,\n dom,\n colliders: arena.colliders,\n limit: arenaSize,\n start: arena.playerStart,\n hooks: {\n primaryDown: () => {\n useHeld = true\n useFirst = true\n },\n primaryUp: () => {\n useHeld = false\n tool.release()\n },\n secondary: () => {\n if (heldEntry) throwHeld()\n else grab()\n },\n key: (code, down, e) => onKey(code, down, e),\n wheel: (dir) => cycleTool(dir),\n },\n })\n player.look(arena.playerStart, [0, 1.5, arena.wallZ])\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Spawning\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let counter = 0\n let slot = 0\n const maxCarry = options.maxCarryKg ?? 60\n\n const massOfObject = (id: string): number => {\n const st = world.state(id)\n let m = 0\n for (const p of st?.parts ?? []) if (p.status !== 'broken' && p.status !== 'melted' && p.status !== 'ashes') m += p.mass\n return m\n }\n\n const registerEntry = (\n objectId: string,\n itemId: string,\n root: THREE_NS.Object3D,\n spec: DestructibleSpec,\n name: string,\n parts: Record<string, THREE_NS.Object3D | THREE_NS.Object3D[]> | undefined,\n item: TestRoomItem | undefined,\n arenaObject: boolean,\n movable: boolean,\n ): Entry => {\n specs.set(objectId, spec)\n renderer.bind(objectId, root, parts ? { parts } : undefined)\n const so: SpawnedObject = { objectId, itemId, root, movable }\n const e: Entry = { so, item, name, arena: arenaObject, fluidOffset: [0, 0, 0], uses: [], piece: null, last: [root.position.x, root.position.y, root.position.z], velocity: [0, 0, 0] }\n entries.set(objectId, e)\n if (movable) {\n e.piece = renderer.makePiece(objectId, { mass: Math.max(0.2, massOfObject(objectId)) })\n rendererPieces.set(objectId, e.piece)\n }\n const f = item?.fluid\n if (f) {\n e.fluidPart = f.part\n e.fluidOffset = f.offset ?? [0, 0, 0]\n e.uses = f.uses ?? ['drink', 'sip', 'pour']\n root.updateMatrixWorld(true)\n const q = root.getWorldQuaternion(tmpQ)\n const p = tmpV.set(e.fluidOffset[0], e.fluidOffset[1], e.fluidOffset[2]).applyMatrix4(root.matrixWorld)\n e.containerId = fluids.addContainer(f.container, { id: `${objectId}_fluid`, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] })\n fluidView.bindContainer(e.containerId, root, { innerOffset: e.fluidOffset })\n }\n return e\n }\n\n const resolveSpec = (item: TestRoomItem, root: THREE_NS.Object3D): { spec: DestructibleSpec; parts?: Record<string, THREE_NS.Object3D[]> } => {\n if (typeof item.spec === 'function') return { spec: structuredCloneSpec(item.spec(root)) }\n if (item.spec) return { spec: structuredCloneSpec(item.spec) }\n const r = specFromObject3D(THREE, root, { name: item.id, ...item.specOptions })\n return { spec: r.spec, parts: r.parts }\n }\n\n const addArena = (): void => {\n for (const o of arena.objects) {\n const root = buildFromSpec(THREE, o.spec, { colors: o.colors })\n root.position.set(o.position[0], o.position[1], o.position[2])\n scene.add(root)\n root.updateMatrixWorld(true)\n world.add(structuredCloneSpec(o.spec), { id: o.id, position: o.position })\n registerEntry(o.id, o.id, root, o.spec, S.text[`arena.${o.id}`] ?? o.id, undefined, undefined, true, false)\n }\n }\n addArena()\n\n const spawn = (itemId: string, position?: Vec3, rotationY?: number): SpawnedObject => {\n const item = catalogMap.get(itemId)\n if (!item) throw new Error(`game-test-room: unknown item \"${itemId}\"`)\n const root = item.build(THREE)\n let pos: Vec3\n if (position) pos = [position[0], position[1], position[2]]\n else {\n const fx = -Math.sin(player.yaw)\n const fz = -Math.cos(player.yaw)\n const rx = Math.cos(player.yaw)\n const rz = -Math.sin(player.yaw)\n const side = ((slot++ % 5) - 2) * 0.55\n const x = camera.position.x + fx * 2.4 + rx * side\n const z = camera.position.z + fz * 2.4 + rz * side\n const lim = arenaSize - 1\n pos = [Math.max(-lim, Math.min(lim, x)), groundAt(x, z), Math.max(-lim, Math.min(lim, z))]\n }\n root.position.set(pos[0], pos[1], pos[2])\n root.rotation.y = rotationY ?? player.yaw\n root.name = item.id\n scene.add(root)\n root.updateMatrixWorld(true)\n const objectId = `${item.id}_${++counter}`\n let own: DestructibleImpl | undefined\n let resolved: { spec: DestructibleSpec; parts?: Record<string, THREE_NS.Object3D[]> }\n if (item.impl) {\n own = item.impl(root, objectId)\n if (own.id !== objectId) throw new Error(`game-test-room: item \"${item.id}\": DestructibleImpl.id is \"${own.id}\", the room gave it \"${objectId}\" (use the id passed to impl)`)\n resolved = { spec: structuredCloneSpec(own.describe()) }\n } else resolved = resolveSpec(item, root)\n const { spec, parts } = resolved\n root.updateMatrixWorld(true)\n const mass = spec.parts.reduce((m, p) => m + (p.mass ?? 0), 0)\n const heavy = (mass || massGuess(spec)) > maxCarry\n const movable = own ? false : (item.movable ?? !heavy)\n if (movable) {\n // things that can fall rest on the floor or the table by the bottom of their bounding box (or hang at the height asked for): no drop on spawn\n const box = new THREE.Box3().setFromObject(root)\n const base = Math.max(pos[1], groundAt(pos[0], pos[2]))\n pos = [pos[0], pos[1] + (base - box.min.y), pos[2]]\n root.position.set(pos[0], pos[1], pos[2])\n root.updateMatrixWorld(true)\n }\n const q = root.getWorldQuaternion(tmpQ)\n if (own) world.register(own, { id: objectId, position: pos, rotation: [q.x, q.y, q.z, q.w] })\n else world.add(spec, { id: objectId, position: pos, rotation: [q.x, q.y, q.z, q.w] })\n const e = registerEntry(objectId, item.id, root, spec, item.name, parts, item, false, movable)\n action('spawn', t('act.spawn', { name: item.name, x: num(pos[0], 1), z: num(pos[2], 1) }), { objectId, itemId: item.id, data: { position: pos, movable, massKg: Math.round(massOfObject(objectId) * 10) / 10 } })\n fire('spawn', e.so)\n return e.so\n }\n const massGuess = (spec: DestructibleSpec): number => {\n let m = 0\n for (const p of spec.parts) {\n const s = p.shape\n const vol = s.kind === 'box' ? s.size[0] * s.size[1] * s.size[2] : s.kind === 'cylinder' ? Math.PI * s.radius * s.radius * s.height : (4 / 3) * Math.PI * s.radius ** 3\n m += p.mass ?? vol * (world.materials.get(p.material)?.density ?? 500) * (p.fill ?? 1)\n }\n return m\n }\n\n const removeEntry = (id: string): void => {\n const e = entries.get(id)\n if (!e) return\n if (heldEntry === e) releaseHeld()\n for (let i = playing.length - 1; i >= 0; i--) if (playing[i].entry === e) playing.splice(i, 1)\n if (e.containerId) {\n fluidView.unbindContainer(e.containerId)\n fluids.removeContainer(e.containerId)\n }\n try {\n renderer.unbind(id)\n } catch {\n // not bound\n }\n if (world.has(id)) world.remove(id)\n e.so.root.removeFromParent()\n entries.delete(id)\n rendererPieces.delete(id)\n specs.delete(id)\n }\n\n const clearLoose = (): void => {\n for (const [id, owner] of [...splitOf]) {\n void owner\n const p = rendererPieces.get(id)\n try {\n renderer.unbind(id)\n } catch {\n // gone already\n }\n if (world.has(id)) world.remove(id)\n p?.root.removeFromParent()\n rendererPieces.delete(id)\n splitOf.delete(id)\n }\n loose.length = 0\n }\n\n const clearEverything = (): void => {\n if (heldEntry || heldPiece) releaseHeld()\n useItemPlayer = null\n playing.length = 0\n projectiles.length = 0\n clearProjectileMeshes()\n fireZones.length = 0\n burningStains.length = 0\n for (const id of [...entries.keys()]) if (!entries.get(id)?.arena) removeEntry(id)\n clearLoose()\n for (const e of entries.values()) {\n world.reset(e.so.objectId)\n renderer.restore(e.so.objectId)\n }\n renderer.clear()\n fluids.clearStains([0, 0, 0], 1e4)\n fluidView.clear()\n fluids.setTap(TAP_ID, false)\n }\n\n const clear = (): void => {\n clearEverything()\n pending = []\n action('clear', t('act.clear'))\n }\n\n const resetAll = (): void => {\n for (const e of entries.values()) {\n if (heldEntry === e) continue\n world.reset(e.so.objectId)\n renderer.restore(e.so.objectId)\n if (e.containerId) {\n const c = fluids.container(e.containerId)\n const f = e.item?.fluid?.container\n if (c && f && f.liquid) fluids.fill(e.containerId, f.liquid, Math.max(0, (f.liters ?? 0) - c.liters), f.temperature)\n }\n }\n action('reset', t('act.reset'))\n }\n\n /** Reset the worlds to their seeded start: used by scenarios so that each one is deterministic. */\n const hardReset = (): void => {\n clearEverything()\n for (const id of [...entries.keys()]) removeEntry(id)\n tools.clear()\n tool = toolState(toolId)\n if (pristineWorld) {\n for (const id of world.ids()) world.remove(id)\n world.load(pristineWorld)\n }\n if (pristineFluids) {\n fluids.load(pristineFluids)\n for (const s of [...arena.surfaces, ...(options.surfaces ?? [])]) fluids.addSurface(s)\n }\n pending = []\n rng = 12345\n counter = 0\n slot = 0\n prevVy.clear()\n lastImpact.clear()\n addArena()\n timeScale = 1\n fastForward = false\n walkPlan = null\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Aiming\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const aimO: Vec3 = [0, 0, 0]\n const aimD: Vec3 = [0, 0, -1]\n const aim = (): void => {\n camera.updateMatrixWorld(true)\n camera.getWorldPosition(tmpV)\n camera.getWorldDirection(tmpV2)\n aimO[0] = tmpV.x\n aimO[1] = tmpV.y\n aimO[2] = tmpV.z\n aimD[0] = tmpV2.x\n aimD[1] = tmpV2.y\n aimD[2] = tmpV2.z\n }\n\n const FAR: Quat = [0, 0, 0, 1]\n /** Run `fn` with the held object moved away, so that rays and bullets do not hit what the player carries. */\n const withoutHeld = <T,>(fn: () => T): T => {\n const e = heldEntry\n if (!e || !world.has(e.so.objectId)) return fn()\n const p = e.so.root.position\n const q = e.so.root.quaternion\n world.setTransform(e.so.objectId, [0, -5000, 0], FAR)\n try {\n return fn()\n } finally {\n world.setTransform(e.so.objectId, [p.x, p.y, p.z], [q.x, q.y, q.z, q.w])\n }\n }\n\n const rayWorld = (o: Vec3, d: Vec3, max: number): RayHit | null => withoutHeld(() => world.raycast(o, d, max))\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Particles helpers and a tiny seeded rng for visuals\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let rng = 12345\n const rnd = (): number => {\n rng = (rng * 1664525 + 1013904223) >>> 0\n return rng / 4294967296\n }\n\n const muzzle = (): Vec3 => {\n aim()\n const e = camera.matrixWorld.elements\n // right = x axis, up = y axis of the camera\n return [\n aimO[0] + aimD[0] * 0.45 + e[0] * 0.16 - e[4] * 0.1,\n aimO[1] + aimD[1] * 0.45 + e[1] * 0.16 - e[5] * 0.1,\n aimO[2] + aimD[2] * 0.45 + e[2] * 0.16 - e[6] * 0.1,\n ]\n }\n\n // tracers\n const tracers: Array<{ line: THREE_NS.Line; life: number }> = []\n const tracerMat = new THREE.LineBasicMaterial({ color: 0xffe9a8, transparent: true, opacity: 0.9 })\n const tracer = (a: Vec3, b: Vec3): void => {\n let tr = tracers.find((x) => x.life <= 0)\n if (!tr) {\n if (tracers.length >= 12) return\n const g = new THREE.BufferGeometry()\n g.setAttribute('position', new THREE.Float32BufferAttribute(6, 3))\n const line = new THREE.Line(g, tracerMat)\n line.frustumCulled = false\n scene.add(line)\n tr = { line, life: 0 }\n tracers.push(tr)\n }\n const attr = tr.line.geometry.getAttribute('position') as THREE_NS.BufferAttribute\n attr.setXYZ(0, a[0], a[1], a[2])\n attr.setXYZ(1, b[0], b[1], b[2])\n attr.needsUpdate = true\n tr.line.visible = true\n tr.life = 0.07\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Fire glue: stains of flammable liquids, fire zones (molotov), dry water near fire\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const fireZones: FireZone[] = []\n const burningStains: BurningStain[] = []\n const stainRadius = (s: StainState): number => {\n let sum = 0\n for (const r of s.front) sum += r\n return s.front.length ? sum / s.front.length : 0.1\n }\n const stainBurning = (s: StainState): boolean => burningStains.some((b) => dist3(b.center, s.center) < 0.05)\n\n function igniteNear(point: Vec3, reach: number): void {\n let lit = false\n let water = false\n for (const s of fluids.stains()) {\n if (s.wetness < 0.05) continue\n if (Math.hypot(s.center[0] - point[0], s.center[2] - point[2]) > reach + stainRadius(s) || Math.abs(s.center[1] - point[1]) > 1.5) continue\n if (fluids.liquids.get(s.liquid)?.flammable) {\n if (stainBurning(s)) continue\n const seconds = Math.max(3, Math.min(20, 4 + s.liters * 30 + stainRadius(s) * 6))\n burningStains.push({ center: [s.center[0], s.center[1], s.center[2]], remaining: seconds, acc: 0 })\n lit = true\n log.add({\n channel: 'event',\n type: 'stain_ignite',\n text: t('ev.stain_ignite', { liquid: fStrings.liquids[s.liquid] ?? s.liquid, x: num(s.center[0], 1), z: num(s.center[2], 1), seconds: num(seconds, 0) }),\n data: { stain: s.id, liquid: s.liquid, seconds },\n })\n } else water = true\n }\n if (water && !lit) {\n fluids.clearStains(point, Math.max(0.5, reach))\n log.coalesce('dry', { channel: 'event', type: 'stain_dried_by_fire', text: t('ev.fire_dries'), data: { point } }, 2)\n }\n }\n\n const hitFireAround = (point: Vec3, radius: number, temperature: number, duration: number): void => {\n for (const id of world.ids()) world.hit(id, { type: 'fire', point, temperature, radius, duration, source: 'fire' })\n }\n\n const updateFires = (dt: number): void => {\n for (let i = fireZones.length - 1; i >= 0; i--) {\n const z = fireZones[i]\n z.remaining -= dt\n z.acc += dt\n if (z.acc >= 0.1) {\n hitFireAround(z.point, z.radius, z.temperature, z.acc)\n igniteNear(z.point, z.radius)\n z.acc = 0\n }\n const a = rnd() * Math.PI * 2\n const r = Math.sqrt(rnd()) * z.radius\n renderer.emit('fire', [z.point[0] + Math.cos(a) * r, z.point[1] + 0.05, z.point[2] + Math.sin(a) * r], [0, 1, 0], 2, 1.5)\n if (z.remaining <= 0) fireZones.splice(i, 1)\n }\n if (burningStains.length) {\n const stains = fluids.stains()\n for (let i = burningStains.length - 1; i >= 0; i--) {\n const b = burningStains[i]\n b.remaining -= dt\n b.acc += dt\n const st = stains.find((s) => dist3(s.center, b.center) < 0.05)\n const r = st ? stainRadius(st) : 0.3\n if (b.acc >= 0.1) {\n hitFireAround([b.center[0], b.center[1] + 0.1, b.center[2]], r + 0.2, 800, b.acc)\n b.acc = 0\n }\n const a = rnd() * Math.PI * 2\n const rr = Math.sqrt(rnd()) * r\n renderer.emit('fire', [b.center[0] + Math.cos(a) * rr, b.center[1] + 0.05, b.center[2] + Math.sin(a) * rr], [0, 1, 0], 3, 1.8)\n if (rnd() < 0.2) renderer.emit('smoke', [b.center[0], b.center[1] + 0.3, b.center[2]], [0, 1, 0], 1, 1)\n if (b.remaining <= 0 || !st) {\n fluids.clearStains(b.center, r + 0.1)\n log.add({ channel: 'event', type: 'stain_burned', text: t('ev.stain_burned'), data: { point: b.center } })\n burningStains.splice(i, 1)\n }\n }\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Tools\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let progress: { label: string; value: number; at: number } | null = null\n let statusLine = ''\n let statusAt = 0\n const say = (msg: string): void => {\n statusLine = msg\n statusAt = simTime\n ui?.toast(msg)\n }\n\n const toolName = (id = toolId): string => arsenal.name(id)\n const hitWhere = (r: RayHit): string => {\n const p = world.part(r.object, r.part)\n return `${nameOf(r.object)} › ${r.part}${p ? ` (${dStrings.materialNames[p.material] ?? p.material})` : ''}`\n }\n\n const pushPiece = (objectId: string, dir: Vec3, momentum: number, point: Vec3): void => {\n if (!rendererPieces.has(objectId)) return\n renderer.impulse(objectId, [dir[0] * momentum, dir[1] * momentum, dir[2] * momentum], point)\n }\n\n const fireShots = (shots: Shot[], recoil: [number, number]): void => {\n if (shots.length === 0) return\n const w = toolName()\n const m = muzzle()\n renderer.emit('flash', m, [aimD[0], aimD[1], aimD[2]], 1, 0)\n renderer.emit('sparks', m, [aimD[0], aimD[1], aimD[2]], 4, 6)\n let hits = 0\n let first: RayHit | null = null\n let energy = 0\n withoutHeld(() => {\n for (const s of shots) {\n energy = Math.max(energy, s.energy)\n const results = world.shoot(s.origin, s.direction, s.energy, s.caliber, 'player')\n const r0 = results.find((r) => r.part && r.point)\n let end: Vec3 = [s.origin[0] + s.direction[0] * 40, s.origin[1] + s.direction[1] * 40, s.origin[2] + s.direction[2] * 40]\n if (r0?.point && r0.part) {\n hits++\n end = r0.point\n if (!first) first = { object: r0.object, part: r0.part, point: r0.point, normal: [0, 1, 0], distance: dist3(s.origin, r0.point) }\n const speed = Math.max(80, s.speed)\n pushPiece(r0.object, s.direction, (2 * s.energy) / speed, r0.point)\n }\n if (shots.length <= 3 || rnd() < 0.34) tracer(m, end)\n }\n })\n player.kick(recoil[0], recoil[1])\n const f = first as RayHit | null\n const d = f ? num(f.distance, 1) : ''\n let text: string\n if (shots.length === 1) text = t(f ? 'act.shoot.hit' : 'act.shoot.miss', { weapon: w, energy: num(energy, 0), where: f ? hitWhere(f) : '', dist: d })\n else text = t('act.shoot.pellets', { weapon: w, n: shots.length, energy: num(energy, 0), hits, where: f ? hitWhere(f) : '', dist: d })\n action('shoot', text, {\n objectId: f?.object,\n itemId: f ? entryOf(f.object)?.so.itemId : undefined,\n part: f?.part,\n data: { weapon: toolId, shots: shots.length, hits, energyJ: Math.round(energy), caliberMm: shots[0].caliber, distanceM: f ? Math.round(f.distance * 100) / 100 : null },\n })\n }\n\n const fireRays = (u: { origin: Vec3; direction: Vec3; range: number; cone: boolean; radius: number }): Array<Vec3> => {\n const d = new THREE.Vector3(u.direction[0], u.direction[1], u.direction[2]).normalize()\n const out: Vec3[] = [[d.x, d.y, d.z]]\n if (u.cone) {\n const a = Math.min(0.2, Math.atan2(u.radius, Math.max(0.1, u.range)))\n const right = new THREE.Vector3().crossVectors(d, new THREE.Vector3(0, 1, 0))\n if (right.lengthSq() < 1e-6) right.set(1, 0, 0)\n right.normalize()\n const up = new THREE.Vector3().crossVectors(right, d).normalize()\n for (const [x, y] of [\n [1, 0],\n [-1, 0],\n [0, 1],\n [0, -1],\n ]) {\n const r = d.clone().addScaledVector(right, x * a).addScaledVector(up, y * a).normalize()\n out.push([r.x, r.y, r.z])\n }\n }\n return out\n }\n\n const heatRays = (u: Extract<Use, { kind: 'flame' | 'heat' }>, type: 'fire' | 'heat'): void => {\n const w = toolName()\n const cone = u.kind === 'flame' ? u.cone : false\n const rays = fireRays({ origin: u.origin, direction: u.direction, range: u.range, cone, radius: u.radius })\n let target: RayHit | null = null\n const m = muzzle()\n withoutHeld(() => {\n for (const d of rays) {\n const r = world.raycast(u.origin, d, u.range)\n if (!r) continue\n if (!target) target = r\n world.hit(r.object, { type, point: r.point, direction: d, temperature: u.temperature, radius: Math.min(u.radius, 0.3), duration: u.duration, source: 'player' })\n if (type === 'fire') igniteNear(r.point, 0.25)\n else renderer.emit('sparks', r.point, r.normal, 2, 4)\n }\n })\n if (type === 'fire') {\n renderer.emit('fire', m, [u.direction[0], u.direction[1], u.direction[2]], cone ? 5 : 1, Math.max(0.6, u.range * 1.1))\n if (cone) renderer.emit('smoke', m, [u.direction[0], u.direction[1] + 0.3, u.direction[2]], 1, u.range * 0.5)\n // nothing hit: the stain on the ground in front may still catch\n if (!target && u.direction[1] < -0.2) {\n const t0 = (0.05 - u.origin[1]) / u.direction[1]\n if (t0 > 0 && t0 < u.range) igniteNear([u.origin[0] + u.direction[0] * t0, 0.05, u.origin[2] + u.direction[2] * t0], 0.3)\n }\n }\n const tg = target as RayHit | null\n log.coalesce(\n `use:${toolId}`,\n {\n channel: 'action',\n type,\n text: tg ? t(type === 'fire' ? 'act.flame.hit' : 'act.heat.hit', { weapon: w, where: hitWhere(tg), temp: num(u.temperature, 0) }) : t(type === 'fire' ? 'act.flame.air' : 'act.heat.air', { weapon: w }),\n objectId: tg?.object,\n part: tg?.part,\n data: { weapon: toolId, temperatureC: u.temperature },\n },\n 1,\n )\n }\n\n const meleeUse = (u: Extract<Use, { kind: 'melee' }>, id = toolId): void => {\n const w = toolName(id)\n const r = rayWorld(u.origin, u.direction, u.reach)\n if (!r) {\n action('melee', t('act.melee.miss', { weapon: w }), { data: { weapon: id } })\n return\n }\n world.hitPart(r.object, r.part, { type: u.damage, point: r.point, direction: u.direction, energy: u.energy, radius: u.radius, source: 'player' })\n pushPiece(r.object, u.direction, (2 * u.energy) / 6, r.point)\n action('melee', t('act.melee.hit', { weapon: w, energy: num(u.energy, 0), where: hitWhere(r), dist: num(r.distance, 1) }), {\n objectId: r.object,\n itemId: entryOf(r.object)?.so.itemId,\n part: r.part,\n data: { weapon: id, damage: u.damage, energyJ: u.energy, distanceM: Math.round(r.distance * 100) / 100 },\n })\n }\n\n const toolWork = (u: Extract<Use, { kind: 'tool' }>, dt: number): void => {\n const w = toolName()\n const r = rayWorld(u.origin, u.direction, u.reach)\n if (!r) {\n progress = null\n log.coalesce(`use:${toolId}`, { channel: 'action', type: 'tool', text: t('act.tool.none', { weapon: w }), data: { weapon: toolId } }, 1)\n return\n }\n const j: JointState | null = world.nearestJoint(r.object, r.point, 0.45, u.tool as ToolKind)\n if (!j) {\n progress = null\n log.coalesce(`use:${toolId}`, { channel: 'action', type: 'tool', text: t('act.tool.nojoint', { weapon: w, where: hitWhere(r) }), objectId: r.object, part: r.part }, 1)\n return\n }\n const tool_ = u.tool as ToolKind\n const p = world.disassemble(r.object, j.id, tool_, dt)\n const kind = dStrings.jointKinds[j.kind] ?? j.kind\n if (p < 0) {\n const need = JOINT_DEFAULTS[j.kind].tools.map((k) => dStrings.toolKinds[k] ?? k).join(', ') || t('tool.none')\n progress = { label: t('hud.refused', { kind }), value: 0, at: simTime }\n log.coalesce(\n `refuse:${r.object}:${j.id}:${toolId}`,\n {\n channel: 'action',\n type: 'tool_refused',\n text: t('act.tool.refused', { weapon: w, kind, obj: nameOf(r.object), need }),\n objectId: r.object,\n itemId: entryOf(r.object)?.so.itemId,\n data: { weapon: toolId, joint: j.id, kind: j.kind, needs: JOINT_DEFAULTS[j.kind].tools },\n },\n 2,\n )\n return\n }\n progress = { label: `${kind} (${j.id})`, value: p, at: simTime }\n renderer.emit('sparks', r.point, r.normal, 1, 2)\n }\n\n const extinguishUse = (u: Extract<Use, { kind: 'extinguish' }>): void => {\n const w = toolName()\n const rays = fireRays({ origin: u.origin, direction: u.direction, range: u.range, cone: true, radius: 0.6 })\n const m = muzzle()\n renderer.emit('foam', m, [u.direction[0], u.direction[1], u.direction[2]], 8, u.range * 1.2)\n const hit = new Set<string>()\n withoutHeld(() => {\n for (const d of rays) {\n const r = world.raycast(u.origin, d, u.range)\n if (!r) continue\n hit.add(r.object)\n world.extinguish(r.object, undefined, u.coolC * Math.max(u.duration, 0.05) * 6)\n fluids.clearStains(r.point, 0.5)\n for (let i = burningStains.length - 1; i >= 0; i--) if (Math.hypot(burningStains[i].center[0] - r.point[0], burningStains[i].center[2] - r.point[2]) < 1.2) burningStains.splice(i, 1)\n for (let i = fireZones.length - 1; i >= 0; i--) if (Math.hypot(fireZones[i].point[0] - r.point[0], fireZones[i].point[2] - r.point[2]) < 1.5) fireZones.splice(i, 1)\n }\n })\n log.coalesce(\n `use:${toolId}`,\n { channel: 'action', type: 'extinguish', text: hit.size ? t('act.extinguish.hit', { weapon: w, what: [...hit].map(nameOf).join(', ') }) : t('act.extinguish.air', { weapon: w }), data: { objects: [...hit] } },\n 1,\n )\n }\n\n // ----- projectiles (grenades and molotovs)\n const projectiles: Projectile[] = []\n const projMeshes: THREE_NS.Object3D[] = []\n const clearProjectileMeshes = (): void => {\n for (const m of projMeshes) m.removeFromParent()\n projMeshes.length = 0\n }\n const throwUse = (u: Extract<Use, { kind: 'throw' }>): void => {\n const w = toolName()\n const molotov = !!u.fire\n const mesh = new THREE.Mesh(\n molotov ? new THREE.CylinderGeometry(0.035, 0.04, 0.2, 8) : new THREE.SphereGeometry(0.045, 8, 6),\n new THREE.MeshStandardMaterial({ color: molotov ? 0x3b7a3b : 0x4b5320, roughness: 0.6, metalness: molotov ? 0 : 0.4 }),\n )\n mesh.castShadow = true\n mesh.position.set(u.origin[0], u.origin[1], u.origin[2])\n scene.add(mesh)\n projMeshes.push(mesh)\n projectiles.push({\n mesh,\n pos: new THREE.Vector3(u.origin[0], u.origin[1], u.origin[2]),\n vel: new THREE.Vector3(u.velocity[0], u.velocity[1], u.velocity[2]),\n weapon: toolId,\n fuse: u.fuse,\n burstOnImpact: molotov && u.fuse <= 0,\n energy: u.energy,\n radius: u.radius,\n fire: u.fire,\n age: 0,\n })\n action('throw_projectile', t(molotov ? 'act.throw.molotov' : 'act.throw.grenade', { weapon: w, fuse: num(u.fuse, 1) }), { data: { weapon: toolId, fuse: u.fuse } })\n }\n\n const detonate = (p: Projectile, at: Vec3, impact: boolean): void => {\n const w = toolName(p.weapon)\n const results = world.explode(at, p.energy, p.radius, 'player')\n action('explode', t('act.explode', { weapon: w, energy: num(p.energy, 0), radius: num(p.radius, 1), n: results.length }), { data: { weapon: p.weapon, energyJ: p.energy, radius: p.radius, point: at } })\n if (p.fire) {\n fluids.splash('fuel', [at[0], Math.max(at[1], groundAt(at[0], at[2])), at[2]], 0.5)\n fireZones.push({ point: [at[0], Math.max(0.02, groundAt(at[0], at[2])), at[2]], radius: p.fire.radius, temperature: p.fire.temperature, remaining: p.fire.seconds, acc: 0 })\n renderer.emit('fire', at, [0, 1, 0], 24, 3)\n action('molotov_fire', t('act.molotov_fire', { weapon: w, seconds: num(p.fire.seconds, 0), radius: num(p.fire.radius, 1) }), { data: { weapon: p.weapon, impact } })\n }\n }\n\n const updateProjectiles = (dt: number): void => {\n for (let i = projectiles.length - 1; i >= 0; i--) {\n const p = projectiles[i]\n p.age += dt\n p.vel.y -= 9.81 * dt\n const speed = p.vel.length()\n const step = speed * dt\n let burst = false\n if (step > 1e-6) {\n const d: Vec3 = [p.vel.x / speed, p.vel.y / speed, p.vel.z / speed]\n const r = withoutHeld(() => world.raycast(v3(p.pos), d, step + 0.05))\n if (r && r.distance <= step + 0.04) {\n p.pos.set(r.point[0] - d[0] * 0.03, r.point[1] - d[1] * 0.03, r.point[2] - d[2] * 0.03)\n if (p.burstOnImpact) burst = true\n else {\n const n = r.normal\n const vn = p.vel.x * n[0] + p.vel.y * n[1] + p.vel.z * n[2]\n p.vel.x = (p.vel.x - 2 * vn * n[0]) * 0.35\n p.vel.y = (p.vel.y - 2 * vn * n[1]) * 0.35\n p.vel.z = (p.vel.z - 2 * vn * n[2]) * 0.35\n }\n } else p.pos.addScaledVector(p.vel, dt)\n }\n const g = groundAt(p.pos.x, p.pos.z) + 0.045\n if (p.pos.y < g) {\n p.pos.y = g\n if (p.burstOnImpact) burst = true\n else {\n p.vel.y = Math.abs(p.vel.y) * 0.35\n p.vel.x *= 0.7\n p.vel.z *= 0.7\n }\n }\n p.mesh.position.copy(p.pos)\n p.mesh.rotation.x += dt * 8\n p.fuse -= dt\n if (burst || (!p.burstOnImpact && p.fuse <= 0) || p.age > 30) {\n detonate(p, v3(p.pos), burst)\n p.mesh.removeFromParent()\n projMeshes.splice(projMeshes.indexOf(p.mesh), 1)\n projectiles.splice(i, 1)\n }\n }\n }\n\n // ----- the trigger\n const useTool = (dt: number, held: boolean): void => {\n aim()\n const cat = tool.def.category\n if (cat === 'hand') return\n const res = tool.trigger([aimO[0], aimO[1], aimO[2]], [aimD[0], aimD[1], aimD[2]], dt, held, 'player')\n if (res.status === 'empty') {\n if (!tool.reloading && tool.reserve > 0) tool.reload()\n say(t(tool.reloading ? 'hud.reloading' : 'hud.empty'))\n return\n }\n if (res.status !== 'ok') {\n if (res.status === 'reloading') say(t('hud.reloading'))\n else if (res.status === 'no_fuel') say(t('hud.no_fuel'))\n return\n }\n if (res.shots.length) fireShots(res.shots, res.recoil)\n for (const u of res.uses) {\n switch (u.kind) {\n case 'melee':\n meleeUse(u)\n break\n case 'flame':\n heatRays(u, 'fire')\n break\n case 'heat':\n heatRays(u, 'heat')\n break\n case 'throw':\n throwUse(u)\n break\n case 'tool':\n toolWork(u, dt)\n break\n case 'extinguish':\n extinguishUse(u)\n break\n default:\n break\n }\n }\n }\n\n /** The V shortcut: a kick with the `kick` tool, whatever tool is selected (it keeps its own cooldown). */\n const kick = (): void => {\n if (!arsenal.weapons.has('kick')) return\n aim()\n const res = toolState('kick').trigger([aimO[0], aimO[1], aimO[2]], [aimD[0], aimD[1], aimD[2]], 0, false, 'player')\n if (res.status !== 'ok') return\n for (const u of res.uses) if (u.kind === 'melee') meleeUse(u, 'kick')\n }\n const setTool = (id: string): void => {\n if (!arsenal.weapons.has(id)) throw new Error(`game-test-room: unknown weapon \"${id}\"`)\n tool.release()\n toolId = id\n const i = loadout.indexOf(id)\n if (i >= 0) toolIndex = i\n tool = toolState(id)\n progress = null\n action('tool', t('act.tool', { weapon: toolName(id) }), { data: { weapon: id } })\n fire('tool', id)\n }\n const cycleTool = (dir: 1 | -1): void => {\n if (!loadout.length) return\n toolIndex = (toolIndex + dir + loadout.length) % loadout.length\n setTool(loadout[toolIndex])\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Grabbing, carrying, throwing\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let heldEntry: Entry | null = null\n let heldPiece: Piece | null = null\n let heldName = ''\n let heldYaw = 0\n let heldTilt = 0\n let tiltKey = 0\n const heldLocal = new THREE.Vector3()\n const heldVel: Vec3 = [0, 0, 0]\n let useItemPlayer: ItemUsePlayer | null = null\n let useItemName = ''\n\n const releaseHeld = (): void => {\n if (heldPiece) {\n heldPiece.held = false\n heldPiece.sleeping = false\n heldPiece.velocity = [heldVel[0], heldVel[1], heldVel[2]]\n }\n useItemPlayer?.cancel()\n useItemPlayer = null\n heldEntry = null\n heldPiece = null\n heldTilt = 0\n }\n\n const grab = (): boolean => {\n if (heldPiece) {\n const name = heldName\n releaseHeld()\n action('drop', t('act.drop', { name }))\n fire('grab', { held: false })\n return true\n }\n aim()\n const r = rayWorld([aimO[0], aimO[1], aimO[2]], [aimD[0], aimD[1], aimD[2]], 3.2)\n if (!r) {\n say(t('hud.nothing_to_grab'))\n return false\n }\n const piece = rendererPieces.get(r.object)\n if (!piece) {\n say(t('hud.cannot_grab', { name: nameOf(r.object) }))\n return false\n }\n const kg = piece.mass\n if (kg > maxCarry) {\n say(t('hud.too_heavy', { name: nameOf(r.object), kg: num(kg, 0) }))\n return false\n }\n heldPiece = piece\n heldEntry = entries.get(r.object) ?? null\n heldName = nameOf(r.object)\n piece.held = true\n piece.sleeping = false\n // centre of the object's bounding box in its own space, to hold it by its middle\n const box = new THREE.Box3().setFromObject(piece.root)\n const c = box.getCenter(new THREE.Vector3())\n piece.root.updateMatrixWorld(true)\n heldLocal.copy(c).sub(piece.root.position)\n heldLocal.applyQuaternion(piece.root.quaternion.clone().invert())\n heldYaw = 0\n heldTilt = 0\n heldVel[0] = heldVel[1] = heldVel[2] = 0\n action('grab', t('act.grab', { name: heldName, kg: num(kg, 1) }), { objectId: r.object, itemId: entryOf(r.object)?.so.itemId, data: { massKg: Math.round(kg * 10) / 10 } })\n fire('grab', { held: true, objectId: r.object })\n return true\n }\n\n const throwHeld = (speed = 9): boolean => {\n if (!heldPiece) return false\n const piece = heldPiece\n const name = heldName\n const id = piece.objectId\n aim()\n releaseHeld()\n piece.velocity = [0, 0, 0]\n renderer.impulse(id, [aimD[0] * speed * piece.mass, (aimD[1] * speed + 1.2) * piece.mass, aimD[2] * speed * piece.mass])\n action('throw', t('act.throw', { name, speed: num(speed, 1) }), { objectId: id, itemId: entryOf(id)?.so.itemId, data: { speedMs: speed, massKg: piece.mass } })\n fire('throw', { objectId: id, speed })\n return true\n }\n\n const followHeld = (dt: number): void => {\n const piece = heldPiece\n if (!piece) return\n camera.updateMatrixWorld(true)\n const root = piece.root\n let pos: THREE_NS.Vector3\n const targetQ = tmpQ\n if (useItemPlayer) {\n // the hand frame follows the camera's yaw only, so looking down at the item does not tilt it\n const pose = useItemPlayer.pose()\n const handQ = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), player.yaw)\n pos = tmpV.set(pose.position[0], pose.position[1], pose.position[2]).applyQuaternion(handQ).add(camera.position)\n const eq = new THREE.Quaternion().setFromEuler(new THREE.Euler(pose.rotation[0], pose.rotation[1], pose.rotation[2], 'XYZ'))\n targetQ.copy(handQ).multiply(eq)\n targetQ.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), heldYaw))\n } else {\n pos = tmpV.set(0.05, -0.28, -1.15).applyMatrix4(camera.matrixWorld)\n targetQ.setFromAxisAngle(new THREE.Vector3(0, 1, 0), player.yaw + heldYaw)\n targetQ.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), -heldTilt))\n }\n const k = Math.min(1, (useItemPlayer ? 30 : 16) * dt)\n const px = root.position.x\n const py = root.position.y\n const pz = root.position.z\n root.quaternion.slerp(targetQ, Math.min(1, k * 0.9))\n // the middle of the carried object follows the target; the offset uses the current rotation so it does not orbit\n const off2 = tmpV2.copy(heldLocal).applyQuaternion(root.quaternion)\n root.position.set(root.position.x + (pos.x - off2.x - root.position.x) * k, root.position.y + (pos.y - off2.y - root.position.y) * k, root.position.z + (pos.z - off2.z - root.position.z) * k)\n if (dt > 0) {\n heldVel[0] = (root.position.x - px) / dt\n heldVel[1] = (root.position.y - py) / dt\n heldVel[2] = (root.position.z - pz) / dt\n }\n root.updateMatrixWorld(true)\n }\n\n const useItem = (useId: string): boolean => {\n const e = heldEntry\n if (!e?.containerId) return false\n const def = itemUseDefs.find((u) => u.id === useId)\n if (!def) return false\n const c = fluids.container(e.containerId)\n if (!c) return false\n if (def.liquids && def.liquids.length > 0 && (!c.liquid || !def.liquids.includes(c.liquid))) return false\n if ((useId === 'drink' || useId === 'sip' || useId === 'chug' || useId === 'pour' || useId === 'pour_out') && c.liters <= 1e-6) {\n say(t('hud.empty_container', { name: e.name }))\n return false\n }\n if (useItemPlayer && !useItemPlayer.done) return false\n useItemPlayer = createItemUse(fluids, e.containerId, def)\n useItemName = def.id\n action('use_item', t('act.use_item', { name: e.name, use: S.text[`use.${def.id}`] ?? def.id }), { objectId: e.so.objectId, itemId: e.so.itemId, data: { use: def.id } })\n return true\n }\n\n const updateItemUse = (dt: number): void => {\n if (!useItemPlayer) return\n useItemPlayer.update(dt)\n if (useItemPlayer.done) {\n useItemPlayer = null\n useItemName = ''\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Tap\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const TAP_ID = 'room_tap'\n const TAP_RATE = 0.25\n fluids.addTap({ id: TAP_ID, position: arena.tapSpout, liquid: 'water', rate: TAP_RATE, temperature: 16, on: false })\n const isTapOn = (): boolean => fluids.taps().some((x) => x.id === TAP_ID && x.on)\n const toggleTap = (on = !isTapOn()): boolean => {\n fluids.setTap(TAP_ID, on)\n action('tap', t(on ? 'act.tap.on' : 'act.tap.off'))\n return on\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Thrown and falling pieces: damage to what they hit\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const lastImpact = new Map<string, number>()\n /** Landings slower than this (m/s) are not logged (the renderer only treats 3 m/s and up as a hard landing; nothing below 1.5 m/s is ever worth a line). */\n const MIN_LANDING_LOG = 3\n const updateImpacts = (): void => {\n const check = (piece: Piece): void => {\n if (piece.held || piece.sleeping) return\n const v = piece.velocity\n const speed = Math.hypot(v[0], v[1], v[2])\n if (speed < 3.5) return\n if ((lastImpact.get(piece.objectId) ?? -9) > simTime - 0.25) return\n const dir: Vec3 = [v[0] / speed, v[1] / speed, v[2] / speed]\n const c = tmpV.copy(new THREE.Vector3(0, 0, 0))\n void c\n const box = tmpBox.setFromObject(piece.root)\n const centre = box.getCenter(tmpV)\n const size = box.getSize(tmpV2)\n const reach = Math.max(size.x, size.y, size.z) * 0.5\n const origin: Vec3 = [centre.x + dir[0] * (reach + 0.02), centre.y + dir[1] * (reach + 0.02), centre.z + dir[2] * (reach + 0.02)]\n const r = withoutHeld(() => world.raycast(origin, dir, speed * FIXED_DT * 2 + 0.06))\n if (!r || r.object === piece.objectId) return\n const energy = 0.5 * piece.mass * speed * speed\n lastImpact.set(piece.objectId, simTime)\n world.hitPart(r.object, r.part, { type: 'blunt', point: r.point, direction: dir, energy, radius: 0.08, source: 'thrown' })\n if (world.has(piece.objectId)) world.hit(piece.objectId, { type: 'blunt', point: r.point, direction: [-dir[0], -dir[1], -dir[2]], energy: energy * 0.4, radius: 0.08, source: 'thrown' })\n pushPiece(r.object, dir, piece.mass * speed * 0.5, r.point)\n piece.velocity = [-v[0] * 0.25, Math.abs(v[1]) * 0.3 + 0.5, -v[2] * 0.25]\n action('impact', t('act.impact', { name: nameOf(piece.objectId), where: hitWhere(r), energy: num(energy, 0), speed: num(speed, 1) }), {\n objectId: piece.objectId,\n itemId: entryOf(piece.objectId)?.so.itemId,\n data: { energyJ: Math.round(energy), speedMs: Math.round(speed * 10) / 10, target: r.object, targetPart: r.part },\n })\n }\n const land = (piece: Piece): void => {\n const vy = piece.velocity[1]\n const prev = prevVy.get(piece.objectId) ?? 0\n prevVy.set(piece.objectId, vy)\n // the renderer applies the landing damage itself (source 'fall'); here we only describe it in the log\n if (piece.held || prev > -MIN_LANDING_LOG || vy < prev + 2 || !world.has(piece.objectId)) return\n const energy = 0.5 * piece.mass * prev * prev\n action('landing', t('act.landing', { name: nameOf(piece.objectId), speed: num(-prev, 1), energy: num(energy, energy < 100 ? 1 : 0) }), {\n objectId: piece.objectId,\n itemId: entryOf(piece.objectId)?.so.itemId,\n data: { energyJ: Math.round(energy * 10) / 10, speedMs: Math.round(-prev * 10) / 10 },\n })\n }\n for (const e of entries.values()) if (e.piece) { check(e.piece); land(e.piece) }\n for (const p of loose) { check(p); land(p) }\n }\n const prevVy = new Map<string, number>()\n const tmpBox = new THREE.Box3()\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Keys\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const onKey = (code: string, down: boolean, e: KeyboardEvent): void => {\n if (!down) {\n if (code === 'KeyZ') tiltKey = 0\n return\n }\n const digit = /^Digit(\\d)$/.exec(code)\n if (digit && !e.ctrlKey && !e.metaKey) {\n const n = (Number(digit[1]) + 9) % 10\n const page = Math.floor(toolIndex / 10)\n const idx = page * 10 + n\n if (idx < loadout.length) setTool(loadout[idx])\n return\n }\n switch (code) {\n case 'KeyE':\n grab()\n break\n case 'KeyG':\n throwHeld()\n break\n case 'KeyR':\n if (heldPiece) heldYaw += Math.PI / 8\n else {\n tool.reload()\n say(t('hud.reloading'))\n }\n break\n case 'KeyQ':\n tool.cycleMode()\n break\n case 'KeyZ':\n tiltKey = 1\n break\n case 'KeyF':\n if (heldEntry?.uses[0]) useItem(heldEntry.uses[0])\n break\n case 'KeyC':\n if (heldEntry?.uses[1]) useItem(heldEntry.uses[1])\n break\n case 'KeyV':\n if (heldEntry?.uses[2]) useItem(heldEntry.uses[2])\n else kick()\n break\n case 'KeyT':\n toggleTap()\n break\n case 'KeyH': {\n const w = (heldEntry ?? entryOf(inspectTarget()?.object ?? ''))?.item?.weapon\n if (w) equip(w)\n break\n }\n case 'BracketRight':\n toolIndex = Math.min(loadout.length - 1, (Math.floor(toolIndex / 10) + 1) * 10)\n setTool(loadout[toolIndex])\n break\n case 'BracketLeft':\n toolIndex = Math.max(0, (Math.floor(toolIndex / 10) - 1) * 10)\n setTool(loadout[toolIndex])\n break\n case 'Tab':\n ui?.togglePanels()\n break\n default:\n break\n }\n }\n\n const equip = (weaponId: string): void => {\n if (!arsenal.weapons.has(weaponId)) return\n if (!loadout.includes(weaponId)) loadout.push(weaponId)\n setTool(weaponId)\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Inspector\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const inspectTarget = (): RayHit | null => {\n aim()\n return rayWorld(aimO, aimD, 14)\n }\n\n const inspectInfo = (): InspectInfo | null => {\n const r = inspectTarget()\n if (!r) return null\n const st = world.state(r.object)\n const p = world.part(r.object, r.part)\n if (!st || !p) return null\n const e = entryOf(r.object)\n const joints = st.joints\n .filter((j) => j.a === r.part || j.b === r.part)\n .map((j) => ({\n id: j.id,\n kind: dStrings.jointKinds[j.kind] ?? j.kind,\n tools: JOINT_DEFAULTS[j.kind].tools.map((k) => dStrings.toolKinds[k] ?? k),\n open: j.open,\n progress: j.progress,\n }))\n const ext = p as unknown as { load?: number; stress?: number }\n return {\n object: nameOf(r.object),\n objectId: r.object,\n part: r.part,\n material: S.text[`material.${p.material}`] ?? dStrings.materialNames[p.material] ?? p.material,\n status: dStrings.partStatus[p.status] ?? p.status,\n hp: p.hp,\n maxHp: p.maxHp,\n temperature: p.temperature,\n burning: p.burning,\n char: p.char,\n melt: p.melt,\n liters: p.liters,\n dents: p.dents.length,\n holes: p.holes.length,\n cracks: p.cracks.length,\n mass: p.mass,\n load: ext.load,\n stress: ext.stress,\n joints,\n note: e?.item?.note,\n distance: r.distance,\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Frame\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let timeScale = 1\n let fastForward = false\n let hudAcc = 1\n let qualityName: 'low' | 'medium' | 'high' = quality\n\n const syncContainers = (sdt: number): void => {\n for (const e of entries.values()) {\n if (!e.containerId) continue\n const host = hostOf(e)\n host.root.updateMatrixWorld(true)\n const q = host.root.getWorldQuaternion(tmpQ)\n const p = tmpV.set(e.fluidOffset[0], e.fluidOffset[1], e.fluidOffset[2]).applyMatrix4(host.root.matrixWorld)\n const vel: Vec3 | undefined = sdt > 0 ? [(p.x - e.last[0]) / sdt, (p.y - e.last[1]) / sdt, (p.z - e.last[2]) / sdt] : undefined\n e.last = [p.x, p.y, p.z]\n fluids.setTransform(e.containerId, [p.x, p.y, p.z], [q.x, q.y, q.z, q.w], vel)\n }\n }\n\n const syncLiters = (): void => {\n for (const e of entries.values()) {\n if (!e.containerId || !e.fluidPart) continue\n const c = fluids.container(e.containerId)\n if (!c) continue\n const host = hostOf(e)\n const part = world.part(host.objectId, e.fluidPart)\n if (part && part.liters !== undefined && Math.abs(part.liters - c.liters) > 1e-4) world.setLiters(host.objectId, e.fluidPart, c.liters)\n }\n }\n\n let paused = false\n let walkPlan: { x: number; z: number; remaining: number } | null = null\n const stepWalk = (dt: number): void => {\n if (!walkPlan) return\n const f = walkPlan.remaining <= dt ? 1 : dt / walkPlan.remaining\n player.moveBy((walkPlan.x - camera.position.x) * f, (walkPlan.z - camera.position.z) * f)\n walkPlan.remaining -= dt\n if (walkPlan.remaining <= 1e-9) walkPlan = null\n }\n\n const stepSim = (dt: number): void => {\n if (paused) return\n // `dt` is simulated seconds; real time only drives input\n simTime += dt\n stepWalk(dt)\n const reps = fastForward ? 10 : 1\n updateAnimations(dt)\n updateItemUse(dt)\n updateProjectiles(dt)\n syncContainers(dt)\n for (let i = 0; i < reps; i++) {\n world.update(dt)\n if (i === 0) updateFires(dt)\n fluids.update(dt)\n }\n syncLiters()\n renderer.update(dt)\n updateImpacts()\n fluidView.update(dt)\n for (const s of tools.values()) s.update(dt)\n for (const tr of tracers) {\n if (tr.life > 0) {\n tr.life -= dt\n if (tr.life <= 0) tr.line.visible = false\n }\n }\n flush()\n }\n\n const update = (dt: number): void => {\n player.update(dt)\n if (tiltKey || heldTilt > 0) {\n heldTilt = Math.max(0, Math.min(2.4, heldTilt + (tiltKey ? 2.2 : -3) * dt))\n }\n if (useHeld && !paused) {\n if (tool.def.category === 'hand') {\n if (useFirst) grab()\n } else useTool(dt, !useFirst)\n useFirst = false\n }\n if (!paused) followHeld(dt)\n stepSim(dt * timeScale)\n if (progress && simTime - progress.at > 0.25) progress = null\n hudAcc += dt\n if (hudAcc >= 0.1 && ui) {\n hudAcc = 0\n ui.hud(hudState())\n }\n }\n\n const hudState = (): HudState => {\n const page = Math.floor(toolIndex / 10)\n const slots = loadout.slice(page * 10, page * 10 + 10).map((id) => arsenal.name(id))\n const ammo = tool.def.action.kind === 'firearm' ? `${tool.ammo}/${tool.capacity}${tool.reserve ? ` · ${tool.reserve}` : ''}` : tool.def.action.kind === 'hand' ? '' : tool.def.action.kind === 'melee' || tool.def.action.kind === 'tool' ? '' : `${num(tool.ammo, 0)}`\n return {\n toolName: toolName(),\n toolId,\n ammo,\n slots,\n slot: toolIndex - page * 10,\n page: page + 1,\n pages: Math.max(1, Math.ceil(loadout.length / 10)),\n status: simTime - statusAt < 2 ? statusLine : '',\n progress: progress ? { label: progress.label, value: progress.value } : null,\n held: heldEntry || heldPiece ? { name: heldName, uses: (heldEntry?.uses ?? []).map((u, i) => ({ key: ['F', 'C', 'V'][i] ?? '', label: S.text[`use.${u}`] ?? u })), weapon: heldEntry?.item?.weapon ? arsenal.name(heldEntry.item.weapon) : undefined, using: useItemName } : null,\n inspect: inspectInfo(),\n animations: animationsOf(),\n locked: player.locked,\n timeScale,\n fast: fastForward,\n tap: isTapOn(),\n quality: qualityName,\n objects: [...entries.values()].filter((e) => !e.arena).length,\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Item animations (clips of AnimationClipSpec)\n // ---------------------------------------------------------------------------------------------------------------------------------------\n interface Playing {\n entry: Entry\n clip: AnimationClipSpec\n t: number\n fired: number\n targets: Map<string, THREE_NS.Object3D>\n }\n const playing: Playing[] = []\n const restPose = new WeakMap<THREE_NS.Object3D, { p: Vec3; r: Vec3 }>()\n const ZERO: Vec3 = [0, 0, 0]\n const animTarget = (): Entry | undefined => {\n if (heldEntry) return heldEntry\n const r = inspectTarget()\n return r ? entryOf(r.object) : undefined\n }\n const poseAt = (clip: AnimationClipSpec, id: string | null, time: number): { position: Vec3; rotation: Vec3 } => {\n const pick = (k: AnimationClipSpec['keys'][number]): { position?: Vec3; rotation?: Vec3 } | undefined => (id === null ? k : k.parts?.[id])\n const pts = clip.keys.map((k) => ({ t: k.t, position: pick(k)?.position ?? ZERO, rotation: pick(k)?.rotation ?? ZERO }))\n if (pts.length === 0 || pts[0].t > 0) pts.unshift({ t: 0, position: ZERO, rotation: ZERO })\n let a = pts[0]\n let b = pts[pts.length - 1]\n if (time >= b.t) a = b\n else for (let i = 0; i < pts.length - 1; i++) if (time >= pts[i].t && time < pts[i + 1].t) [a, b] = [pts[i], pts[i + 1]]\n const f = a === b || b.t <= a.t ? 0 : (time - a.t) / (b.t - a.t)\n const mix = (x: Vec3, y: Vec3): Vec3 => [x[0] + (y[0] - x[0]) * f, x[1] + (y[1] - x[1]) * f, x[2] + (y[2] - x[2]) * f]\n return { position: mix(a.position, b.position), rotation: mix(a.rotation, b.rotation) }\n }\n const applyClip = (pl: Playing): void => {\n for (const [id, obj] of pl.targets) {\n const rest = restPose.get(obj)\n if (!rest) continue\n const pose = poseAt(pl.clip, id === '' ? null : id, pl.t)\n obj.position.set(rest.p[0] + pose.position[0], rest.p[1] + pose.position[1], rest.p[2] + pose.position[2])\n obj.rotation.set(rest.r[0] + pose.rotation[0], rest.r[1] + pose.rotation[1], rest.r[2] + pose.rotation[2])\n // animations are visual only: move the part's collision/raycast shape to the same pose (spec rest + clip offset)\n const ps = id === '' ? undefined : specs.get(pl.entry.so.objectId)?.parts.find((p) => p.id === id)\n if (ps) {\n const r0 = ps.rotation ?? ZERO\n world.setPartPose(\n pl.entry.so.objectId, id,\n [ps.position[0] + pose.position[0], ps.position[1] + pose.position[1], ps.position[2] + pose.position[2]],\n [r0[0] + pose.rotation[0], r0[1] + pose.rotation[1], r0[2] + pose.rotation[2]],\n )\n }\n }\n }\n const updateAnimations = (dt: number): void => {\n for (let i = playing.length - 1; i >= 0; i--) {\n const pl = playing[i]\n pl.t = Math.min(pl.clip.duration, pl.t + dt)\n applyClip(pl)\n const evs = pl.clip.events ?? []\n while (pl.fired < evs.length && evs[pl.fired].t <= pl.t) {\n const ev = evs[pl.fired++]\n action('animation_event', t('act.anim_event', { name: pl.entry.name, clip: pl.clip.id, type: ev.type }), { objectId: pl.entry.so.objectId, itemId: pl.entry.so.itemId, data: { clip: pl.clip.id, type: ev.type, at: ev.t, ...(ev.data ?? {}) } })\n const key = ev.type === 'sound' ? ev.data?.key : undefined\n if (typeof key === 'string') options.onSound?.(key, v3(pl.entry.so.root.getWorldPosition(tmpV)), 1)\n }\n if (pl.t >= pl.clip.duration) {\n playing.splice(i, 1)\n action('animation_end', t('act.anim_end', { name: pl.entry.name, clip: pl.clip.id }), { objectId: pl.entry.so.objectId, itemId: pl.entry.so.itemId, data: { clip: pl.clip.id } })\n }\n }\n }\n const animationsOf = (): AnimationInfo | null => {\n const e = animTarget()\n if (!e || e.arena) return null\n const clips = (e.item?.animations ?? []).map((c) => ({ id: c.id, duration: c.duration }))\n return { objectId: e.so.objectId, itemId: e.so.itemId, name: e.name, clips, playing: playing.find((p) => p.entry === e)?.clip.id ?? null }\n }\n const playAnimation = (clipId: string, objectId?: string): boolean => {\n const e = objectId ? entries.get(objectId) : animTarget()\n const clip = e?.item?.animations?.find((c) => c.id === clipId)\n if (!e || !clip) return false\n for (let i = playing.length - 1; i >= 0; i--) if (playing[i].entry === e && playing[i].clip.id === clipId) playing.splice(i, 1)\n const targets = new Map<string, THREE_NS.Object3D>()\n const ids = new Set<string>()\n for (const k of clip.keys) for (const id of Object.keys(k.parts ?? {})) ids.add(id)\n const grab = (key: string, obj: THREE_NS.Object3D | undefined): void => {\n if (!obj) return\n if (!restPose.has(obj)) restPose.set(obj, { p: [obj.position.x, obj.position.y, obj.position.z], r: [obj.rotation.x, obj.rotation.y, obj.rotation.z] })\n targets.set(key, obj)\n }\n if (clip.keys.some((k) => k.position || k.rotation)) grab('', e.so.root)\n for (const id of ids) grab(id, e.so.root.getObjectByName(id) ?? undefined)\n const pl: Playing = { entry: e, clip, t: 0, fired: 0, targets }\n playing.push(pl)\n applyClip(pl)\n action('animation', t('act.anim_start', { name: e.name, clip: clip.id, seconds: num(clip.duration, 1) }), { objectId: e.so.objectId, itemId: e.so.itemId, data: { clip: clip.id, duration: clip.duration } })\n return true\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Scenarios and modules\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const extraScenarios: TestRoomScenario[] = [...(options.scenarios ?? [])]\n const moduleCheck = (ok: boolean, text: string, data: Record<string, unknown>, itemId?: string): void => {\n log.add({ channel: 'check', type: ok ? 'pass' : 'fail', text: `${ok ? '✓' : '✗'} ${text}`, itemId, data: { ok, ...data } })\n }\n const loadModule = (mod: TestableModule<ScenarioContext>): ModuleReport => {\n const report: ModuleReport = { module: mod.id, items: [], scenarios: [], ok: true, problems: [] }\n const fail = (problem: string): void => {\n report.ok = false\n report.problems.push(problem)\n }\n const added = mod.items(locale)\n for (const ti of added) {\n const item: TestRoomItem = {\n id: ti.id,\n name: ti.name,\n group: mod.group,\n build: (T) => ti.build(T) as THREE_NS.Object3D,\n spec: ti.spec as TestRoomItem['spec'],\n movable: ti.movable,\n fluid: ti.fluid,\n weapon: ti.weapon,\n impl: ti.impl as TestRoomItem['impl'],\n animations: ti.animations,\n }\n catalogMap.set(item.id, item)\n const at = catalog.findIndex((c) => c.id === item.id)\n if (at >= 0) catalog[at] = item\n else catalog.push(item)\n report.items.push(item.id)\n // contract checks on a throwaway build of the item (never added to the scene)\n let partIds: string[] = []\n const base = { module: mod.id, item: item.id }\n try {\n const root = item.build(THREE)\n root.updateMatrixWorld(true)\n if (item.impl) {\n const probe = item.impl(root, `${item.id}_check`)\n const r = checkDestructible(probe, { materials: world.materials.keys() })\n partIds = probe.describe().parts.map((p) => p.id)\n moduleCheck(r.ok, r.ok ? t('mod.destructible_ok', { name: item.name, parts: partIds.length }) : t('mod.destructible_fail', { name: item.name, problems: r.problems.join('; ') }), { ...base, check: 'destructible', problems: r.problems }, item.id)\n for (const p of r.problems) fail(`${item.id}: ${p}`)\n }\n if (!item.impl || item.spec) {\n // the spec is resolved after the build (it may be a function of the root, or derived from the meshes)\n const spec = resolveSpec(item, root).spec\n if (!item.impl) partIds = spec.parts.map((p) => p.id)\n const r = checkSpec(spec, { materials: world.materials.keys() })\n moduleCheck(r.ok, r.ok ? t('mod.spec_ok', { name: item.name, parts: spec.parts.length }) : t('mod.spec_fail', { name: item.name, problems: r.problems.join('; ') }), { ...base, check: 'spec', problems: r.problems, warnings: r.warnings }, item.id)\n for (const p of r.problems) fail(`${item.id}: ${p}`)\n for (const w of r.warnings) log.add({ channel: 'check', type: 'warn', text: `⚠ ${t('mod.spec_warn', { name: item.name, warning: w })}`, itemId: item.id, data: { ok: true, ...base, check: 'spec', warning: w } })\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n moduleCheck(false, t('mod.destructible_fail', { name: item.name, problems: msg }), { ...base, check: 'destructible', problems: [msg] }, item.id)\n fail(`${item.id}: ${msg}`)\n }\n for (const clip of item.animations ?? []) {\n const r = checkAnimation(clip, partIds)\n moduleCheck(r.ok, r.ok ? t('mod.animation_ok', { name: item.name, clip: clip.id, seconds: num(clip.duration, 1) }) : t('mod.animation_fail', { name: item.name, clip: clip.id, problems: r.problems.join('; ') }), { ...base, check: 'animation', clip: clip.id, problems: r.problems }, item.id)\n for (const p of r.problems) fail(`${item.id}: ${p}`)\n }\n }\n for (const ms of mod.scenarios?.(locale) ?? []) {\n const sc: TestRoomScenario = { id: ms.id, name: ms.name, run: ms.run }\n const at = extraScenarios.findIndex((x) => x.id === sc.id)\n if (at >= 0) extraScenarios[at] = sc\n else extraScenarios.push(sc)\n report.scenarios.push(sc.id)\n }\n action('module', t('act.module_loaded', { name: mod.name, items: report.items.length, scenarios: report.scenarios.length, result: t(report.ok ? 'mod.all_ok' : 'mod.some_failed') }), { data: { module: mod.id, items: report.items, scenarios: report.scenarios, ok: report.ok } })\n ui?.refresh()\n return report\n }\n\n const allScenarios = (): TestRoomScenario[] => [...makeScenarios(t, num, locale), ...extraScenarios]\n let scenarioRunning = false\n\n const step = (seconds: number): void => {\n const dt = seconds > 6 ? 1 / 30 : FIXED_DT\n const n = Math.max(1, Math.round(seconds / dt))\n for (let i = 0; i < n; i++) {\n player.update(0)\n followHeld(dt)\n stepSim(dt)\n }\n }\n\n const runScenarios = async (list?: TestRoomScenario[]): Promise<ScenarioReport> => {\n const all = list ?? allScenarios()\n const report: ScenarioReport = { passed: 0, failed: 0, results: [] }\n scenarioRunning = true\n const wasPaused = paused\n paused = false\n try {\n for (const sc of all) {\n hardReset()\n player.look(arena.playerStart, [0, 1.5, arena.wallZ])\n useHeld = false\n const checks: Array<{ label: string; ok: boolean }> = []\n log.add({ channel: 'check', type: 'scenario', text: t('sc.start', { name: sc.name }), data: { id: sc.id } })\n const ctx: ScenarioContext = {\n room,\n step,\n expect(condition, label, data) {\n checks.push({ label, ok: !!condition })\n log.add({ channel: 'check', type: condition ? 'pass' : 'fail', text: `${condition ? '✓' : '✗'} ${label}`, data: { scenario: sc.id, ok: !!condition, ...(data ?? {}) } })\n },\n }\n try {\n await sc.run(ctx)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n ctx.expect(false, t('sc.error', { msg }))\n }\n flush()\n const ok = checks.length > 0 && checks.every((c) => c.ok)\n report.results.push({ id: sc.id, name: sc.name, ok, checks })\n if (ok) report.passed++\n else report.failed++\n log.add({ channel: 'check', type: ok ? 'scenario_pass' : 'scenario_fail', text: t(ok ? 'sc.pass' : 'sc.fail', { name: sc.name }), data: { id: sc.id, ok } })\n await new Promise<void>((res) => setTimeout(res, 0))\n }\n } finally {\n scenarioRunning = false\n paused = wasPaused\n }\n return report\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // The room object\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const room: TestRoom & {\n tilt(rad: number): void\n toggleTap(on?: boolean): boolean\n setSlowMotion(on: boolean): void\n setFastForward(on: boolean): void\n equip(weaponId: string): void\n readonly scenarios: TestRoomScenario[]\n readonly fluidRenderer: FluidRenderer\n inspectInfo(): InspectInfo | null\n } = {\n world,\n renderer,\n scene,\n camera,\n arsenal,\n fluids,\n fluidRenderer: fluidView,\n log,\n get tool() {\n return tool\n },\n get scenarios() {\n return allScenarios()\n },\n spawn,\n clear,\n resetAll,\n setTool,\n useItem,\n use(hold = 0) {\n if (tool.def.category === 'hand') {\n grab()\n return\n }\n useTool(FIXED_DT, false)\n flush()\n let t0 = 0\n while (t0 < hold) {\n useTool(FIXED_DT, true)\n stepSim(FIXED_DT)\n t0 += FIXED_DT\n }\n tool.release()\n },\n grab,\n throwHeld,\n look(position, target) {\n player.look(position, target)\n },\n inspect() {\n const r = inspectTarget()\n if (!r) return null\n return { objectId: r.object, partId: r.part, itemId: entryOf(r.object)?.so.itemId ?? '' }\n },\n inspectInfo,\n spawned() {\n return [...entries.values()].filter((e) => !e.arena).map((e) => e.so)\n },\n update,\n on(type, fn) {\n listeners[type].add(fn)\n return () => listeners[type].delete(fn)\n },\n runScenarios,\n tilt(rad) {\n heldTilt = rad\n },\n toggleTap,\n pause() {\n paused = true\n },\n resume() {\n paused = false\n },\n get paused() {\n return paused\n },\n walk(to, seconds) {\n walkPlan = seconds > 0 ? { x: to[0], z: to[2], remaining: seconds } : null\n if (!walkPlan) player.moveBy(to[0] - camera.position.x, to[2] - camera.position.z)\n },\n setSlowMotion(on) {\n timeScale = on ? 0.25 : 1\n },\n setFastForward(on) {\n fastForward = on\n },\n equip,\n loadModule,\n animations: animationsOf,\n playAnimation,\n dispose() {\n cancelAnimationFrame?.(raf)\n window.removeEventListener('resize', onResize)\n player.dispose()\n ui?.dispose()\n renderer.dispose()\n fluidView.dispose()\n for (const tr of tracers) tr.line.removeFromParent()\n clearProjectileMeshes()\n if (ownRenderer) {\n gl.dispose()\n dom.remove()\n }\n },\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // UI and loop\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let ui: RoomUi | null = null\n if (options.ui !== false) {\n const groups = (): Map<string, TestRoomItem[]> => {\n const m = new Map<string, TestRoomItem[]>()\n for (const i of catalog) {\n const g = m.get(i.group) ?? []\n g.push(i)\n m.set(i.group, g)\n }\n return m\n }\n ui = createUi({\n container,\n strings: S,\n t,\n log,\n groups,\n loadout: () => loadout.map((id) => ({ id, name: arsenal.name(id) })),\n onSpawn: (id) => {\n spawn(id)\n },\n onEquip: (itemId) => {\n const w = catalogMap.get(itemId)?.weapon\n if (w) equip(w)\n },\n onClear: clear,\n onResetAll: resetAll,\n onSlow: (on) => room.setSlowMotion(on),\n onFast: (on) => room.setFastForward(on),\n onQuality: (q) => {\n qualityName = q\n if (ownRenderer) {\n gl.shadowMap.enabled = q !== 'low'\n gl.setPixelRatio(q === 'low' ? 1 : Math.min(typeof devicePixelRatio === 'number' ? devicePixelRatio : 1, 2))\n arena.sun.shadow.mapSize.set(q === 'high' ? 2048 : 1024, q === 'high' ? 2048 : 1024)\n arena.sun.shadow.map?.dispose()\n arena.sun.shadow.map = null\n resize()\n }\n },\n quality: qualityName,\n scenarios: allScenarios,\n onRun: async (sc) => {\n await runScenarios([sc])\n },\n onRunAll: async () => {\n await runScenarios()\n },\n onTool: (index) => {\n toolIndex = index\n setTool(loadout[index])\n },\n onTap: () => toggleTap(),\n onPlay: (objectId, clipId) => {\n playAnimation(clipId, objectId)\n },\n onResize: resize,\n })\n ui.hud(hudState())\n }\n\n let raf = 0\n if (ownRenderer && typeof requestAnimationFrame === 'function') {\n let last = performance.now()\n const loop = (now: number): void => {\n raf = requestAnimationFrame(loop)\n const dt = Math.min(0.05, (now - last) / 1000)\n last = now\n if (!scenarioRunning) update(dt)\n gl.render(scene, camera)\n }\n raf = requestAnimationFrame(loop)\n }\n\n if (options.initial) {\n for (const [i, id] of options.initial.entries()) spawn(id, [(i - (options.initial.length - 1) / 2) * 1.3, 0, 0.5])\n }\n\n return room\n}\n\nfunction structuredCloneSpec(spec: DestructibleSpec): DestructibleSpec {\n return JSON.parse(JSON.stringify(spec)) as DestructibleSpec\n}\n","import type * as THREE_NS from 'three'\nimport { buildFrame } from '@adatechnology/game-destruction'\nimport type { DestructibleSpec, JointSpec, MaterialDef, PartSpec, Vec3 } from '@adatechnology/game-destruction'\nimport { buildFromSpec } from './build-from-spec'\nimport { resolveStrings } from './locale'\nimport type { TestRoomItem } from './types'\n\n/**\n * Extra materials the demo items need on top of the core ones. None any more (the bottle uses the core `glass`, which now breaks from a drop);\n * kept so that code passing it to `worldOptions.materials` keeps working.\n */\nexport const DEMO_MATERIALS: MaterialDef[] = []\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Small spec helpers\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\n\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst cyl = (id: string, material: string, radius: number, height: number, position: Vec3, extra: Extra = {}): PartSpec => ({\n id,\n material,\n shape: { kind: 'cylinder', radius, height },\n position,\n ...extra,\n})\nconst sph = (id: string, material: string, radius: number, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'sphere', radius }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind'], extra: Partial<JointSpec> = {}): JointSpec => ({ a, b, kind, ...extra })\n\n/** Spec of the brick target wall: `cols` x `rows` brick panels, the bottom row anchored, mortar joints between neighbours. */\nexport function brickWallSpec(cols = 8, rows = 6, panel: Vec3 = [1.25, 0.5, 0.2]): DestructibleSpec {\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n const id = (c: number, r: number): string => `brick_${r}_${c}`\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n parts.push(box(id(c, r), 'brick', panel, [(c - (cols - 1) / 2) * panel[0], panel[1] / 2 + r * panel[1], 0], { anchored: r === 0 }))\n if (c > 0) joints.push(joint(id(c - 1, r), id(c, r), 'mortar'))\n if (r > 0) joints.push(joint(id(c, r - 1), id(c, r), 'mortar'))\n }\n }\n return { name: 'brick wall', parts, joints, tags: ['structure'] }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Demo specs\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\nconst chair = (): DestructibleSpec => {\n const legs = [\n [-0.18, -0.18],\n [0.18, -0.18],\n [-0.18, 0.18],\n [0.18, 0.18],\n ]\n return {\n name: 'chair',\n parts: [\n box('seat', 'wood_soft', [0.42, 0.04, 0.42], [0, 0.45, 0]),\n ...legs.map(([x, z], i) => box(`leg_${i + 1}`, 'wood_soft', [0.04, 0.43, 0.04], [x, 0.215, z])),\n box('backrest', 'wood_soft', [0.4, 0.3, 0.03], [0, 0.64, -0.195]),\n ],\n joints: [...legs.map((_, i) => joint(`leg_${i + 1}`, 'seat', 'screw')), joint('backrest', 'seat', 'screw')],\n tags: ['furniture'],\n }\n}\n\nconst crate = (): DestructibleSpec => ({\n name: 'wooden crate',\n parts: [\n box('front', 'wood_soft', [0.5, 0.5, 0.02], [0, 0.25, 0.24], { hp: 70 }),\n box('back', 'wood_soft', [0.5, 0.5, 0.02], [0, 0.25, -0.24], { hp: 70 }),\n box('left', 'wood_soft', [0.02, 0.5, 0.46], [-0.24, 0.25, 0], { hp: 70 }),\n box('right', 'wood_soft', [0.02, 0.5, 0.46], [0.24, 0.25, 0], { hp: 70 }),\n box('bottom', 'wood_soft', [0.46, 0.02, 0.46], [0, 0.01, 0], { hp: 70 }),\n ],\n joints: [\n joint('front', 'left', 'nail'),\n joint('front', 'right', 'nail'),\n joint('back', 'left', 'nail'),\n joint('back', 'right', 'nail'),\n joint('front', 'bottom', 'nail'),\n joint('back', 'bottom', 'nail'),\n joint('left', 'bottom', 'nail'),\n joint('right', 'bottom', 'nail'),\n ],\n tags: ['container'],\n})\n\nconst drum = (): DestructibleSpec => ({\n name: 'steel drum',\n parts: [\n cyl('drum_body', 'steel', 0.29, 0.86, [0, 0.45, 0], { mass: 12, thickness: 0.0012 }),\n cyl('drum_top', 'steel', 0.29, 0.02, [0, 0.89, 0], { mass: 1.5, thickness: 0.0012 }),\n cyl('drum_bottom', 'steel', 0.29, 0.02, [0, 0.01, 0], { mass: 1.5, thickness: 0.0012 }),\n ],\n joints: [joint('drum_body', 'drum_top', 'weld'), joint('drum_body', 'drum_bottom', 'weld')],\n tags: ['container'],\n})\n\nconst steelSheet = (): DestructibleSpec => ({\n name: 'steel sheet',\n parts: [\n box('sheet', 'steel', [1, 1, 0.003], [0, 1.1, 0]),\n box('post_l', 'steel', [0.04, 0.54, 0.04], [-0.35, 0.33, 0], { mass: 4 }),\n box('post_r', 'steel', [0.04, 0.54, 0.04], [0.35, 0.33, 0], { mass: 4 }),\n box('foot_l', 'steel', [0.06, 0.06, 0.5], [-0.35, 0.03, 0], { mass: 6 }),\n box('foot_r', 'steel', [0.06, 0.06, 0.5], [0.35, 0.03, 0], { mass: 6 }),\n ],\n joints: [joint('sheet', 'post_l', 'weld'), joint('sheet', 'post_r', 'weld'), joint('post_l', 'foot_l', 'weld'), joint('post_r', 'foot_r', 'weld')],\n tags: ['structure'],\n})\n\nconst glassPane = (): DestructibleSpec => ({\n name: 'glass pane',\n parts: [\n box('pane', 'glass', [0.8, 1, 0.006], [0, 1.05, 0], { hp: 40 }),\n box('frame_top', 'aluminium', [0.88, 0.04, 0.04], [0, 1.57, 0], { mass: 1 }),\n box('frame_bottom', 'aluminium', [0.88, 0.04, 0.04], [0, 0.53, 0], { mass: 1 }),\n box('frame_l', 'aluminium', [0.04, 1.04, 0.04], [-0.42, 1.05, 0], { mass: 1 }),\n box('frame_r', 'aluminium', [0.04, 1.04, 0.04], [0.42, 1.05, 0], { mass: 1 }),\n box('foot_l', 'steel', [0.06, 0.5, 0.4], [-0.35, 0.25, 0], { mass: 5 }),\n box('foot_r', 'steel', [0.06, 0.5, 0.4], [0.35, 0.25, 0], { mass: 5 }),\n ],\n joints: [\n joint('pane', 'frame_top', 'clip'),\n joint('pane', 'frame_bottom', 'clip'),\n joint('pane', 'frame_l', 'clip'),\n joint('pane', 'frame_r', 'clip'),\n joint('frame_bottom', 'foot_l', 'bolt'),\n joint('frame_bottom', 'foot_r', 'bolt'),\n joint('frame_l', 'frame_top', 'weld'),\n joint('frame_r', 'frame_top', 'weld'),\n joint('frame_l', 'frame_bottom', 'weld'),\n joint('frame_r', 'frame_bottom', 'weld'),\n ],\n tags: ['structure'],\n})\n\nconst concreteBlock = (): DestructibleSpec => ({\n name: 'concrete block',\n parts: [box('block', 'concrete', [0.4, 0.4, 0.4], [0, 0.2, 0])],\n tags: ['structure'],\n})\n\nconst brickColumn = (): DestructibleSpec => {\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n const layers = 8\n const id = (l: number, x: number, z: number): string => `brick_${l}_${x}${z}`\n for (let l = 0; l < layers; l++) {\n for (let x = 0; x < 2; x++) {\n for (let z = 0; z < 2; z++) {\n parts.push(box(id(l, x, z), 'brick', [0.2, 0.2, 0.2], [(x - 0.5) * 0.2, 0.1 + l * 0.2, (z - 0.5) * 0.2], { anchored: l === 0 }))\n if (x > 0) joints.push(joint(id(l, x - 1, z), id(l, x, z), 'mortar'))\n if (z > 0) joints.push(joint(id(l, x, z - 1), id(l, x, z), 'mortar'))\n if (l > 0) joints.push(joint(id(l - 1, x, z), id(l, x, z), 'mortar'))\n }\n }\n }\n return { name: 'brick column', parts, joints, tags: ['structure'] }\n}\n\n/**\n * A small house frame (2 x 2 columns on foundations, beams, a roof slab) from the core's `buildFrame`. The columns are rated at 4.4 t so that\n * losing one column leaves the roof standing (the others carry about 90% of their capacity) and losing two overloads the rest until the roof\n * comes down.\n */\nconst frame = (): DestructibleSpec => ({ ...buildFrame({ spanX: 4, spanZ: 4, columnsX: 2, columnsZ: 2, height: 2.8, floors: 1, walls: false, roof: true, columnCapacity: 4400 }), name: 'building frame' })\n\nconst bucket = (): DestructibleSpec => ({\n name: 'plastic bucket',\n parts: [\n cyl('bucket_body', 'plastic', 0.14, 0.28, [0, 0.14, 0], { mass: 0.5, thickness: 0.002 }),\n box('handle', 'plastic', [0.3, 0.012, 0.012], [0, 0.3, 0], { mass: 0.05 }),\n ],\n joints: [joint('handle', 'bucket_body', 'clip')],\n tags: ['container'],\n})\n\nconst bottle = (): DestructibleSpec => ({\n name: 'glass bottle',\n parts: [\n cyl('bottle_body', 'glass', 0.037, 0.17, [0, 0.085, 0], { mass: 0.3, thickness: 0.003, contains: { fluid: 'water', liters: 0.5 } }),\n cyl('bottle_neck', 'glass', 0.015, 0.09, [0, 0.215, 0], { mass: 0.08, thickness: 0.002 }),\n ],\n joints: [joint('bottle_neck', 'bottle_body', 'fused')],\n tags: ['item'],\n})\n\nconst cup = (): DestructibleSpec => ({\n name: 'coffee cup',\n parts: [\n cyl('cup', 'ceramic', 0.05, 0.11, [0, 0.055, 0], { mass: 0.3, thickness: 0.004, contains: { fluid: 'coffee', liters: 0.25 } }),\n box('cup_handle', 'ceramic', [0.02, 0.06, 0.014], [0.068, 0.06, 0], { mass: 0.04 }),\n ],\n joints: [joint('cup_handle', 'cup', 'fused')],\n tags: ['item'],\n})\n\nconst jerrycan = (): DestructibleSpec => ({\n name: 'jerrycan',\n parts: [\n box('tank', 'plastic', [0.34, 0.45, 0.14], [0, 0.225, 0], { mass: 1.2, thickness: 0.003, contains: { fluid: 'fuel', liters: 20 } }),\n cyl('cap', 'plastic', 0.025, 0.03, [0.08, 0.465, 0], { mass: 0.05 }),\n box('handle', 'plastic', [0.1, 0.03, 0.03], [-0.07, 0.465, 0], { mass: 0.1 }),\n ],\n joints: [joint('cap', 'tank', 'screw'), joint('handle', 'tank', 'fused')],\n tags: ['container'],\n})\n\nconst gasBottle = (): DestructibleSpec => ({\n name: 'gas bottle',\n parts: [\n cyl('cylinder', 'steel', 0.15, 0.7, [0, 0.4, 0], {\n mass: 11,\n thickness: 0.003,\n contains: { fluid: 'gas', liters: 13, pressurized: true },\n explodes: { energy: 120000, radius: 5, atC: 300 },\n }),\n cyl('valve', 'steel', 0.03, 0.1, [0, 0.8, 0], { mass: 0.5 }),\n cyl('foot_ring', 'steel', 0.14, 0.05, [0, 0.025, 0], { mass: 1 }),\n ],\n joints: [joint('valve', 'cylinder', 'weld'), joint('foot_ring', 'cylinder', 'weld')],\n tags: ['container'],\n})\n\nconst tree = (): DestructibleSpec => ({\n name: 'small tree',\n parts: [\n cyl('trunk', 'green_wood', 0.08, 2.2, [0, 1.1, 0], { anchored: true }),\n cyl('branch_1', 'green_wood', 0.03, 0.8, [0.34, 1.7, 0], { rotation: [0, 0, -0.9] }),\n cyl('branch_2', 'green_wood', 0.03, 0.8, [-0.3, 1.9, 0.12], { rotation: [0, 0, 0.8] }),\n cyl('branch_3', 'green_wood', 0.025, 0.7, [0.05, 2.0, -0.28], { rotation: [0.8, 0, 0] }),\n sph('crown_top', 'foliage', 0.55, [0, 2.55, 0], { mass: 2 }),\n sph('crown_1', 'foliage', 0.38, [0.62, 2.0, 0], { mass: 1 }),\n sph('crown_2', 'foliage', 0.38, [-0.58, 2.2, 0.15], { mass: 1 }),\n sph('crown_3', 'foliage', 0.32, [0.05, 2.3, -0.55], { mass: 1 }),\n ],\n joints: [\n joint('branch_1', 'trunk', 'stem'),\n joint('branch_2', 'trunk', 'stem'),\n joint('branch_3', 'trunk', 'stem'),\n joint('crown_top', 'trunk', 'stem'),\n joint('crown_1', 'branch_1', 'stem'),\n joint('crown_2', 'branch_2', 'stem'),\n joint('crown_3', 'branch_3', 'stem'),\n ],\n tags: ['plant'],\n})\n\nconst pottedPlant = (): DestructibleSpec => ({\n name: 'potted plant',\n parts: [\n cyl('pot', 'ceramic', 0.15, 0.25, [0, 0.125, 0], { mass: 2, thickness: 0.008 }),\n cyl('soil', 'soil', 0.14, 0.06, [0, 0.26, 0], { mass: 1.5 }),\n sph('leaves_1', 'foliage', 0.16, [0, 0.46, 0], { mass: 0.3 }),\n sph('leaves_2', 'foliage', 0.12, [0.12, 0.38, 0.04], { mass: 0.2 }),\n sph('leaves_3', 'foliage', 0.12, [-0.1, 0.4, -0.06], { mass: 0.2 }),\n ],\n joints: [joint('soil', 'pot', 'fused'), joint('leaves_1', 'soil', 'stem'), joint('leaves_2', 'soil', 'stem'), joint('leaves_3', 'soil', 'stem')],\n tags: ['plant'],\n})\n\nconst oldTv = (): DestructibleSpec => ({\n name: 'old TV',\n parts: [\n box('stand', 'wood_soft', [0.6, 0.35, 0.42], [0, 0.175, 0]),\n box('shell', 'plastic', [0.58, 0.44, 0.42], [0, 0.57, 0], { mass: 3, thickness: 0.004 }),\n box('screen', 'glass', [0.42, 0.32, 0.012], [0, 0.57, 0.212], { mass: 1.5 }),\n box('coil', 'copper', [0.2, 0.1, 0.2], [0, 0.55, -0.05], { mass: 1.5 }),\n ],\n joints: [joint('shell', 'stand', 'screw'), joint('screen', 'shell', 'clip'), joint('coil', 'shell', 'screw')],\n tags: ['furniture'],\n})\n\nconst carDoor = (): DestructibleSpec => ({\n name: 'car door',\n parts: [\n box('post', 'steel', [0.1, 1.3, 0.1], [-0.58, 0.65, 0], { mass: 12, anchored: true }),\n box('skin', 'steel', [1, 0.8, 0.05], [0, 0.75, 0], { mass: 14, thickness: 0.0008 }),\n box('window', 'glass', [0.78, 0.32, 0.01], [0.04, 1.31, 0.01], { mass: 3 }),\n box('seal', 'rubber', [0.84, 0.03, 0.03], [0.04, 1.14, 0.01], { mass: 0.3 }),\n ],\n joints: [\n joint('skin', 'post', 'hinge', { id: 'hinge_upper' }),\n joint('skin', 'post', 'hinge', { id: 'hinge_lower' }),\n joint('window', 'seal', 'clip'),\n joint('seal', 'skin', 'clip'),\n ],\n tags: ['vehicle'],\n})\n\nconst sofa = (): DestructibleSpec => ({\n name: 'sofa',\n parts: [\n box('frame', 'wood_soft', [1.8, 0.3, 0.8], [0, 0.15, 0], { mass: 14 }),\n box('seat_cushion', 'foam', [1.5, 0.18, 0.62], [0, 0.39, 0.06], { mass: 4 }),\n box('back_cushion', 'foam', [1.5, 0.5, 0.16], [0, 0.65, -0.3], { mass: 4 }),\n box('arm_l', 'fabric', [0.15, 0.4, 0.8], [-0.82, 0.5, 0], { mass: 3 }),\n box('arm_r', 'fabric', [0.15, 0.4, 0.8], [0.82, 0.5, 0], { mass: 3 }),\n ],\n joints: [\n joint('seat_cushion', 'frame', 'clip'),\n joint('back_cushion', 'frame', 'clip'),\n joint('arm_l', 'frame', 'screw'),\n joint('arm_r', 'frame', 'screw'),\n ],\n tags: ['furniture'],\n})\n\nconst shelf = (): DestructibleSpec => ({\n name: 'shelf',\n parts: [\n box('back', 'plywood', [0.84, 1.5, 0.012], [0, 0.75, -0.14], { anchored: true }),\n box('board_1', 'wood_soft', [0.8, 0.025, 0.28], [0, 0.35, 0]),\n box('board_2', 'wood_soft', [0.8, 0.025, 0.28], [0, 0.75, 0]),\n box('board_3', 'wood_soft', [0.8, 0.025, 0.28], [0, 1.15, 0]),\n box('board_4', 'wood_soft', [0.8, 0.025, 0.28], [0, 1.5, 0]),\n ],\n joints: [joint('board_1', 'back', 'screw'), joint('board_2', 'back', 'screw'), joint('board_3', 'back', 'screw'), joint('board_4', 'back', 'screw')],\n tags: ['furniture'],\n})\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Catalogue\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\ninterface DemoDef {\n id: string\n group: string\n spec: () => DestructibleSpec\n colors?: Record<string, number>\n movable?: boolean\n fluid?: TestRoomItem['fluid']\n}\n\nconst DEFS: DemoDef[] = [\n { id: 'chair', group: 'furniture', spec: chair, colors: { wood_soft: 0xa8703a } },\n { id: 'sofa', group: 'furniture', spec: sofa, colors: { frame: 0x6b4426, seat_cushion: 0x7d3b4c, back_cushion: 0x7d3b4c, arm_l: 0x6a2f40, arm_r: 0x6a2f40 } },\n { id: 'shelf', group: 'furniture', spec: shelf, colors: { back: 0xd9c9a3 }, movable: false },\n { id: 'old_tv', group: 'furniture', spec: oldTv, colors: { shell: 0x6d5a3e, stand: 0x8a5a30, screen: 0x4f6f68 } },\n { id: 'steel_sheet', group: 'structure', spec: steelSheet, movable: false, colors: { sheet: 0xb5bcc4 } },\n { id: 'glass_pane', group: 'structure', spec: glassPane, movable: false },\n { id: 'concrete_block', group: 'structure', spec: concreteBlock },\n { id: 'brick_column', group: 'structure', spec: brickColumn, movable: false },\n { id: 'building_frame', group: 'structure', spec: frame, movable: false, colors: { roof: 0x7d7d79 } },\n { id: 'car_door', group: 'vehicles', spec: carDoor, movable: false, colors: { skin: 0xc0392b, window: 0x9cd6e6 } },\n { id: 'small_tree', group: 'plants', spec: tree, movable: false },\n { id: 'potted_plant', group: 'plants', spec: pottedPlant, colors: { pot: 0xc4673a } },\n { id: 'coffee_cup', group: 'items', spec: cup, colors: { cup: 0xf3efe6 }, fluid: { container: { capacity: 0.6, liquid: 'coffee', liters: 0.25, temperature: 80, shape: { kind: 'cylinder', radius: 0.045, height: 0.1 }, opening: 0.045 }, part: 'cup', uses: ['drink', 'sip', 'pour'], offset: [0, 0.01, 0] } },\n {\n id: 'glass_bottle',\n group: 'items',\n spec: bottle,\n colors: { bottle_body: 0x7fd6b0, bottle_neck: 0x7fd6b0 },\n fluid: { container: { capacity: 0.5, liquid: 'water', liters: 0.5, temperature: 18, shape: { kind: 'cylinder', radius: 0.034, height: 0.14 }, opening: 0.012 }, part: 'bottle_body', uses: ['drink', 'sip', 'pour'], offset: [0, 0.015, 0] },\n },\n { id: 'wooden_crate', group: 'containers', spec: crate },\n { id: 'steel_drum', group: 'containers', spec: drum, colors: { drum_body: 0x2b5f9e, drum_top: 0x2b5f9e, drum_bottom: 0x2b5f9e } },\n { id: 'plastic_bucket', group: 'containers', spec: bucket, colors: { bucket_body: 0xd9482b, handle: 0x8a8a8a } },\n {\n id: 'jerrycan',\n group: 'containers',\n spec: jerrycan,\n colors: { tank: 0xc23b22, cap: 0xf2c230, handle: 0xc23b22 },\n fluid: { container: { capacity: 20, liquid: 'fuel', liters: 20, temperature: 20, shape: { kind: 'box', size: [0.33, 0.44, 0.13] }, opening: 0.025, closed: true }, part: 'tank', uses: ['pour', 'open', 'close'], offset: [0, 0.008, 0] },\n },\n { id: 'gas_bottle', group: 'containers', spec: gasBottle, colors: { cylinder: 0xd8d8d0, valve: 0x777777, foot_ring: 0x555555 } },\n]\n\n/**\n * The generic demo catalogue, names and groups translated for `locale` (`en` or `pt-BR`). Every item is a procedural low-poly build (one mesh per\n * destruction part, drawn by `buildFromSpec`) plus an explicit destruction spec. Containers carry a fluid container where it makes sense.\n */\nexport function demoItems(locale = 'en', extra: TestRoomItem[] = []): TestRoomItem[] {\n const s = resolveStrings(locale)\n const out: TestRoomItem[] = DEFS.map((d) => ({\n id: d.id,\n name: s.items[d.id] ?? d.id,\n group: s.groups[d.group] ?? d.group,\n build: (THREE: typeof THREE_NS) => buildFromSpec(THREE, d.spec(), { colors: d.colors }),\n spec: d.spec,\n movable: d.movable,\n fluid: d.fluid,\n }))\n return [...out, ...extra]\n}\n\n/** The demo catalogue in English (see `demoItems` for other locales). */\nexport const DEMO_ITEMS: TestRoomItem[] = demoItems('en')\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, PartSpec } from '@adatechnology/game-destruction'\n\n/** Default look of each built-in destruction material (`0xRRGGBB`). */\nexport const MATERIAL_COLORS: Record<string, number> = {\n steel: 0x8d949c,\n cast_iron: 0x4a4d52,\n aluminium: 0xc4c9ce,\n copper: 0xb8733a,\n wood_soft: 0xb9854f,\n wood_hard: 0x7a4a26,\n plywood: 0xc9a46a,\n mdf: 0xa88b64,\n glass: 0x9cd6e6,\n tempered_glass: 0x9cd6e6,\n ceramic: 0xe9e4da,\n concrete: 0x9a9a96,\n brick: 0xa5472e,\n plaster: 0xe6e1d4,\n stone: 0x77746f,\n plastic: 0x3b78c4,\n rubber: 0x1f1f22,\n fabric: 0x8a4b5e,\n foam: 0xe3c458,\n leather: 0x5b3a26,\n paper: 0xeeeadf,\n foliage: 0x3f8f3a,\n green_wood: 0x6b4a2b,\n cactus: 0x3e7d4a,\n flesh_fruit: 0xd24b32,\n wax: 0xefe2b5,\n soil: 0x4a3322,\n}\n\nexport interface BuildFromSpecOptions {\n /** Colour per part id, then per material id (falls back to `MATERIAL_COLORS`, then grey). */\n colors?: Record<string, number>\n /** Segments of cylinders and spheres (default 12: low poly on purpose). */\n segments?: number\n /** Cast and receive shadows (default true). */\n shadows?: boolean\n}\n\nconst TRANSPARENT: Record<string, number> = { glass: 0.38, tempered_glass: 0.38 }\n\n/**\n * Draw any `DestructibleSpec` as plain meshes: one mesh per part (box, cylinder or sphere) with `name` and `userData.destructionPart` set to the\n * part id and `userData.destructionMaterial` to its material, so `renderer.bind` and `specFromObject3D` find them. Useful for teams that describe\n * objects as specs and want something to look at while they tune them.\n */\nexport function buildFromSpec(THREE: typeof THREE_NS, spec: DestructibleSpec, options: BuildFromSpecOptions = {}): THREE_NS.Group {\n const root = new THREE.Group()\n root.name = spec.name ?? 'object'\n const seg = options.segments ?? 12\n const shadows = options.shadows !== false\n const mats = new Map<string, THREE_NS.Material>()\n const materialFor = (p: PartSpec): THREE_NS.Material => {\n const color = options.colors?.[p.id] ?? options.colors?.[p.material] ?? MATERIAL_COLORS[p.material] ?? 0x888888\n const key = `${p.material}:${color}`\n let m = mats.get(key)\n if (!m) {\n const alpha = TRANSPARENT[p.material]\n const metal = p.material === 'steel' || p.material === 'aluminium' || p.material === 'copper' || p.material === 'cast_iron'\n m = new THREE.MeshStandardMaterial({\n color,\n roughness: alpha ? 0.1 : metal ? 0.45 : 0.85,\n metalness: metal ? 0.7 : 0,\n transparent: !!alpha,\n opacity: alpha ?? 1,\n depthWrite: !alpha,\n })\n mats.set(key, m)\n }\n return m\n }\n for (const p of spec.parts) {\n let geo: THREE_NS.BufferGeometry\n const s = p.shape\n if (s.kind === 'box') geo = new THREE.BoxGeometry(s.size[0], s.size[1], s.size[2])\n else if (s.kind === 'cylinder') geo = new THREE.CylinderGeometry(s.radius, s.radius, s.height, seg)\n else geo = new THREE.SphereGeometry(s.radius, seg, Math.max(6, seg - 4))\n const mesh = new THREE.Mesh(geo, materialFor(p))\n mesh.name = p.id\n mesh.userData.destructionPart = p.id\n mesh.userData.destructionMaterial = p.material\n mesh.position.set(p.position[0], p.position[1], p.position[2])\n if (p.rotation) mesh.rotation.set(p.rotation[0], p.rotation[1], p.rotation[2], 'XYZ')\n mesh.castShadow = shadows && !TRANSPARENT[p.material]\n mesh.receiveShadow = shadows\n root.add(mesh)\n }\n return root\n}\n","/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type TestRoomLocale = 'en' | 'pt-BR'\n\nexport interface RoomStrings {\n /** Display name per demo item id (see `DEMO_ITEMS`). */\n items: Record<string, string>\n /** Display name per demo catalogue group. */\n groups: Record<string, string>\n /** Every other text: UI, log lines, scenario names and checks. `{name}` placeholders are replaced. */\n text: Record<string, string>\n}\n\nconst en: RoomStrings = {\n items: {\n chair: 'Wooden chair',\n sofa: 'Sofa',\n shelf: 'Shelf with boards',\n old_tv: 'Old TV',\n steel_sheet: 'Steel sheet on a stand',\n glass_pane: 'Glass pane',\n concrete_block: 'Concrete block',\n brick_column: 'Brick column',\n building_frame: 'Building frame',\n car_door: 'Car door',\n small_tree: 'Small tree',\n potted_plant: 'Potted plant',\n coffee_cup: 'Cup of coffee',\n glass_bottle: 'Glass bottle',\n wooden_crate: 'Wooden crate',\n steel_drum: 'Steel drum',\n plastic_bucket: 'Plastic bucket',\n jerrycan: 'Jerrycan',\n gas_bottle: 'Gas bottle',\n },\n groups: { furniture: 'Furniture', structure: 'Structure', vehicles: 'Vehicles', plants: 'Plants', items: 'Items', containers: 'Containers' },\n text: {\n 'locale.decimal': '.',\n yes: 'yes',\n no: 'no',\n piece: 'piece',\n coords: 'x {x} · z {z}',\n 'count.piece.one': '1 piece',\n 'count.piece.other': '{n} pieces',\n 'count.joint.one': '1 joint',\n 'count.joint.other': '{n} joints',\n 'count.dent.one': '1 dent',\n 'count.dent.other': '{n} dents',\n 'count.hole.one': '1 hole',\n 'count.hole.other': '{n} holes',\n 'count.crack.one': '1 crack',\n 'count.crack.other': '{n} cracks',\n 'joint.generic': 'joint',\n 'lost.broken': 'broke',\n 'lost.melted': 'melted away',\n 'lost.ashes': 'burned to ash',\n 'tool.none': 'by hand only',\n 'arena.target_wall': 'Target wall',\n 'arena.table': 'Table',\n 'arena.shelf': 'Shelf',\n 'surface.floor': 'on the floor',\n 'surface.ground': 'on the floor',\n 'surface.table': 'on the table',\n 'by.break': 'broken loose',\n 'by.tool': 'undone with a tool',\n 'by.part_lost': 'the part next to it was lost',\n 'dmg.ballistic': 'ballistic',\n 'dmg.blunt': 'blunt',\n 'dmg.slash': 'slash',\n 'dmg.explosive': 'blast',\n 'dmg.fire': 'fire',\n 'dmg.heat': 'heat',\n 'effect.caffeine': 'caffeine',\n 'effect.alcohol': 'alcohol',\n 'effect.poison': 'poison',\n 'effect.disgust': 'disgust',\n\n 'ev.dent': '{where}: dent of {mm} mm, {hp}',\n 'ev.hole.through': '{where}: {mm} mm hole went through, {hp}',\n 'ev.hole.stuck': '{where}: {mm} mm hole, did not go through, {hp}',\n 'ev.dents': '{where}: {n} dents, deepest {mm} mm, {hp}',\n 'ev.holes': '{where}: {n} holes of {mm} mm, {thr} went through, {hp}',\n 'ev.leak.tail': ', leaking {liquid} at {rate} l/s',\n 'ev.leak.alone': '{where}: leaking {liquid} at {rate} l/s',\n 'ev.crack': '{where}: cracked, {rays} rays up to {cm} cm, {hp}',\n 'ev.ricochet': '{where}: bullet ricocheted, {energy} J left',\n 'ev.fracture.shatter': '{where}: shattered into {n} shards',\n 'ev.fracture.crumble': '{where}: crumbled into {n} chunks',\n 'ev.fracture.splinter': '{where}: splintered into {n} pieces',\n 'ev.fracture.tear': '{where}: torn into {n} scraps',\n 'ev.fracture.snap': '{where}: snapped into {n} pieces',\n 'ev.fracture.none': '{where}: broke into {n} pieces',\n 'ev.detach': '{obj}: {a} came off {b} ({by}); the object now has {pieces}',\n 'ev.detach.many.break': '{obj}: {joints} broke loose; the object now has {pieces}',\n 'ev.detach.many.tool': '{obj}: {joints} undone with a tool; the object now has {pieces}',\n 'ev.lost.tail': ' and came loose from {joints}; the object now has {pieces}',\n 'ev.lost.alone': '{where}: {verb} and came loose from {joints}; the object now has {pieces}',\n 'ev.cracks': '{where}: cracking under the load, {n} cracks so far, longest {cm} cm, {hp}',\n 'ev.disassemble': '{obj}: undoing the {kind} between {a} and {b} with {tool}: {pct}%',\n 'ev.ignite': '{where}: caught fire at {temp} °C',\n 'ev.ignite.many': '{obj}: {n} parts caught fire at {temp} °C ({parts})',\n 'ev.extinguish': '{where}: fire put out',\n 'ev.extinguish.many': '{obj}: fire put out on {n} parts ({parts})',\n 'ev.burnout': '{where}: burned to ash',\n 'ev.melt': '{where}: melting, {pct}% melted away',\n 'ev.drip': '{where}: dripping molten material',\n 'ev.explode': '{where}: exploded, {energy} J within {radius} m',\n 'ev.destroyed': '{obj}: destroyed',\n 'ev.damage': '{where}: {type} damage {amount}, {hp}',\n 'ev.damage.overload': '{where}: crushed by the weight it carries, lost {amount} hp so far, {hp}',\n 'ev.stress': '{where}: overloaded at {stress}% of its capacity, carrying {load} kg',\n 'ev.collapse': '{obj}: collapsed, {pieces} fell ({mass} kg): {parts}',\n 'ev.stain_ignite': 'The {liquid} stain at x {x} · z {z} caught fire and will burn for about {seconds} s',\n 'ev.stain_burned': 'The burning stain burned itself out',\n 'ev.fire_dries': 'Fire dried the wet stains nearby',\n\n 'fl.fill': '{who}: filled with {liquid} (+{liters} l)',\n 'fl.pour': '{who}: pouring {liquid} at {rate} l/s',\n 'fl.spill': '{who}: spilled {liquid} over the lip at {rate} l/s',\n 'fl.leak': '{who}: leaking {liquid} at {rate} l/s',\n 'fl.drink': '{who}: drank {liters} l, thirst +{thirst}',\n 'fl.burn': 'too hot: burned the mouth',\n 'fl.empty': '{who}: empty',\n 'fl.splash': 'Splash of {liquid}',\n 'fl.stain': 'Stain of {liquid} {surface} at {where}',\n 'fl.stains': '{n} stains of {liquid} {surface}, the latest at {where}',\n 'fl.dried': 'A stain dried up',\n 'fl.dried.mark': 'A stain dried and left a mark',\n 'fl.dried.known': 'The {liquid} stain {surface} at {where} dried up',\n 'fl.dried.known.mark': 'The {liquid} stain {surface} at {where} dried and left a mark',\n 'fl.dried.many': '{n} {liquid} stains dried up',\n 'fl.dried.many.mark': '{n} {liquid} stains dried and left marks',\n 'fl.mix': '{who}: {from} mixed into {into}',\n\n 'act.anim_start': '{name}: animation \"{clip}\" ({seconds} s)',\n 'act.anim_event': '{name}: \"{clip}\" event {type}',\n 'act.anim_end': '{name}: animation \"{clip}\" finished',\n 'act.module_loaded': 'Module \"{name}\" loaded: {items} item(s), {scenarios} scenario(s), contract checks: {result}',\n 'mod.all_ok': 'all passed',\n 'mod.some_failed': 'some FAILED',\n 'mod.destructible_ok': '{name}: destructible contract ok ({parts} parts, hit and state well-formed)',\n 'mod.destructible_fail': '{name}: destructible contract broken: {problems}',\n 'mod.animation_ok': '{name}: animation \"{clip}\" ok ({seconds} s)',\n 'mod.spec_ok': '{name}: spec ok ({parts} parts)',\n 'mod.spec_fail': '{name}: spec broken: {problems}',\n 'mod.spec_warn': '{name}: spec warning: {warning}',\n 'mod.animation_fail': '{name}: animation \"{clip}\" broken: {problems}',\n 'ui.animations': 'Animations',\n 'ui.animations_aim': 'Aim at an item or hold it to see its animations.',\n 'ui.animations_none': 'This item brings no animations.',\n 'act.spawn': 'Spawned {name} at x {x} · z {z}',\n 'act.clear': 'Cleared the room',\n 'act.reset': 'Repaired every object',\n 'act.tool': 'Equipped {weapon}',\n 'act.shoot.hit': '{weapon}: shot, {energy} J, hit {where} at {dist} m',\n 'act.shoot.miss': '{weapon}: shot, {energy} J, hit nothing',\n 'act.shoot.pellets': '{weapon}: shot, {n} projectiles of up to {energy} J, {hits} hit {where} at {dist} m',\n 'act.melee.hit': '{weapon}: strike, {energy} J, hit {where} at {dist} m',\n 'act.melee.miss': '{weapon}: struck the air',\n 'act.flame.hit': '{weapon}: flame at {temp} °C on {where}',\n 'act.flame.air': '{weapon}: flame, nothing in range',\n 'act.heat.hit': '{weapon}: heating {where} at {temp} °C',\n 'act.heat.air': '{weapon}: nothing in range',\n 'act.throw.grenade': '{weapon}: thrown, fuse {fuse} s',\n 'act.throw.molotov': '{weapon}: thrown, breaks on impact',\n 'act.explode': '{weapon}: exploded, {energy} J within {radius} m, {n} objects in range',\n 'act.molotov_fire': '{weapon}: fire on the ground, radius {radius} m for {seconds} s',\n 'act.tool.none': '{weapon}: nothing in reach',\n 'act.tool.nojoint': '{weapon}: no joint near {where}',\n 'act.tool.refused': '{weapon} cannot undo the {kind} of {obj}; it needs: {need}',\n 'act.extinguish.hit': '{weapon}: foam on {what}',\n 'act.extinguish.air': '{weapon}: foam, nothing in range',\n 'act.grab': 'Grabbed {name} ({kg} kg)',\n 'act.drop': 'Dropped {name}',\n 'act.throw': 'Threw {name} at {speed} m/s',\n 'act.landing': '{name} landed at {speed} m/s: {energy} J',\n 'act.impact': '{name} hit {where} at {speed} m/s: {energy} J of blunt damage',\n 'act.use_item': '{name}: {use}',\n 'act.tap.on': 'Tap opened',\n 'act.tap.off': 'Tap closed',\n\n 'use.drink': 'drink',\n 'use.sip': 'sip',\n 'use.chug': 'chug',\n 'use.pour': 'pour',\n 'use.pour_out': 'pour out',\n 'use.open': 'open',\n 'use.close': 'close',\n\n 'hud.reloading': 'Reloading...',\n 'hud.empty': 'Empty',\n 'hud.no_fuel': 'Out of fuel',\n 'hud.nothing_to_grab': 'Nothing to grab here',\n 'hud.cannot_grab': '{name} cannot be picked up',\n 'hud.too_heavy': '{name} is too heavy ({kg} kg)',\n 'hud.empty_container': '{name} is empty',\n 'hud.refused': 'Wrong tool for the {kind}',\n 'hud.drop': 'drop',\n 'hud.rotate': 'rotate',\n 'hud.throw': 'throw',\n 'hud.tilt': 'tilt (hold)',\n 'hud.equip': 'equip {weapon}',\n\n 'ui.help': 'Click: look · WASD: walk · Shift: run · Space: jump · 1-0 / wheel: tool · LMB: use · E: grab/drop · G or RMB: throw · Tab: panels · Esc: free the mouse',\n 'ui.log': 'Behaviour log',\n 'ui.filter.action': 'actions',\n 'ui.filter.event': 'events',\n 'ui.filter.check': 'checks',\n 'ui.autoscroll': 'autoscroll',\n 'log.export_cancelled': 'export cancelled',\n 'ui.copy_json': 'Copy JSON',\n 'ui.download_ndjson': 'Download NDJSON',\n 'ui.download_txt': 'Download TXT',\n 'ui.clear_log': 'Clear',\n 'ui.catalog': 'Catalogue',\n 'ui.clear': 'Clear',\n 'ui.reset_all': 'Reset all',\n 'ui.slow': 'Slow motion 0.25×',\n 'ui.fast': 'Time ×10',\n 'ui.tap': 'Tap',\n 'ui.quality': 'Quality',\n 'ui.quality.low': 'low',\n 'ui.quality.medium': 'medium',\n 'ui.quality.high': 'high',\n 'ui.equip': 'Equip as a tool',\n 'ui.objects': '{n} objects',\n 'ui.tests': 'Tests',\n 'ui.run_all': 'Run all',\n 'ui.running': 'Running...',\n 'ui.report': '{passed} passed, {failed} failed',\n 'ui.panel': 'Panels',\n 'ui.inspector': 'Inspector',\n 'ui.aim_at_something': 'Aim at an object',\n 'ins.material': 'Material',\n 'ins.status': 'Status',\n 'ins.burning': 'burning',\n 'ins.hp': 'Hit points',\n 'ins.temperature': 'Temperature',\n 'ins.char': 'Charred',\n 'ins.melt': 'Melted',\n 'ins.liters': 'Liquid',\n 'ins.damage': 'Marks',\n 'ins.damage_counts': '{dents}, {holes}, {cracks}',\n 'ins.mass': 'Mass',\n 'ins.load': 'Load',\n 'ins.stress': 'Stress',\n 'ins.joints': 'Joints',\n 'ins.open': 'open',\n\n 'sc.start': 'Scenario: {name}',\n 'sc.pass': 'Scenario passed: {name}',\n 'sc.fail': 'Scenario FAILED: {name}',\n 'sc.error': 'the scenario threw an error: {msg}',\n 'leg.still': 'leg_1 still attached',\n 'leg.gone': 'leg_1 came off',\n\n 'sc.steel_through_hole': '9 mm into a steel sheet makes a through hole',\n 'sc.steel_through_hole.check': '9 mm into 3 mm steel: {holes} hole(s) of {mm} mm, went through: {through}, sheet {hp} hp (expected: through)',\n 'sc.concrete_stops_bullet': '9 mm into a concrete block does not go through',\n 'sc.concrete_stops_bullet.check': '9 mm into 40 cm of concrete: went through: {through}, {dents}, {holes}, {cracks}, block {hp} hp (expected: stopped, wall behind untouched)',\n 'sc.hammer_dents_drum': 'Hammer dents a steel drum',\n 'sc.hammer_dents_drum.check': 'Hammer on the drum: {swings} swing(s), {dents} dent(s), first {depth} mm deep, body {hp} hp (expected: dented, not broken)',\n 'sc.glass_shatters': 'Glass pane shatters on the first 9 mm shot',\n 'sc.glass_shatters.check': 'Glass pane: broken after {shots} shot(s) into {n} shards (expected: broken on the first shot, at least 4 shards)',\n 'sc.shotgun_splinters_crate': 'Shotgun splinters a wooden crate',\n 'sc.shotgun_splinters_crate.check': '12 ga on the crate: {shots} shot(s), {splinters} board(s) splintered, {holes} holes (expected: at least one splintered)',\n 'sc.kick_chair_leg': 'A kick takes a chair leg off',\n 'sc.kick_chair_leg.check': 'Chair: {kicks} kick(s), {groups} group(s), loose pieces {before} → {after}, {leg} (expected: a loose piece appears)',\n 'sc.kick_detaches_leg_via_tool': 'The kick tool (hotbar) takes a chair leg off',\n 'sc.kick_detaches_leg_via_tool.check': 'Chair, kick tool: {kicks} kick(s), loose pieces {before} → {after}, {leg} (expected: a loose piece appears)',\n 'sc.screwdriver_shelf_board': 'Screwdriver takes a screwed shelf board off in about 2.5 s',\n 'sc.screwdriver_shelf_board.check': 'Screwdriver on the shelf board: took {secs} s, expected about {want} s, the shelf is now in {pieces}',\n 'sc.wrong_tool_refused': 'The wrong tool is refused',\n 'sc.wrong_tool_refused.check': 'Screwdriver on a weld: refused {refused} time(s), joints opened {opened} (expected: refused, none opened)',\n 'sc.lighter_burns_crate': 'A lighter ignites a wooden crate and it ends as ash',\n 'sc.lighter_burns_crate.lit': 'Lighter on the crate: burning: {lit} (expected: yes)',\n 'sc.lighter_burns_crate.ash': 'After burning for 500 s: {ash} of {total} boards are ash, most charred {char}% (expected: all ash or charred)',\n 'sc.torch_melts_steel': 'Wood fire does not melt a steel drum, the cutting torch does',\n 'sc.torch_melts_steel.wood': 'Burning crate next to the drum: drum peaked at {peak} °C, melted {melt}%, crate still burning: {crate} (expected: no melt)',\n 'sc.torch_melts_steel.torch': 'Cutting torch on the drum: {temp} °C, melted {melt}% (expected: melting)',\n 'sc.bucket_melts_drips': 'A plastic bucket melts and drips near fire',\n 'sc.bucket_melts_drips.check': 'Bucket in flames: melted {melt}%, {temp} °C, {drips} drip line(s) (expected: melting)',\n 'sc.gas_bottle_explodes': 'A gas bottle in a fire explodes and pushes a crate',\n 'sc.gas_bottle_explodes.explode': 'Gas bottle in fire: exploded after {seconds} s (expected: explodes)',\n 'sc.gas_bottle_explodes.push': 'Crate 1.3 m away: moved {moved} m, lost {lost} (expected: pushed or broken)',\n 'sc.bottle_drop_shatters': 'A glass bottle dropped from 1.5 m shatters',\n 'sc.bottle_drop_shatters.check': 'Bottle dropped from 1.5 m: status {status}, {cracks} cracks, water stain: {stain} (expected: broken, water on the floor)',\n 'sc.throw_chair_at_wall': 'A chair thrown at the wall deals blunt damage',\n 'sc.throw_chair_at_wall.check': 'Chair thrown at the wall: {impacts} impact(s), first {energy} J, {wall} damage line(s) on the wall (expected: impact and damage)',\n 'sc.coffee_three_sips': 'Three sips of coffee lower the level and log caffeine',\n 'sc.coffee_three_sips.check': 'Coffee: {sips} sip(s), level {before} → {after} l, caffeine logged: {caffeine}, burned the mouth: {burn} (expected: 3 sips, caffeine)',\n 'sc.tilt_cup_spills': 'Tilting the cup spills coffee and leaves a stain',\n 'sc.tilt_cup_spills.check': 'Cup tilted: level {before} → {after} l, {stains} coffee stain(s) (expected: spilled with a stain)',\n 'sc.jerrycan_leaks_fuel': 'Shooting the jerrycan makes a leak and a fuel stain',\n 'sc.jerrycan_leaks_fuel.check': 'Jerrycan shot: {streams} leak stream(s), fuel stain: {stain}, {left} l left of 20, hole line mentions the leak: {leak} (expected: leaking, stain)',\n 'sc.fuel_stain_burns': 'A lit fuel stain burns',\n 'sc.fuel_stain_burns.stain': 'Fuel stain on the floor after the leak: {stain} (expected: yes)',\n 'sc.fuel_stain_burns.ignite': 'Lighter on the stain: {ignited} ignition(s), fire reached nearby objects: {near} (expected: ignited)',\n 'sc.fuel_stain_burns.out': 'After 30 s the stain burned out: {burned} (expected: yes)',\n 'roof.standing': 'roof standing',\n 'roof.fell': 'roof fell',\n 'sc.one_column_roof_stands': 'One column destroyed: the roof stays up',\n 'sc.one_column_roof_stands.check': 'Frame with one column gone: {roof}, heaviest collapse {heavy} kg, peak stress {stress}% (expected: standing, no big collapse)',\n 'sc.two_columns_roof_collapses': 'Two columns destroyed: the roof collapses',\n 'sc.two_columns_roof_collapses.check': 'Frame with two columns gone: the others at {stress}% right away, then heavy loose pieces: {pieces} ({kg} kg), collapse event logged: {logged} (expected: the roof comes down)',\n 'sc.extinguisher_puts_out_fire': 'The extinguisher puts out a burning crate',\n 'sc.extinguisher_puts_out_fire.burning': 'Crate set on fire: burning: {burning} (expected: yes)',\n 'sc.extinguisher_puts_out_fire.out': 'After the extinguisher: still burning: {burning}, {events} extinguish event(s) (expected: out)',\n },\n}\n\nconst ptBR: RoomStrings = {\n items: {\n chair: 'Cadeira de madeira',\n sofa: 'Sofá',\n shelf: 'Estante com prateleiras',\n old_tv: 'TV antiga',\n steel_sheet: 'Chapa de aço com suporte',\n glass_pane: 'Vidro de janela',\n concrete_block: 'Bloco de concreto',\n brick_column: 'Coluna de tijolos',\n building_frame: 'Estrutura de prédio',\n car_door: 'Porta de carro',\n small_tree: 'Árvore pequena',\n potted_plant: 'Vaso de planta',\n coffee_cup: 'Copo de café',\n glass_bottle: 'Garrafa de vidro',\n wooden_crate: 'Caixote de madeira',\n steel_drum: 'Tambor de aço',\n plastic_bucket: 'Balde de plástico',\n jerrycan: 'Galão',\n gas_bottle: 'Botijão de gás',\n },\n groups: { furniture: 'Móveis', structure: 'Estrutura', vehicles: 'Veículos', plants: 'Plantas', items: 'Itens', containers: 'Recipientes' },\n text: {\n 'locale.decimal': ',',\n yes: 'sim',\n no: 'não',\n piece: 'peça',\n coords: 'x {x} · z {z}',\n 'count.piece.one': '1 peça',\n 'count.piece.other': '{n} peças',\n 'count.joint.one': '1 encaixe',\n 'count.joint.other': '{n} encaixes',\n 'count.dent.one': '1 amassado',\n 'count.dent.other': '{n} amassados',\n 'count.hole.one': '1 furo',\n 'count.hole.other': '{n} furos',\n 'count.crack.one': '1 trinca',\n 'count.crack.other': '{n} trincas',\n 'joint.generic': 'junta',\n 'lost.broken': 'quebrou',\n 'lost.melted': 'derreteu',\n 'lost.ashes': 'virou cinza',\n 'tool.none': 'só com a mão',\n 'arena.target_wall': 'Parede de alvo',\n 'arena.table': 'Mesa',\n 'arena.shelf': 'Estante',\n 'surface.floor': 'no chão',\n 'surface.ground': 'no chão',\n 'surface.table': 'na mesa',\n 'by.break': 'arrebentou',\n 'by.tool': 'desmontado com ferramenta',\n 'by.part_lost': 'a peça ao lado se perdeu',\n 'dmg.ballistic': 'de tiro',\n 'dmg.blunt': 'de impacto',\n 'dmg.slash': 'de corte',\n 'dmg.explosive': 'de explosão',\n 'dmg.fire': 'de fogo',\n 'dmg.heat': 'de calor',\n 'effect.caffeine': 'cafeína',\n 'effect.alcohol': 'álcool',\n 'effect.poison': 'veneno',\n 'effect.disgust': 'nojo',\n\n 'ev.dent': '{where}: amassado de {mm} mm, {hp}',\n 'ev.hole.through': '{where}: furo de {mm} mm atravessou, {hp}',\n 'ev.hole.stuck': '{where}: furo de {mm} mm não atravessou, {hp}',\n 'ev.dents': '{where}: {n} amassados, o mais fundo com {mm} mm, {hp}',\n 'ev.holes': '{where}: {n} furos de {mm} mm, {thr} atravessaram, {hp}',\n 'ev.leak.tail': ', vazando {liquid} a {rate} l/s',\n 'ev.leak.alone': '{where}: vazando {liquid} a {rate} l/s',\n 'ev.crack': '{where}: trincou, {rays} raios de até {cm} cm, {hp}',\n 'ev.ricochet': '{where}: a bala ricocheteou, sobraram {energy} J',\n 'ev.fracture.shatter': '{where}: estilhaçou em {n} cacos',\n 'ev.fracture.crumble': '{where}: esfarelou em {n} pedaços',\n 'ev.fracture.splinter': '{where}: lascou em {n} pedaços',\n 'ev.fracture.tear': '{where}: rasgou em {n} retalhos',\n 'ev.fracture.snap': '{where}: partiu em {n} pedaços',\n 'ev.fracture.none': '{where}: quebrou em {n} pedaços',\n 'ev.detach': '{obj}: {a} soltou de {b} ({by}); o objeto agora tem {pieces}',\n 'ev.detach.many.break': '{obj}: {joints} arrebentaram; o objeto agora tem {pieces}',\n 'ev.detach.many.tool': '{obj}: {joints} soltos com ferramenta; o objeto agora tem {pieces}',\n 'ev.lost.tail': ' e se soltou de {joints}; o objeto agora tem {pieces}',\n 'ev.lost.alone': '{where}: {verb} e se soltou de {joints}; o objeto agora tem {pieces}',\n 'ev.cracks': '{where}: rachando sob o peso, {n} trincas até agora, a maior com {cm} cm, {hp}',\n 'ev.disassemble': '{obj}: soltando {kind} entre {a} e {b} com {tool}: {pct}%',\n 'ev.ignite': '{where}: pegou fogo a {temp} °C',\n 'ev.ignite.many': '{obj}: {n} peças pegaram fogo a {temp} °C ({parts})',\n 'ev.extinguish': '{where}: fogo apagado',\n 'ev.extinguish.many': '{obj}: fogo apagado em {n} peças ({parts})',\n 'ev.burnout': '{where}: virou cinza',\n 'ev.melt': '{where}: derretendo, {pct}% já derreteu',\n 'ev.drip': '{where}: pingando material derretido',\n 'ev.explode': '{where}: explodiu, {energy} J em {radius} m',\n 'ev.destroyed': '{obj}: destruído',\n 'ev.damage': '{where}: dano {type} de {amount}, {hp}',\n 'ev.damage.overload': '{where}: esmagado pelo peso que sustenta, perdeu {amount} hp até agora, {hp}',\n 'ev.stress': '{where}: sobrecarregado a {stress}% da capacidade, sustentando {load} kg',\n 'ev.collapse': '{obj}: desabou, caíram {pieces} ({mass} kg): {parts}',\n 'ev.stain_ignite': 'A mancha de {liquid} em x {x} · z {z} pegou fogo e vai queimar por uns {seconds} s',\n 'ev.stain_burned': 'A mancha em chamas se consumiu',\n 'ev.fire_dries': 'O fogo secou as manchas molhadas por perto',\n\n 'fl.fill': '{who}: encheu de {liquid} (+{liters} l)',\n 'fl.pour': '{who}: despejando {liquid} a {rate} l/s',\n 'fl.spill': '{who}: derramou {liquid} pela borda a {rate} l/s',\n 'fl.leak': '{who}: vazando {liquid} a {rate} l/s',\n 'fl.drink': '{who}: bebeu {liters} l, sede +{thirst}',\n 'fl.burn': 'quente demais: queimou a boca',\n 'fl.empty': '{who}: vazio',\n 'fl.splash': 'Respingo de {liquid}',\n 'fl.stain': 'Mancha de {liquid} {surface} em {where}',\n 'fl.stains': '{n} manchas de {liquid} {surface}, a última em {where}',\n 'fl.dried': 'Uma mancha secou',\n 'fl.dried.mark': 'Uma mancha secou e deixou marca',\n 'fl.dried.known': 'A mancha de {liquid} {surface} em {where} secou',\n 'fl.dried.known.mark': 'A mancha de {liquid} {surface} em {where} secou e deixou marca',\n 'fl.dried.many': '{n} manchas de {liquid} secaram',\n 'fl.dried.many.mark': '{n} manchas de {liquid} secaram e deixaram marca',\n 'fl.mix': '{who}: {from} misturou em {into}',\n\n 'act.anim_start': '{name}: animação \"{clip}\" ({seconds} s)',\n 'act.anim_event': '{name}: \"{clip}\" evento {type}',\n 'act.anim_end': '{name}: animação \"{clip}\" terminou',\n 'act.module_loaded': 'Módulo \"{name}\" carregado: {items} item(ns), {scenarios} cenário(s), verificações do contrato: {result}',\n 'mod.all_ok': 'todas passaram',\n 'mod.some_failed': 'algumas FALHARAM',\n 'mod.destructible_ok': '{name}: contrato de destruição ok ({parts} peças, golpe e estado bem formados)',\n 'mod.destructible_fail': '{name}: contrato de destruição quebrado: {problems}',\n 'mod.animation_ok': '{name}: animação \"{clip}\" ok ({seconds} s)',\n 'mod.spec_ok': '{name}: spec ok ({parts} peças)',\n 'mod.spec_fail': '{name}: spec quebrada: {problems}',\n 'mod.spec_warn': '{name}: aviso na spec: {warning}',\n 'mod.animation_fail': '{name}: animação \"{clip}\" quebrada: {problems}',\n 'ui.animations': 'Animações',\n 'ui.animations_aim': 'Mire num item ou segure-o para ver as animações.',\n 'ui.animations_none': 'Este item não traz animações.',\n 'act.spawn': 'Criou {name} em x {x} · z {z}',\n 'act.clear': 'Limpou a sala',\n 'act.reset': 'Consertou todos os objetos',\n 'act.tool': 'Equipou {weapon}',\n 'act.shoot.hit': '{weapon}: disparo, {energy} J, acertou {where} a {dist} m',\n 'act.shoot.miss': '{weapon}: disparo, {energy} J, não acertou nada',\n 'act.shoot.pellets': '{weapon}: disparo, {n} projéteis de até {energy} J, {hits} acertaram {where} a {dist} m',\n 'act.melee.hit': '{weapon}: golpe, {energy} J, acertou {where} a {dist} m',\n 'act.melee.miss': '{weapon}: golpe no ar',\n 'act.flame.hit': '{weapon}: chama a {temp} °C em {where}',\n 'act.flame.air': '{weapon}: chama, nada ao alcance',\n 'act.heat.hit': '{weapon}: esquentando {where} a {temp} °C',\n 'act.heat.air': '{weapon}: nada ao alcance',\n 'act.throw.grenade': '{weapon}: arremessada, pavio de {fuse} s',\n 'act.throw.molotov': '{weapon}: arremessado, quebra no impacto',\n 'act.explode': '{weapon}: explodiu, {energy} J em {radius} m, {n} objetos ao alcance',\n 'act.molotov_fire': '{weapon}: fogo no chão, raio de {radius} m por {seconds} s',\n 'act.tool.none': '{weapon}: nada ao alcance',\n 'act.tool.nojoint': '{weapon}: nenhuma junta perto de {where}',\n 'act.tool.refused': '{weapon} não solta {kind} de {obj}; precisa de: {need}',\n 'act.extinguish.hit': '{weapon}: espuma em {what}',\n 'act.extinguish.air': '{weapon}: espuma, nada ao alcance',\n 'act.grab': 'Pegou {name} ({kg} kg)',\n 'act.drop': 'Soltou {name}',\n 'act.throw': 'Arremessou {name} a {speed} m/s',\n 'act.landing': '{name} caiu a {speed} m/s: {energy} J',\n 'act.impact': '{name} bateu em {where} a {speed} m/s: {energy} J de dano de impacto',\n 'act.use_item': '{name}: {use}',\n 'act.tap.on': 'Abriu a torneira',\n 'act.tap.off': 'Fechou a torneira',\n\n 'use.drink': 'beber',\n 'use.sip': 'golinho',\n 'use.chug': 'virar',\n 'use.pour': 'despejar',\n 'use.pour_out': 'esvaziar',\n 'use.open': 'abrir',\n 'use.close': 'fechar',\n\n 'hud.reloading': 'Recarregando...',\n 'hud.empty': 'Sem munição',\n 'hud.no_fuel': 'Sem combustível',\n 'hud.nothing_to_grab': 'Nada para pegar aqui',\n 'hud.cannot_grab': '{name} não dá para pegar',\n 'hud.too_heavy': '{name} é pesado demais ({kg} kg)',\n 'hud.empty_container': '{name} está vazio',\n 'hud.refused': 'Ferramenta errada para {kind}',\n 'hud.drop': 'soltar',\n 'hud.rotate': 'girar',\n 'hud.throw': 'arremessar',\n 'hud.tilt': 'inclinar (segurar)',\n 'hud.equip': 'equipar {weapon}',\n\n 'ui.help': 'Clique: olhar · WASD: andar · Shift: correr · Espaço: pular · 1-0 / roda: ferramenta · botão esquerdo: usar · E: pegar/soltar · G ou botão direito: arremessar · Tab: painéis · Esc: soltar o mouse',\n 'ui.log': 'Registro de comportamento',\n 'ui.filter.action': 'ações',\n 'ui.filter.event': 'eventos',\n 'ui.filter.check': 'testes',\n 'ui.autoscroll': 'rolar sozinho',\n 'log.export_cancelled': 'exportação cancelada',\n 'ui.copy_json': 'Copiar JSON',\n 'ui.download_ndjson': 'Baixar NDJSON',\n 'ui.download_txt': 'Baixar TXT',\n 'ui.clear_log': 'Limpar',\n 'ui.catalog': 'Catálogo',\n 'ui.clear': 'Limpar',\n 'ui.reset_all': 'Consertar tudo',\n 'ui.slow': 'Câmera lenta 0,25×',\n 'ui.fast': 'Tempo ×10',\n 'ui.tap': 'Torneira',\n 'ui.quality': 'Qualidade',\n 'ui.quality.low': 'baixa',\n 'ui.quality.medium': 'média',\n 'ui.quality.high': 'alta',\n 'ui.equip': 'Equipar como ferramenta',\n 'ui.objects': '{n} objetos',\n 'ui.tests': 'Testes',\n 'ui.run_all': 'Rodar todos',\n 'ui.running': 'Rodando...',\n 'ui.report': '{passed} passaram, {failed} falharam',\n 'ui.panel': 'Painéis',\n 'ui.inspector': 'Inspetor',\n 'ui.aim_at_something': 'Mire em um objeto',\n 'ins.material': 'Material',\n 'ins.status': 'Estado',\n 'ins.burning': 'em chamas',\n 'ins.hp': 'Pontos de vida',\n 'ins.temperature': 'Temperatura',\n 'ins.char': 'Carbonizado',\n 'ins.melt': 'Derretido',\n 'ins.liters': 'Líquido',\n 'ins.damage': 'Marcas',\n 'ins.damage_counts': '{dents}, {holes}, {cracks}',\n 'ins.mass': 'Massa',\n 'ins.load': 'Carga',\n 'ins.stress': 'Tensão',\n 'ins.joints': 'Juntas',\n 'ins.open': 'aberta',\n\n 'sc.start': 'Cenário: {name}',\n 'sc.pass': 'Cenário passou: {name}',\n 'sc.fail': 'Cenário FALHOU: {name}',\n 'sc.error': 'o cenário lançou um erro: {msg}',\n 'leg.still': 'leg_1 continua presa',\n 'leg.gone': 'leg_1 soltou',\n\n 'sc.steel_through_hole': 'Tiro de 9 mm em chapa de aço faz furo que atravessa',\n 'sc.steel_through_hole.check': '9 mm em aço de 3 mm: {holes} furo(s) de {mm} mm, atravessou: {through}, chapa com {hp} hp (esperado: atravessar)',\n 'sc.concrete_stops_bullet': 'Tiro de 9 mm em bloco de concreto não atravessa',\n 'sc.concrete_stops_bullet.check': '9 mm em 40 cm de concreto: atravessou: {through}, {dents}, {holes}, {cracks}, bloco com {hp} hp (esperado: parou, parede atrás intacta)',\n 'sc.hammer_dents_drum': 'Martelo amassa um tambor de aço',\n 'sc.hammer_dents_drum.check': 'Martelo no tambor: {swings} golpe(s), {dents} amassado(s), o primeiro com {depth} mm, corpo com {hp} hp (esperado: amassado, sem quebrar)',\n 'sc.glass_shatters': 'Vidro estilhaça no primeiro tiro de 9 mm',\n 'sc.glass_shatters.check': 'Vidro: quebrou depois de {shots} tiro(s) em {n} cacos (esperado: quebrado no primeiro tiro, pelo menos 4 cacos)',\n 'sc.shotgun_splinters_crate': 'Escopeta lasca um caixote de madeira',\n 'sc.shotgun_splinters_crate.check': 'Calibre 12 no caixote: {shots} tiro(s), {splinters} tábua(s) lascada(s), {holes} furos (esperado: pelo menos uma lascada)',\n 'sc.kick_chair_leg': 'Um chute solta a perna da cadeira',\n 'sc.kick_chair_leg.check': 'Cadeira: {kicks} chute(s), {groups} grupo(s), peças soltas {before} → {after}, {leg} (esperado: aparece uma peça solta)',\n 'sc.kick_detaches_leg_via_tool': 'A ferramenta chute (barra de atalhos) solta a perna da cadeira',\n 'sc.kick_detaches_leg_via_tool.check': 'Cadeira, ferramenta chute: {kicks} chute(s), peças soltas {before} → {after}, {leg} (esperado: aparece uma peça solta)',\n 'sc.screwdriver_shelf_board': 'Chave de fenda solta a prateleira parafusada em cerca de 2,5 s',\n 'sc.screwdriver_shelf_board.check': 'Chave de fenda na prateleira: levou {secs} s, esperado cerca de {want} s, a estante agora está em {pieces}',\n 'sc.wrong_tool_refused': 'A ferramenta errada é recusada',\n 'sc.wrong_tool_refused.check': 'Chave de fenda numa solda: recusou {refused} vez(es), juntas abertas {opened} (esperado: recusar, nenhuma aberta)',\n 'sc.lighter_burns_crate': 'Isqueiro acende o caixote de madeira e ele vira cinza',\n 'sc.lighter_burns_crate.lit': 'Isqueiro no caixote: pegou fogo: {lit} (esperado: sim)',\n 'sc.lighter_burns_crate.ash': 'Depois de queimar por 500 s: {ash} de {total} tábuas viraram cinza, a mais queimada {char}% (esperado: tudo cinza ou carbonizado)',\n 'sc.torch_melts_steel': 'Fogo de madeira não derrete o tambor de aço, o maçarico derrete',\n 'sc.torch_melts_steel.wood': 'Caixote em chamas ao lado do tambor: o tambor chegou a {peak} °C, derreteu {melt}%, caixote ainda queimando: {crate} (esperado: sem derreter)',\n 'sc.torch_melts_steel.torch': 'Maçarico no tambor: {temp} °C, derreteu {melt}% (esperado: derretendo)',\n 'sc.bucket_melts_drips': 'Balde de plástico derrete e pinga perto do fogo',\n 'sc.bucket_melts_drips.check': 'Balde nas chamas: derreteu {melt}%, {temp} °C, {drips} linha(s) de pingos (esperado: derretendo)',\n 'sc.gas_bottle_explodes': 'Botijão de gás no fogo explode e empurra um caixote',\n 'sc.gas_bottle_explodes.explode': 'Botijão no fogo: explodiu depois de {seconds} s (esperado: explode)',\n 'sc.gas_bottle_explodes.push': 'Caixote a 1,3 m: andou {moved} m, perdeu {lost} (esperado: empurrado ou quebrado)',\n 'sc.bottle_drop_shatters': 'Garrafa de vidro solta de 1,5 m estilhaça',\n 'sc.bottle_drop_shatters.check': 'Garrafa solta de 1,5 m: estado {status}, {cracks} trincas, mancha de água: {stain} (esperado: quebrada, água no chão)',\n 'sc.throw_chair_at_wall': 'Cadeira arremessada na parede causa dano de impacto',\n 'sc.throw_chair_at_wall.check': 'Cadeira na parede: {impacts} impacto(s), o primeiro com {energy} J, {wall} linha(s) de dano na parede (esperado: impacto e dano)',\n 'sc.coffee_three_sips': 'Três goles de café baixam o nível e registram cafeína',\n 'sc.coffee_three_sips.check': 'Café: {sips} gole(s), nível {before} → {after} l, cafeína registrada: {caffeine}, queimou a boca: {burn} (esperado: 3 goles, cafeína)',\n 'sc.tilt_cup_spills': 'Inclinar o copo derrama café e deixa mancha',\n 'sc.tilt_cup_spills.check': 'Copo inclinado: nível {before} → {after} l, {stains} mancha(s) de café (esperado: derramou com mancha)',\n 'sc.jerrycan_leaks_fuel': 'Tiro no galão faz vazamento e mancha de combustível',\n 'sc.jerrycan_leaks_fuel.check': 'Galão baleado: {streams} jato(s) de vazamento, mancha de combustível: {stain}, restam {left} l de 20, a linha do furo cita o vazamento: {leak} (esperado: vazando, mancha)',\n 'sc.fuel_stain_burns': 'Mancha de combustível acesa queima',\n 'sc.fuel_stain_burns.stain': 'Mancha de combustível no chão depois do vazamento: {stain} (esperado: sim)',\n 'sc.fuel_stain_burns.ignite': 'Isqueiro na mancha: {ignited} ignição(ões), o fogo alcançou objetos por perto: {near} (esperado: acendeu)',\n 'sc.fuel_stain_burns.out': 'Depois de 30 s a mancha se consumiu: {burned} (esperado: sim)',\n 'roof.standing': 'laje de pé',\n 'roof.fell': 'laje caiu',\n 'sc.one_column_roof_stands': 'Pilar destruído: a laje fica de pé',\n 'sc.one_column_roof_stands.check': 'Estrutura sem um pilar: {roof}, maior desabamento {heavy} kg, tensão máxima {stress}% (esperado: de pé, sem desabamento grande)',\n 'sc.two_columns_roof_collapses': 'Dois pilares destruídos: a laje desaba',\n 'sc.two_columns_roof_collapses.check': 'Estrutura sem dois pilares: os outros logo a {stress}%, depois peças pesadas soltas: {pieces} ({kg} kg), evento de desabamento registrado: {logged} (esperado: a laje desaba)',\n 'sc.extinguisher_puts_out_fire': 'Extintor apaga um caixote em chamas',\n 'sc.extinguisher_puts_out_fire.burning': 'Caixote incendiado: queimando: {burning} (esperado: sim)',\n 'sc.extinguisher_puts_out_fire.out': 'Depois do extintor: ainda queimando: {burning}, {events} evento(s) de apagar (esperado: apagado)',\n },\n}\n\nexport const locales: Record<TestRoomLocale, RoomStrings> = { en, 'pt-BR': ptBR }\n\nexport const resolveStrings = (locale: string | undefined): RoomStrings => locales[(locale as TestRoomLocale) ?? 'en'] ?? locales.en\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-destruction'\nimport type { SurfaceSpec } from '@adatechnology/game-fluids'\nimport { brickWallSpec } from './items'\n\nexport interface ArenaObject {\n id: string\n spec: DestructibleSpec\n position: Vec3\n colors?: Record<string, number>\n}\n\n/** The static part of the room: lights, floor, grid, ruler and the destructible scenery. */\nexport interface Arena {\n group: THREE_NS.Group\n /** Objects to register in the world (target wall, table, shelf). */\n objects: ArenaObject[]\n surfaces: SurfaceSpec[]\n /** `[minX, minZ, maxX, maxZ]` boxes the player cannot walk into. */\n colliders: Array<[number, number, number, number]>\n playerStart: Vec3\n wallZ: number\n /** Rectangle and height of the table top (pieces rest on it while the table stands). */\n table: { minX: number; maxX: number; minZ: number; maxZ: number; top: number; id: string; topPart: string }\n tapSpout: Vec3\n sun: THREE_NS.DirectionalLight\n}\n\nconst tableSpec = (): DestructibleSpec => {\n const parts: PartSpec[] = [{ id: 'top', material: 'wood_hard', shape: { kind: 'box', size: [1.6, 0.05, 0.8] }, position: [0, 0.755, 0] }]\n const joints: JointSpec[] = []\n for (const [i, [x, z]] of [\n [-0.72, -0.32],\n [0.72, -0.32],\n [-0.72, 0.32],\n [0.72, 0.32],\n ].entries()) {\n parts.push({ id: `leg_${i + 1}`, material: 'wood_hard', shape: { kind: 'box', size: [0.06, 0.73, 0.06] }, position: [x, 0.365, z], anchored: true })\n joints.push({ a: `leg_${i + 1}`, b: 'top', kind: 'screw' })\n }\n return { name: 'table', parts, joints, tags: ['furniture'] }\n}\n\nconst shelfSpec = (): DestructibleSpec => {\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n for (const [i, x] of [-0.6, 0.6].entries()) {\n parts.push({ id: `upright_${i + 1}`, material: 'wood_hard', shape: { kind: 'box', size: [0.04, 1.7, 0.4] }, position: [x, 0.85, 0], anchored: true })\n }\n for (const [i, y] of [0.4, 0.9, 1.4].entries()) {\n parts.push({ id: `board_${i + 1}`, material: 'wood_soft', shape: { kind: 'box', size: [1.2, 0.03, 0.4] }, position: [0, y, 0] })\n joints.push({ a: `board_${i + 1}`, b: 'upright_1', kind: 'screw' }, { a: `board_${i + 1}`, b: 'upright_2', kind: 'screw' })\n }\n return { name: 'shelf', parts, joints, tags: ['furniture'] }\n}\n\nexport function createArena(THREE: typeof THREE_NS, size: number, scene: THREE_NS.Scene): Arena {\n const group = new THREE.Group()\n group.name = 'test-room-arena'\n scene.background = new THREE.Color(0x9fb4c8)\n\n group.add(new THREE.HemisphereLight(0xcfe3ff, 0x6b6257, 0.75))\n const sun = new THREE.DirectionalLight(0xffffff, 2.1)\n sun.position.set(7, 13, 8)\n sun.castShadow = true\n sun.shadow.mapSize.set(1024, 1024)\n const sc = sun.shadow.camera\n sc.left = -16\n sc.right = 16\n sc.top = 16\n sc.bottom = -16\n sc.near = 1\n sc.far = 40\n sun.shadow.bias = -0.0006\n group.add(sun)\n\n const floor = new THREE.Mesh(new THREE.PlaneGeometry(size * 2, size * 2), new THREE.MeshStandardMaterial({ color: 0x8e8e8a, roughness: 0.95 }))\n floor.rotation.x = -Math.PI / 2\n floor.receiveShadow = true\n floor.name = 'floor'\n group.add(floor)\n\n const grid = new THREE.GridHelper(size * 2, size * 2, 0x4c4c52, 0x77777b)\n grid.position.y = 0.004\n group.add(grid)\n\n const wallZ = -11\n const playerStart: Vec3 = [0, 1.7, 5]\n\n // distance ruler along the left of the lane: a tick every metre (taller every 5 m) and a label every 5 m\n const pts: number[] = []\n const rx = -1.6\n for (let z = Math.round(playerStart[2]); z >= wallZ; z--) {\n const d = playerStart[2] - z\n const len = d % 5 === 0 ? 0.5 : 0.2\n pts.push(rx, 0.01, z, rx + len, 0.01, z)\n }\n pts.push(rx, 0.01, playerStart[2], rx, 0.01, wallZ)\n const rg = new THREE.BufferGeometry()\n rg.setAttribute('position', new THREE.Float32BufferAttribute(pts, 3))\n group.add(new THREE.LineSegments(rg, new THREE.LineBasicMaterial({ color: 0xffd23f })))\n for (let d = 5; playerStart[2] - d >= wallZ; d += 5) {\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 128\n canvas.height = 64\n const ctx = canvas.getContext('2d')\n if (!ctx) break\n ctx.fillStyle = '#ffd23f'\n ctx.font = 'bold 44px sans-serif'\n ctx.textAlign = 'center'\n ctx.fillText(`${d} m`, 64, 48)\n const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(canvas), transparent: true, depthWrite: false }))\n sprite.scale.set(1.2, 0.6, 1)\n sprite.position.set(rx - 0.8, 0.45, playerStart[2] - d)\n group.add(sprite)\n } catch {\n break\n }\n }\n\n // tap on a post at the end of the table, spout over the tabletop\n const tableX = 3.5\n const tapMat = new THREE.MeshStandardMaterial({ color: 0xb9bec4, metalness: 0.8, roughness: 0.35 })\n const post = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 1.4, 10), tapMat)\n post.position.set(tableX + 1.15, 0.7, 0)\n const arm = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.025, 1.15 - 0.3, 10), tapMat)\n arm.rotation.z = Math.PI / 2\n arm.position.set(tableX + (1.15 + 0.3) / 2, 1.38, 0)\n const spoutMesh = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.025, 0.1, 10), tapMat)\n spoutMesh.position.set(tableX + 0.3, 1.33, 0)\n for (const m of [post, arm, spoutMesh]) {\n m.castShadow = true\n group.add(m)\n }\n const tapSpout: Vec3 = [tableX + 0.3, 1.28, 0]\n\n const objects: ArenaObject[] = [\n { id: 'target_wall', spec: brickWallSpec(), position: [0, 0, wallZ], colors: { brick: 0xa5472e } },\n { id: 'table', spec: tableSpec(), position: [tableX, 0, 0] },\n { id: 'shelf', spec: shelfSpec(), position: [-3.5, 0, 0], colors: { wood_soft: 0xc79a62 } },\n ]\n\n return {\n group,\n objects,\n surfaces: [\n { id: 'floor', point: [0, 0, 0], normal: [0, 1, 0], halfSize: [size, size], porosity: 0.05 },\n { id: 'table', point: [tableX, 0.78, 0], normal: [0, 1, 0], halfSize: [0.8, 0.4], porosity: 0.3 },\n ],\n colliders: [\n [tableX - 0.8, -0.4, tableX + 0.8, 0.4],\n [tableX + 1.1, -0.1, tableX + 1.2, 0.1],\n [-3.5 - 0.62, -0.2, -3.5 + 0.62, 0.2],\n [-size, wallZ - 1, size, wallZ + 0.2],\n ],\n playerStart,\n wallZ,\n table: { minX: tableX - 0.8, maxX: tableX + 0.8, minZ: -0.4, maxZ: 0.4, top: 0.78, id: 'table', topPart: 'top' },\n tapSpout,\n sun,\n }\n}\n","import type { LogEntry, NewLogEntry, TestRoomLog } from './types'\n\nexport type NewEntry = NewLogEntry\n\n/** The log the room writes to (a `TestRoomLog` plus the write side). */\nexport interface WritableLog extends TestRoomLog {\n /** Called before every read, so pending work (the room batches events per frame) is flushed first. */\n setBeforeRead(fn: (() => void) | null): void\n setClock(fn: () => number): void\n}\n\nconst MAX_ENTRIES = 5000\n\nconst pad = (n: number, w = 2): string => String(n).padStart(w, '0')\n\n/** `00:03.21` style clock for the text export. */\nexport const formatTime = (t: number): string => {\n const m = Math.floor(t / 60)\n const s = t - m * 60\n return `${pad(m)}:${s.toFixed(2).padStart(5, '0')}`\n}\n\n/** Minimal shape of the `downloads` capability a claude.ai Artifact page gets from `claude.use('downloads')`. */\ninterface DownloadsApi {\n save(request: { filename: string; data: string }): Promise<unknown>\n}\n\nexport interface LogOptions {\n /** Text of the `action` line written when the viewer declines (or fails) an export from an Artifact page. */\n exportCancelled?: () => string\n}\n\nexport function createLog(options: LogOptions = {}): WritableLog {\n // In a claude.ai Artifact the page cannot use <a download> / blob links: it asks the host for the `downloads` capability. The promise is\n // created once, never awaited here (`use` may take up to 10 s and resolve null); `download` awaits it when somebody actually exports.\n const host = (globalThis as { claude?: { use?: (name: string) => Promise<unknown> } }).claude\n let downloadsP: Promise<DownloadsApi | null> | null = null\n if (host && typeof host.use === 'function') {\n try {\n downloadsP = Promise.resolve(host.use('downloads')).then((d) => (d as DownloadsApi | null) ?? null, () => null)\n } catch {\n downloadsP = null\n }\n }\n let list: LogEntry[] = []\n let seq = 0\n let clock = (): number => 0\n let beforeRead: (() => void) | null = null\n const listeners = new Set<(entry: LogEntry, updated: boolean) => void>()\n const keyed = new Map<string, { entry: LogEntry; last: number; count: number }>()\n\n const read = (): LogEntry[] => {\n beforeRead?.()\n return list\n }\n const emit = (e: LogEntry, updated: boolean): void => {\n for (const fn of listeners) {\n try {\n fn(e, updated)\n } catch {\n // a broken listener must not break the room\n }\n }\n }\n\n const add = (entry: NewEntry): LogEntry => {\n const { t, ...rest } = entry\n const e: LogEntry = { seq: seq++, t: Math.round((t ?? clock()) * 1000) / 1000, ...rest }\n list.push(e)\n if (list.length > MAX_ENTRIES) list = list.slice(list.length - MAX_ENTRIES)\n emit(e, false)\n return e\n }\n\n const log: WritableLog = {\n add,\n coalesce(key, entry, windowS = 1) {\n const now = entry.t ?? clock()\n const k = keyed.get(key)\n if (k && now - k.last <= windowS && list.includes(k.entry)) {\n const { t: _t, ...rest } = entry\n k.count++\n Object.assign(k.entry, rest)\n k.entry.data = { ...(rest.data ?? {}), updates: k.count }\n k.last = now\n emit(k.entry, true)\n return k.entry\n }\n const e = add(entry)\n keyed.set(key, { entry: e, last: now, count: 1 })\n return e\n },\n setBeforeRead(fn) {\n beforeRead = fn\n },\n setClock(fn) {\n clock = fn\n },\n entries(filter) {\n const all = read()\n if (!filter) return all.slice()\n return all.filter(\n (e) =>\n (!filter.channel || e.channel === filter.channel) && (!filter.type || e.type === filter.type) && (!filter.objectId || e.objectId === filter.objectId),\n )\n },\n clear() {\n beforeRead?.()\n list = []\n keyed.clear()\n },\n toJSON: () => JSON.stringify(read(), null, 2),\n toNDJSON: () => read().map((e) => JSON.stringify(e)).join('\\n') + (list.length ? '\\n' : ''),\n toText: () => read().map((e) => `[${formatTime(e.t)}] ${e.channel.padEnd(6)} ${e.text}`).join('\\n'),\n async download(format = 'ndjson') {\n const body = format === 'json' ? log.toJSON() : format === 'txt' ? log.toText() : log.toNDJSON()\n const downloads = downloadsP ? await downloadsP : null\n if (downloads) {\n // the Artifact allowlist has no `.ndjson`: it goes out as text\n const filename = format === 'ndjson' ? 'test-room-log.ndjson.txt' : `test-room-log.${format}`\n try {\n await downloads.save({ filename, data: body })\n } catch (err) {\n const code = (err as { code?: unknown } | null)?.code\n log.add({ channel: 'action', type: 'export_cancelled', text: options.exportCancelled?.() ?? 'export cancelled', data: { format, ...(typeof code === 'string' ? { code } : {}) } })\n }\n return\n }\n if (typeof document === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL) return\n const mime = format === 'json' ? 'application/json' : 'text/plain'\n const url = URL.createObjectURL(new Blob([body], { type: mime }))\n const a = document.createElement('a')\n a.href = url\n a.download = `test-room-log.${format}`\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n },\n summary() {\n const byType: Record<string, number> = {}\n const byMaterial: Record<string, number> = {}\n const objects = new Set<string>()\n let destroyed = 0\n for (const e of read()) {\n byType[e.type] = (byType[e.type] ?? 0) + 1\n if (e.material) byMaterial[e.material] = (byMaterial[e.material] ?? 0) + 1\n if (e.objectId) objects.add(e.objectId)\n if (e.type === 'destroyed') destroyed++\n }\n return { byType, byMaterial, objects: objects.size, destroyed }\n },\n on(fn) {\n listeners.add(fn)\n return () => listeners.delete(fn)\n },\n }\n return log\n}\n","import type { DestructionEvent, DestructionWorld, PartState, ToolKind } from '@adatechnology/game-destruction'\nimport type { FluidEvent, FluidWorld } from '@adatechnology/game-fluids'\nimport type { WritableLog } from './log'\nimport type { LogEntry } from './types'\n\ntype Vars = Record<string, string | number>\n\n/** What the narrator needs to know about the room. */\nexport interface NarrateContext {\n world: DestructionWorld\n fluids: FluidWorld\n log: WritableLog\n /** Current room time in seconds. */\n now: () => number\n t: (key: string, vars?: Vars) => string\n /** Locale number: `1.5` -> `1,5` in pt-BR. */\n num: (n: number, digits?: number) => string\n /** Item display name of an object id (also loose pieces). */\n nameOf: (objectId: string) => string\n itemIdOf: (objectId: string) => string | undefined\n materialName: (id: string) => string\n liquidName: (id: string) => string\n jointKind: (kind: string) => string\n toolName: (tool: string) => string\n /** Display name of the item that carries a fluid container. */\n containerName: (containerId: string) => { name: string; objectId?: string; itemId?: string } | undefined\n /** Where a part lives now: its object, or the loose piece it broke off into. */\n locatePart?: (objectId: string, partId: string) => { objectId: string; part: PartState } | null\n}\n\nconst SKIP_DAMAGE: ReadonlySet<string> = new Set(['fire', 'heat'])\n\n/**\n * Turns destruction and fluid events into plain log lines in the room locale. Events of one frame arrive as a batch: a `damage` event is merged\n * into the dent, hole or crack it caused, a `leak` event into the hole that opened it, and the noisy ones (melt, drip, disassembly) become one\n * line that is updated while it goes on.\n */\nexport function createNarrator(c: NarrateContext) {\n const { t, num } = c\n\n /** Materials seen per `object|part`, so a line about a part that already broke off its object still names the material. */\n const materialMemo = new Map<string, string>()\n const findPart = (objectId: string, partId: string): PartState | null => {\n const p = c.world.part(objectId, partId) ?? c.locatePart?.(objectId, partId)?.part ?? null\n if (p) materialMemo.set(`${objectId}|${partId}`, p.material)\n return p\n }\n const plural = (key: string, n: number): string => t(`${key}.${n === 1 ? 'one' : 'other'}`, { n })\n const pieces = (n: number): string => plural('count.piece', n)\n const joints = (n: number): string => plural('count.joint', n)\n const xz = (x: number, z: number): string => t('coords', { x: num(x, 1), z: num(z, 1) })\n\n const where = (objectId: string, partId: string): string => {\n const p = findPart(objectId, partId)\n const m = p?.material ?? materialMemo.get(`${objectId}|${partId}`)\n return `${c.nameOf(objectId)} › ${partId}${m ? ` (${c.materialName(m)})` : ''}`\n }\n\n const stateOf = (objectId: string, partId: string): LogEntry['state'] => {\n const p = findPart(objectId, partId)\n if (!p) return undefined\n const s: Record<string, number | string | boolean> = {\n status: p.status,\n hp: Math.round(p.hp * 10) / 10,\n maxHp: Math.round(p.maxHp * 10) / 10,\n temperature: Math.round(p.temperature),\n char: Math.round(p.char * 100) / 100,\n melt: Math.round(p.melt * 100) / 100,\n }\n if (p.liters !== undefined) s.liters = Math.round(p.liters * 1000) / 1000\n return s\n }\n\n const base = (ev: DestructionEvent, part?: string): Pick<LogEntry, 'channel' | 'objectId' | 'itemId' | 'part' | 'material' | 'state'> => ({\n channel: 'event',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n part,\n material: part ? (findPart(ev.object, part)?.material ?? materialMemo.get(`${ev.object}|${part}`)) : undefined,\n state: part ? stateOf(ev.object, part) : undefined,\n })\n\n const hpText = (obj: string, part: string): string => {\n const p = findPart(obj, part)\n return p ? `hp ${num(p.hp, 0)}/${num(p.maxHp, 0)}` : ''\n }\n\n const isLost = (obj: string, part: string): boolean => {\n const st = findPart(obj, part)?.status\n return st === 'broken' || st === 'melted' || st === 'ashes'\n }\n\n /** Per-part running totals for lines that repeat while something goes on (cracks under load, overload damage). */\n const crackAcc = new Map<string, { n: number; cm: number; last: number }>()\n const damageAcc = new Map<string, { total: number; last: number }>()\n const stressAt = new Map<string, number>()\n const leakAt = new Map<string, number>()\n const list = (names: string[]): string => (names.length > 6 ? `${names.slice(0, 6).join(', ')}…` : names.join(', '))\n\n const events = (batch: DestructionEvent[]): void => {\n const now = c.now()\n const damage = new Map<string, { amount: number; type: string }>()\n const holes = new Map<string, LogEntry>()\n const dents = new Map<string, LogEntry>()\n for (const ev of batch) {\n if (ev.type !== 'damage') continue\n const k = `${ev.object}|${ev.part}`\n const prev = damage.get(k)\n damage.set(k, { amount: (prev?.amount ?? 0) + ev.amount, type: ev.damageType })\n }\n\n // A part that breaks, melts or burns away opens every joint it had: those `detach` events become part of ONE line about the part\n // (appended to its fracture or burnout line, or standing alone), instead of one line per joint.\n const lostJoints = new Map<string, { obj: string; part: string; joints: number; groups: number; merged: boolean }>()\n // Joints that open for another reason (a blow, a tool) are counted per object.\n const openJoints = new Map<string, { obj: string; by: string; list: Array<{ joint: string; a: string; b: string }>; groups: number; done: boolean }>()\n // Several parts of one object catching fire or being put out at once are one line.\n const fireParts = new Map<string, { obj: string; parts: string[]; temp: number; done: boolean }>()\n const outParts = new Map<string, { obj: string; parts: string[]; done: boolean }>()\n for (const ev of batch) {\n if (ev.type === 'detach') {\n if (ev.by === 'part_lost') {\n const [a, b] = ev.parts\n const lost = isLost(ev.object, a) && !isLost(ev.object, b) ? a : isLost(ev.object, b) && !isLost(ev.object, a) ? b : isLost(ev.object, a) ? a : b\n const key = `${ev.object}|${lost}`\n const g = lostJoints.get(key) ?? { obj: ev.object, part: lost, joints: 0, groups: 0, merged: false }\n g.joints++\n g.groups = ev.groups.length\n lostJoints.set(key, g)\n } else {\n const key = `${ev.object}|${ev.by}`\n const g = openJoints.get(key) ?? { obj: ev.object, by: ev.by, list: [], groups: 0, done: false }\n const [a, b] = ev.parts\n g.list.push({ joint: ev.joint, a, b })\n g.groups = ev.groups.length\n openJoints.set(key, g)\n }\n } else if (ev.type === 'ignite') {\n const g = fireParts.get(ev.object) ?? { obj: ev.object, parts: [], temp: 0, done: false }\n g.parts.push(ev.part)\n g.temp = Math.max(g.temp, findPart(ev.object, ev.part)?.temperature ?? 0)\n fireParts.set(ev.object, g)\n } else if (ev.type === 'extinguish') {\n const g = outParts.get(ev.object) ?? { obj: ev.object, parts: [], done: false }\n g.parts.push(ev.part)\n outParts.set(ev.object, g)\n }\n }\n const lostTail = (key: string): string => {\n const g = lostJoints.get(key)\n if (!g) return ''\n g.merged = true\n return t('ev.lost.tail', { joints: joints(g.joints), pieces: pieces(g.groups) })\n }\n const lostData = (key: string): Record<string, unknown> => {\n const g = lostJoints.get(key)\n return g ? { jointsOpened: g.joints, pieces: g.groups } : {}\n }\n\n for (const ev of batch) {\n switch (ev.type) {\n case 'damage':\n break\n case 'dent': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n const mm = ev.dent.depth * 1000\n const prev = dents.get(k)\n if (prev) {\n const n = Number(prev.data?.count ?? 1) + 1\n const deepest = Math.max(Number(prev.data?.depthMm ?? 0), mm)\n prev.text = t('ev.dents', { where: where(ev.object, ev.part), n, mm: num(deepest, 0), hp: hpText(ev.object, ev.part) })\n prev.data = { ...prev.data, count: n, depthMm: Math.round(deepest * 10) / 10 }\n break\n }\n dents.set(\n k,\n c.log.add({\n ...base(ev, ev.part),\n type: 'dent',\n text: t('ev.dent', { where: where(ev.object, ev.part), mm: num(mm, 0), hp: hpText(ev.object, ev.part) }),\n data: { count: 1, depthMm: Math.round(mm * 10) / 10, radius: ev.dent.radius, damage: d?.amount, point: ev.worldPoint, source: ev.source },\n }),\n )\n break\n }\n case 'hole': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n const mm = ev.hole.diameter * 1000\n const prev = holes.get(k)\n if (prev) {\n const n = Number(prev.data?.count ?? 1) + 1\n const through = Number(prev.data?.throughCount ?? 0) + (ev.hole.through ? 1 : 0)\n prev.text = t('ev.holes', { where: where(ev.object, ev.part), n, mm: num(mm, 0), thr: through, hp: hpText(ev.object, ev.part) })\n prev.data = { ...prev.data, count: n, throughCount: through, through: through > 0 }\n break\n }\n holes.set(\n k,\n c.log.add({\n ...base(ev, ev.part),\n type: 'hole',\n text: t(ev.hole.through ? 'ev.hole.through' : 'ev.hole.stuck', { where: where(ev.object, ev.part), mm: num(mm, 0), hp: hpText(ev.object, ev.part) }),\n data: { count: 1, throughCount: ev.hole.through ? 1 : 0, diameterMm: Math.round(mm * 10) / 10, through: ev.hole.through, damage: d?.amount, point: ev.worldPoint, source: ev.source },\n }),\n )\n break\n }\n case 'crack': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n // a part under load cracks again and again: that is one line that counts them (a cracking shot or blow stays its own line)\n const loaded = (findPart(ev.object, ev.part)?.stress ?? 0) > 0.8 && ev.source === undefined\n const cm = ev.crack.length * 100\n if (loaded) {\n const acc = crackAcc.get(k)\n const n = acc && now - acc.last <= 1 ? acc.n + 1 : 1\n const longest = acc && n > 1 ? Math.max(acc.cm, cm) : cm\n crackAcc.set(k, { n, cm: longest, last: now })\n c.log.coalesce(\n `crack:${k}`,\n {\n ...base(ev, ev.part),\n type: 'crack',\n text: t('ev.cracks', { where: where(ev.object, ev.part), n, cm: num(longest, 0), hp: hpText(ev.object, ev.part) }),\n data: { rays: ev.crack.rays, lengthM: ev.crack.length, count: n, underLoad: true },\n },\n 1,\n )\n break\n }\n c.log.add({\n ...base(ev, ev.part),\n type: 'crack',\n text: t('ev.crack', { where: where(ev.object, ev.part), rays: ev.crack.rays, cm: num(cm, 0), hp: hpText(ev.object, ev.part) }),\n data: { rays: ev.crack.rays, lengthM: ev.crack.length, damage: d?.amount, source: ev.source },\n })\n break\n }\n case 'ricochet':\n c.log.add({\n ...base(ev, ev.part),\n type: 'ricochet',\n text: t('ev.ricochet', { where: where(ev.object, ev.part), energy: num(ev.energy, 0) }),\n data: { energy: ev.energy, direction: ev.direction },\n })\n break\n case 'leak': {\n const k = `${ev.object}|${ev.part}`\n const liquid = c.liquidName(ev.fluid)\n const hole = holes.get(k)\n const rate = num(ev.rate, 2)\n leakAt.set(ev.object, now)\n if (hole) {\n hole.text += t('ev.leak.tail', { liquid, rate })\n hole.data = { ...hole.data, leak: { fluid: ev.fluid, ratePerS: ev.rate, pressurized: ev.pressurized } }\n } else {\n c.log.add({ ...base(ev, ev.part), type: 'leak', text: t('ev.leak.alone', { where: where(ev.object, ev.part), liquid, rate }), data: { fluid: ev.fluid, ratePerS: ev.rate } })\n }\n break\n }\n case 'fracture': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n c.log.add({\n ...base(ev, ev.part),\n type: 'fracture',\n text: t(`ev.fracture.${ev.style}`, { where: where(ev.object, ev.part), n: ev.fragments.length }) + lostTail(k),\n data: { style: ev.style, fragments: ev.fragments.length, damage: d?.amount, point: ev.point, source: ev.source, ...lostData(k) },\n })\n break\n }\n case 'detach': {\n if (ev.by === 'part_lost') {\n // the part's own line (fracture, burnout) already says it; with none in this batch, say it here, once\n const [a, b] = ev.parts\n const lost = isLost(ev.object, a) && !isLost(ev.object, b) ? a : isLost(ev.object, b) && !isLost(ev.object, a) ? b : isLost(ev.object, a) ? a : b\n const key = `${ev.object}|${lost}`\n const g = lostJoints.get(key)\n if (!g || g.merged) break\n const hasOwnLine = batch.some((e) => (e.type === 'fracture' || e.type === 'burnout') && e.object === ev.object && e.part === lost)\n if (hasOwnLine) break\n g.merged = true\n const status = findPart(ev.object, lost)?.status\n const verb = t(`lost.${status === 'ashes' ? 'ashes' : status === 'melted' ? 'melted' : 'broken'}`)\n c.log.add({\n ...base(ev, lost),\n type: 'detach',\n text: t('ev.lost.alone', { where: where(ev.object, lost), verb, joints: joints(g.joints), pieces: pieces(g.groups) }),\n data: { parts: [a, b], by: ev.by, ...lostData(key) },\n })\n break\n }\n const key = `${ev.object}|${ev.by}`\n const g = openJoints.get(key)\n if (!g || g.done) break\n g.done = true\n const [a, b] = ev.parts\n const many = g.list.length > 1\n c.log.add({\n channel: 'event',\n type: 'detach',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: many\n ? t(`ev.detach.many.${ev.by === 'tool' ? 'tool' : 'break'}`, { obj: c.nameOf(ev.object), joints: joints(g.list.length), pieces: pieces(g.groups) })\n : t('ev.detach', { obj: c.nameOf(ev.object), a, b, by: t(`by.${ev.by}`), pieces: pieces(g.groups) }),\n data: { joint: ev.joint, joints: g.list.map((j) => j.joint), parts: ev.parts, by: ev.by, groups: g.groups },\n })\n break\n }\n case 'disassemble_progress': {\n const pct = Math.round(ev.progress * 100)\n const kind = kindOf(ev.object, ev.joint)\n const [a, b] = ev.joint.split('~')\n c.log.coalesce(\n `dis:${ev.object}:${ev.joint}`,\n {\n channel: 'event',\n type: 'disassemble_progress',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: t('ev.disassemble', { obj: c.nameOf(ev.object), a: a ?? ev.joint, b: b ?? '', kind: kind ? c.jointKind(kind) : t('joint.generic'), tool: c.toolName(ev.tool as ToolKind), pct }),\n data: { joint: ev.joint, tool: ev.tool, progress: ev.progress },\n },\n 1.5,\n )\n break\n }\n case 'ignite': {\n const g = fireParts.get(ev.object)\n if (g && g.parts.length >= 3) {\n if (g.done) break\n g.done = true\n c.log.add({\n channel: 'event',\n type: 'ignite',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: t('ev.ignite.many', { obj: c.nameOf(ev.object), n: g.parts.length, temp: num(g.temp, 0), parts: list(g.parts) }),\n data: { parts: g.parts, temperature: Math.round(g.temp) },\n })\n break\n }\n c.log.add({ ...base(ev, ev.part), type: 'ignite', text: t('ev.ignite', { where: where(ev.object, ev.part), temp: num(findPart(ev.object, ev.part)?.temperature ?? 0, 0) }) })\n break\n }\n case 'extinguish': {\n const g = outParts.get(ev.object)\n if (g && g.parts.length >= 3) {\n if (g.done) break\n g.done = true\n c.log.add({\n channel: 'event',\n type: 'extinguish',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: t('ev.extinguish.many', { obj: c.nameOf(ev.object), n: g.parts.length, parts: list(g.parts) }),\n data: { parts: g.parts },\n })\n break\n }\n c.log.add({ ...base(ev, ev.part), type: 'extinguish', text: t('ev.extinguish', { where: where(ev.object, ev.part) }) })\n break\n }\n case 'burnout': {\n const k = `${ev.object}|${ev.part}`\n c.log.add({ ...base(ev, ev.part), type: 'burnout', text: t('ev.burnout', { where: where(ev.object, ev.part) }) + lostTail(k), data: lostData(k) })\n break\n }\n case 'melt':\n c.log.coalesce(\n `melt:${ev.object}:${ev.part}`,\n { ...base(ev, ev.part), type: 'melt', text: t('ev.melt', { where: where(ev.object, ev.part), pct: Math.round(ev.melt * 100) }), data: { melt: ev.melt } },\n 2,\n )\n break\n case 'drip':\n c.log.coalesce(`drip:${ev.object}:${ev.part}`, { ...base(ev, ev.part), type: 'drip', text: t('ev.drip', { where: where(ev.object, ev.part) }), data: { point: ev.point } }, 2)\n break\n case 'explode':\n c.log.add({\n ...base(ev, ev.part),\n type: 'explode',\n text: t('ev.explode', { where: where(ev.object, ev.part), energy: num(ev.energy, 0), radius: num(ev.radius, 1) }),\n data: { energy: ev.energy, radius: ev.radius, point: ev.point },\n })\n break\n case 'destroyed':\n c.log.add({ channel: 'event', type: 'destroyed', objectId: ev.object, itemId: c.itemIdOf(ev.object), text: t('ev.destroyed', { obj: c.nameOf(ev.object) }) })\n break\n default: {\n // structural events (`stress`, `collapse`) come from newer versions of the core\n const x = ev as unknown as Record<string, unknown> & { type: string; object: string; time: number }\n if (x.type === 'stress') {\n const part = String(x.part ?? '')\n stressAt.set(`${x.object}|${part}`, now)\n c.log.coalesce(\n `stress:${x.object}:${part}`,\n {\n ...base(ev, part),\n type: 'stress',\n text: t('ev.stress', { where: where(x.object, part), stress: num(Number(x.stress ?? 0) * 100, 0), load: num(Number(x.load ?? 0), 0) }),\n data: { stress: x.stress, load: x.load },\n },\n 1,\n )\n } else if (x.type === 'collapse') {\n const parts = Array.isArray(x.parts) ? (x.parts as unknown[]).map(String) : []\n c.log.add({\n channel: 'event',\n type: 'collapse',\n objectId: x.object,\n itemId: c.itemIdOf(x.object),\n text: t('ev.collapse', { obj: c.nameOf(x.object), pieces: pieces(parts.length), mass: num(Number(x.mass ?? 0), 0), parts: list(parts) }),\n data: { parts: parts.length, partIds: parts, massKg: x.mass, cause: x.cause },\n })\n }\n }\n }\n }\n // damage that no dent, hole, crack or fracture explained (blunt thuds, blast, absorbed bullets, a structure carrying too much)\n for (const [k, d] of damage) {\n if (SKIP_DAMAGE.has(d.type) || d.amount < 0.5) continue\n const [obj, part] = k.split('|')\n const overload = d.type === 'blunt' && now - (stressAt.get(k) ?? -99) <= 3\n const entry = {\n channel: 'event' as const,\n type: 'damage',\n objectId: obj,\n itemId: c.itemIdOf(obj),\n part,\n material: findPart(obj, part)?.material ?? materialMemo.get(k),\n state: stateOf(obj, part),\n }\n if (!overload) {\n c.log.add({ ...entry, text: t('ev.damage', { where: where(obj, part), type: t(`dmg.${d.type}`), amount: num(d.amount, 0), hp: hpText(obj, part) }), data: { amount: d.amount, damageType: d.type } })\n continue\n }\n // a structure carrying too much loses hit points every tick: one line with the running total\n const acc = damageAcc.get(k)\n const total = acc && now - acc.last <= 1 ? acc.total + d.amount : d.amount\n damageAcc.set(k, { total, last: now })\n c.log.coalesce(\n `damage:${k}`,\n { ...entry, text: t('ev.damage.overload', { where: where(obj, part), amount: num(total, 0), hp: hpText(obj, part) }), data: { amount: total, damageType: d.type, overload: true } },\n 1,\n )\n }\n }\n\n const kindMemo = new Map<string, string>()\n const kindOf = (objectId: string, jointId: string): string => {\n const key = `${objectId}|${jointId}`\n const own = c.world.state(objectId)?.joints.find((j) => j.id === jointId)?.kind\n if (own) {\n kindMemo.set(key, own)\n return own\n }\n const known = kindMemo.get(key)\n if (known) return known\n for (const id of c.world.ids()) {\n const k = c.world.state(id)?.joints.find((j) => j.id === jointId)?.kind\n if (k) return k\n }\n return ''\n }\n\n const stainInfo = new Map<string, { liquid: string; surface: string; x: number; z: number }>()\n const stainAcc = new Map<string, { n: number; last: number }>()\n const driedAcc = new Map<string, { n: number; last: number }>()\n const drinkAcc = new Map<string, { liters: number; thirst: number; burn: boolean; effects: Set<string>; last: number; start: number }>()\n const fluid = (ev: FluidEvent): void => {\n const who = (id: string): string => c.containerName(id)?.name ?? id\n const meta = (id: string): { objectId?: string; itemId?: string } => {\n const m = c.containerName(id)\n return { objectId: m?.objectId, itemId: m?.itemId }\n }\n const f = 'fluid.'\n switch (ev.type) {\n case 'fill':\n c.log.coalesce(`fill:${ev.container}`, { channel: 'event', type: f + 'fill', ...meta(ev.container), text: t('fl.fill', { who: who(ev.container), liquid: c.liquidName(ev.liquid), liters: num(ev.liters, 2) }), data: { liters: ev.liters } }, 1.5)\n break\n case 'pour':\n c.log.coalesce(`pour:${ev.container}`, { channel: 'event', type: f + 'pour', ...meta(ev.container), text: t('fl.pour', { who: who(ev.container), liquid: c.liquidName(ev.liquid), rate: num(ev.rate, 2) }), data: { rate: ev.rate } }, 2)\n break\n case 'spill':\n c.log.coalesce(`spill:${ev.container}`, { channel: 'event', type: f + 'spill', ...meta(ev.container), text: t('fl.spill', { who: who(ev.container), liquid: c.liquidName(ev.liquid), rate: num(ev.rate, 2) }), data: { rate: ev.rate } }, 2)\n break\n case 'leak': {\n // the hole line of the destruction event already says the object is leaking\n const owner = meta(ev.container).objectId\n if (owner && c.now() - (leakAt.get(owner) ?? -99) <= 2) break\n c.log.coalesce(`fleak:${ev.container}`, { channel: 'event', type: f + 'leak', ...meta(ev.container), text: t('fl.leak', { who: who(ev.container), liquid: c.liquidName(ev.liquid), rate: num(ev.rate, ev.rate < 0.01 ? 3 : 2) }), data: { rate: ev.rate, point: ev.point } }, 2)\n break\n }\n case 'drink': {\n // a sip arrives as many small drink events: one line per sip, updated while it goes on\n const now = c.now()\n let acc = drinkAcc.get(ev.container)\n if (!acc || now - acc.last > 0.5) acc = { liters: 0, thirst: 0, burn: false, effects: new Set<string>(), last: now, start: now }\n acc.liters += ev.liters\n acc.thirst += ev.thirst\n acc.burn = acc.burn || ev.burn\n for (const e of ev.effects) acc.effects.add(e)\n acc.last = now\n drinkAcc.set(ev.container, acc)\n const effects = [...acc.effects].map((e) => t(`effect.${e}`)).join(', ')\n c.log.coalesce(\n `drink:${ev.container}:${acc.start}`,\n {\n channel: 'event',\n type: f + 'drink',\n ...meta(ev.container),\n text:\n t('fl.drink', { who: who(ev.container), liters: num(acc.liters, 2), thirst: num(acc.thirst, 0) }) +\n (effects ? `, ${effects}` : '') +\n (acc.burn ? `, ${t('fl.burn')}` : ''),\n data: { liters: acc.liters, temperature: ev.temperature, thirst: acc.thirst, effects: [...acc.effects], burn: acc.burn },\n },\n 0.5,\n )\n break\n }\n case 'empty':\n c.log.add({ channel: 'event', type: f + 'empty', ...meta(ev.container), text: t('fl.empty', { who: who(ev.container) }) })\n break\n case 'splash':\n c.log.coalesce(`splash:${ev.liquid}`, { channel: 'event', type: f + 'splash', text: t('fl.splash', { liquid: c.liquidName(ev.liquid) }), data: { point: ev.point, intensity: ev.intensity } }, 1)\n break\n case 'stain': {\n const surface = t(`surface.${ev.surface}`)\n const liquid = c.liquidName(ev.liquid)\n stainInfo.set(ev.stain, { liquid: ev.liquid, surface, x: ev.point[0], z: ev.point[2] })\n // a leak or a spill makes several stains in a row: one line that counts them\n const key = `stain:${ev.liquid}:${ev.surface}`\n const acc = stainAcc.get(key)\n const n = acc && c.now() - acc.last <= 1 ? acc.n + 1 : 1\n stainAcc.set(key, { n, last: c.now() })\n c.log.coalesce(\n key,\n {\n channel: 'event',\n type: f + 'stain',\n text: n > 1 ? t('fl.stains', { n, liquid, surface, where: xz(ev.point[0], ev.point[2]) }) : t('fl.stain', { liquid, surface, where: xz(ev.point[0], ev.point[2]) }),\n data: { stain: ev.stain, surface: ev.surface, liquid: ev.liquid, point: ev.point, count: n },\n },\n 1,\n )\n break\n }\n case 'dried': {\n const info = stainInfo.get(ev.stain)\n const key = `dried:${info?.liquid ?? '?'}:${ev.mark}`\n const acc = driedAcc.get(key)\n const n = acc && c.now() - acc.last <= 1.5 ? acc.n + 1 : 1\n driedAcc.set(key, { n, last: c.now() })\n const vars = { liquid: info ? c.liquidName(info.liquid) : '', surface: info?.surface ?? '', where: info ? xz(info.x, info.z) : '', n }\n const text = !info\n ? t(ev.mark ? 'fl.dried.mark' : 'fl.dried')\n : n > 1\n ? t(ev.mark ? 'fl.dried.many.mark' : 'fl.dried.many', vars)\n : t(ev.mark ? 'fl.dried.known.mark' : 'fl.dried.known', vars)\n c.log.coalesce(key, { channel: 'event', type: f + 'dried', text, data: { stain: ev.stain, mark: ev.mark, count: n } }, 1.5)\n break\n }\n case 'mix':\n c.log.add({ channel: 'event', type: f + 'mix', ...meta(ev.container), text: t('fl.mix', { who: who(ev.container), from: c.liquidName(ev.from), into: c.liquidName(ev.into) }) })\n break\n default:\n break\n }\n }\n\n return { events, fluid }\n}\n","import type * as THREE_NS from 'three'\nimport type { Vec3 } from '@adatechnology/game-destruction'\n\nexport interface PlayerHooks {\n /** Primary button pressed / released (use the tool). `click` is a press without a drag, for the no-pointer-lock fallback. */\n primaryDown(): void\n primaryUp(): void\n secondary(): void\n key(code: string, down: boolean, event: KeyboardEvent): void\n wheel(direction: 1 | -1): void\n}\n\nexport interface PlayerOptions {\n camera: THREE_NS.PerspectiveCamera\n dom: HTMLElement\n /** `[minX, minZ, maxX, maxZ]` boxes to stay out of. */\n colliders: Array<[number, number, number, number]>\n /** Half size of the arena. */\n limit: number\n start: Vec3\n hooks: PlayerHooks\n}\n\nexport interface Player {\n readonly yaw: number\n readonly pitch: number\n readonly locked: boolean\n /** Held keys, by `KeyboardEvent.code`. */\n keys: ReadonlySet<string>\n update(dt: number): void\n setPose(position: Vec3, yaw: number, pitch: number): void\n /** Put the eye at `position` looking at `target`. */\n look(position: Vec3, target: Vec3): void\n /** Camera kick in degrees. */\n kick(pitchDeg: number, yawDeg: number): void\n /** Move the player by a world offset on the floor plane, stopped by the colliders and the arena limit (scripted walks). */\n moveBy(dx: number, dz: number): void\n /** Walk by hand (tests): moves the player `forward` and `right` metres along its facing. */\n walk(forward: number, right: number): void\n dispose(): void\n}\n\nconst EYE = 1.7\nconst RADIUS = 0.3\nconst WALK = 3.4\nconst RUN = 6.2\nconst JUMP = 4.6\nconst GRAVITY = 13\nconst LOOK = 0.0022\n\n/**\n * First-person controller: WASD, Shift, Space, mouse look with pointer lock, and a drag-to-look fallback for pages where the lock is not\n * available (iframes, headless browsers, touch). In the fallback a press that does not move is a click (tool use), a drag looks around.\n */\nexport function createPlayer(THREE: typeof THREE_NS, o: PlayerOptions): Player {\n const cam = o.camera\n let yaw = 0\n let pitch = 0\n let y = 0\n let eye = EYE\n let vy = 0\n const px = { x: o.start[0], z: o.start[2] }\n let locked = false\n const keys = new Set<string>()\n const euler = new THREE.Euler(0, 0, 0, 'YXZ')\n\n const apply = (): void => {\n euler.set(pitch, yaw, 0, 'YXZ')\n cam.quaternion.setFromEuler(euler)\n cam.position.set(px.x, eye + y, px.z)\n cam.updateMatrixWorld(true)\n }\n apply()\n\n const blocked = (x: number, z: number): boolean => {\n if (Math.abs(x) > o.limit - RADIUS || Math.abs(z) > o.limit - RADIUS) return true\n for (const c of o.colliders) if (x > c[0] - RADIUS && x < c[2] + RADIUS && z > c[1] - RADIUS && z < c[3] + RADIUS) return true\n return false\n }\n const move = (dx: number, dz: number): void => {\n if (!blocked(px.x + dx, px.z)) px.x += dx\n if (!blocked(px.x, px.z + dz)) px.z += dz\n }\n\n let dragging = false\n let moved = 0\n let downAt = 0\n let useStarted = false\n let holdTimer: ReturnType<typeof setTimeout> | null = null\n\n const look = (dx: number, dy: number): void => {\n yaw -= dx * LOOK\n pitch = Math.max(-1.5, Math.min(1.5, pitch - dy * LOOK))\n }\n const onLockChange = (): void => {\n locked = document.pointerLockElement === o.dom\n }\n const onMouseDown = (e: MouseEvent): void => {\n o.dom.focus?.()\n if (e.button === 2) {\n e.preventDefault()\n o.hooks.secondary()\n return\n }\n if (e.button !== 0) return\n if (!locked) {\n try {\n const r = (o.dom.requestPointerLock as unknown as (() => Promise<void> | void) | undefined)?.call(o.dom)\n if (r && typeof (r as Promise<void>).catch === 'function') (r as Promise<void>).catch(() => undefined)\n } catch {\n // no pointer lock here: drag to look\n }\n dragging = true\n moved = 0\n downAt = performance.now()\n useStarted = false\n holdTimer = setTimeout(() => {\n if (dragging && moved < 4 && !useStarted) {\n useStarted = true\n o.hooks.primaryDown()\n }\n }, 220)\n return\n }\n useStarted = true\n o.hooks.primaryDown()\n }\n const onMouseUp = (e: MouseEvent): void => {\n if (e.button !== 0) return\n if (holdTimer) clearTimeout(holdTimer)\n if (dragging) {\n dragging = false\n if (!useStarted && moved < 4 && performance.now() - downAt < 400) {\n o.hooks.primaryDown()\n o.hooks.primaryUp()\n } else if (useStarted) o.hooks.primaryUp()\n useStarted = false\n return\n }\n if (useStarted) o.hooks.primaryUp()\n useStarted = false\n }\n const onMouseMove = (e: MouseEvent): void => {\n if (locked) look(e.movementX, e.movementY)\n else if (dragging) {\n moved += Math.abs(e.movementX) + Math.abs(e.movementY)\n if (moved >= 4) {\n if (useStarted) {\n useStarted = false\n o.hooks.primaryUp()\n }\n look(e.movementX, e.movementY)\n }\n }\n }\n const onWheel = (e: WheelEvent): void => {\n e.preventDefault()\n o.hooks.wheel(e.deltaY > 0 ? 1 : -1)\n }\n const typing = (e: Event): boolean => {\n const t = e.target as HTMLElement | null\n return !!t && (t.tagName === 'INPUT' || t.tagName === 'SELECT' || t.tagName === 'TEXTAREA')\n }\n const onKeyDown = (e: KeyboardEvent): void => {\n if (typing(e)) return\n if (e.code === 'Space' || e.code === 'Tab') e.preventDefault()\n if (!e.repeat) keys.add(e.code)\n o.hooks.key(e.code, true, e)\n }\n const onKeyUp = (e: KeyboardEvent): void => {\n keys.delete(e.code)\n if (typing(e)) return\n o.hooks.key(e.code, false, e)\n }\n const onContext = (e: Event): void => e.preventDefault()\n const onBlur = (): void => keys.clear()\n\n o.dom.addEventListener('mousedown', onMouseDown)\n window.addEventListener('mouseup', onMouseUp)\n window.addEventListener('mousemove', onMouseMove)\n o.dom.addEventListener('wheel', onWheel, { passive: false })\n o.dom.addEventListener('contextmenu', onContext)\n document.addEventListener('pointerlockchange', onLockChange)\n window.addEventListener('keydown', onKeyDown)\n window.addEventListener('keyup', onKeyUp)\n window.addEventListener('blur', onBlur)\n\n return {\n get yaw() {\n return yaw\n },\n get pitch() {\n return pitch\n },\n get locked() {\n return locked\n },\n keys,\n update(dt) {\n const run = keys.has('ShiftLeft') || keys.has('ShiftRight')\n const speed = run ? RUN : WALK\n let f = 0\n let r = 0\n if (keys.has('KeyW') || keys.has('ArrowUp')) f += 1\n if (keys.has('KeyS') || keys.has('ArrowDown')) f -= 1\n if (keys.has('KeyD') || keys.has('ArrowRight')) r += 1\n if (keys.has('KeyA') || keys.has('ArrowLeft')) r -= 1\n if ((f || r || keys.has('Space')) && eye !== EYE) eye = EYE\n if (f || r) {\n const len = Math.hypot(f, r)\n const fx = -Math.sin(yaw)\n const fz = -Math.cos(yaw)\n const rx = Math.cos(yaw)\n const rz = -Math.sin(yaw)\n move(((fx * f + rx * r) / len) * speed * dt, ((fz * f + rz * r) / len) * speed * dt)\n }\n if (y <= 0 && keys.has('Space')) vy = JUMP\n if (y > 0 || vy > 0) {\n vy -= GRAVITY * dt\n y += vy * dt\n if (y <= 0) {\n y = 0\n vy = 0\n }\n }\n apply()\n },\n setPose(position, yw, pt) {\n px.x = position[0]\n px.z = position[2]\n eye = position[1]\n y = 0\n vy = 0\n yaw = yw\n pitch = pt\n apply()\n },\n look(position, target) {\n px.x = position[0]\n px.z = position[2]\n eye = position[1]\n y = 0\n vy = 0\n const dx = target[0] - position[0]\n const dy = target[1] - position[1]\n const dz = target[2] - position[2]\n yaw = Math.atan2(-dx, -dz)\n pitch = Math.atan2(dy, Math.hypot(dx, dz))\n apply()\n },\n kick(pitchDeg, yawDeg) {\n pitch = Math.max(-1.5, Math.min(1.5, pitch + (pitchDeg * Math.PI) / 180))\n yaw += (yawDeg * Math.PI) / 180\n apply()\n },\n moveBy(dx, dz) {\n move(dx, dz)\n apply()\n },\n walk(forward, right) {\n move(-Math.sin(yaw) * forward + Math.cos(yaw) * right, -Math.cos(yaw) * forward - Math.sin(yaw) * right)\n apply()\n },\n dispose() {\n if (holdTimer) clearTimeout(holdTimer)\n o.dom.removeEventListener('mousedown', onMouseDown)\n window.removeEventListener('mouseup', onMouseUp)\n window.removeEventListener('mousemove', onMouseMove)\n o.dom.removeEventListener('wheel', onWheel)\n o.dom.removeEventListener('contextmenu', onContext)\n document.removeEventListener('pointerlockchange', onLockChange)\n window.removeEventListener('keydown', onKeyDown)\n window.removeEventListener('keyup', onKeyUp)\n window.removeEventListener('blur', onBlur)\n if (document.pointerLockElement === o.dom) document.exitPointerLock?.()\n },\n }\n}\n","import { JOINT_DEFAULTS, rotateVec, toWorld } from '@adatechnology/game-destruction'\nimport type { Vec3 } from '@adatechnology/game-destruction'\nimport { resolveStrings } from './locale'\nimport type { ScenarioContext, TestRoom, TestRoomScenario } from './types'\n\ntype T = (key: string, vars?: Record<string, string | number>) => string\ntype Num = (n: number, digits?: number) => string\n\n/** Built-in scripted checks over the generic `DEMO_ITEMS`. Names and check texts come from the room locale. */\nexport function makeScenarios(t: T, num: Num, _locale = 'en'): TestRoomScenario[] {\n const yn = (b: boolean): string => t(b ? 'yes' : 'no')\n const cn = (what: string, n: number): string => t(`count.${what}.${n === 1 ? 'one' : 'other'}`, { n })\n const pc = (n: number): string => t(n === 1 ? 'count.piece.one' : 'count.piece.other', { n })\n const sc = (id: string, run: (c: ScenarioContext) => void | Promise<void>): TestRoomScenario => ({ id, name: t(`sc.${id}`), run })\n\n const at = (room: TestRoom, itemId: string, x: number, z: number, y = 0, rot = 0): string => room.spawn(itemId, [x, y, z], rot).objectId\n const look = (room: TestRoom, from: Vec3, to: Vec3): void => room.look(from, to)\n const part = (room: TestRoom, id: string, p: string) => room.world.part(id, p)\n const count = (room: TestRoom, type: string, objectId?: string): number => room.log.entries({ type, objectId }).length\n const anyBurning = (room: TestRoom, id: string): boolean => (room.world.state(id)?.parts ?? []).some((p) => p.burning)\n const igniteHit = (room: TestRoom, id: string, point: Vec3, temperature = 900, seconds = 3): void => {\n room.world.hit(id, { type: 'fire', point, temperature, radius: 0.6, duration: seconds })\n }\n\n // columns of the demo `building_frame` placed at (0, 0, -6): x = -2 / 2, z = -8 / -4\n const COLUMN: Record<string, Vec3> = { column_0_0_0: [-2, 1.4, -8], column_0_1_0: [2, 1.4, -8], column_0_0_1: [-2, 1.4, -4], column_0_1_1: [2, 1.4, -4] }\n const killColumns = (room: TestRoom, id: string, ids: string[]): void => {\n for (const c of ids) room.world.hitPart(id, c, { type: 'blunt', point: COLUMN[c], energy: 3e6, radius: 0.05, source: 'test' })\n }\n const heavyCollapse = (room: TestRoom): number => room.log.entries({ type: 'collapse' }).reduce((m, e) => Math.max(m, Number(e.data?.massKg ?? 0)), 0)\n\n return [\n sc('steel_through_hole', ({ room, step, expect }) => {\n const id = at(room, 'steel_sheet', 0, -4)\n room.setTool('pistol_9mm')\n look(room, [0, 1.1, -1.5], [0, 1.1, -4])\n room.use()\n step(0.2)\n const p = part(room, id, 'sheet')\n const hole = p?.holes[0]\n expect(\n !!hole?.through,\n t('sc.steel_through_hole.check', { mm: num((hole?.diameter ?? 0) * 1000, 0), through: yn(!!hole?.through), holes: p?.holes.length ?? 0, hp: `${num(p?.hp ?? 0, 0)}/${num(p?.maxHp ?? 0, 0)}` }),\n { holes: p?.holes.length, through: hole?.through },\n )\n }),\n\n sc('concrete_stops_bullet', ({ room, step, expect }) => {\n const id = at(room, 'concrete_block', 0, -4)\n room.setTool('pistol_9mm')\n look(room, [0, 0.5, -1.5], [0, 0.2, -3.8])\n room.use()\n step(0.2)\n const p = part(room, id, 'block')\n const wall = part(room, 'target_wall', 'brick_1_4')\n const through = p?.holes.some((h) => h.through) ?? true\n expect(\n !through && (p?.holes.length ?? 0) + (p?.dents.length ?? 0) + (p?.cracks.length ?? 0) > 0 && (wall?.holes.length ?? 0) === 0,\n t('sc.concrete_stops_bullet.check', { through: yn(through), dents: cn('dent', p?.dents.length ?? 0), holes: cn('hole', p?.holes.length ?? 0), cracks: cn('crack', p?.cracks.length ?? 0), hp: `${num(p?.hp ?? 0, 0)}/${num(p?.maxHp ?? 0, 0)}` }),\n { through },\n )\n }),\n\n sc('hammer_dents_drum', ({ room, step, expect }) => {\n const id = at(room, 'steel_drum', 0, -4)\n room.setTool('hammer')\n look(room, [0, 0.6, -3.35], [0, 0.5, -4])\n let swings = 0\n for (; swings < 8 && (part(room, id, 'drum_body')?.dents.length ?? 0) === 0; swings++) {\n room.use()\n step(1)\n }\n const p = part(room, id, 'drum_body')\n expect(\n (p?.dents.length ?? 0) > 0 && p?.status !== 'broken',\n t('sc.hammer_dents_drum.check', { swings, dents: p?.dents.length ?? 0, depth: num((p?.dents[0]?.depth ?? 0) * 1000, 1), hp: `${num(p?.hp ?? 0, 0)}/${num(p?.maxHp ?? 0, 0)}` }),\n { swings },\n )\n }),\n\n sc('glass_shatters', ({ room, step, expect }) => {\n const id = at(room, 'glass_pane', 0, -4)\n room.setTool('pistol_9mm')\n look(room, [0, 1.3, -1.5], [0, 1.05, -4])\n let shots = 0\n for (; shots < 10 && part(room, id, 'pane')?.status !== 'broken'; shots++) {\n room.use()\n step(0.25)\n }\n step(0.5)\n const fr = room.log.entries({ type: 'fracture', objectId: id }).find((e) => e.part === 'pane')\n const n = Number(fr?.data?.fragments ?? 0)\n expect(part(room, id, 'pane')?.status === 'broken' && shots === 1 && n >= 4, t('sc.glass_shatters.check', { shots, n }), { shots, fragments: n })\n }),\n\n sc('shotgun_splinters_crate', ({ room, step, expect }) => {\n const id = at(room, 'wooden_crate', 0, -4)\n room.setTool('shotgun_pump_12')\n look(room, [0, 0.6, -1.8], [0, 0.25, -3.77])\n let shots = 0\n const splinters = (): number => room.log.entries({ type: 'fracture', objectId: id }).filter((e) => e.data?.style === 'splinter').length\n for (; shots < 4 && splinters() === 0; shots++) {\n room.use()\n step(1.1)\n }\n const holes = (room.world.state(id)?.parts ?? []).reduce((n, p) => n + p.holes.length, 0)\n expect(splinters() > 0, t('sc.shotgun_splinters_crate.check', { shots, splinters: splinters(), holes }), { shots })\n }),\n\n sc('kick_chair_leg', ({ room, step, expect }) => {\n const id = at(room, 'chair', 0, -4)\n const before = room.renderer.pieces().length\n const leg = part(room, id, 'leg_1')\n void leg\n let kicks = 0\n for (; kicks < 6 && room.renderer.pieces().length <= before && part(room, id, 'leg_1'); kicks++) {\n room.world.hitPart(id, 'leg_1', { type: 'blunt', point: [-0.18, 0.2, -4.18], direction: [1, 0, 0], energy: 220, radius: 0.05, source: 'kick' })\n step(0.3)\n }\n step(0.5)\n const after = room.renderer.pieces().length\n const groups = room.world.state(id)?.groups.length ?? 1\n expect(\n after > before,\n t('sc.kick_chair_leg.check', { kicks, groups, before, after, leg: part(room, id, 'leg_1') ? t('leg.still') : t('leg.gone') }),\n { kicks, before, after },\n )\n }),\n\n sc('kick_detaches_leg_via_tool', ({ room, step, expect }) => {\n const id = at(room, 'chair', 0, -4)\n const before = room.renderer.pieces().length\n room.setTool('kick')\n let kicks = 0\n for (; kicks < 8 && room.renderer.pieces().length <= before && part(room, id, 'leg_1'); kicks++) {\n // the chair moves when it is kicked: aim at the leg where it is now, from the side\n const st = room.world.state(id)!\n const leg = toWorld(st.position, st.rotation, [-0.18, 0.2, -0.18])\n const side = rotateVec(st.rotation, [-0.8, 0, 0])\n look(room, [leg[0] + side[0], leg[1] + side[1], leg[2] + side[2]], leg)\n room.use()\n step(1.05)\n }\n step(0.5)\n const after = room.renderer.pieces().length\n expect(after > before, t('sc.kick_detaches_leg_via_tool.check', { kicks, before, after, leg: part(room, id, 'leg_1') ? t('leg.still') : t('leg.gone') }), { kicks, before, after })\n }),\n\n sc('screwdriver_shelf_board', ({ room, step, expect }) => {\n const id = at(room, 'shelf', 0, -4)\n room.setTool('screwdriver')\n look(room, [0, 0.8, -3.5], [0, 0.75, -3.86])\n const t0 = room.log.entries().length ? room.log.entries().slice(-1)[0].t : 0\n room.use(5)\n const done = room.log.entries({ type: 'detach', objectId: id })[0]\n const elapsed = done ? done.t - t0 : 5\n const want = JOINT_DEFAULTS.screw.seconds\n const groups = room.renderer.pieces().length\n expect(!!done && Math.abs(elapsed - want) < 0.6 && groups >= 1, t('sc.screwdriver_shelf_board.check', { secs: num(elapsed, 1), want: num(want, 1), pieces: pc(groups) }), { elapsed, want })\n step(0.2)\n }),\n\n sc('wrong_tool_refused', ({ room, expect }) => {\n const id = at(room, 'steel_sheet', 0, -4)\n room.setTool('screwdriver')\n look(room, [0.2, 1.05, -3.6], [0.34, 1.0, -4])\n room.use(0.5)\n const refused = count(room, 'tool_refused')\n const opened = (room.world.state(id)?.joints ?? []).filter((j) => j.open).length\n expect(refused > 0 && opened === 0, t('sc.wrong_tool_refused.check', { refused, opened }), { refused, opened })\n }),\n\n sc('lighter_burns_crate', ({ room, step, expect }) => {\n const id = at(room, 'wooden_crate', 0, -4)\n room.setTool('lighter')\n look(room, [0, 0.3, -3.65], [0, 0.25, -3.76])\n room.use(5)\n const lit = anyBurning(room, id)\n expect(lit, t('sc.lighter_burns_crate.lit', { lit: yn(lit) }))\n step(500)\n const parts = room.world.state(id)?.parts ?? []\n const ash = parts.filter((p) => p.status === 'ashes').length\n const charred = Math.max(...parts.map((p) => p.char))\n expect(ash === parts.length || (ash > 0 && parts.every((p) => p.status === 'ashes' || p.status === 'broken' || p.char > 0.8)), t('sc.lighter_burns_crate.ash', { ash, total: parts.length, char: num(charred * 100, 0) }), { ash, total: parts.length })\n }),\n\n sc('torch_melts_steel', ({ room, step, expect }) => {\n const drum = at(room, 'steel_drum', 0, -4)\n const crate = at(room, 'wooden_crate', 0.7, -4)\n igniteHit(room, crate, [0.7, 0.25, -3.8], 900, 2)\n let peak = 0\n for (let i = 0; i < 40; i++) {\n step(1)\n peak = Math.max(peak, part(room, drum, 'drum_body')?.temperature ?? 0)\n }\n const melt0 = part(room, drum, 'drum_body')?.melt ?? 0\n expect(melt0 === 0 && peak < 1450, t('sc.torch_melts_steel.wood', { peak: num(peak, 0), melt: num(melt0 * 100, 0), crate: yn(anyBurning(room, crate)) }), { peak })\n room.setTool('cutting_torch')\n look(room, [-0.15, 0.55, -3.55], [-0.15, 0.5, -3.72])\n room.use(20)\n const p = part(room, drum, 'drum_body')\n expect((p?.melt ?? 0) > 0.02 || p?.status === 'melted' || (p?.holes.length ?? 0) > 0, t('sc.torch_melts_steel.torch', { temp: num(p?.temperature ?? 0, 0), melt: num((p?.melt ?? 0) * 100, 0) }), { temperature: p?.temperature, melt: p?.melt })\n }),\n\n sc('bucket_melts_drips', ({ room, step, expect }) => {\n const id = at(room, 'plastic_bucket', 0, -4)\n room.setTool('flamethrower')\n look(room, [0, 0.5, -2.4], [0, 0.15, -4])\n room.use(2.5)\n step(10)\n const p = part(room, id, 'bucket_body')\n const drips = count(room, 'drip', id)\n expect((p?.melt ?? 0) > 0.05 || p?.status === 'melted', t('sc.bucket_melts_drips.check', { melt: num((p?.melt ?? 0) * 100, 0), drips, temp: num(p?.temperature ?? 0, 0) }), { melt: p?.melt, drips })\n }),\n\n sc('gas_bottle_explodes', ({ room, step, expect }) => {\n const bottle = at(room, 'gas_bottle', 0, -4)\n const crate = at(room, 'wooden_crate', 1.3, -4)\n const c0 = room.spawned().find((s) => s.objectId === crate)?.root.position.clone()\n let seconds = 0\n for (; seconds < 60 && count(room, 'explode', bottle) === 0; seconds++) {\n igniteHit(room, bottle, [0, 0.4, -3.9], 1000, 1)\n step(1)\n }\n step(1.5)\n const c1 = room.spawned().find((s) => s.objectId === crate)?.root.position\n const moved = c0 && c1 ? c0.distanceTo(c1) : 0\n const state = room.world.state(crate)\n const lost = (state?.parts ?? []).filter((p) => p.status === 'broken').length + (state && state.groups.length > 1 ? 1 : 0)\n expect(count(room, 'explode', bottle) > 0, t('sc.gas_bottle_explodes.explode', { seconds }), { seconds })\n expect(moved > 0.3 || lost > 0, t('sc.gas_bottle_explodes.push', { moved: num(moved, 1), lost: pc(lost) }), { moved, lost })\n }),\n\n sc('bottle_drop_shatters', ({ room, step, expect }) => {\n const id = at(room, 'glass_bottle', 0, -3, 1.5)\n step(2)\n const p = part(room, id, 'bottle_body')\n const stain = room.fluids.stains().find((s) => s.liquid === 'water')\n expect(p?.status === 'broken', t('sc.bottle_drop_shatters.check', { status: p?.status ?? '?', cracks: p?.cracks.length ?? 0, stain: yn(!!stain) }), { status: p?.status })\n }),\n\n sc('throw_chair_at_wall', ({ room, step, expect }) => {\n const id = at(room, 'chair', 0, -5.2)\n look(room, [0, 1.7, -4.2], [0, 0.35, -5.2])\n room.grab()\n look(room, [0, 1.7, -4.2], [0, 2.3, -11])\n step(0.3)\n room.throwHeld(16)\n step(2.5)\n const hits = room.log.entries({ type: 'impact' })\n const wallDamage = room.log.entries().filter((e) => e.objectId === 'target_wall' && (e.type === 'dent' || e.type === 'damage' || e.type === 'crack' || e.type === 'fracture')).length\n expect(hits.length > 0 && wallDamage > 0, t('sc.throw_chair_at_wall.check', { impacts: hits.length, wall: wallDamage, energy: num(Number(hits[0]?.data?.energyJ ?? 0), 0) }), { id })\n }),\n\n sc('coffee_three_sips', ({ room, step, expect }) => {\n const id = at(room, 'coffee_cup', 0, -3)\n look(room, [0, 1.0, -1.8], [0, 0.05, -3])\n const cid = `${id}_fluid`\n const before = room.fluids.container(cid)?.liters ?? 0\n room.grab()\n for (let i = 0; i < 3; i++) {\n room.useItem('sip')\n step(1.4)\n }\n const after = room.fluids.container(cid)?.liters ?? 0\n const drinks = room.log.entries().filter((e) => e.type === 'fluid.drink')\n const caffeine = drinks.some((e) => Array.isArray(e.data?.effects) && (e.data?.effects as string[]).includes('caffeine'))\n expect(drinks.length === 3 && before - after > 0.06 && caffeine, t('sc.coffee_three_sips.check', { sips: drinks.length, before: num(before, 2), after: num(after, 2), caffeine: yn(caffeine), burn: yn(drinks.some((e) => !!e.data?.burn)) }), { before, after })\n }),\n\n sc('tilt_cup_spills', ({ room, step, expect }) => {\n const id = at(room, 'coffee_cup', 0, -3)\n look(room, [0, 1.0, -1.8], [0, 0.05, -3])\n const cid = `${id}_fluid`\n const before = room.fluids.container(cid)?.liters ?? 0\n room.grab()\n step(0.6)\n room.tilt(2.0)\n step(2.5)\n const after = room.fluids.container(cid)?.liters ?? 0\n const stains = room.fluids.stains().filter((s) => s.liquid === 'coffee').length\n expect(before - after > 0.03 && stains > 0, t('sc.tilt_cup_spills.check', { before: num(before, 2), after: num(after, 2), stains }), { before, after })\n }),\n\n sc('jerrycan_leaks_fuel', ({ room, step, expect }) => {\n const id = at(room, 'jerrycan', 0, -3.5)\n room.setTool('pistol_9mm')\n look(room, [0, 0.4, -1.5], [0, 0.12, -3.43])\n room.use()\n step(1.5)\n const streams = room.fluids.streams().filter((s) => s.cause === 'leak' && s.liquid === 'fuel')\n step(5)\n const stain = room.fluids.stains().find((s) => s.liquid === 'fuel')\n const left = room.fluids.container(`${id}_fluid`)?.liters ?? 20\n const hole = room.log.entries({ type: 'hole', objectId: id })[0]\n expect(streams.length > 0 && !!stain && left < 20, t('sc.jerrycan_leaks_fuel.check', { streams: streams.length, stain: yn(!!stain), left: num(left, 2), leak: hole?.data?.leak ? yn(true) : yn(false) }), { left })\n }),\n\n sc('fuel_stain_burns', ({ room, step, expect }) => {\n const id = at(room, 'jerrycan', 0, -3.5)\n const crate = at(room, 'wooden_crate', 0.9, -3.2)\n room.setTool('pistol_9mm')\n look(room, [0, 0.4, -1.5], [0, 0.12, -3.43])\n room.use()\n step(6)\n const stain = room.fluids.stains().find((s) => s.liquid === 'fuel')\n expect(!!stain, t('sc.fuel_stain_burns.stain', { stain: yn(!!stain) }))\n if (!stain) return\n room.setTool('lighter')\n look(room, [stain.center[0], 0.1, stain.center[2] + 0.06], [stain.center[0], 0, stain.center[2]])\n room.use(1)\n step(4)\n const ignited = count(room, 'stain_ignite')\n const fireHits = (room.world.state(id)?.parts ?? []).some((p) => p.burning || p.temperature > 100) || anyBurning(room, crate)\n expect(ignited > 0, t('sc.fuel_stain_burns.ignite', { ignited, near: yn(fireHits) }), { ignited })\n step(30)\n expect(count(room, 'stain_burned') > 0 || room.fluids.stains().filter((s) => s.liquid === 'fuel' && s.wetness > 0.05).length === 0, t('sc.fuel_stain_burns.out', { burned: count(room, 'stain_burned') }))\n }),\n\n sc('one_column_roof_stands', ({ room, step, expect }) => {\n const id = at(room, 'building_frame', 0, -6)\n killColumns(room, id, ['column_0_0_0'])\n step(40)\n const roof = part(room, id, 'roof')\n const neighbour = (part(room, id, 'column_0_0_1') as unknown as { stress?: number } | null)?.stress ?? 0\n const heavy = Math.max(heavyCollapse(room), ...room.renderer.pieces().map((p) => p.mass))\n expect(!!roof && roof.status !== 'broken' && heavy < 2000, t('sc.one_column_roof_stands.check', { roof: roof ? t('roof.standing') : t('roof.fell'), heavy: num(heavy, 0), stress: num(neighbour * 100, 0) }), { heavy, neighbour })\n }),\n\n sc('two_columns_roof_collapses', ({ room, step, expect }) => {\n const id = at(room, 'building_frame', 0, -6)\n killColumns(room, id, ['column_0_0_0', 'column_0_1_0'])\n const stress0 = (room.world.part(id, 'column_0_0_1') as unknown as { stress?: number } | null)?.stress ?? 0\n step(40)\n const pieces = room.renderer.pieces().filter((p) => p.mass >= 2000)\n const logged = heavyCollapse(room) >= 2000\n const kg = pieces.reduce((m, p) => m + p.mass, 0)\n expect(!part(room, id, 'roof') && pieces.length > 0, t('sc.two_columns_roof_collapses.check', { stress: num(stress0 * 100, 0), pieces: pc(pieces.length), kg: num(kg, 0), logged: yn(logged) }), { kg, logged })\n }),\n\n sc('extinguisher_puts_out_fire', ({ room, step, expect }) => {\n const id = at(room, 'wooden_crate', 0, -4)\n igniteHit(room, id, [0, 0.25, -3.8], 900, 4)\n step(6)\n const before = anyBurning(room, id)\n expect(before, t('sc.extinguisher_puts_out_fire.burning', { burning: yn(before) }))\n room.setTool('extinguisher')\n look(room, [0, 0.9, -2.2], [0, 0.25, -4])\n room.use(2.5)\n step(1)\n const after = anyBurning(room, id)\n expect(!after, t('sc.extinguisher_puts_out_fire.out', { burning: yn(after), events: count(room, 'extinguish', id) }), { events: count(room, 'extinguish', id) })\n }),\n ]\n}\n\nconst makeT =\n (locale: string): T =>\n (key, vars) => {\n let s = resolveStrings(locale).text[key] ?? key\n if (vars) for (const k of Object.keys(vars)) s = s.split(`{${k}}`).join(String(vars[k]))\n return s\n }\n\n/** The built-in scenarios for a locale (`en` or `pt-BR`), standalone: no room needed to list them. */\nexport function scenariosFor(locale = 'en'): TestRoomScenario[] {\n const pt = locale.toLowerCase().startsWith('pt')\n return makeScenarios(makeT(locale), (n, d = 1) => (pt ? (Math.round(n * 10 ** d) / 10 ** d).toFixed(d).replace('.', ',') : (Math.round(n * 10 ** d) / 10 ** d).toFixed(d)), locale)\n}\n\n/** The built-in scenarios in English. The room offers them in its own locale. */\nexport const SCENARIOS: TestRoomScenario[] = scenariosFor('en')\n","import type { WritableLog } from './log'\nimport type { RoomStrings } from './locale'\nimport type { AnimationInfo, LogEntry, ScenarioReport, TestRoomItem, TestRoomScenario } from './types'\n\nexport interface InspectInfo {\n object: string\n objectId: string\n part: string\n material: string\n status: string\n hp: number\n maxHp: number\n temperature: number\n burning: boolean\n char: number\n melt: number\n liters?: number\n dents: number\n holes: number\n cracks: number\n mass: number\n /** Structural load in kg and stress (load / capacity) when the core reports them. */\n load?: number\n stress?: number\n joints: Array<{ id: string; kind: string; tools: string[]; open: boolean; progress: number }>\n note?: string\n distance: number\n}\n\nexport interface HudState {\n toolName: string\n toolId: string\n ammo: string\n slots: string[]\n slot: number\n page: number\n pages: number\n status: string\n progress: { label: string; value: number } | null\n held: { name: string; uses: Array<{ key: string; label: string }>; weapon?: string; using: string } | null\n inspect: InspectInfo | null\n /** Animations of the aimed or held item. */\n animations: AnimationInfo | null\n locked: boolean\n timeScale: number\n fast: boolean\n tap: boolean\n quality: string\n objects: number\n}\n\nexport interface UiOptions {\n container: HTMLElement\n strings: RoomStrings\n t: (key: string, vars?: Record<string, string | number>) => string\n log: WritableLog\n groups: () => Map<string, TestRoomItem[]>\n loadout: () => Array<{ id: string; name: string }>\n onSpawn: (itemId: string) => void\n onEquip: (itemId: string) => void\n onClear: () => void\n onResetAll: () => void\n onSlow: (on: boolean) => void\n onFast: (on: boolean) => void\n onQuality: (q: 'low' | 'medium' | 'high') => void\n quality: 'low' | 'medium' | 'high'\n scenarios: () => TestRoomScenario[]\n onRun: (s: TestRoomScenario) => Promise<ScenarioReport | void>\n onRunAll: () => Promise<ScenarioReport | void>\n onTool: (index: number) => void\n onTap: () => void\n onPlay: (objectId: string, clipId: string) => void\n onResize: () => void\n}\n\nexport interface RoomUi {\n hud(state: HudState): void\n toast(text: string): void\n /** Re-read the catalogue and the scenarios (after `loadModule`). */\n refresh(): void\n togglePanels(): void\n dispose(): void\n}\n\nconst CSS = `\n.tr-root{position:absolute;inset:0;pointer-events:none;font:12px/1.35 system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;color:#e8eaee;overflow:hidden}\n.tr-root *{box-sizing:border-box}\n.tr-root button,.tr-root select,.tr-root label{pointer-events:auto}\n.tr-cross{position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-9px 0 0 -9px}\n.tr-cross:before,.tr-cross:after{content:\"\";position:absolute;background:#fff;opacity:.85;box-shadow:0 0 2px #000}\n.tr-cross:before{left:8px;top:0;width:2px;height:18px}.tr-cross:after{top:8px;left:0;height:2px;width:18px}\n.tr-cross i{position:absolute;left:6px;top:6px;width:6px;height:6px;background:#0b0c0e;border-radius:50%;z-index:1}\n.tr-top{position:absolute;top:8px;left:50%;transform:translateX(-50%);text-align:center;max-width:46vw}\n.tr-tool{display:inline-block;background:rgba(10,12,16,.72);padding:4px 12px;border-radius:6px;font-size:14px;font-weight:600}\n.tr-tool small{font-weight:400;opacity:.8;margin-left:8px}\n.tr-status{margin-top:4px;min-height:16px;color:#ffd23f;text-shadow:0 1px 2px #000}\n.tr-prog{margin:4px auto 0;width:260px;background:rgba(10,12,16,.72);border-radius:6px;padding:4px 8px;display:none}\n.tr-prog b{display:block;font-weight:500;margin-bottom:3px}\n.tr-bar{height:7px;background:#2a2e36;border-radius:4px;overflow:hidden}\n.tr-bar i{display:block;height:100%;background:#4fc3f7;width:0}\n.tr-bar.hp i{background:#66bb6a}.tr-bar.warn i{background:#ffb300}.tr-bar.bad i{background:#ef5350}\n.tr-bottom{position:absolute;bottom:8px;left:50%;transform:translateX(-50%);text-align:center;max-width:56vw}\n.tr-held{margin-bottom:6px;background:rgba(10,12,16,.72);padding:4px 10px;border-radius:6px;display:none}\n.tr-held kbd,.tr-help kbd{background:#2a2e36;border:1px solid #4a505c;border-radius:3px;padding:0 4px;font:inherit;font-weight:700}\n.tr-hotbar{display:inline-flex;gap:3px;flex-wrap:wrap;justify-content:center}\n.tr-slot{pointer-events:auto;min-width:64px;max-width:92px;padding:3px 5px;background:rgba(10,12,16,.68);border:1px solid #3a404c;border-radius:5px;color:#cfd3da;cursor:pointer;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.tr-slot b{color:#ffd23f;margin-right:3px}\n.tr-slot.on{border-color:#ffd23f;color:#fff;background:rgba(60,50,10,.8)}\n.tr-help{position:absolute;left:8px;bottom:8px;max-width:360px;opacity:.75;font-size:11px;background:rgba(10,12,16,.55);padding:4px 8px;border-radius:6px}\n.tr-left{position:absolute;top:8px;left:8px;bottom:70px;width:min(400px,36vw);display:flex;flex-direction:column;gap:8px}\n.tr-right{position:absolute;top:8px;right:8px;bottom:8px;width:min(310px,34vw);display:flex;flex-direction:column;gap:8px}\n.tr-panel{background:rgba(12,14,19,.82);border:1px solid #2c313b;border-radius:8px;padding:8px;pointer-events:auto;overflow:auto}\n.tr-panel h3{margin:0 0 6px;font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:#9aa3b2;font-weight:600}\n.tr-insp{flex:0 0 auto;max-height:46%;min-height:60px}\n.tr-insp .r{display:flex;justify-content:space-between;gap:8px}.tr-insp .r span:first-child{color:#9aa3b2}\n.tr-insp .t{font-weight:600;font-size:13px;margin-bottom:3px}\n.tr-log{flex:1 1 auto;display:flex;flex-direction:column;min-height:120px;overflow:hidden}\n.tr-logbar{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:5px;align-items:center}\n.tr-logbody{flex:1;overflow:auto;font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;background:#090a0d;border-radius:5px;padding:4px 6px}\n.tr-logbody div{white-space:pre-wrap;word-break:break-word;border-bottom:1px solid #15171c}\n.tr-logbody .action{color:#8fd3ff}.tr-logbody .event{color:#dfe3ea}.tr-logbody .check{color:#c8e6c9}.tr-logbody .check.fail{color:#ff8a80;font-weight:700}.tr-logbody .check.pass{color:#9be59f}\n.tr-logbody time{color:#6b7280;margin-right:6px}\n.tr-btn,.tr-root button.tr-btn{background:#232831;border:1px solid #3a404c;color:#e8eaee;border-radius:5px;padding:3px 8px;cursor:pointer;font:inherit}\n.tr-btn:hover{background:#2d3440}.tr-btn.on{background:#3b3a14;border-color:#ffd23f;color:#fff}\n.tr-btn.pass{border-color:#4caf50}.tr-btn.fail{border-color:#ef5350;background:#3a1d1d}\n.tr-tabs{display:flex;flex-wrap:wrap;gap:3px;margin-bottom:6px}\n.tr-items{display:grid;grid-template-columns:1fr 1fr;gap:4px}\n.tr-item{display:flex;gap:2px}.tr-item .tr-btn:first-child{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.tr-cat{flex:0 1 auto;max-height:40%}\n.tr-anim{flex:0 0 auto;max-height:18%}\n.tr-anim .list{display:flex;flex-wrap:wrap;gap:4px}.tr-anim .sub{color:#9aa3b2;margin-bottom:4px}\n.tr-tests{flex:1 1 auto;min-height:100px}\n.tr-tests .list{display:flex;flex-direction:column;gap:3px;margin-top:6px}.tr-tests .list .tr-btn{text-align:left}\n.tr-row{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px;align-items:center}\n.tr-toggle{position:absolute;top:8px;right:8px;display:none}\n.tr-summary{margin-top:6px;color:#9aa3b2}\n@media (max-width:980px){.tr-left,.tr-right{display:none}.tr-root.open .tr-left,.tr-root.open .tr-right{display:flex}.tr-toggle{display:block;pointer-events:auto}.tr-root.open .tr-toggle{right:min(310px,34vw)}.tr-left{width:min(400px,46vw)}.tr-help{display:none}}\n`\n\nconst mk = <K extends keyof HTMLElementTagNameMap>(tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] => {\n const e = document.createElement(tag)\n if (cls) e.className = cls\n if (text !== undefined) e.textContent = text\n return e\n}\n\nexport function createUi(o: UiOptions): RoomUi {\n const { t } = o\n const style = mk('style')\n style.textContent = CSS\n const root = mk('div', 'tr-root')\n const pos = getComputedStyle?.(o.container)?.position\n if (!pos || pos === 'static') o.container.style.position = 'relative'\n root.appendChild(style)\n o.container.appendChild(root)\n\n // crosshair, top bar\n const cross = mk('div', 'tr-cross')\n cross.appendChild(mk('i'))\n const top = mk('div', 'tr-top')\n const toolBox = mk('div', 'tr-tool')\n const status = mk('div', 'tr-status')\n const prog = mk('div', 'tr-prog')\n const progLabel = mk('b')\n const progBar = mk('div', 'tr-bar')\n const progFill = mk('i')\n progBar.appendChild(progFill)\n prog.append(progLabel, progBar)\n top.append(toolBox, status, prog)\n\n // bottom: held hint and hotbar\n const bottom = mk('div', 'tr-bottom')\n const held = mk('div', 'tr-held')\n const hotbar = mk('div', 'tr-hotbar')\n bottom.append(held, hotbar)\n const help = mk('div', 'tr-help')\n help.textContent = t('ui.help')\n\n // left: inspector + log\n const left = mk('div', 'tr-left')\n const insp = mk('div', 'tr-panel tr-insp')\n const logPanel = mk('div', 'tr-panel tr-log')\n left.append(insp, logPanel)\n\n // log panel\n const logTitle = mk('h3', undefined, t('ui.log'))\n const logBar = mk('div', 'tr-logbar')\n const logBody = mk('div', 'tr-logbody')\n const filters: Record<LogEntry['channel'], boolean> = { action: true, event: true, check: true }\n const filterBtns: HTMLButtonElement[] = []\n for (const ch of ['action', 'event', 'check'] as const) {\n const b = mk('button', 'tr-btn on', t(`ui.filter.${ch}`))\n b.type = 'button'\n b.onclick = () => {\n filters[ch] = !filters[ch]\n b.classList.toggle('on', filters[ch])\n rebuildLog()\n }\n filterBtns.push(b)\n logBar.appendChild(b)\n }\n let autoscroll = true\n const asLabel = mk('label')\n const asBox = mk('input')\n asBox.type = 'checkbox'\n asBox.checked = true\n asBox.onchange = () => {\n autoscroll = asBox.checked\n }\n asLabel.append(asBox, document.createTextNode(' ' + t('ui.autoscroll')))\n logBar.appendChild(asLabel)\n const logBtn = (label: string, fn: () => void): void => {\n const b = mk('button', 'tr-btn', label)\n b.type = 'button'\n b.onclick = fn\n logBar.appendChild(b)\n }\n logBtn(t('ui.copy_json'), () => {\n const text = o.log.toJSON()\n // no clipboard API (an Artifact iframe, file://): select the text in a textarea and ask the browser to copy it, leaving it selected\n const select = (): void => {\n const ta = mk('textarea')\n ta.value = text\n ta.setAttribute('readonly', '')\n ta.style.cssText = 'position:fixed;left:8px;bottom:8px;width:min(480px,80vw);height:120px;z-index:99999'\n document.body.appendChild(ta)\n ta.focus()\n ta.select()\n let copied = false\n try {\n copied = !!document.execCommand?.('copy')\n } catch {\n copied = false\n }\n if (copied) ta.remove()\n else ta.onblur = () => ta.remove()\n }\n if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) navigator.clipboard.writeText(text).catch(select)\n else select()\n })\n logBtn(t('ui.download_ndjson'), () => o.log.download('ndjson'))\n logBtn(t('ui.download_txt'), () => o.log.download('txt'))\n logBtn(t('ui.clear_log'), () => {\n o.log.clear()\n logBody.textContent = ''\n nodes.clear()\n })\n logPanel.append(logTitle, logBar, logBody)\n\n const MAX_LINES = 200\n const nodes = new Map<number, HTMLElement>()\n const fmtTime = (s: number): string => `${Math.floor(s / 60)\n .toString()\n .padStart(2, '0')}:${(s % 60).toFixed(1).padStart(4, '0')}`\n const lineClass = (e: LogEntry): string => `${e.channel}${e.type === 'fail' || e.type === 'scenario_fail' ? ' fail' : e.type === 'pass' || e.type === 'scenario_pass' ? ' pass' : ''}`\n const fill = (n: HTMLElement, e: LogEntry): void => {\n n.className = lineClass(e)\n n.textContent = ''\n const tm = mk('time', undefined, fmtTime(e.t))\n n.append(tm, document.createTextNode(e.text))\n }\n const addNode = (e: LogEntry): void => {\n if (!filters[e.channel]) return\n const n = mk('div')\n fill(n, e)\n nodes.set(e.seq, n)\n logBody.appendChild(n)\n while (logBody.childElementCount > MAX_LINES) {\n const first = logBody.firstElementChild as HTMLElement\n for (const [k, v] of nodes) if (v === first) nodes.delete(k)\n first.remove()\n }\n if (autoscroll) logBody.scrollTop = logBody.scrollHeight\n }\n function rebuildLog(): void {\n logBody.textContent = ''\n nodes.clear()\n for (const e of o.log.entries().slice(-MAX_LINES * 3)) addNode(e)\n }\n const offLog = o.log.on((e, updated) => {\n if (updated) {\n const n = nodes.get(e.seq)\n if (n) fill(n, e)\n } else addNode(e)\n })\n\n // right: catalogue and tests\n const right = mk('div', 'tr-right')\n const cat = mk('div', 'tr-panel tr-cat')\n const anim = mk('div', 'tr-panel tr-anim')\n const tests = mk('div', 'tr-panel tr-tests')\n right.append(cat, anim, tests)\n\n cat.appendChild(mk('h3', undefined, t('ui.catalog')))\n const tabs = mk('div', 'tr-tabs')\n const items = mk('div', 'tr-items')\n cat.append(tabs, items)\n let activeGroup = ''\n const renderItems = (): void => {\n items.textContent = ''\n for (const it of o.groups().get(activeGroup) ?? []) {\n const wrap = mk('div', 'tr-item')\n const b = mk('button', 'tr-btn', it.name)\n b.type = 'button'\n b.title = it.note ?? it.name\n b.onclick = () => o.onSpawn(it.id)\n wrap.appendChild(b)\n if (it.weapon) {\n const w = mk('button', 'tr-btn', '⚔')\n w.type = 'button'\n w.title = t('ui.equip')\n w.onclick = () => o.onEquip(it.id)\n wrap.appendChild(w)\n }\n items.appendChild(wrap)\n }\n }\n const renderTabs = (): void => {\n tabs.textContent = ''\n const groupNames = [...o.groups().keys()]\n if (!groupNames.includes(activeGroup)) activeGroup = groupNames[0] ?? ''\n for (const g of groupNames) {\n const b = mk('button', g === activeGroup ? 'tr-btn on' : 'tr-btn', g)\n b.type = 'button'\n b.onclick = () => {\n activeGroup = g\n renderTabs()\n }\n tabs.appendChild(b)\n }\n renderItems()\n }\n renderTabs()\n\n const controls = mk('div', 'tr-row')\n const ctl = (label: string, fn: (b: HTMLButtonElement) => void): HTMLButtonElement => {\n const b = mk('button', 'tr-btn', label)\n b.type = 'button'\n b.onclick = () => fn(b)\n controls.appendChild(b)\n return b\n }\n ctl(t('ui.clear'), () => o.onClear())\n ctl(t('ui.reset_all'), () => o.onResetAll())\n let slow = false\n ctl(t('ui.slow'), (b) => {\n slow = !slow\n b.classList.toggle('on', slow)\n o.onSlow(slow)\n })\n let fast = false\n ctl(t('ui.fast'), (b) => {\n fast = !fast\n b.classList.toggle('on', fast)\n o.onFast(fast)\n })\n const tapBtn = ctl(t('ui.tap'), () => o.onTap())\n const qSel = mk('select')\n for (const q of ['low', 'medium', 'high'] as const) {\n const op = mk('option', undefined, t(`ui.quality.${q}`))\n op.value = q\n qSel.appendChild(op)\n }\n qSel.value = o.quality\n qSel.onchange = () => o.onQuality(qSel.value as 'low' | 'medium' | 'high')\n const qLabel = mk('label', undefined, t('ui.quality') + ' ')\n qLabel.appendChild(qSel)\n controls.appendChild(qLabel)\n const count = mk('span')\n controls.appendChild(count)\n cat.appendChild(controls)\n\n // tests\n tests.appendChild(mk('h3', undefined, t('ui.tests')))\n const runAll = mk('button', 'tr-btn', t('ui.run_all'))\n runAll.type = 'button'\n const summary = mk('div', 'tr-summary')\n const list = mk('div', 'list')\n tests.append(runAll, summary, list)\n const scBtns = new Map<string, HTMLButtonElement>()\n let busy = false\n const mark = (rep: ScenarioReport | void): void => {\n if (!rep) return\n for (const r of rep.results) {\n const b = scBtns.get(r.id)\n if (!b) continue\n b.classList.remove('pass', 'fail')\n b.classList.add(r.ok ? 'pass' : 'fail')\n b.textContent = `${r.ok ? '✓' : '✗'} ${r.name}`\n }\n summary.textContent = t('ui.report', { passed: rep.passed, failed: rep.failed })\n }\n const renderScenarios = (): void => {\n list.textContent = ''\n scBtns.clear()\n for (const s of o.scenarios()) {\n const b = mk('button', 'tr-btn', s.name)\n b.type = 'button'\n b.onclick = async () => {\n if (busy) return\n busy = true\n try {\n mark(await o.onRun(s))\n } finally {\n busy = false\n }\n }\n scBtns.set(s.id, b)\n list.appendChild(b)\n }\n }\n renderScenarios()\n runAll.onclick = async () => {\n if (busy) return\n busy = true\n summary.textContent = t('ui.running')\n try {\n mark(await o.onRunAll())\n } finally {\n busy = false\n }\n }\n\n const toggle = mk('button', 'tr-btn tr-toggle', t('ui.panel'))\n toggle.type = 'button'\n const togglePanels = (): void => {\n root.classList.toggle('open')\n o.onResize()\n }\n toggle.onclick = togglePanels\n\n root.append(cross, top, bottom, help, left, right, toggle)\n\n // inspector\n const bar = (value: number, max: number, cls: string): HTMLElement => {\n const b = mk('div', `tr-bar ${cls}`)\n const i = mk('i')\n i.style.width = `${Math.max(0, Math.min(100, (value / Math.max(1e-9, max)) * 100))}%`\n b.appendChild(i)\n return b\n }\n const row = (k: string, v: string): HTMLElement => {\n const r = mk('div', 'r')\n r.append(mk('span', undefined, k), mk('span', undefined, v))\n return r\n }\n const num = (n: number, d = 1): string => {\n const s = (Math.round(n * 10 ** d) / 10 ** d).toFixed(d)\n return t('locale.decimal') === ',' ? s.replace('.', ',') : s\n }\n const renderInspector = (i: InspectInfo | null): void => {\n insp.textContent = ''\n insp.appendChild(mk('h3', undefined, t('ui.inspector')))\n if (!i) {\n insp.appendChild(mk('div', undefined, t('ui.aim_at_something')))\n return\n }\n insp.appendChild(mk('div', 't', `${i.object} › ${i.part}`))\n insp.appendChild(row(t('ins.material'), i.material))\n insp.appendChild(row(t('ins.status'), i.status + (i.burning ? ` · ${t('ins.burning')}` : '')))\n insp.appendChild(row(t('ins.hp'), `${num(i.hp, 0)} / ${num(i.maxHp, 0)}`))\n const frac = i.hp / Math.max(1e-9, i.maxHp)\n insp.appendChild(bar(i.hp, i.maxHp, frac < 0.25 ? 'bad' : frac < 0.6 ? 'warn' : 'hp'))\n insp.appendChild(row(t('ins.temperature'), `${num(i.temperature, 0)} °C`))\n if (i.char > 0.01) insp.appendChild(row(t('ins.char'), `${num(i.char * 100, 0)} %`))\n if (i.melt > 0.01) insp.appendChild(row(t('ins.melt'), `${num(i.melt * 100, 0)} %`))\n if (i.liters !== undefined) insp.appendChild(row(t('ins.liters'), `${num(i.liters, 2)} l`))\n const cn = (what: string, n: number): string => t(`count.${what}.${n === 1 ? 'one' : 'other'}`, { n })\n insp.appendChild(row(t('ins.damage'), t('ins.damage_counts', { dents: cn('dent', i.dents), holes: cn('hole', i.holes), cracks: cn('crack', i.cracks) })))\n insp.appendChild(row(t('ins.mass'), `${num(i.mass, 1)} kg`))\n if (i.load !== undefined) insp.appendChild(row(t('ins.load'), `${num(i.load, 0)} kg`))\n if (i.stress !== undefined) {\n insp.appendChild(row(t('ins.stress'), `${num(i.stress * 100, 0)} %`))\n insp.appendChild(bar(Math.min(i.stress, 1.2), 1.2, i.stress > 1 ? 'bad' : i.stress > 0.7 ? 'warn' : 'hp'))\n }\n if (i.joints.length) {\n insp.appendChild(mk('div', undefined, t('ins.joints') + ':'))\n for (const j of i.joints) {\n const tools = j.tools.length ? j.tools.join(', ') : t('tool.none')\n insp.appendChild(mk('div', undefined, `• ${j.kind} (${j.id})${j.open ? ` · ${t('ins.open')}` : ` → ${tools}`}`))\n }\n }\n if (i.note) insp.appendChild(mk('div', undefined, i.note))\n }\n\n let lastAnim = ''\n const renderAnimations = (a: AnimationInfo | null): void => {\n anim.textContent = ''\n anim.appendChild(mk('h3', undefined, t('ui.animations')))\n if (!a) {\n anim.appendChild(mk('div', 'sub', t('ui.animations_aim')))\n return\n }\n anim.appendChild(mk('div', 'sub', a.name))\n if (a.clips.length === 0) {\n anim.appendChild(mk('div', 'sub', t('ui.animations_none')))\n return\n }\n const l = mk('div', 'list')\n for (const c of a.clips) {\n const b = mk('button', a.playing === c.id ? 'tr-btn on' : 'tr-btn', `▶ ${t(`anim.${c.id}`) === `anim.${c.id}` ? c.id : t(`anim.${c.id}`)} (${num(c.duration, 1)} s)`)\n b.type = 'button'\n b.onclick = () => o.onPlay(a.objectId, c.id)\n l.appendChild(b)\n }\n anim.appendChild(l)\n }\n renderAnimations(null)\n\n let toastTimer: ReturnType<typeof setTimeout> | null = null\n const slotsEl: HTMLButtonElement[] = []\n let lastSlotsKey = ''\n let lastInspect = ''\n let hudPage = 0\n\n const api: RoomUi = {\n hud(s) {\n toolBox.textContent = ''\n toolBox.append(document.createTextNode(s.toolName))\n if (s.ammo) toolBox.append(mk('small', undefined, s.ammo))\n if (s.status) status.textContent = s.status\n else if (!toastTimer) status.textContent = ''\n if (s.progress) {\n prog.style.display = 'block'\n progLabel.textContent = s.progress.label\n progFill.style.width = `${Math.round(s.progress.value * 100)}%`\n } else prog.style.display = 'none'\n if (s.held) {\n held.style.display = 'block'\n held.textContent = ''\n held.append(document.createTextNode(`${s.held.name} · `))\n const keys: Array<[string, string]> = [\n ['E', t('hud.drop')],\n ['R', t('hud.rotate')],\n ['G', t('hud.throw')],\n ['Z', t('hud.tilt')],\n ...s.held.uses.map((u) => [u.key, u.label] as [string, string]),\n ]\n if (s.held.weapon) keys.push(['H', t('hud.equip', { weapon: s.held.weapon })])\n for (const [k, label] of keys) {\n held.append(mk('kbd', undefined, k), document.createTextNode(` ${label} `))\n }\n } else held.style.display = 'none'\n const key = s.slots.join('|') + s.page\n if (key !== lastSlotsKey) {\n lastSlotsKey = key\n hotbar.textContent = ''\n slotsEl.length = 0\n hudPage = s.page - 1\n s.slots.forEach((name, i) => {\n const b = mk('button', 'tr-slot')\n b.type = 'button'\n b.append(mk('b', undefined, String((i + 1) % 10)), document.createTextNode(name))\n b.title = name\n b.onclick = () => o.onTool(hudPage * 10 + i)\n hotbar.appendChild(b)\n slotsEl.push(b)\n })\n }\n slotsEl.forEach((b, i) => b.classList.toggle('on', i === s.slot))\n tapBtn.classList.toggle('on', s.tap)\n count.textContent = t('ui.objects', { n: s.objects })\n const ak = JSON.stringify(s.animations)\n if (ak !== lastAnim) {\n lastAnim = ak\n renderAnimations(s.animations)\n }\n const ik = JSON.stringify(s.inspect)\n if (ik !== lastInspect) {\n lastInspect = ik\n renderInspector(s.inspect)\n }\n },\n toast(text) {\n status.textContent = text\n if (toastTimer) clearTimeout(toastTimer)\n toastTimer = setTimeout(() => {\n toastTimer = null\n }, 2000)\n },\n refresh() {\n renderTabs()\n renderScenarios()\n },\n togglePanels,\n dispose() {\n offLog()\n if (toastTimer) clearTimeout(toastTimer)\n root.remove()\n },\n }\n rebuildLog()\n return api\n}\n"],"mappings":"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","names":["JOINT_DEFAULTS","a","b","key","g","drum","crate","bottle","box","JOINT_DEFAULTS","step","grab"]}
|
|
1
|
+
{"version":3,"sources":["../src/room.ts","../src/items.ts","../src/build-from-spec.ts","../src/locale.ts","../src/arena.ts","../src/bench.ts","../src/log.ts","../src/metrics.ts","../src/narrate.ts","../src/player.ts","../src/scenarios.ts","../src/bench-panel.ts","../src/ui.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport { createDestruction, JOINT_DEFAULTS, resolveStrings as resolveDestructionStrings } from '@adatechnology/game-destruction'\nimport type { DestructibleImpl, DestructibleSpec, DestructionEvent, JointState, Quat, RayHit, ToolKind, Vec3 } from '@adatechnology/game-destruction'\nimport { createDestructionRenderer, specFromObject3D } from '@adatechnology/game-destruction-three'\nimport type { Piece } from '@adatechnology/game-destruction-three'\nimport { createArsenal, DEFAULT_LOADOUT } from '@adatechnology/game-weapons'\nimport type { Shot, Use, WeaponState } from '@adatechnology/game-weapons'\nimport { createFluids, createItemUse, ITEM_USES, resolveStrings as resolveFluidStrings } from '@adatechnology/game-fluids'\nimport type { FluidEvent, ItemUsePlayer, StainState } from '@adatechnology/game-fluids'\nimport { createFluidRenderer } from '@adatechnology/game-fluids-three'\nimport type { FluidRenderer } from '@adatechnology/game-fluids-three'\nimport { checkAnimation, checkBench, checkDestructible, checkSpec } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, HostEvent, ModuleArea, ModuleBench, ModuleHost, TestableModule } from '@adatechnology/game-contracts'\nimport { createArena } from './arena'\nimport type { Arena } from './arena'\nimport { createBenchStore } from './bench'\nimport type { BenchStore } from './bench'\nimport type { BenchView, MetricRow } from './bench-panel'\nimport { buildFromSpec } from './build-from-spec'\nimport { DEMO_MATERIALS, demoItems } from './items'\nimport { createLog } from './log'\nimport { createRoomMetrics, ROOM_METRICS } from './metrics'\nimport { createNarrator } from './narrate'\nimport { createPlayer } from './player'\nimport { makeScenarios } from './scenarios'\nimport { resolveStrings } from './locale'\nimport { createUi } from './ui'\nimport type { HudState, InspectInfo, RoomUi } from './ui'\nimport type {\n AnimationInfo,\n ModuleReport,\n RoomMetricId,\n ScenarioContext,\n ScenarioReport,\n SpawnedObject,\n TestRoom,\n TestRoomItem,\n TestRoomOptions,\n TestRoomScenario,\n} from './types'\n\ntype Vars = Record<string, string | number>\n\ninterface Entry {\n so: SpawnedObject\n item?: TestRoomItem\n name: string\n arena: boolean\n containerId?: string\n fluidPart?: string\n fluidOffset: Vec3\n uses: string[]\n piece: Piece | null\n last: Vec3\n velocity: Vec3\n}\n\ninterface Projectile {\n mesh: THREE_NS.Object3D\n pos: THREE_NS.Vector3\n vel: THREE_NS.Vector3\n weapon: string\n fuse: number\n burstOnImpact: boolean\n energy: number\n radius: number\n fire?: { temperature: number; radius: number; seconds: number }\n age: number\n}\n\ninterface FireZone {\n point: Vec3\n radius: number\n temperature: number\n remaining: number\n acc: number\n}\n\ninterface BurningStain {\n center: Vec3\n remaining: number\n acc: number\n}\n\nconst FIXED_DT = 1 / 60\nconst METRICS_INTERVAL_S = 0.25\n\nconst v3 = (v: THREE_NS.Vector3): Vec3 => [v.x, v.y, v.z]\nconst dist3 = (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\n\n/**\n * Create the test room. See `TestRoomOptions`. The room owns a renderer, scene and camera unless you pass them; with your own renderer you call\n * `room.update(dt)` every frame and render yourself.\n */\nexport function createTestRoom(options: TestRoomOptions): TestRoom {\n const THREE = options.THREE\n const locale = options.locale ?? 'en'\n const S = resolveStrings(locale)\n const dStrings = resolveDestructionStrings(locale)\n const fStrings = resolveFluidStrings(locale)\n const t = (key: string, vars?: Vars): string => {\n let s = S.text[key] ?? key\n if (vars) for (const k of Object.keys(vars)) s = s.split(`{${k}}`).join(String(vars[k]))\n return s\n }\n const num = (n: number, digits = 1): string => {\n const s = (Math.round(n * 10 ** digits) / 10 ** digits).toFixed(digits)\n return locale.toLowerCase().startsWith('pt') ? s.replace('.', ',') : s\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Renderer, scene, camera\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const ownRenderer = !options.renderer\n const gl: THREE_NS.WebGLRenderer = options.renderer ?? new THREE.WebGLRenderer({ antialias: true })\n const container = options.container\n const width = (): number => container.clientWidth || 960\n const height = (): number => container.clientHeight || 600\n if (ownRenderer) {\n const r = gl as THREE_NS.WebGLRenderer\n r.setPixelRatio(Math.min(typeof devicePixelRatio === 'number' ? devicePixelRatio : 1, 2))\n r.shadowMap.enabled = true\n r.shadowMap.type = THREE.PCFSoftShadowMap\n r.toneMapping = THREE.ACESFilmicToneMapping\n r.toneMappingExposure = 1\n r.outputColorSpace = THREE.SRGBColorSpace\n container.appendChild(r.domElement)\n }\n gl.setSize(width(), height())\n const dom = gl.domElement\n if (dom && !dom.hasAttribute?.('tabindex')) dom.setAttribute?.('tabindex', '0')\n const scene = options.scene ?? new THREE.Scene()\n const camera = options.camera ?? new THREE.PerspectiveCamera(72, width() / height(), 0.05, 140)\n if (!options.camera) scene.add(camera)\n const resize = (): void => {\n const w = width()\n const h = height()\n gl.setSize(w, h)\n camera.aspect = w / h\n camera.updateProjectionMatrix()\n }\n const onResize = (): void => resize()\n window.addEventListener('resize', onResize)\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Worlds\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const arenaSize = options.arenaSize ?? 14\n const arena: Arena = createArena(THREE, arenaSize, scene)\n scene.add(arena.group)\n\n const ownWorld = !options.world\n const world = options.world ?? createDestruction({ seed: 1, ...options.worldOptions, materials: [...DEMO_MATERIALS, ...(options.worldOptions?.materials ?? [])] })\n const pristineWorld = ownWorld ? world.serialize() : null\n const tableOk = (): boolean => {\n const p = world.part(arena.table.id, arena.table.topPart)\n return !!p && p.status !== 'broken' && p.status !== 'melted' && p.status !== 'ashes'\n }\n // tops of spawned objects that hold others (a module's counter, a shelf board): loose things rest on them while the object is in the world\n const restingTops: Array<{ objectId: string; minX: number; maxX: number; minZ: number; maxZ: number; top: number }> = []\n const restingTopAt = (x: number, z: number): number => {\n let top = 0\n for (const c of restingTops) if (x > c.minX && x < c.maxX && z > c.minZ && z < c.maxZ && world.has(c.objectId)) top = Math.max(top, c.top)\n return top\n }\n const groundAt = (x: number, z: number): number =>\n Math.max(x > arena.table.minX && x < arena.table.maxX && z > arena.table.minZ && z < arena.table.maxZ && tableOk() ? arena.table.top : 0, restingTopAt(x, z))\n\n const ownFluids = !options.fluids\n const fluids = options.fluids ?? createFluids({ seed: 1, locale, liquids: options.liquids, groundAt })\n const pristineFluids = ownFluids ? fluids.serialize() : null\n for (const s of [...arena.surfaces, ...(options.surfaces ?? [])]) fluids.addSurface(s)\n const itemUseDefs = [...ITEM_USES, ...(options.itemUses ?? [])]\n\n const quality = options.quality ?? 'medium'\n const pointScale = height() / (2 * Math.tan((camera.fov * Math.PI) / 360))\n const rendererPieces = new Map<string, Piece>()\n const entries = new Map<string, Entry>()\n const splitOf = new Map<string, Entry>()\n let simTime = 0\n const log = createLog({ exportCancelled: () => t('log.export_cancelled') })\n log.setClock(() => simTime)\n\n const renderer = createDestructionRenderer(THREE, {\n scene,\n world,\n quality,\n groundAt,\n pointScale,\n onSound: options.onSound,\n onPiece: (piece) => {\n rendererPieces.set(piece.objectId, piece)\n loose.push(piece)\n // find the entry it came from: the one whose spec holds all its parts and that is nearest\n const st = world.state(piece.objectId)\n if (!st) return\n let best: Entry | null = null\n let bestD = Infinity\n for (const e of entries.values()) {\n const spec = specs.get(e.so.objectId)\n if (!spec) continue\n const ids = new Set(spec.parts.map((p) => p.id))\n if (!st.parts.every((p) => ids.has(p.id))) continue\n const d = e.so.root.position.distanceTo(piece.root.position)\n if (d < bestD) {\n bestD = d\n best = e\n }\n }\n if (best) splitOf.set(piece.objectId, best)\n },\n })\n const fluidView: FluidRenderer = createFluidRenderer(THREE, { scene, fluids, quality, pointScale })\n const specs = new Map<string, DestructibleSpec>()\n const loose: Piece[] = []\n\n const arsenal = options.arsenal ?? createArsenal({ locale, weapons: options.weapons, seed: 1 })\n const loadout = (options.loadout ?? DEFAULT_LOADOUT).filter((id) => arsenal.weapons.has(id))\n const tools = new Map<string, WeaponState>()\n let toolIndex = Math.max(0, loadout.indexOf('hand'))\n let toolId = loadout[toolIndex] ?? 'hand'\n const toolState = (id: string): WeaponState => {\n let s = tools.get(id)\n if (!s) {\n s = arsenal.create(id, { seed: 7, reserve: 999 })\n s.refill()\n tools.set(id, s)\n }\n return s\n }\n let tool = toolState(toolId)\n\n const catalogMap = new Map<string, TestRoomItem>()\n for (const i of demoItems(locale)) catalogMap.set(i.id, i)\n for (const i of options.catalog) catalogMap.set(i.id, i)\n const catalog = [...options.catalog]\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Names and narration\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const entryOf = (objectId: string): Entry | undefined => entries.get(objectId) ?? splitOf.get(objectId)\n const nameOf = (objectId: string): string => {\n const e = entries.get(objectId)\n if (e) return e.name\n const s = splitOf.get(objectId)\n return s ? `${s.name} (${t('piece')})` : objectId\n }\n const narrator = createNarrator({\n world,\n fluids,\n log,\n now: () => simTime,\n t,\n num,\n nameOf,\n itemIdOf: (id) => entryOf(id)?.so.itemId,\n materialName: (id) => S.text[`material.${id}`] ?? dStrings.materialNames[id] ?? id,\n liquidName: (id) => fStrings.liquids[id] ?? id,\n jointKind: (k) => dStrings.jointKinds[k as keyof typeof dStrings.jointKinds] ?? k,\n toolName: (k) => dStrings.toolKinds[k as keyof typeof dStrings.toolKinds] ?? k,\n locatePart: (objectId, partId) => {\n const own = world.part(objectId, partId)\n if (own) return { objectId, part: own }\n for (const [id, owner] of splitOf) {\n if (owner.so.objectId !== objectId) continue\n const p = world.part(id, partId)\n if (p) return { objectId: id, part: p }\n }\n return null\n },\n containerName: (cid) => {\n for (const e of entries.values()) if (e.containerId === cid) return { name: e.name, objectId: e.so.objectId, itemId: e.so.itemId }\n return undefined\n },\n })\n\n let pending: DestructionEvent[] = []\n const eventListeners = new Set<(d: unknown) => void>()\n const listeners: Record<string, Set<(d: unknown) => void>> = { spawn: new Set(), tool: new Set(), grab: new Set(), throw: new Set(), event: eventListeners }\n const fire = (type: string, data: unknown): void => {\n for (const fn of listeners[type] ?? []) fn(data)\n }\n world.on('*', (ev) => {\n pending.push(ev)\n })\n fluids.on('*', (ev: FluidEvent) => {\n narrator.fluid(ev)\n fire('event', ev)\n })\n\n const action = (type: string, text: string, extra: Partial<{ objectId: string; itemId: string; part: string; data: Record<string, unknown>; material: string }> = {}): void => {\n log.add({ channel: 'action', type, text, ...extra })\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Flush: events of the frame -> log, fluids glue, fire glue\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const tmpV = new THREE.Vector3()\n const tmpV2 = new THREE.Vector3()\n const tmpQ = new THREE.Quaternion()\n const tmpM = new THREE.Matrix4()\n\n const hostOf = (e: Entry): { objectId: string; root: THREE_NS.Object3D } => {\n if (e.fluidPart && !e.arena && !world.part(e.so.objectId, e.fluidPart)) {\n for (const [id, owner] of splitOf) {\n if (owner === e && world.part(id, e.fluidPart)) {\n const p = rendererPieces.get(id)\n if (p) return { objectId: id, root: p.root }\n }\n }\n }\n return { objectId: e.so.objectId, root: e.so.root }\n }\n\n const puncture = (ev: Extract<DestructionEvent, { type: 'leak' }>): void => {\n const e = entryOf(ev.object)\n if (!e?.containerId || e.fluidPart !== ev.part) return\n const host = hostOf(e)\n host.root.updateMatrixWorld(true)\n tmpM.copy(host.root.matrixWorld).invert()\n const local = tmpV.set(ev.point[0], ev.point[1], ev.point[2]).applyMatrix4(tmpM)\n local.x -= e.fluidOffset[0]\n local.y -= e.fluidOffset[1]\n local.z -= e.fluidOffset[2]\n host.root.getWorldQuaternion(tmpQ).invert()\n const n = tmpV2.set(ev.direction[0], ev.direction[1], ev.direction[2]).applyQuaternion(tmpQ)\n const part = world.part(host.objectId, ev.part)\n const hole = part?.holes[part.holes.length - 1]\n fluids.puncture(e.containerId, [local.x, local.y, local.z], [n.x, n.y, n.z], hole?.diameter ?? 0.009)\n }\n\n const flush = (): void => {\n if (pending.length === 0) return\n const batch = pending\n pending = []\n narrator.events(batch)\n for (const ev of batch) {\n if (ev.type === 'leak') puncture(ev)\n else if (ev.type === 'ignite') igniteNear(ev.point, 0.9)\n fire('event', ev)\n options.onEvent?.(ev)\n }\n }\n log.setBeforeRead(flush)\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Player\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let useHeld = false\n let useFirst = false\n const player = createPlayer(THREE, {\n camera,\n dom,\n colliders: arena.colliders,\n limit: arenaSize,\n start: arena.playerStart,\n hooks: {\n primaryDown: () => {\n useHeld = true\n useFirst = true\n },\n primaryUp: () => {\n useHeld = false\n tool.release()\n },\n secondary: () => {\n if (heldEntry) throwHeld()\n else grab()\n },\n key: (code, down, e) => onKey(code, down, e),\n wheel: (dir) => cycleTool(dir),\n },\n })\n player.look(arena.playerStart, [0, 1.5, arena.wallZ])\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Spawning\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let counter = 0\n let slot = 0\n const maxCarry = options.maxCarryKg ?? 60\n\n const massOfObject = (id: string): number => {\n const st = world.state(id)\n let m = 0\n for (const p of st?.parts ?? []) if (p.status !== 'broken' && p.status !== 'melted' && p.status !== 'ashes') m += p.mass\n return m\n }\n\n const registerEntry = (\n objectId: string,\n itemId: string,\n root: THREE_NS.Object3D,\n spec: DestructibleSpec,\n name: string,\n parts: Record<string, THREE_NS.Object3D | THREE_NS.Object3D[]> | undefined,\n item: TestRoomItem | undefined,\n arenaObject: boolean,\n movable: boolean,\n ): Entry => {\n specs.set(objectId, spec)\n renderer.bind(objectId, root, parts ? { parts } : undefined)\n const so: SpawnedObject = { objectId, itemId, root, movable }\n const e: Entry = { so, item, name, arena: arenaObject, fluidOffset: [0, 0, 0], uses: [], piece: null, last: [root.position.x, root.position.y, root.position.z], velocity: [0, 0, 0] }\n entries.set(objectId, e)\n if (movable) {\n e.piece = renderer.makePiece(objectId, { mass: Math.max(0.2, massOfObject(objectId)) })\n rendererPieces.set(objectId, e.piece)\n }\n const f = item?.fluid\n if (f) {\n e.fluidPart = f.part\n e.fluidOffset = f.offset ?? [0, 0, 0]\n e.uses = f.uses ?? ['drink', 'sip', 'pour']\n root.updateMatrixWorld(true)\n const q = root.getWorldQuaternion(tmpQ)\n const p = tmpV.set(e.fluidOffset[0], e.fluidOffset[1], e.fluidOffset[2]).applyMatrix4(root.matrixWorld)\n e.containerId = fluids.addContainer(f.container, { id: `${objectId}_fluid`, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] })\n fluidView.bindContainer(e.containerId, root, { innerOffset: e.fluidOffset })\n }\n return e\n }\n\n const resolveSpec = (item: TestRoomItem, root: THREE_NS.Object3D): { spec: DestructibleSpec; parts?: Record<string, THREE_NS.Object3D[]> } => {\n if (typeof item.spec === 'function') return { spec: structuredCloneSpec(item.spec(root)) }\n if (item.spec) return { spec: structuredCloneSpec(item.spec) }\n const r = specFromObject3D(THREE, root, { name: item.id, ...item.specOptions })\n return { spec: r.spec, parts: r.parts }\n }\n\n const addArena = (): void => {\n for (const o of arena.objects) {\n const root = buildFromSpec(THREE, o.spec, { colors: o.colors })\n root.position.set(o.position[0], o.position[1], o.position[2])\n scene.add(root)\n root.updateMatrixWorld(true)\n world.add(structuredCloneSpec(o.spec), { id: o.id, position: o.position })\n registerEntry(o.id, o.id, root, o.spec, S.text[`arena.${o.id}`] ?? o.id, undefined, undefined, true, false)\n }\n }\n addArena()\n\n const spawn = (itemId: string, position?: Vec3, rotationY?: number): SpawnedObject => {\n const item = catalogMap.get(itemId)\n if (!item) throw new Error(`game-test-room: unknown item \"${itemId}\"`)\n const root = item.build(THREE)\n let pos: Vec3\n if (position) pos = [position[0], position[1], position[2]]\n else {\n const fx = -Math.sin(player.yaw)\n const fz = -Math.cos(player.yaw)\n const rx = Math.cos(player.yaw)\n const rz = -Math.sin(player.yaw)\n const side = ((slot++ % 5) - 2) * 0.55\n const x = camera.position.x + fx * 2.4 + rx * side\n const z = camera.position.z + fz * 2.4 + rz * side\n const lim = arenaSize - 1\n pos = [Math.max(-lim, Math.min(lim, x)), groundAt(x, z), Math.max(-lim, Math.min(lim, z))]\n }\n root.position.set(pos[0], pos[1], pos[2])\n root.rotation.y = rotationY ?? player.yaw\n root.name = item.id\n scene.add(root)\n root.updateMatrixWorld(true)\n const objectId = `${item.id}_${++counter}`\n let own: DestructibleImpl | undefined\n let resolved: { spec: DestructibleSpec; parts?: Record<string, THREE_NS.Object3D[]> }\n if (item.impl) {\n own = item.impl(root, objectId)\n if (own.id !== objectId) throw new Error(`game-test-room: item \"${item.id}\": DestructibleImpl.id is \"${own.id}\", the room gave it \"${objectId}\" (use the id passed to impl)`)\n resolved = { spec: structuredCloneSpec(own.describe()) }\n } else resolved = resolveSpec(item, root)\n const { spec, parts } = resolved\n root.updateMatrixWorld(true)\n const mass = spec.parts.reduce((m, p) => m + (p.mass ?? 0), 0)\n const heavy = (mass || massGuess(spec)) > maxCarry\n const movable = own ? false : (item.movable ?? !heavy)\n if (movable) {\n // things that can fall rest on the floor or the table by the bottom of their bounding box (or hang at the height asked for): no drop on spawn\n const box = new THREE.Box3().setFromObject(root)\n const base = Math.max(pos[1], groundAt(pos[0], pos[2]))\n pos = [pos[0], pos[1] + (base - box.min.y), pos[2]]\n root.position.set(pos[0], pos[1], pos[2])\n root.updateMatrixWorld(true)\n }\n const q = root.getWorldQuaternion(tmpQ)\n if (own) world.register(own, { id: objectId, position: pos, rotation: [q.x, q.y, q.z, q.w] })\n else world.add(spec, { id: objectId, position: pos, rotation: [q.x, q.y, q.z, q.w] })\n const e = registerEntry(objectId, item.id, root, spec, item.name, parts, item, false, movable)\n action('spawn', t('act.spawn', { name: item.name, x: num(pos[0], 1), z: num(pos[2], 1) }), { objectId, itemId: item.id, data: { position: pos, movable, massKg: Math.round(massOfObject(objectId) * 10) / 10 } })\n fire('spawn', e.so)\n return e.so\n }\n const massGuess = (spec: DestructibleSpec): number => {\n let m = 0\n for (const p of spec.parts) {\n const s = p.shape\n const vol = s.kind === 'box' ? s.size[0] * s.size[1] * s.size[2] : s.kind === 'cylinder' ? Math.PI * s.radius * s.radius * s.height : (4 / 3) * Math.PI * s.radius ** 3\n m += p.mass ?? vol * (world.materials.get(p.material)?.density ?? 500) * (p.fill ?? 1)\n }\n return m\n }\n\n const removeEntry = (id: string): void => {\n const e = entries.get(id)\n if (!e) return\n if (heldEntry === e) releaseHeld()\n for (let i = playing.length - 1; i >= 0; i--) if (playing[i].entry === e) playing.splice(i, 1)\n if (e.containerId) {\n fluidView.unbindContainer(e.containerId)\n fluids.removeContainer(e.containerId)\n }\n try {\n renderer.unbind(id)\n } catch {\n // not bound\n }\n if (world.has(id)) world.remove(id)\n e.so.root.removeFromParent()\n entries.delete(id)\n rendererPieces.delete(id)\n specs.delete(id)\n }\n\n const clearLoose = (): void => {\n for (const [id, owner] of [...splitOf]) {\n void owner\n const p = rendererPieces.get(id)\n try {\n renderer.unbind(id)\n } catch {\n // gone already\n }\n if (world.has(id)) world.remove(id)\n p?.root.removeFromParent()\n rendererPieces.delete(id)\n splitOf.delete(id)\n }\n loose.length = 0\n }\n\n const clearEverything = (): void => {\n if (heldEntry || heldPiece) releaseHeld()\n useItemPlayer = null\n playing.length = 0\n projectiles.length = 0\n clearProjectileMeshes()\n fireZones.length = 0\n burningStains.length = 0\n for (const id of [...entries.keys()]) if (!entries.get(id)?.arena) removeEntry(id)\n clearLoose()\n for (const e of entries.values()) {\n world.reset(e.so.objectId)\n renderer.restore(e.so.objectId)\n }\n renderer.clear()\n fluids.clearStains([0, 0, 0], 1e4)\n fluidView.clear()\n fluids.setTap(TAP_ID, false)\n }\n\n const clear = (): void => {\n clearEverything()\n restingTops.length = 0\n pending = []\n action('clear', t('act.clear'))\n }\n\n const resetAll = (): void => {\n for (const e of entries.values()) {\n if (heldEntry === e) continue\n world.reset(e.so.objectId)\n renderer.restore(e.so.objectId)\n if (e.containerId) {\n const c = fluids.container(e.containerId)\n const f = e.item?.fluid?.container\n if (c && f && f.liquid) fluids.fill(e.containerId, f.liquid, Math.max(0, (f.liters ?? 0) - c.liters), f.temperature)\n }\n }\n action('reset', t('act.reset'))\n }\n\n /** Reset the worlds to their seeded start: used by scenarios so that each one is deterministic. */\n const hardReset = (): void => {\n clearEverything()\n for (const id of [...entries.keys()]) removeEntry(id)\n tools.clear()\n tool = toolState(toolId)\n if (pristineWorld) {\n for (const id of world.ids()) world.remove(id)\n world.load(pristineWorld)\n }\n if (pristineFluids) {\n fluids.load(pristineFluids)\n for (const s of [...arena.surfaces, ...(options.surfaces ?? [])]) fluids.addSurface(s)\n }\n pending = []\n rng = 12345\n counter = 0\n slot = 0\n prevVy.clear()\n lastImpact.clear()\n addArena()\n timeScale = 1\n fastForward = false\n walkPlan = null\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Aiming\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const aimO: Vec3 = [0, 0, 0]\n const aimD: Vec3 = [0, 0, -1]\n const aim = (): void => {\n camera.updateMatrixWorld(true)\n camera.getWorldPosition(tmpV)\n camera.getWorldDirection(tmpV2)\n aimO[0] = tmpV.x\n aimO[1] = tmpV.y\n aimO[2] = tmpV.z\n aimD[0] = tmpV2.x\n aimD[1] = tmpV2.y\n aimD[2] = tmpV2.z\n }\n\n const FAR: Quat = [0, 0, 0, 1]\n /** Run `fn` with the held object moved away, so that rays and bullets do not hit what the player carries. */\n const withoutHeld = <T,>(fn: () => T): T => {\n const e = heldEntry\n if (!e || !world.has(e.so.objectId)) return fn()\n const p = e.so.root.position\n const q = e.so.root.quaternion\n world.setTransform(e.so.objectId, [0, -5000, 0], FAR)\n try {\n return fn()\n } finally {\n world.setTransform(e.so.objectId, [p.x, p.y, p.z], [q.x, q.y, q.z, q.w])\n }\n }\n\n const rayWorld = (o: Vec3, d: Vec3, max: number): RayHit | null => withoutHeld(() => world.raycast(o, d, max))\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Particles helpers and a tiny seeded rng for visuals\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let rng = 12345\n const rnd = (): number => {\n rng = (rng * 1664525 + 1013904223) >>> 0\n return rng / 4294967296\n }\n\n const muzzle = (): Vec3 => {\n aim()\n const e = camera.matrixWorld.elements\n // right = x axis, up = y axis of the camera\n return [\n aimO[0] + aimD[0] * 0.45 + e[0] * 0.16 - e[4] * 0.1,\n aimO[1] + aimD[1] * 0.45 + e[1] * 0.16 - e[5] * 0.1,\n aimO[2] + aimD[2] * 0.45 + e[2] * 0.16 - e[6] * 0.1,\n ]\n }\n\n // tracers\n const tracers: Array<{ line: THREE_NS.Line; life: number }> = []\n const tracerMat = new THREE.LineBasicMaterial({ color: 0xffe9a8, transparent: true, opacity: 0.9 })\n const tracer = (a: Vec3, b: Vec3): void => {\n let tr = tracers.find((x) => x.life <= 0)\n if (!tr) {\n if (tracers.length >= 12) return\n const g = new THREE.BufferGeometry()\n g.setAttribute('position', new THREE.Float32BufferAttribute(6, 3))\n const line = new THREE.Line(g, tracerMat)\n line.frustumCulled = false\n scene.add(line)\n tr = { line, life: 0 }\n tracers.push(tr)\n }\n const attr = tr.line.geometry.getAttribute('position') as THREE_NS.BufferAttribute\n attr.setXYZ(0, a[0], a[1], a[2])\n attr.setXYZ(1, b[0], b[1], b[2])\n attr.needsUpdate = true\n tr.line.visible = true\n tr.life = 0.07\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Fire glue: stains of flammable liquids, fire zones (molotov), dry water near fire\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const fireZones: FireZone[] = []\n const burningStains: BurningStain[] = []\n const stainRadius = (s: StainState): number => {\n let sum = 0\n for (const r of s.front) sum += r\n return s.front.length ? sum / s.front.length : 0.1\n }\n const stainBurning = (s: StainState): boolean => burningStains.some((b) => dist3(b.center, s.center) < 0.05)\n\n function igniteNear(point: Vec3, reach: number): void {\n let lit = false\n let water = false\n for (const s of fluids.stains()) {\n if (s.wetness < 0.05) continue\n if (Math.hypot(s.center[0] - point[0], s.center[2] - point[2]) > reach + stainRadius(s) || Math.abs(s.center[1] - point[1]) > 1.5) continue\n if (fluids.liquids.get(s.liquid)?.flammable) {\n if (stainBurning(s)) continue\n const seconds = Math.max(3, Math.min(20, 4 + s.liters * 30 + stainRadius(s) * 6))\n burningStains.push({ center: [s.center[0], s.center[1], s.center[2]], remaining: seconds, acc: 0 })\n lit = true\n log.add({\n channel: 'event',\n type: 'stain_ignite',\n text: t('ev.stain_ignite', { liquid: fStrings.liquids[s.liquid] ?? s.liquid, x: num(s.center[0], 1), z: num(s.center[2], 1), seconds: num(seconds, 0) }),\n data: { stain: s.id, liquid: s.liquid, seconds },\n })\n } else water = true\n }\n if (water && !lit) {\n fluids.clearStains(point, Math.max(0.5, reach))\n log.coalesce('dry', { channel: 'event', type: 'stain_dried_by_fire', text: t('ev.fire_dries'), data: { point } }, 2)\n }\n }\n\n const hitFireAround = (point: Vec3, radius: number, temperature: number, duration: number): void => {\n for (const id of world.ids()) world.hit(id, { type: 'fire', point, temperature, radius, duration, source: 'fire' })\n }\n\n const updateFires = (dt: number): void => {\n for (let i = fireZones.length - 1; i >= 0; i--) {\n const z = fireZones[i]\n z.remaining -= dt\n z.acc += dt\n if (z.acc >= 0.1) {\n hitFireAround(z.point, z.radius, z.temperature, z.acc)\n igniteNear(z.point, z.radius)\n z.acc = 0\n }\n const a = rnd() * Math.PI * 2\n const r = Math.sqrt(rnd()) * z.radius\n renderer.emit('fire', [z.point[0] + Math.cos(a) * r, z.point[1] + 0.05, z.point[2] + Math.sin(a) * r], [0, 1, 0], 2, 1.5)\n if (z.remaining <= 0) fireZones.splice(i, 1)\n }\n if (burningStains.length) {\n const stains = fluids.stains()\n for (let i = burningStains.length - 1; i >= 0; i--) {\n const b = burningStains[i]\n b.remaining -= dt\n b.acc += dt\n const st = stains.find((s) => dist3(s.center, b.center) < 0.05)\n const r = st ? stainRadius(st) : 0.3\n if (b.acc >= 0.1) {\n hitFireAround([b.center[0], b.center[1] + 0.1, b.center[2]], r + 0.2, 800, b.acc)\n b.acc = 0\n }\n const a = rnd() * Math.PI * 2\n const rr = Math.sqrt(rnd()) * r\n renderer.emit('fire', [b.center[0] + Math.cos(a) * rr, b.center[1] + 0.05, b.center[2] + Math.sin(a) * rr], [0, 1, 0], 3, 1.8)\n if (rnd() < 0.2) renderer.emit('smoke', [b.center[0], b.center[1] + 0.3, b.center[2]], [0, 1, 0], 1, 1)\n if (b.remaining <= 0 || !st) {\n fluids.clearStains(b.center, r + 0.1)\n log.add({ channel: 'event', type: 'stain_burned', text: t('ev.stain_burned'), data: { point: b.center } })\n burningStains.splice(i, 1)\n }\n }\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Tools\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let progress: { label: string; value: number; at: number } | null = null\n let statusLine = ''\n let statusAt = 0\n const say = (msg: string): void => {\n statusLine = msg\n statusAt = simTime\n ui?.toast(msg)\n }\n\n const toolName = (id = toolId): string => arsenal.name(id)\n const hitWhere = (r: RayHit): string => {\n const p = world.part(r.object, r.part)\n return `${nameOf(r.object)} › ${r.part}${p ? ` (${dStrings.materialNames[p.material] ?? p.material})` : ''}`\n }\n\n const pushPiece = (objectId: string, dir: Vec3, momentum: number, point: Vec3): void => {\n if (!rendererPieces.has(objectId)) return\n renderer.impulse(objectId, [dir[0] * momentum, dir[1] * momentum, dir[2] * momentum], point)\n }\n\n const fireShots = (shots: Shot[], recoil: [number, number]): void => {\n if (shots.length === 0) return\n const w = toolName()\n const m = muzzle()\n renderer.emit('flash', m, [aimD[0], aimD[1], aimD[2]], 1, 0)\n renderer.emit('sparks', m, [aimD[0], aimD[1], aimD[2]], 4, 6)\n let hits = 0\n let first: RayHit | null = null\n let energy = 0\n withoutHeld(() => {\n for (const s of shots) {\n energy = Math.max(energy, s.energy)\n const results = world.shoot(s.origin, s.direction, s.energy, s.caliber, 'player')\n const r0 = results.find((r) => r.part && r.point)\n let end: Vec3 = [s.origin[0] + s.direction[0] * 40, s.origin[1] + s.direction[1] * 40, s.origin[2] + s.direction[2] * 40]\n if (r0?.point && r0.part) {\n hits++\n end = r0.point\n if (!first) first = { object: r0.object, part: r0.part, point: r0.point, normal: [0, 1, 0], distance: dist3(s.origin, r0.point) }\n const speed = Math.max(80, s.speed)\n pushPiece(r0.object, s.direction, (2 * s.energy) / speed, r0.point)\n }\n if (shots.length <= 3 || rnd() < 0.34) tracer(m, end)\n }\n })\n player.kick(recoil[0], recoil[1])\n emitHost({ type: 'shot', weapon: toolId, shots: shots.length, recoil, rounds: shots.filter((s) => s.pellet === 0).length, mode: tool.mode })\n const f = first as RayHit | null\n const d = f ? num(f.distance, 1) : ''\n let text: string\n if (shots.length === 1) text = t(f ? 'act.shoot.hit' : 'act.shoot.miss', { weapon: w, energy: num(energy, 0), where: f ? hitWhere(f) : '', dist: d })\n else text = t('act.shoot.pellets', { weapon: w, n: shots.length, energy: num(energy, 0), hits, where: f ? hitWhere(f) : '', dist: d })\n action('shoot', text, {\n objectId: f?.object,\n itemId: f ? entryOf(f.object)?.so.itemId : undefined,\n part: f?.part,\n data: { weapon: toolId, shots: shots.length, hits, energyJ: Math.round(energy), caliberMm: shots[0].caliber, distanceM: f ? Math.round(f.distance * 100) / 100 : null },\n })\n }\n\n const fireRays = (u: { origin: Vec3; direction: Vec3; range: number; cone: boolean; radius: number }): Array<Vec3> => {\n const d = new THREE.Vector3(u.direction[0], u.direction[1], u.direction[2]).normalize()\n const out: Vec3[] = [[d.x, d.y, d.z]]\n if (u.cone) {\n const a = Math.min(0.2, Math.atan2(u.radius, Math.max(0.1, u.range)))\n const right = new THREE.Vector3().crossVectors(d, new THREE.Vector3(0, 1, 0))\n if (right.lengthSq() < 1e-6) right.set(1, 0, 0)\n right.normalize()\n const up = new THREE.Vector3().crossVectors(right, d).normalize()\n for (const [x, y] of [\n [1, 0],\n [-1, 0],\n [0, 1],\n [0, -1],\n ]) {\n const r = d.clone().addScaledVector(right, x * a).addScaledVector(up, y * a).normalize()\n out.push([r.x, r.y, r.z])\n }\n }\n return out\n }\n\n const heatRays = (u: Extract<Use, { kind: 'flame' | 'heat' }>, type: 'fire' | 'heat'): void => {\n const w = toolName()\n const cone = u.kind === 'flame' ? u.cone : false\n const rays = fireRays({ origin: u.origin, direction: u.direction, range: u.range, cone, radius: u.radius })\n let target: RayHit | null = null\n const m = muzzle()\n withoutHeld(() => {\n for (const d of rays) {\n const r = world.raycast(u.origin, d, u.range)\n if (!r) continue\n if (!target) target = r\n world.hit(r.object, { type, point: r.point, direction: d, temperature: u.temperature, radius: Math.min(u.radius, 0.3), duration: u.duration, source: 'player' })\n if (type === 'fire') igniteNear(r.point, 0.25)\n else renderer.emit('sparks', r.point, r.normal, 2, 4)\n }\n })\n if (type === 'fire') {\n renderer.emit('fire', m, [u.direction[0], u.direction[1], u.direction[2]], cone ? 5 : 1, Math.max(0.6, u.range * 1.1))\n if (cone) renderer.emit('smoke', m, [u.direction[0], u.direction[1] + 0.3, u.direction[2]], 1, u.range * 0.5)\n // nothing hit: the stain on the ground in front may still catch\n if (!target && u.direction[1] < -0.2) {\n const t0 = (0.05 - u.origin[1]) / u.direction[1]\n if (t0 > 0 && t0 < u.range) igniteNear([u.origin[0] + u.direction[0] * t0, 0.05, u.origin[2] + u.direction[2] * t0], 0.3)\n }\n }\n const tg = target as RayHit | null\n log.coalesce(\n `use:${toolId}`,\n {\n channel: 'action',\n type,\n text: tg ? t(type === 'fire' ? 'act.flame.hit' : 'act.heat.hit', { weapon: w, where: hitWhere(tg), temp: num(u.temperature, 0) }) : t(type === 'fire' ? 'act.flame.air' : 'act.heat.air', { weapon: w }),\n objectId: tg?.object,\n part: tg?.part,\n data: { weapon: toolId, temperatureC: u.temperature },\n },\n 1,\n )\n }\n\n const meleeUse = (u: Extract<Use, { kind: 'melee' }>, id = toolId): void => {\n const w = toolName(id)\n const r = rayWorld(u.origin, u.direction, u.reach)\n if (!r) {\n action('melee', t('act.melee.miss', { weapon: w }), { data: { weapon: id } })\n return\n }\n world.hitPart(r.object, r.part, { type: u.damage, point: r.point, direction: u.direction, energy: u.energy, radius: u.radius, source: 'player' })\n pushPiece(r.object, u.direction, (2 * u.energy) / 6, r.point)\n action('melee', t('act.melee.hit', { weapon: w, energy: num(u.energy, 0), where: hitWhere(r), dist: num(r.distance, 1) }), {\n objectId: r.object,\n itemId: entryOf(r.object)?.so.itemId,\n part: r.part,\n data: { weapon: id, damage: u.damage, energyJ: u.energy, distanceM: Math.round(r.distance * 100) / 100 },\n })\n }\n\n const toolWork = (u: Extract<Use, { kind: 'tool' }>, dt: number): void => {\n const w = toolName()\n const r = rayWorld(u.origin, u.direction, u.reach)\n if (!r) {\n progress = null\n log.coalesce(`use:${toolId}`, { channel: 'action', type: 'tool', text: t('act.tool.none', { weapon: w }), data: { weapon: toolId } }, 1)\n return\n }\n const j: JointState | null = world.nearestJoint(r.object, r.point, 0.45, u.tool as ToolKind)\n if (!j) {\n progress = null\n log.coalesce(`use:${toolId}`, { channel: 'action', type: 'tool', text: t('act.tool.nojoint', { weapon: w, where: hitWhere(r) }), objectId: r.object, part: r.part }, 1)\n return\n }\n const tool_ = u.tool as ToolKind\n const p = world.disassemble(r.object, j.id, tool_, dt)\n const kind = dStrings.jointKinds[j.kind] ?? j.kind\n if (p < 0) {\n const need = JOINT_DEFAULTS[j.kind].tools.map((k) => dStrings.toolKinds[k] ?? k).join(', ') || t('tool.none')\n progress = { label: t('hud.refused', { kind }), value: 0, at: simTime }\n log.coalesce(\n `refuse:${r.object}:${j.id}:${toolId}`,\n {\n channel: 'action',\n type: 'tool_refused',\n text: t('act.tool.refused', { weapon: w, kind, obj: nameOf(r.object), need }),\n objectId: r.object,\n itemId: entryOf(r.object)?.so.itemId,\n data: { weapon: toolId, joint: j.id, kind: j.kind, needs: JOINT_DEFAULTS[j.kind].tools },\n },\n 2,\n )\n return\n }\n progress = { label: `${kind} (${j.id})`, value: p, at: simTime }\n renderer.emit('sparks', r.point, r.normal, 1, 2)\n }\n\n const extinguishUse = (u: Extract<Use, { kind: 'extinguish' }>): void => {\n const w = toolName()\n const rays = fireRays({ origin: u.origin, direction: u.direction, range: u.range, cone: true, radius: 0.6 })\n const m = muzzle()\n renderer.emit('foam', m, [u.direction[0], u.direction[1], u.direction[2]], 8, u.range * 1.2)\n const hit = new Set<string>()\n withoutHeld(() => {\n for (const d of rays) {\n const r = world.raycast(u.origin, d, u.range)\n if (!r) continue\n hit.add(r.object)\n world.extinguish(r.object, undefined, u.coolC * Math.max(u.duration, 0.05) * 6)\n fluids.clearStains(r.point, 0.5)\n for (let i = burningStains.length - 1; i >= 0; i--) if (Math.hypot(burningStains[i].center[0] - r.point[0], burningStains[i].center[2] - r.point[2]) < 1.2) burningStains.splice(i, 1)\n for (let i = fireZones.length - 1; i >= 0; i--) if (Math.hypot(fireZones[i].point[0] - r.point[0], fireZones[i].point[2] - r.point[2]) < 1.5) fireZones.splice(i, 1)\n }\n })\n log.coalesce(\n `use:${toolId}`,\n { channel: 'action', type: 'extinguish', text: hit.size ? t('act.extinguish.hit', { weapon: w, what: [...hit].map(nameOf).join(', ') }) : t('act.extinguish.air', { weapon: w }), data: { objects: [...hit] } },\n 1,\n )\n }\n\n // ----- projectiles (grenades and molotovs)\n const projectiles: Projectile[] = []\n const projMeshes: THREE_NS.Object3D[] = []\n const clearProjectileMeshes = (): void => {\n for (const m of projMeshes) m.removeFromParent()\n projMeshes.length = 0\n }\n const throwUse = (u: Extract<Use, { kind: 'throw' }>): void => {\n const w = toolName()\n const molotov = !!u.fire\n const mesh = new THREE.Mesh(\n molotov ? new THREE.CylinderGeometry(0.035, 0.04, 0.2, 8) : new THREE.SphereGeometry(0.045, 8, 6),\n new THREE.MeshStandardMaterial({ color: molotov ? 0x3b7a3b : 0x4b5320, roughness: 0.6, metalness: molotov ? 0 : 0.4 }),\n )\n mesh.castShadow = true\n mesh.position.set(u.origin[0], u.origin[1], u.origin[2])\n scene.add(mesh)\n projMeshes.push(mesh)\n projectiles.push({\n mesh,\n pos: new THREE.Vector3(u.origin[0], u.origin[1], u.origin[2]),\n vel: new THREE.Vector3(u.velocity[0], u.velocity[1], u.velocity[2]),\n weapon: toolId,\n fuse: u.fuse,\n burstOnImpact: molotov && u.fuse <= 0,\n energy: u.energy,\n radius: u.radius,\n fire: u.fire,\n age: 0,\n })\n action('throw_projectile', t(molotov ? 'act.throw.molotov' : 'act.throw.grenade', { weapon: w, fuse: num(u.fuse, 1) }), { data: { weapon: toolId, fuse: u.fuse } })\n }\n\n const detonate = (p: Projectile, at: Vec3, impact: boolean): void => {\n const w = toolName(p.weapon)\n const results = world.explode(at, p.energy, p.radius, 'player')\n renderer.explode(at, p.energy, p.radius)\n action('explode', t('act.explode', { weapon: w, energy: num(p.energy, 0), radius: num(p.radius, 1), n: results.length }), { data: { weapon: p.weapon, energyJ: p.energy, radius: p.radius, point: at } })\n if (p.fire) {\n fluids.splash('fuel', [at[0], Math.max(at[1], groundAt(at[0], at[2])), at[2]], 0.5)\n fireZones.push({ point: [at[0], Math.max(0.02, groundAt(at[0], at[2])), at[2]], radius: p.fire.radius, temperature: p.fire.temperature, remaining: p.fire.seconds, acc: 0 })\n renderer.emit('fire', at, [0, 1, 0], 24, 3)\n action('molotov_fire', t('act.molotov_fire', { weapon: w, seconds: num(p.fire.seconds, 0), radius: num(p.fire.radius, 1) }), { data: { weapon: p.weapon, impact } })\n }\n }\n\n const updateProjectiles = (dt: number): void => {\n for (let i = projectiles.length - 1; i >= 0; i--) {\n const p = projectiles[i]\n p.age += dt\n p.vel.y -= 9.81 * dt\n const speed = p.vel.length()\n const step = speed * dt\n let burst = false\n if (step > 1e-6) {\n const d: Vec3 = [p.vel.x / speed, p.vel.y / speed, p.vel.z / speed]\n const r = withoutHeld(() => world.raycast(v3(p.pos), d, step + 0.05))\n if (r && r.distance <= step + 0.04) {\n p.pos.set(r.point[0] - d[0] * 0.03, r.point[1] - d[1] * 0.03, r.point[2] - d[2] * 0.03)\n if (p.burstOnImpact) burst = true\n else {\n const n = r.normal\n const vn = p.vel.x * n[0] + p.vel.y * n[1] + p.vel.z * n[2]\n p.vel.x = (p.vel.x - 2 * vn * n[0]) * 0.35\n p.vel.y = (p.vel.y - 2 * vn * n[1]) * 0.35\n p.vel.z = (p.vel.z - 2 * vn * n[2]) * 0.35\n }\n } else p.pos.addScaledVector(p.vel, dt)\n }\n const g = groundAt(p.pos.x, p.pos.z) + 0.045\n if (p.pos.y < g) {\n p.pos.y = g\n if (p.burstOnImpact) burst = true\n else {\n p.vel.y = Math.abs(p.vel.y) * 0.35\n p.vel.x *= 0.7\n p.vel.z *= 0.7\n }\n }\n p.mesh.position.copy(p.pos)\n p.mesh.rotation.x += dt * 8\n p.fuse -= dt\n if (burst || (!p.burstOnImpact && p.fuse <= 0) || p.age > 30) {\n detonate(p, v3(p.pos), burst)\n p.mesh.removeFromParent()\n projMeshes.splice(projMeshes.indexOf(p.mesh), 1)\n projectiles.splice(i, 1)\n }\n }\n }\n\n // ----- the trigger\n const useTool = (dt: number, held: boolean): void => {\n aim()\n const cat = tool.def.category\n if (cat === 'hand') return\n const res = tool.trigger([aimO[0], aimO[1], aimO[2]], [aimD[0], aimD[1], aimD[2]], dt, held, 'player')\n if (res.status === 'empty') {\n emitHost({ type: 'empty', weapon: toolId })\n if (!tool.reloading && tool.reserve > 0) startReload()\n say(t(tool.reloading ? 'hud.reloading' : 'hud.empty'))\n return\n }\n if (res.status !== 'ok') {\n if (res.status === 'reloading') say(t('hud.reloading'))\n else if (res.status === 'no_fuel') say(t('hud.no_fuel'))\n return\n }\n if (res.shots.length) fireShots(res.shots, res.recoil)\n for (const u of res.uses) {\n switch (u.kind) {\n case 'melee':\n meleeUse(u)\n break\n case 'flame':\n heatRays(u, 'fire')\n break\n case 'heat':\n heatRays(u, 'heat')\n break\n case 'throw':\n throwUse(u)\n break\n case 'tool':\n toolWork(u, dt)\n break\n case 'extinguish':\n extinguishUse(u)\n break\n default:\n break\n }\n }\n }\n\n /** The V shortcut: a kick with the `kick` tool, whatever tool is selected (it keeps its own cooldown). */\n const kick = (): void => {\n if (!arsenal.weapons.has('kick')) return\n aim()\n const res = toolState('kick').trigger([aimO[0], aimO[1], aimO[2]], [aimD[0], aimD[1], aimD[2]], 0, false, 'player')\n if (res.status !== 'ok') return\n for (const u of res.uses) if (u.kind === 'melee') meleeUse(u, 'kick')\n }\n const setTool = (id: string): void => {\n if (!arsenal.weapons.has(id)) throw new Error(`game-test-room: unknown weapon \"${id}\"`)\n tool.release()\n toolId = id\n const i = loadout.indexOf(id)\n if (i >= 0) toolIndex = i\n tool = toolState(id)\n progress = null\n action('tool', t('act.tool', { weapon: toolName(id) }), { data: { weapon: id } })\n fire('tool', id)\n emitHost({ type: 'tool', weapon: id })\n }\n const cycleTool = (dir: 1 | -1): void => {\n if (!loadout.length) return\n toolIndex = (toolIndex + dir + loadout.length) % loadout.length\n setTool(loadout[toolIndex])\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Grabbing, carrying, throwing\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let heldEntry: Entry | null = null\n let heldPiece: Piece | null = null\n let heldName = ''\n let heldYaw = 0\n let heldTilt = 0\n let tiltKey = 0\n const heldLocal = new THREE.Vector3()\n const heldVel: Vec3 = [0, 0, 0]\n let useItemPlayer: ItemUsePlayer | null = null\n let useItemName = ''\n\n const releaseHeld = (): void => {\n if (heldPiece) {\n heldPiece.held = false\n heldPiece.sleeping = false\n heldPiece.velocity = [heldVel[0], heldVel[1], heldVel[2]]\n }\n useItemPlayer?.cancel()\n useItemPlayer = null\n heldEntry = null\n heldPiece = null\n heldTilt = 0\n }\n\n const grab = (): boolean => {\n if (heldPiece) {\n const name = heldName\n releaseHeld()\n action('drop', t('act.drop', { name }))\n fire('grab', { held: false })\n return true\n }\n aim()\n const r = rayWorld([aimO[0], aimO[1], aimO[2]], [aimD[0], aimD[1], aimD[2]], 3.2)\n if (!r) {\n say(t('hud.nothing_to_grab'))\n return false\n }\n const piece = rendererPieces.get(r.object)\n if (!piece) {\n say(t('hud.cannot_grab', { name: nameOf(r.object) }))\n return false\n }\n const kg = piece.mass\n if (kg > maxCarry) {\n say(t('hud.too_heavy', { name: nameOf(r.object), kg: num(kg, 0) }))\n return false\n }\n heldPiece = piece\n heldEntry = entries.get(r.object) ?? null\n heldName = nameOf(r.object)\n piece.held = true\n piece.sleeping = false\n // centre of the object's bounding box in its own space, to hold it by its middle\n const box = new THREE.Box3().setFromObject(piece.root)\n const c = box.getCenter(new THREE.Vector3())\n piece.root.updateMatrixWorld(true)\n heldLocal.copy(c).sub(piece.root.position)\n heldLocal.applyQuaternion(piece.root.quaternion.clone().invert())\n heldYaw = 0\n heldTilt = 0\n heldVel[0] = heldVel[1] = heldVel[2] = 0\n action('grab', t('act.grab', { name: heldName, kg: num(kg, 1) }), { objectId: r.object, itemId: entryOf(r.object)?.so.itemId, data: { massKg: Math.round(kg * 10) / 10 } })\n fire('grab', { held: true, objectId: r.object })\n return true\n }\n\n const throwHeld = (speed = 9): boolean => {\n if (!heldPiece) return false\n const piece = heldPiece\n const name = heldName\n const id = piece.objectId\n aim()\n releaseHeld()\n piece.velocity = [0, 0, 0]\n renderer.impulse(id, [aimD[0] * speed * piece.mass, (aimD[1] * speed + 1.2) * piece.mass, aimD[2] * speed * piece.mass])\n action('throw', t('act.throw', { name, speed: num(speed, 1) }), { objectId: id, itemId: entryOf(id)?.so.itemId, data: { speedMs: speed, massKg: piece.mass } })\n fire('throw', { objectId: id, speed })\n return true\n }\n\n const followHeld = (dt: number): void => {\n const piece = heldPiece\n if (!piece) return\n camera.updateMatrixWorld(true)\n const root = piece.root\n let pos: THREE_NS.Vector3\n const targetQ = tmpQ\n if (useItemPlayer) {\n // the hand frame follows the camera's yaw only, so looking down at the item does not tilt it\n const pose = useItemPlayer.pose()\n const handQ = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), player.yaw)\n pos = tmpV.set(pose.position[0], pose.position[1], pose.position[2]).applyQuaternion(handQ).add(camera.position)\n const eq = new THREE.Quaternion().setFromEuler(new THREE.Euler(pose.rotation[0], pose.rotation[1], pose.rotation[2], 'XYZ'))\n targetQ.copy(handQ).multiply(eq)\n targetQ.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), heldYaw))\n } else {\n pos = tmpV.set(0.05, -0.28, -1.15).applyMatrix4(camera.matrixWorld)\n targetQ.setFromAxisAngle(new THREE.Vector3(0, 1, 0), player.yaw + heldYaw)\n targetQ.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), -heldTilt))\n }\n const k = Math.min(1, (useItemPlayer ? 30 : 16) * dt)\n const px = root.position.x\n const py = root.position.y\n const pz = root.position.z\n root.quaternion.slerp(targetQ, Math.min(1, k * 0.9))\n // the middle of the carried object follows the target; the offset uses the current rotation so it does not orbit\n const off2 = tmpV2.copy(heldLocal).applyQuaternion(root.quaternion)\n root.position.set(root.position.x + (pos.x - off2.x - root.position.x) * k, root.position.y + (pos.y - off2.y - root.position.y) * k, root.position.z + (pos.z - off2.z - root.position.z) * k)\n if (dt > 0) {\n heldVel[0] = (root.position.x - px) / dt\n heldVel[1] = (root.position.y - py) / dt\n heldVel[2] = (root.position.z - pz) / dt\n }\n root.updateMatrixWorld(true)\n }\n\n const useItem = (useId: string): boolean => {\n const e = heldEntry\n if (!e?.containerId) return false\n const def = itemUseDefs.find((u) => u.id === useId)\n if (!def) return false\n const c = fluids.container(e.containerId)\n if (!c) return false\n if (def.liquids && def.liquids.length > 0 && (!c.liquid || !def.liquids.includes(c.liquid))) return false\n if ((useId === 'drink' || useId === 'sip' || useId === 'chug' || useId === 'pour' || useId === 'pour_out') && c.liters <= 1e-6) {\n say(t('hud.empty_container', { name: e.name }))\n return false\n }\n if (useItemPlayer && !useItemPlayer.done) return false\n useItemPlayer = createItemUse(fluids, e.containerId, def)\n useItemName = def.id\n action('use_item', t('act.use_item', { name: e.name, use: S.text[`use.${def.id}`] ?? def.id }), { objectId: e.so.objectId, itemId: e.so.itemId, data: { use: def.id } })\n return true\n }\n\n const updateItemUse = (dt: number): void => {\n if (!useItemPlayer) return\n useItemPlayer.update(dt)\n if (useItemPlayer.done) {\n useItemPlayer = null\n useItemName = ''\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Tap\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const TAP_ID = 'room_tap'\n const TAP_RATE = 0.25\n fluids.addTap({ id: TAP_ID, position: arena.tapSpout, liquid: 'water', rate: TAP_RATE, temperature: 16, on: false })\n const isTapOn = (): boolean => fluids.taps().some((x) => x.id === TAP_ID && x.on)\n const toggleTap = (on = !isTapOn()): boolean => {\n fluids.setTap(TAP_ID, on)\n action('tap', t(on ? 'act.tap.on' : 'act.tap.off'))\n return on\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Thrown and falling pieces: damage to what they hit\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const lastImpact = new Map<string, number>()\n /** Landings slower than this (m/s) are not logged (the renderer only treats 3 m/s and up as a hard landing; nothing below 1.5 m/s is ever worth a line). */\n const MIN_LANDING_LOG = 3\n const updateImpacts = (): void => {\n const check = (piece: Piece): void => {\n if (piece.held || piece.sleeping) return\n const v = piece.velocity\n const speed = Math.hypot(v[0], v[1], v[2])\n if (speed < 3.5) return\n if ((lastImpact.get(piece.objectId) ?? -9) > simTime - 0.25) return\n const dir: Vec3 = [v[0] / speed, v[1] / speed, v[2] / speed]\n const c = tmpV.copy(new THREE.Vector3(0, 0, 0))\n void c\n const box = tmpBox.setFromObject(piece.root)\n const centre = box.getCenter(tmpV)\n const size = box.getSize(tmpV2)\n const reach = Math.max(size.x, size.y, size.z) * 0.5\n const origin: Vec3 = [centre.x + dir[0] * (reach + 0.02), centre.y + dir[1] * (reach + 0.02), centre.z + dir[2] * (reach + 0.02)]\n const r = withoutHeld(() => world.raycast(origin, dir, speed * FIXED_DT * 2 + 0.06))\n if (!r || r.object === piece.objectId) return\n const energy = 0.5 * piece.mass * speed * speed\n lastImpact.set(piece.objectId, simTime)\n world.hitPart(r.object, r.part, { type: 'blunt', point: r.point, direction: dir, energy, radius: 0.08, source: 'thrown' })\n if (world.has(piece.objectId)) world.hit(piece.objectId, { type: 'blunt', point: r.point, direction: [-dir[0], -dir[1], -dir[2]], energy: energy * 0.4, radius: 0.08, source: 'thrown' })\n pushPiece(r.object, dir, piece.mass * speed * 0.5, r.point)\n piece.velocity = [-v[0] * 0.25, Math.abs(v[1]) * 0.3 + 0.5, -v[2] * 0.25]\n action('impact', t('act.impact', { name: nameOf(piece.objectId), where: hitWhere(r), energy: num(energy, 0), speed: num(speed, 1) }), {\n objectId: piece.objectId,\n itemId: entryOf(piece.objectId)?.so.itemId,\n data: { energyJ: Math.round(energy), speedMs: Math.round(speed * 10) / 10, target: r.object, targetPart: r.part },\n })\n }\n const land = (piece: Piece): void => {\n const vy = piece.velocity[1]\n const prev = prevVy.get(piece.objectId) ?? 0\n prevVy.set(piece.objectId, vy)\n // the renderer applies the landing damage itself (source 'fall'); here we only describe it in the log\n if (piece.held || prev > -MIN_LANDING_LOG || vy < prev + 2 || !world.has(piece.objectId)) return\n const energy = 0.5 * piece.mass * prev * prev\n action('landing', t('act.landing', { name: nameOf(piece.objectId), speed: num(-prev, 1), energy: num(energy, energy < 100 ? 1 : 0) }), {\n objectId: piece.objectId,\n itemId: entryOf(piece.objectId)?.so.itemId,\n data: { energyJ: Math.round(energy * 10) / 10, speedMs: Math.round(-prev * 10) / 10 },\n })\n }\n for (const e of entries.values()) if (e.piece) { check(e.piece); land(e.piece) }\n for (const p of loose) { check(p); land(p) }\n }\n const prevVy = new Map<string, number>()\n const tmpBox = new THREE.Box3()\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Keys\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const onKey = (code: string, down: boolean, e: KeyboardEvent): void => {\n if (!down) {\n if (code === 'KeyZ') tiltKey = 0\n return\n }\n const digit = /^Digit(\\d)$/.exec(code)\n if (digit && !e.ctrlKey && !e.metaKey) {\n const n = (Number(digit[1]) + 9) % 10\n const page = Math.floor(toolIndex / 10)\n const idx = page * 10 + n\n if (idx < loadout.length) setTool(loadout[idx])\n return\n }\n switch (code) {\n case 'KeyE':\n grab()\n break\n case 'KeyG':\n throwHeld()\n break\n case 'KeyR':\n if (heldPiece) heldYaw += Math.PI / 8\n else {\n startReload()\n say(t('hud.reloading'))\n }\n break\n case 'KeyQ': {\n const before = tool.mode\n const mode = tool.cycleMode()\n if (mode !== before) emitHost({ type: 'mode', weapon: toolId, mode })\n break\n }\n case 'KeyZ':\n tiltKey = 1\n break\n case 'KeyF':\n if (heldEntry?.uses[0]) useItem(heldEntry.uses[0])\n break\n case 'KeyC':\n if (heldEntry?.uses[1]) useItem(heldEntry.uses[1])\n break\n case 'KeyV':\n if (heldEntry?.uses[2]) useItem(heldEntry.uses[2])\n else kick()\n break\n case 'KeyT':\n toggleTap()\n break\n case 'KeyH': {\n const w = (heldEntry ?? entryOf(inspectTarget()?.object ?? ''))?.item?.weapon\n if (w) equip(w)\n break\n }\n case 'BracketRight':\n toolIndex = Math.min(loadout.length - 1, (Math.floor(toolIndex / 10) + 1) * 10)\n setTool(loadout[toolIndex])\n break\n case 'BracketLeft':\n toolIndex = Math.max(0, (Math.floor(toolIndex / 10) - 1) * 10)\n setTool(loadout[toolIndex])\n break\n case 'Tab':\n ui?.togglePanels()\n break\n default:\n break\n }\n }\n\n const equip = (weaponId: string): void => {\n if (!arsenal.weapons.has(weaponId)) return\n if (!loadout.includes(weaponId)) loadout.push(weaponId)\n setTool(weaponId)\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Inspector\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const inspectTarget = (): RayHit | null => {\n aim()\n return rayWorld(aimO, aimD, 14)\n }\n\n const inspectInfo = (): InspectInfo | null => {\n const r = inspectTarget()\n if (!r) return null\n const st = world.state(r.object)\n const p = world.part(r.object, r.part)\n if (!st || !p) return null\n const e = entryOf(r.object)\n const joints = st.joints\n .filter((j) => j.a === r.part || j.b === r.part)\n .map((j) => ({\n id: j.id,\n kind: dStrings.jointKinds[j.kind] ?? j.kind,\n tools: JOINT_DEFAULTS[j.kind].tools.map((k) => dStrings.toolKinds[k] ?? k),\n open: j.open,\n progress: j.progress,\n }))\n const ext = p as unknown as { load?: number; stress?: number }\n return {\n object: nameOf(r.object),\n objectId: r.object,\n part: r.part,\n material: S.text[`material.${p.material}`] ?? dStrings.materialNames[p.material] ?? p.material,\n status: dStrings.partStatus[p.status] ?? p.status,\n hp: p.hp,\n maxHp: p.maxHp,\n temperature: p.temperature,\n burning: p.burning,\n char: p.char,\n melt: p.melt,\n liters: p.liters,\n dents: p.dents.length,\n holes: p.holes.length,\n cracks: p.cracks.length,\n mass: p.mass,\n load: ext.load,\n stress: ext.stress,\n joints,\n note: e?.item?.note,\n distance: r.distance,\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Frame\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let timeScale = 1\n let fastForward = false\n let hudAcc = 1\n let metricsAcc = 0\n // when the room runs its own loop it feeds the counters the unclamped real delta; otherwise update(dt) is the only source\n let ownsLoop = false\n const roomMetricIds: readonly RoomMetricId[] = options.metrics === false ? [] : options.metrics ?? ROOM_METRICS\n const roomMetrics = createRoomMetrics({ gl, destruction: renderer, fluids: fluidView, ids: roomMetricIds })\n let qualityName: 'low' | 'medium' | 'high' = quality\n\n const syncContainers = (sdt: number): void => {\n for (const e of entries.values()) {\n if (!e.containerId) continue\n const host = hostOf(e)\n host.root.updateMatrixWorld(true)\n const q = host.root.getWorldQuaternion(tmpQ)\n const p = tmpV.set(e.fluidOffset[0], e.fluidOffset[1], e.fluidOffset[2]).applyMatrix4(host.root.matrixWorld)\n const vel: Vec3 | undefined = sdt > 0 ? [(p.x - e.last[0]) / sdt, (p.y - e.last[1]) / sdt, (p.z - e.last[2]) / sdt] : undefined\n e.last = [p.x, p.y, p.z]\n fluids.setTransform(e.containerId, [p.x, p.y, p.z], [q.x, q.y, q.z, q.w], vel)\n }\n }\n\n const syncLiters = (): void => {\n for (const e of entries.values()) {\n if (!e.containerId || !e.fluidPart) continue\n const c = fluids.container(e.containerId)\n if (!c) continue\n const host = hostOf(e)\n const part = world.part(host.objectId, e.fluidPart)\n if (part && part.liters !== undefined && Math.abs(part.liters - c.liters) > 1e-4) world.setLiters(host.objectId, e.fluidPart, c.liters)\n }\n }\n\n let paused = false\n let walkPlan: { x: number; z: number; remaining: number } | null = null\n const stepWalk = (dt: number): void => {\n if (!walkPlan) return\n const f = walkPlan.remaining <= dt ? 1 : dt / walkPlan.remaining\n player.moveBy((walkPlan.x - camera.position.x) * f, (walkPlan.z - camera.position.z) * f)\n walkPlan.remaining -= dt\n if (walkPlan.remaining <= 1e-9) walkPlan = null\n }\n\n const stepSim = (dt: number): void => {\n if (paused) return\n // `dt` is simulated seconds; real time only drives input\n simTime += dt\n stepWalk(dt)\n const reps = fastForward ? 10 : 1\n updateAnimations(dt)\n updateItemUse(dt)\n updateProjectiles(dt)\n syncContainers(dt)\n for (let i = 0; i < reps; i++) {\n world.update(dt)\n if (i === 0) updateFires(dt)\n fluids.update(dt)\n }\n syncLiters()\n renderer.update(dt)\n updateImpacts()\n fluidView.update(dt)\n for (const s of tools.values()) s.update(dt)\n if (reloadingSeen && !tool.reloading) emitHost({ type: 'reload', weapon: toolId, phase: 'end' })\n reloadingSeen = tool.reloading\n for (const update of frameListeners) update(dt)\n for (const tr of tracers) {\n if (tr.life > 0) {\n tr.life -= dt\n if (tr.life <= 0) tr.line.visible = false\n }\n }\n flush()\n }\n\n const update = (dt: number): void => {\n if (!ownsLoop) roomMetrics.frame(dt)\n player.update(dt)\n if (tiltKey || heldTilt > 0) {\n heldTilt = Math.max(0, Math.min(2.4, heldTilt + (tiltKey ? 2.2 : -3) * dt))\n }\n if (useHeld && !paused) {\n if (tool.def.category === 'hand') {\n if (useFirst) grab()\n } else useTool(dt, !useFirst)\n useFirst = false\n }\n if (!paused) followHeld(dt)\n stepSim(dt * timeScale)\n if (progress && simTime - progress.at > 0.25) progress = null\n hudAcc += dt\n if (hudAcc >= 0.1 && ui) {\n hudAcc = 0\n ui.hud(hudState())\n }\n metricsAcc += dt\n if (metricsAcc >= METRICS_INTERVAL_S && ui) {\n metricsAcc = 0\n if (ui.benchVisible) ui.metrics(metricRows())\n }\n }\n\n const hudState = (): HudState => {\n const page = Math.floor(toolIndex / 10)\n const slots = loadout.slice(page * 10, page * 10 + 10).map((id) => arsenal.name(id))\n const ammo = tool.def.action.kind === 'firearm' ? `${tool.ammo}/${tool.capacity}${tool.reserve ? ` · ${tool.reserve}` : ''}` : tool.def.action.kind === 'hand' ? '' : tool.def.action.kind === 'melee' || tool.def.action.kind === 'tool' ? '' : `${num(tool.ammo, 0)}`\n return {\n toolName: toolName(),\n toolId,\n ammo,\n slots,\n slot: toolIndex - page * 10,\n page: page + 1,\n pages: Math.max(1, Math.ceil(loadout.length / 10)),\n status: simTime - statusAt < 2 ? statusLine : '',\n progress: progress ? { label: progress.label, value: progress.value } : null,\n held: heldEntry || heldPiece ? { name: heldName, uses: (heldEntry?.uses ?? []).map((u, i) => ({ key: ['F', 'C', 'V'][i] ?? '', label: S.text[`use.${u}`] ?? u })), weapon: heldEntry?.item?.weapon ? arsenal.name(heldEntry.item.weapon) : undefined, using: useItemName } : null,\n inspect: inspectInfo(),\n animations: animationsOf(),\n locked: player.locked,\n timeScale,\n fast: fastForward,\n tap: isTapOn(),\n quality: qualityName,\n objects: [...entries.values()].filter((e) => !e.arena).length,\n }\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Item animations (clips of AnimationClipSpec)\n // ---------------------------------------------------------------------------------------------------------------------------------------\n interface Playing {\n entry: Entry\n clip: AnimationClipSpec\n t: number\n fired: number\n targets: Map<string, THREE_NS.Object3D>\n }\n const playing: Playing[] = []\n const restPose = new WeakMap<THREE_NS.Object3D, { p: Vec3; r: Vec3 }>()\n const ZERO: Vec3 = [0, 0, 0]\n const animTarget = (): Entry | undefined => {\n if (heldEntry) return heldEntry\n const r = inspectTarget()\n return r ? entryOf(r.object) : undefined\n }\n const poseAt = (clip: AnimationClipSpec, id: string | null, time: number): { position: Vec3; rotation: Vec3 } => {\n const pick = (k: AnimationClipSpec['keys'][number]): { position?: Vec3; rotation?: Vec3 } | undefined => (id === null ? k : k.parts?.[id])\n const pts = clip.keys.map((k) => ({ t: k.t, position: pick(k)?.position ?? ZERO, rotation: pick(k)?.rotation ?? ZERO }))\n if (pts.length === 0 || pts[0].t > 0) pts.unshift({ t: 0, position: ZERO, rotation: ZERO })\n let a = pts[0]\n let b = pts[pts.length - 1]\n if (time >= b.t) a = b\n else for (let i = 0; i < pts.length - 1; i++) if (time >= pts[i].t && time < pts[i + 1].t) [a, b] = [pts[i], pts[i + 1]]\n const f = a === b || b.t <= a.t ? 0 : (time - a.t) / (b.t - a.t)\n const mix = (x: Vec3, y: Vec3): Vec3 => [x[0] + (y[0] - x[0]) * f, x[1] + (y[1] - x[1]) * f, x[2] + (y[2] - x[2]) * f]\n return { position: mix(a.position, b.position), rotation: mix(a.rotation, b.rotation) }\n }\n const applyClip = (pl: Playing): void => {\n for (const [id, obj] of pl.targets) {\n const rest = restPose.get(obj)\n if (!rest) continue\n const pose = poseAt(pl.clip, id === '' ? null : id, pl.t)\n obj.position.set(rest.p[0] + pose.position[0], rest.p[1] + pose.position[1], rest.p[2] + pose.position[2])\n obj.rotation.set(rest.r[0] + pose.rotation[0], rest.r[1] + pose.rotation[1], rest.r[2] + pose.rotation[2])\n // animations are visual only: move the part's collision/raycast shape to the same pose (spec rest + clip offset)\n const ps = id === '' ? undefined : specs.get(pl.entry.so.objectId)?.parts.find((p) => p.id === id)\n if (ps) {\n const r0 = ps.rotation ?? ZERO\n world.setPartPose(\n pl.entry.so.objectId, id,\n [ps.position[0] + pose.position[0], ps.position[1] + pose.position[1], ps.position[2] + pose.position[2]],\n [r0[0] + pose.rotation[0], r0[1] + pose.rotation[1], r0[2] + pose.rotation[2]],\n )\n }\n }\n }\n const updateAnimations = (dt: number): void => {\n for (let i = playing.length - 1; i >= 0; i--) {\n const pl = playing[i]\n pl.t = Math.min(pl.clip.duration, pl.t + dt)\n applyClip(pl)\n const evs = pl.clip.events ?? []\n while (pl.fired < evs.length && evs[pl.fired].t <= pl.t) {\n const ev = evs[pl.fired++]\n action('animation_event', t('act.anim_event', { name: pl.entry.name, clip: pl.clip.id, type: ev.type }), { objectId: pl.entry.so.objectId, itemId: pl.entry.so.itemId, data: { clip: pl.clip.id, type: ev.type, at: ev.t, ...(ev.data ?? {}) } })\n const key = ev.type === 'sound' ? ev.data?.key : undefined\n if (typeof key === 'string') options.onSound?.(key, v3(pl.entry.so.root.getWorldPosition(tmpV)), 1)\n }\n if (pl.t >= pl.clip.duration) {\n playing.splice(i, 1)\n action('animation_end', t('act.anim_end', { name: pl.entry.name, clip: pl.clip.id }), { objectId: pl.entry.so.objectId, itemId: pl.entry.so.itemId, data: { clip: pl.clip.id } })\n }\n }\n }\n const animationsOf = (): AnimationInfo | null => {\n const e = animTarget()\n if (!e || e.arena) return null\n const clips = (e.item?.animations ?? []).map((c) => ({ id: c.id, duration: c.duration }))\n return { objectId: e.so.objectId, itemId: e.so.itemId, name: e.name, clips, playing: playing.find((p) => p.entry === e)?.clip.id ?? null }\n }\n const playAnimation = (clipId: string, objectId?: string): boolean => {\n const e = objectId ? entries.get(objectId) : animTarget()\n const clip = e?.item?.animations?.find((c) => c.id === clipId)\n if (!e || !clip) return false\n for (let i = playing.length - 1; i >= 0; i--) if (playing[i].entry === e && playing[i].clip.id === clipId) playing.splice(i, 1)\n const targets = new Map<string, THREE_NS.Object3D>()\n const ids = new Set<string>()\n for (const k of clip.keys) for (const id of Object.keys(k.parts ?? {})) ids.add(id)\n const grab = (key: string, obj: THREE_NS.Object3D | undefined): void => {\n if (!obj) return\n if (!restPose.has(obj)) restPose.set(obj, { p: [obj.position.x, obj.position.y, obj.position.z], r: [obj.rotation.x, obj.rotation.y, obj.rotation.z] })\n targets.set(key, obj)\n }\n if (clip.keys.some((k) => k.position || k.rotation)) grab('', e.so.root)\n for (const id of ids) grab(id, e.so.root.getObjectByName(id) ?? undefined)\n const pl: Playing = { entry: e, clip, t: 0, fired: 0, targets }\n playing.push(pl)\n applyClip(pl)\n action('animation', t('act.anim_start', { name: e.name, clip: clip.id, seconds: num(clip.duration, 1) }), { objectId: e.so.objectId, itemId: e.so.itemId, data: { clip: clip.id, duration: clip.duration } })\n return true\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // Scenarios and modules\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const extraScenarios: TestRoomScenario[] = [...(options.scenarios ?? [])]\n const moduleCheck = (ok: boolean, text: string, data: Record<string, unknown>, itemId?: string): void => {\n log.add({ channel: 'check', type: ok ? 'pass' : 'fail', text: `${ok ? '✓' : '✗'} ${text}`, itemId, data: { ok, ...data } })\n }\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // What modules get from the room (game-contracts ModuleHost): the scene, the tool events and the frame\n // ---------------------------------------------------------------------------------------------------------------------------------------\n const modules = new Map<string, TestableModule<ScenarioContext>>()\n const detachers = new Map<string, () => void>()\n const benches = new Map<string, BenchStore>()\n let activeBench: string | null = null\n const lastBench = (): string | null => [...benches.keys()].pop() ?? null\n const benchView = (): BenchView | null => {\n const store = activeBench ? benches.get(activeBench) : undefined\n if (!store) return null\n return { title: modules.get(store.moduleId)?.name ?? store.moduleId, controls: store.controls(), layers: store.layers() }\n }\n const METRIC_UNAVAILABLE = 'n/a'\n const metricText = (value: number | string | undefined, digits: number, unit?: string): string =>\n typeof value === 'number' ? `${num(value, digits)}${unit ? ` ${unit}` : ''}` : value ?? METRIC_UNAVAILABLE\n const reportedFailures = new Set<string>()\n // a module's failure is told once (not every metrics tick) in the room log\n const reportOnce = (key: string, text: string): void => {\n if (reportedFailures.has(key)) return\n reportedFailures.add(key)\n host.log(text)\n }\n const failureText = (error: unknown): string => (error instanceof Error ? error.message : String(error))\n const moduleMetrics = (): Record<string, number | string> => {\n const store = activeBench ? benches.get(activeBench) : undefined\n const out: Record<string, number | string> = {}\n for (const metric of store?.metrics ?? []) {\n try {\n out[metric.id] = metric.read()\n } catch (error) {\n out[metric.id] = METRIC_UNAVAILABLE\n reportOnce(`${store?.moduleId}:metric:${metric.id}`, t('mod.metric_failed', { name: modules.get(store?.moduleId ?? '')?.name ?? '', metric: metric.id, error: failureText(error) }))\n }\n }\n return out\n }\n const metricRows = (): { room: MetricRow[]; module: MetricRow[] } => {\n const sampled = roomMetrics.sample()\n const room = roomMetricIds.flatMap((id) => {\n const value = sampled[id]\n return value === undefined ? [] : [{ id, name: t(`metric.${id}`), text: num(value, id === 'frame_ms' ? 1 : 0) }]\n })\n const values = moduleMetrics()\n const declared = (activeBench ? benches.get(activeBench)?.metrics : undefined) ?? []\n const module = declared.map((metric) => {\n const value = values[metric.id]\n const ratio = metric.max && typeof value === 'number' ? value / metric.max : undefined\n return { id: metric.id, name: metric.name, text: metricText(value, metric.digits ?? 0, metric.unit), ...(ratio === undefined ? {} : { ratio }) }\n })\n return { room, module }\n }\n const showBench = (): void => {\n if (!ui) return\n ui.bench(benchView())\n ui.metrics(metricRows())\n }\n const hostListeners = new Set<(event: HostEvent) => void>()\n const frameListeners = new Set<(dt: number) => void>()\n let reloadingSeen = false\n function emitHost(event: HostEvent): void {\n for (const listener of hostListeners) listener(event)\n }\n function startReload(): void {\n if (tool.reload()) emitHost({ type: 'reload', weapon: toolId, phase: 'start' })\n }\n const host: ModuleHost = {\n THREE,\n scene,\n camera,\n locale,\n groundAt,\n tool: () => ({ weapon: toolId, category: tool.def.category, ammo: tool.ammo, capacity: tool.capacity, reserve: tool.reserve, reloading: tool.reloading, mode: tool.mode }),\n on(listener) {\n hostListeners.add(listener)\n return () => hostListeners.delete(listener)\n },\n onFrame(update) {\n frameListeners.add(update)\n return () => frameListeners.delete(update)\n },\n log(text, data) {\n action('module_note', text, { data })\n },\n }\n const lendBench = (store: BenchStore): ModuleBench => ({\n value: store.value,\n layer: store.layer,\n onChange: store.onChange,\n patch: store.patch,\n look: (eye, target) => room.look(eye, target),\n })\n const checkModuleBench = (mod: TestableModule<ScenarioContext>, fail: (problem: string) => void): BenchStore | null => {\n const store = createBenchStore(mod, locale, (error) => reportOnce(`${mod.id}:listener`, t('mod.listener_failed', { name: mod.name, error: failureText(error) })))\n const { controls, layers, metrics } = store.declared\n if (controls.length + layers.length + metrics.length === 0) return null\n const r = checkBench(store.declared)\n const text = r.ok ? t('mod.bench_ok', { name: mod.name, controls: controls.length, layers: layers.length, metrics: metrics.length }) : t('mod.bench_fail', { name: mod.name, problems: r.problems.join('; ') })\n moduleCheck(r.ok, text, { module: mod.id, check: 'bench', problems: r.problems })\n for (const p of r.problems) fail(`bench: ${p}`)\n return r.ok ? store : null\n }\n\n const loadModule = (mod: TestableModule<ScenarioContext>): ModuleReport => {\n const report: ModuleReport = { module: mod.id, items: [], scenarios: [], ok: true, problems: [] }\n const fail = (problem: string): void => {\n report.ok = false\n report.problems.push(problem)\n }\n const added = mod.items(locale)\n for (const ti of added) {\n const item: TestRoomItem = {\n id: ti.id,\n name: ti.name,\n group: mod.group,\n build: (T) => ti.build(T) as THREE_NS.Object3D,\n spec: ti.spec as TestRoomItem['spec'],\n movable: ti.movable,\n fluid: ti.fluid,\n weapon: ti.weapon,\n impl: ti.impl as TestRoomItem['impl'],\n animations: ti.animations,\n }\n catalogMap.set(item.id, item)\n const at = catalog.findIndex((c) => c.id === item.id)\n if (at >= 0) catalog[at] = item\n else catalog.push(item)\n report.items.push(item.id)\n // contract checks on a throwaway build of the item (never added to the scene)\n let partIds: string[] = []\n const base = { module: mod.id, item: item.id }\n try {\n const root = item.build(THREE)\n root.updateMatrixWorld(true)\n if (item.impl) {\n const probe = item.impl(root, `${item.id}_check`)\n const r = checkDestructible(probe, { materials: world.materials.keys() })\n partIds = probe.describe().parts.map((p) => p.id)\n moduleCheck(r.ok, r.ok ? t('mod.destructible_ok', { name: item.name, parts: partIds.length }) : t('mod.destructible_fail', { name: item.name, problems: r.problems.join('; ') }), { ...base, check: 'destructible', problems: r.problems }, item.id)\n for (const p of r.problems) fail(`${item.id}: ${p}`)\n }\n if (!item.impl || item.spec) {\n // the spec is resolved after the build (it may be a function of the root, or derived from the meshes)\n const spec = resolveSpec(item, root).spec\n if (!item.impl) partIds = spec.parts.map((p) => p.id)\n const r = checkSpec(spec, { materials: world.materials.keys() })\n moduleCheck(r.ok, r.ok ? t('mod.spec_ok', { name: item.name, parts: spec.parts.length }) : t('mod.spec_fail', { name: item.name, problems: r.problems.join('; ') }), { ...base, check: 'spec', problems: r.problems, warnings: r.warnings }, item.id)\n for (const p of r.problems) fail(`${item.id}: ${p}`)\n for (const w of r.warnings) log.add({ channel: 'check', type: 'warn', text: `⚠ ${t('mod.spec_warn', { name: item.name, warning: w })}`, itemId: item.id, data: { ok: true, ...base, check: 'spec', warning: w } })\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n moduleCheck(false, t('mod.destructible_fail', { name: item.name, problems: msg }), { ...base, check: 'destructible', problems: [msg] }, item.id)\n fail(`${item.id}: ${msg}`)\n }\n for (const clip of item.animations ?? []) {\n const r = checkAnimation(clip, partIds)\n moduleCheck(r.ok, r.ok ? t('mod.animation_ok', { name: item.name, clip: clip.id, seconds: num(clip.duration, 1) }) : t('mod.animation_fail', { name: item.name, clip: clip.id, problems: r.problems.join('; ') }), { ...base, check: 'animation', clip: clip.id, problems: r.problems }, item.id)\n for (const p of r.problems) fail(`${item.id}: ${p}`)\n }\n }\n for (const ms of mod.scenarios?.(locale) ?? []) {\n const sc: TestRoomScenario = { id: ms.id, name: ms.name, run: ms.run }\n const at = extraScenarios.findIndex((x) => x.id === sc.id)\n if (at >= 0) extraScenarios[at] = sc\n else extraScenarios.push(sc)\n report.scenarios.push(sc.id)\n }\n action('module', t('act.module_loaded', { name: mod.name, items: report.items.length, scenarios: report.scenarios.length, result: t(report.ok ? 'mod.all_ok' : 'mod.some_failed') }), { data: { module: mod.id, items: report.items, scenarios: report.scenarios, ok: report.ok } })\n const bench = checkModuleBench(mod, fail)\n detachers.get(mod.id)?.()\n detachers.delete(mod.id)\n // a reloaded module keeps its live bench state; the host's state only seeds a module the room has not seen\n const previous = benches.get(mod.id)\n const kept = previous?.encode()\n previous?.dispose()\n benches.delete(mod.id)\n for (const key of [...reportedFailures]) if (key.startsWith(`${mod.id}:`)) reportedFailures.delete(key)\n modules.set(mod.id, mod)\n if (bench) {\n const seed = options.bench?.state?.[mod.id]\n const restored = kept ?? (typeof seed === 'string' ? seed : undefined)\n if (restored !== undefined) bench.restore(restored)\n benches.set(mod.id, bench)\n bench.watch(() => {\n options.bench?.onChange?.(mod.id, bench.encode())\n if (activeBench === mod.id) ui?.bench(benchView())\n })\n if (!activeBench || !benches.has(activeBench)) activeBench = mod.id\n } else if (activeBench === mod.id) activeBench = lastBench()\n if (mod.attach) detachers.set(mod.id, mod.attach(bench ? { ...host, bench: lendBench(bench) } : host))\n bench?.sendInitial()\n showBench()\n ui?.refresh()\n return report\n }\n\n const allScenarios = (): TestRoomScenario[] => [...makeScenarios(t, num, locale), ...extraScenarios]\n let scenarioRunning = false\n\n const step = (seconds: number): void => {\n const dt = seconds > 6 ? 1 / 30 : FIXED_DT\n const n = Math.max(1, Math.round(seconds / dt))\n for (let i = 0; i < n; i++) {\n player.update(0)\n followHeld(dt)\n stepSim(dt)\n }\n }\n\n const runScenarios = async (list?: TestRoomScenario[]): Promise<ScenarioReport> => {\n const all = list ?? allScenarios()\n const report: ScenarioReport = { passed: 0, failed: 0, results: [] }\n scenarioRunning = true\n const wasPaused = paused\n paused = false\n try {\n for (const sc of all) {\n hardReset()\n player.look(arena.playerStart, [0, 1.5, arena.wallZ])\n useHeld = false\n const checks: Array<{ label: string; ok: boolean }> = []\n log.add({ channel: 'check', type: 'scenario', text: t('sc.start', { name: sc.name }), data: { id: sc.id } })\n const ctx: ScenarioContext = {\n room,\n step,\n expect(condition, label, data) {\n checks.push({ label, ok: !!condition })\n log.add({ channel: 'check', type: condition ? 'pass' : 'fail', text: `${condition ? '✓' : '✗'} ${label}`, data: { scenario: sc.id, ok: !!condition, ...(data ?? {}) } })\n },\n }\n try {\n await sc.run(ctx)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n ctx.expect(false, t('sc.error', { msg }))\n }\n flush()\n const ok = checks.length > 0 && checks.every((c) => c.ok)\n report.results.push({ id: sc.id, name: sc.name, ok, checks })\n if (ok) report.passed++\n else report.failed++\n log.add({ channel: 'check', type: ok ? 'scenario_pass' : 'scenario_fail', text: t(ok ? 'sc.pass' : 'sc.fail', { name: sc.name }), data: { id: sc.id, ok } })\n await new Promise<void>((res) => setTimeout(res, 0))\n }\n } finally {\n scenarioRunning = false\n paused = wasPaused\n }\n return report\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // The room object\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // lays a module area: things that hold others first, so what goes on them finds their top\n const layArea = (layout: ModuleArea): SpawnedObject[] => {\n const holders = layout.placements.filter((p) => p.surface)\n const rest = layout.placements.filter((p) => !p.surface)\n const placed = [...holders, ...rest].map((p) => {\n const so = spawn(p.item, p.position, p.rotationY ?? 0)\n if (p.surface) {\n const [hx, hz] = p.surface.halfSize\n restingTops.push({ objectId: so.objectId, minX: p.position[0] - hx, maxX: p.position[0] + hx, minZ: p.position[2] - hz, maxZ: p.position[2] + hz, top: p.surface.height })\n }\n return { so, asleep: p.asleep === true }\n })\n for (const { so, asleep } of placed) {\n const piece = asleep ? rendererPieces.get(so.objectId) : undefined\n if (piece) piece.sleeping = true\n }\n if (layout.view) room.look(layout.view.eye, layout.view.target)\n return placed.map(({ so }) => so)\n }\n\n // a test environment per catalogue group, the way the demo site links each area of the index: a loaded module brings its own area,\n // any other group is laid in rows (small things in front, fixed big ones behind)\n const openArea = (area: string): SpawnedObject[] => {\n clear()\n const mod = [...modules.values()].find((m) => m.id === area || m.group === area)\n const label = mod?.group ?? S.groups[area] ?? area\n ui?.showGroup(label)\n activeBench = mod && benches.has(mod.id) ? mod.id : lastBench()\n showBench()\n const layout = mod?.area?.(locale)\n if (layout) return layArea(layout)\n const items = catalog.filter((item) => item.group === label)\n const front = items.filter((item) => item.movable !== false)\n const back = items.filter((item) => item.movable === false)\n const row = (list: TestRoomItem[], gap: number, z: number): SpawnedObject[] => list.map((item, index) => spawn(item.id, [(index - (list.length - 1) / 2) * gap, 0, z], 0))\n return [...row(front, 1.6, 1.5), ...row(back, 4.5, -4)]\n }\n\n const room: TestRoom & {\n tilt(rad: number): void\n toggleTap(on?: boolean): boolean\n setSlowMotion(on: boolean): void\n setFastForward(on: boolean): void\n equip(weaponId: string): void\n readonly scenarios: TestRoomScenario[]\n readonly fluidRenderer: FluidRenderer\n inspectInfo(): InspectInfo | null\n } = {\n world,\n renderer,\n scene,\n camera,\n arsenal,\n fluids,\n fluidRenderer: fluidView,\n log,\n get tool() {\n return tool\n },\n get scenarios() {\n return allScenarios()\n },\n spawn,\n clear,\n resetAll,\n setTool,\n useItem,\n use(hold = 0) {\n if (tool.def.category === 'hand') {\n grab()\n return\n }\n useTool(FIXED_DT, false)\n flush()\n let t0 = 0\n while (t0 < hold) {\n useTool(FIXED_DT, true)\n stepSim(FIXED_DT)\n t0 += FIXED_DT\n }\n tool.release()\n },\n grab,\n throwHeld,\n look(position, target) {\n player.look(position, target)\n },\n inspect() {\n const r = inspectTarget()\n if (!r) return null\n return { objectId: r.object, partId: r.part, itemId: entryOf(r.object)?.so.itemId ?? '' }\n },\n inspectInfo,\n spawned() {\n return [...entries.values()].filter((e) => !e.arena).map((e) => e.so)\n },\n update,\n on(type, fn) {\n listeners[type].add(fn)\n return () => listeners[type].delete(fn)\n },\n runScenarios,\n tilt(rad) {\n heldTilt = rad\n },\n toggleTap,\n pause() {\n paused = true\n },\n resume() {\n paused = false\n },\n get paused() {\n return paused\n },\n walk(to, seconds) {\n walkPlan = seconds > 0 ? { x: to[0], z: to[2], remaining: seconds } : null\n if (!walkPlan) player.moveBy(to[0] - camera.position.x, to[2] - camera.position.z)\n },\n setSlowMotion(on) {\n timeScale = on ? 0.25 : 1\n },\n setFastForward(on) {\n fastForward = on\n },\n equip,\n openArea,\n loadModule,\n animations: animationsOf,\n playAnimation,\n bench(moduleId) {\n const id = moduleId ?? activeBench\n return (id ? benches.get(id) : undefined) ?? null\n },\n metrics() {\n return { room: roomMetrics.sample(), module: moduleMetrics() }\n },\n dispose() {\n for (const detach of detachers.values()) detach()\n detachers.clear()\n for (const store of benches.values()) store.dispose()\n benches.clear()\n cancelAnimationFrame?.(raf)\n window.removeEventListener('resize', onResize)\n player.dispose()\n ui?.dispose()\n renderer.dispose()\n fluidView.dispose()\n for (const tr of tracers) tr.line.removeFromParent()\n clearProjectileMeshes()\n if (ownRenderer) {\n gl.dispose()\n dom.remove()\n }\n },\n }\n\n // ---------------------------------------------------------------------------------------------------------------------------------------\n // UI and loop\n // ---------------------------------------------------------------------------------------------------------------------------------------\n let ui: RoomUi | null = null\n if (options.ui !== false) {\n const groups = (): Map<string, TestRoomItem[]> => {\n const m = new Map<string, TestRoomItem[]>()\n for (const i of catalog) {\n const g = m.get(i.group) ?? []\n g.push(i)\n m.set(i.group, g)\n }\n return m\n }\n ui = createUi({\n container,\n strings: S,\n t,\n log,\n groups,\n loadout: () => loadout.map((id) => ({ id, name: arsenal.name(id) })),\n onSpawn: (id) => {\n spawn(id)\n },\n onEquip: (itemId) => {\n const w = catalogMap.get(itemId)?.weapon\n if (w) equip(w)\n },\n onClear: clear,\n onResetAll: resetAll,\n onSlow: (on) => room.setSlowMotion(on),\n onFast: (on) => room.setFastForward(on),\n onQuality: (q) => {\n qualityName = q\n if (ownRenderer) {\n gl.shadowMap.enabled = q !== 'low'\n gl.setPixelRatio(q === 'low' ? 1 : Math.min(typeof devicePixelRatio === 'number' ? devicePixelRatio : 1, 2))\n arena.sun.shadow.mapSize.set(q === 'high' ? 2048 : 1024, q === 'high' ? 2048 : 1024)\n arena.sun.shadow.map?.dispose()\n arena.sun.shadow.map = null\n resize()\n }\n },\n quality: qualityName,\n scenarios: allScenarios,\n onRun: async (sc) => {\n await runScenarios([sc])\n },\n onRunAll: async () => {\n await runScenarios()\n },\n onTool: (index) => {\n toolIndex = index\n setTool(loadout[index])\n },\n onTap: () => toggleTap(),\n onPlay: (objectId, clipId) => {\n playAnimation(clipId, objectId)\n },\n onResize: resize,\n onControl: (id, value) => {\n if (activeBench) benches.get(activeBench)?.set(id, value)\n },\n onLayer: (id, on) => {\n if (activeBench) benches.get(activeBench)?.setLayer(id, on)\n },\n onAction: (id) => {\n if (activeBench) benches.get(activeBench)?.act(id)\n },\n })\n ui.hud(hudState())\n showBench()\n }\n\n let raf = 0\n if (ownRenderer && typeof requestAnimationFrame === 'function') {\n let last = performance.now()\n ownsLoop = true\n const loop = (now: number): void => {\n raf = requestAnimationFrame(loop)\n const realDelta = (now - last) / 1000\n roomMetrics.frame(realDelta)\n const dt = Math.min(0.05, realDelta)\n last = now\n if (!scenarioRunning) update(dt)\n gl.render(scene, camera)\n roomMetrics.rendered()\n }\n raf = requestAnimationFrame(loop)\n }\n\n if (options.initial) {\n for (const [i, id] of options.initial.entries()) spawn(id, [(i - (options.initial.length - 1) / 2) * 1.3, 0, 0.5])\n }\n if (options.area) openArea(options.area)\n\n return room\n}\n\nfunction structuredCloneSpec(spec: DestructibleSpec): DestructibleSpec {\n return JSON.parse(JSON.stringify(spec)) as DestructibleSpec\n}\n","import type * as THREE_NS from 'three'\nimport { buildFrame } from '@adatechnology/game-destruction'\nimport type { DestructibleSpec, JointSpec, MaterialDef, PartSpec, Vec3 } from '@adatechnology/game-destruction'\nimport { buildFromSpec } from './build-from-spec'\nimport { resolveStrings } from './locale'\nimport type { TestRoomItem } from './types'\n\n/**\n * Extra materials the demo items need on top of the core ones. None any more (the bottle uses the core `glass`, which now breaks from a drop);\n * kept so that code passing it to `worldOptions.materials` keeps working.\n */\nexport const DEMO_MATERIALS: MaterialDef[] = []\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Small spec helpers\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\n\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst cyl = (id: string, material: string, radius: number, height: number, position: Vec3, extra: Extra = {}): PartSpec => ({\n id,\n material,\n shape: { kind: 'cylinder', radius, height },\n position,\n ...extra,\n})\nconst sph = (id: string, material: string, radius: number, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'sphere', radius }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind'], extra: Partial<JointSpec> = {}): JointSpec => ({ a, b, kind, ...extra })\n\n/** Spec of the brick target wall: `cols` x `rows` brick panels, the bottom row anchored, mortar joints between neighbours. */\nexport function brickWallSpec(cols = 8, rows = 6, panel: Vec3 = [1.25, 0.5, 0.2]): DestructibleSpec {\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n const id = (c: number, r: number): string => `brick_${r}_${c}`\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n parts.push(box(id(c, r), 'brick', panel, [(c - (cols - 1) / 2) * panel[0], panel[1] / 2 + r * panel[1], 0], { anchored: r === 0 }))\n if (c > 0) joints.push(joint(id(c - 1, r), id(c, r), 'mortar'))\n if (r > 0) joints.push(joint(id(c, r - 1), id(c, r), 'mortar'))\n }\n }\n return { name: 'brick wall', parts, joints, tags: ['structure'] }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Demo specs\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\nconst chair = (): DestructibleSpec => {\n const legs = [\n [-0.18, -0.18],\n [0.18, -0.18],\n [-0.18, 0.18],\n [0.18, 0.18],\n ]\n return {\n name: 'chair',\n parts: [\n box('seat', 'wood_soft', [0.42, 0.04, 0.42], [0, 0.45, 0]),\n ...legs.map(([x, z], i) => box(`leg_${i + 1}`, 'wood_soft', [0.04, 0.43, 0.04], [x, 0.215, z])),\n box('backrest', 'wood_soft', [0.4, 0.3, 0.03], [0, 0.64, -0.195]),\n ],\n joints: [...legs.map((_, i) => joint(`leg_${i + 1}`, 'seat', 'screw')), joint('backrest', 'seat', 'screw')],\n tags: ['furniture'],\n }\n}\n\nconst crate = (): DestructibleSpec => ({\n name: 'wooden crate',\n parts: [\n box('front', 'wood_soft', [0.5, 0.5, 0.02], [0, 0.25, 0.24], { hp: 70 }),\n box('back', 'wood_soft', [0.5, 0.5, 0.02], [0, 0.25, -0.24], { hp: 70 }),\n box('left', 'wood_soft', [0.02, 0.5, 0.46], [-0.24, 0.25, 0], { hp: 70 }),\n box('right', 'wood_soft', [0.02, 0.5, 0.46], [0.24, 0.25, 0], { hp: 70 }),\n box('bottom', 'wood_soft', [0.46, 0.02, 0.46], [0, 0.01, 0], { hp: 70 }),\n ],\n joints: [\n joint('front', 'left', 'nail'),\n joint('front', 'right', 'nail'),\n joint('back', 'left', 'nail'),\n joint('back', 'right', 'nail'),\n joint('front', 'bottom', 'nail'),\n joint('back', 'bottom', 'nail'),\n joint('left', 'bottom', 'nail'),\n joint('right', 'bottom', 'nail'),\n ],\n tags: ['container'],\n})\n\nconst drum = (): DestructibleSpec => ({\n name: 'steel drum',\n parts: [\n cyl('drum_body', 'steel', 0.29, 0.86, [0, 0.45, 0], { mass: 12, thickness: 0.0012 }),\n cyl('drum_top', 'steel', 0.29, 0.02, [0, 0.89, 0], { mass: 1.5, thickness: 0.0012 }),\n cyl('drum_bottom', 'steel', 0.29, 0.02, [0, 0.01, 0], { mass: 1.5, thickness: 0.0012 }),\n ],\n joints: [joint('drum_body', 'drum_top', 'weld'), joint('drum_body', 'drum_bottom', 'weld')],\n tags: ['container'],\n})\n\nconst steelSheet = (): DestructibleSpec => ({\n name: 'steel sheet',\n parts: [\n box('sheet', 'steel', [1, 1, 0.003], [0, 1.1, 0]),\n box('post_l', 'steel', [0.04, 0.54, 0.04], [-0.35, 0.33, 0], { mass: 4 }),\n box('post_r', 'steel', [0.04, 0.54, 0.04], [0.35, 0.33, 0], { mass: 4 }),\n box('foot_l', 'steel', [0.06, 0.06, 0.5], [-0.35, 0.03, 0], { mass: 6 }),\n box('foot_r', 'steel', [0.06, 0.06, 0.5], [0.35, 0.03, 0], { mass: 6 }),\n ],\n joints: [joint('sheet', 'post_l', 'weld'), joint('sheet', 'post_r', 'weld'), joint('post_l', 'foot_l', 'weld'), joint('post_r', 'foot_r', 'weld')],\n tags: ['structure'],\n})\n\nconst glassPane = (): DestructibleSpec => ({\n name: 'glass pane',\n parts: [\n box('pane', 'glass', [0.8, 1, 0.006], [0, 1.05, 0], { hp: 40 }),\n box('frame_top', 'aluminium', [0.88, 0.04, 0.04], [0, 1.57, 0], { mass: 1 }),\n box('frame_bottom', 'aluminium', [0.88, 0.04, 0.04], [0, 0.53, 0], { mass: 1 }),\n box('frame_l', 'aluminium', [0.04, 1.04, 0.04], [-0.42, 1.05, 0], { mass: 1 }),\n box('frame_r', 'aluminium', [0.04, 1.04, 0.04], [0.42, 1.05, 0], { mass: 1 }),\n box('foot_l', 'steel', [0.06, 0.5, 0.4], [-0.35, 0.25, 0], { mass: 5 }),\n box('foot_r', 'steel', [0.06, 0.5, 0.4], [0.35, 0.25, 0], { mass: 5 }),\n ],\n joints: [\n joint('pane', 'frame_top', 'clip'),\n joint('pane', 'frame_bottom', 'clip'),\n joint('pane', 'frame_l', 'clip'),\n joint('pane', 'frame_r', 'clip'),\n joint('frame_bottom', 'foot_l', 'bolt'),\n joint('frame_bottom', 'foot_r', 'bolt'),\n joint('frame_l', 'frame_top', 'weld'),\n joint('frame_r', 'frame_top', 'weld'),\n joint('frame_l', 'frame_bottom', 'weld'),\n joint('frame_r', 'frame_bottom', 'weld'),\n ],\n tags: ['structure'],\n})\n\nconst concreteBlock = (): DestructibleSpec => ({\n name: 'concrete block',\n parts: [box('block', 'concrete', [0.4, 0.4, 0.4], [0, 0.2, 0])],\n tags: ['structure'],\n})\n\nconst brickColumn = (): DestructibleSpec => {\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n const layers = 8\n const id = (l: number, x: number, z: number): string => `brick_${l}_${x}${z}`\n for (let l = 0; l < layers; l++) {\n for (let x = 0; x < 2; x++) {\n for (let z = 0; z < 2; z++) {\n parts.push(box(id(l, x, z), 'brick', [0.2, 0.2, 0.2], [(x - 0.5) * 0.2, 0.1 + l * 0.2, (z - 0.5) * 0.2], { anchored: l === 0 }))\n if (x > 0) joints.push(joint(id(l, x - 1, z), id(l, x, z), 'mortar'))\n if (z > 0) joints.push(joint(id(l, x, z - 1), id(l, x, z), 'mortar'))\n if (l > 0) joints.push(joint(id(l - 1, x, z), id(l, x, z), 'mortar'))\n }\n }\n }\n return { name: 'brick column', parts, joints, tags: ['structure'] }\n}\n\n/**\n * A small house frame (2 x 2 columns on foundations, beams, a roof slab) from the core's `buildFrame`. The columns are rated at 4.4 t so that\n * losing one column leaves the roof standing (the others carry about 90% of their capacity) and losing two overloads the rest until the roof\n * comes down.\n */\nconst frame = (): DestructibleSpec => ({ ...buildFrame({ spanX: 4, spanZ: 4, columnsX: 2, columnsZ: 2, height: 2.8, floors: 1, walls: false, roof: true, columnCapacity: 4400 }), name: 'building frame' })\n\nconst bucket = (): DestructibleSpec => ({\n name: 'plastic bucket',\n parts: [\n cyl('bucket_body', 'plastic', 0.14, 0.28, [0, 0.14, 0], { mass: 0.5, thickness: 0.002 }),\n box('handle', 'plastic', [0.3, 0.012, 0.012], [0, 0.3, 0], { mass: 0.05 }),\n ],\n joints: [joint('handle', 'bucket_body', 'clip')],\n tags: ['container'],\n})\n\nconst bottle = (): DestructibleSpec => ({\n name: 'glass bottle',\n parts: [\n cyl('bottle_body', 'glass', 0.037, 0.17, [0, 0.085, 0], { mass: 0.3, thickness: 0.003, contains: { fluid: 'water', liters: 0.5 } }),\n cyl('bottle_neck', 'glass', 0.015, 0.09, [0, 0.215, 0], { mass: 0.08, thickness: 0.002 }),\n ],\n joints: [joint('bottle_neck', 'bottle_body', 'fused')],\n tags: ['item'],\n})\n\nconst cup = (): DestructibleSpec => ({\n name: 'coffee cup',\n parts: [\n cyl('cup', 'ceramic', 0.05, 0.11, [0, 0.055, 0], { mass: 0.3, thickness: 0.004, contains: { fluid: 'coffee', liters: 0.25 } }),\n box('cup_handle', 'ceramic', [0.02, 0.06, 0.014], [0.068, 0.06, 0], { mass: 0.04 }),\n ],\n joints: [joint('cup_handle', 'cup', 'fused')],\n tags: ['item'],\n})\n\nconst jerrycan = (): DestructibleSpec => ({\n name: 'jerrycan',\n parts: [\n box('tank', 'plastic', [0.34, 0.45, 0.14], [0, 0.225, 0], { mass: 1.2, thickness: 0.003, contains: { fluid: 'fuel', liters: 20 } }),\n cyl('cap', 'plastic', 0.025, 0.03, [0.08, 0.465, 0], { mass: 0.05 }),\n box('handle', 'plastic', [0.1, 0.03, 0.03], [-0.07, 0.465, 0], { mass: 0.1 }),\n ],\n joints: [joint('cap', 'tank', 'screw'), joint('handle', 'tank', 'fused')],\n tags: ['container'],\n})\n\nconst gasBottle = (): DestructibleSpec => ({\n name: 'gas bottle',\n parts: [\n cyl('cylinder', 'steel', 0.15, 0.7, [0, 0.4, 0], {\n mass: 11,\n thickness: 0.003,\n contains: { fluid: 'gas', liters: 13, pressurized: true },\n explodes: { energy: 120000, radius: 5, atC: 300 },\n }),\n cyl('valve', 'steel', 0.03, 0.1, [0, 0.8, 0], { mass: 0.5 }),\n cyl('foot_ring', 'steel', 0.14, 0.05, [0, 0.025, 0], { mass: 1 }),\n ],\n joints: [joint('valve', 'cylinder', 'weld'), joint('foot_ring', 'cylinder', 'weld')],\n tags: ['container'],\n})\n\nconst tree = (): DestructibleSpec => ({\n name: 'small tree',\n parts: [\n cyl('trunk', 'green_wood', 0.08, 2.2, [0, 1.1, 0], { anchored: true }),\n cyl('branch_1', 'green_wood', 0.03, 0.8, [0.34, 1.7, 0], { rotation: [0, 0, -0.9] }),\n cyl('branch_2', 'green_wood', 0.03, 0.8, [-0.3, 1.9, 0.12], { rotation: [0, 0, 0.8] }),\n cyl('branch_3', 'green_wood', 0.025, 0.7, [0.05, 2.0, -0.28], { rotation: [0.8, 0, 0] }),\n sph('crown_top', 'foliage', 0.55, [0, 2.55, 0], { mass: 2 }),\n sph('crown_1', 'foliage', 0.38, [0.62, 2.0, 0], { mass: 1 }),\n sph('crown_2', 'foliage', 0.38, [-0.58, 2.2, 0.15], { mass: 1 }),\n sph('crown_3', 'foliage', 0.32, [0.05, 2.3, -0.55], { mass: 1 }),\n ],\n joints: [\n joint('branch_1', 'trunk', 'stem'),\n joint('branch_2', 'trunk', 'stem'),\n joint('branch_3', 'trunk', 'stem'),\n joint('crown_top', 'trunk', 'stem'),\n joint('crown_1', 'branch_1', 'stem'),\n joint('crown_2', 'branch_2', 'stem'),\n joint('crown_3', 'branch_3', 'stem'),\n ],\n tags: ['plant'],\n})\n\nconst pottedPlant = (): DestructibleSpec => ({\n name: 'potted plant',\n parts: [\n cyl('pot', 'ceramic', 0.15, 0.25, [0, 0.125, 0], { mass: 2, thickness: 0.008 }),\n cyl('soil', 'soil', 0.14, 0.06, [0, 0.26, 0], { mass: 1.5 }),\n sph('leaves_1', 'foliage', 0.16, [0, 0.46, 0], { mass: 0.3 }),\n sph('leaves_2', 'foliage', 0.12, [0.12, 0.38, 0.04], { mass: 0.2 }),\n sph('leaves_3', 'foliage', 0.12, [-0.1, 0.4, -0.06], { mass: 0.2 }),\n ],\n joints: [joint('soil', 'pot', 'fused'), joint('leaves_1', 'soil', 'stem'), joint('leaves_2', 'soil', 'stem'), joint('leaves_3', 'soil', 'stem')],\n tags: ['plant'],\n})\n\nconst oldTv = (): DestructibleSpec => ({\n name: 'old TV',\n parts: [\n box('stand', 'wood_soft', [0.6, 0.35, 0.42], [0, 0.175, 0]),\n box('shell', 'plastic', [0.58, 0.44, 0.42], [0, 0.57, 0], { mass: 3, thickness: 0.004 }),\n box('screen', 'glass', [0.42, 0.32, 0.012], [0, 0.57, 0.212], { mass: 1.5 }),\n box('coil', 'copper', [0.2, 0.1, 0.2], [0, 0.55, -0.05], { mass: 1.5 }),\n ],\n joints: [joint('shell', 'stand', 'screw'), joint('screen', 'shell', 'clip'), joint('coil', 'shell', 'screw')],\n tags: ['furniture'],\n})\n\nconst carDoor = (): DestructibleSpec => ({\n name: 'car door',\n parts: [\n box('post', 'steel', [0.1, 1.3, 0.1], [-0.58, 0.65, 0], { mass: 12, anchored: true }),\n box('skin', 'steel', [1, 0.8, 0.05], [0, 0.75, 0], { mass: 14, thickness: 0.0008 }),\n box('window', 'glass', [0.78, 0.32, 0.01], [0.04, 1.31, 0.01], { mass: 3 }),\n box('seal', 'rubber', [0.84, 0.03, 0.03], [0.04, 1.14, 0.01], { mass: 0.3 }),\n ],\n joints: [\n joint('skin', 'post', 'hinge', { id: 'hinge_upper' }),\n joint('skin', 'post', 'hinge', { id: 'hinge_lower' }),\n joint('window', 'seal', 'clip'),\n joint('seal', 'skin', 'clip'),\n ],\n tags: ['vehicle'],\n})\n\nconst sofa = (): DestructibleSpec => ({\n name: 'sofa',\n parts: [\n box('frame', 'wood_soft', [1.8, 0.3, 0.8], [0, 0.15, 0], { mass: 14 }),\n box('seat_cushion', 'foam', [1.5, 0.18, 0.62], [0, 0.39, 0.06], { mass: 4 }),\n box('back_cushion', 'foam', [1.5, 0.5, 0.16], [0, 0.65, -0.3], { mass: 4 }),\n box('arm_l', 'fabric', [0.15, 0.4, 0.8], [-0.82, 0.5, 0], { mass: 3 }),\n box('arm_r', 'fabric', [0.15, 0.4, 0.8], [0.82, 0.5, 0], { mass: 3 }),\n ],\n joints: [\n joint('seat_cushion', 'frame', 'clip'),\n joint('back_cushion', 'frame', 'clip'),\n joint('arm_l', 'frame', 'screw'),\n joint('arm_r', 'frame', 'screw'),\n ],\n tags: ['furniture'],\n})\n\nconst shelf = (): DestructibleSpec => ({\n name: 'shelf',\n parts: [\n box('back', 'plywood', [0.84, 1.5, 0.012], [0, 0.75, -0.14], { anchored: true }),\n box('board_1', 'wood_soft', [0.8, 0.025, 0.28], [0, 0.35, 0]),\n box('board_2', 'wood_soft', [0.8, 0.025, 0.28], [0, 0.75, 0]),\n box('board_3', 'wood_soft', [0.8, 0.025, 0.28], [0, 1.15, 0]),\n box('board_4', 'wood_soft', [0.8, 0.025, 0.28], [0, 1.5, 0]),\n ],\n joints: [joint('board_1', 'back', 'screw'), joint('board_2', 'back', 'screw'), joint('board_3', 'back', 'screw'), joint('board_4', 'back', 'screw')],\n tags: ['furniture'],\n})\n\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n// Catalogue\n// ---------------------------------------------------------------------------------------------------------------------------------------------\n\ninterface DemoDef {\n id: string\n group: string\n spec: () => DestructibleSpec\n colors?: Record<string, number>\n movable?: boolean\n fluid?: TestRoomItem['fluid']\n}\n\nconst DEFS: DemoDef[] = [\n { id: 'chair', group: 'furniture', spec: chair, colors: { wood_soft: 0xa8703a } },\n { id: 'sofa', group: 'furniture', spec: sofa, colors: { frame: 0x6b4426, seat_cushion: 0x7d3b4c, back_cushion: 0x7d3b4c, arm_l: 0x6a2f40, arm_r: 0x6a2f40 } },\n { id: 'shelf', group: 'furniture', spec: shelf, colors: { back: 0xd9c9a3 }, movable: false },\n { id: 'old_tv', group: 'furniture', spec: oldTv, colors: { shell: 0x6d5a3e, stand: 0x8a5a30, screen: 0x4f6f68 } },\n { id: 'steel_sheet', group: 'structure', spec: steelSheet, movable: false, colors: { sheet: 0xb5bcc4 } },\n { id: 'glass_pane', group: 'structure', spec: glassPane, movable: false },\n { id: 'concrete_block', group: 'structure', spec: concreteBlock },\n { id: 'brick_column', group: 'structure', spec: brickColumn, movable: false },\n { id: 'building_frame', group: 'structure', spec: frame, movable: false, colors: { roof: 0x7d7d79 } },\n { id: 'car_door', group: 'vehicles', spec: carDoor, movable: false, colors: { skin: 0xc0392b, window: 0x9cd6e6 } },\n { id: 'small_tree', group: 'plants', spec: tree, movable: false },\n { id: 'potted_plant', group: 'plants', spec: pottedPlant, colors: { pot: 0xc4673a } },\n { id: 'coffee_cup', group: 'items', spec: cup, colors: { cup: 0xf3efe6 }, fluid: { container: { capacity: 0.6, liquid: 'coffee', liters: 0.25, temperature: 80, shape: { kind: 'cylinder', radius: 0.045, height: 0.1 }, opening: 0.045 }, part: 'cup', uses: ['drink', 'sip', 'pour'], offset: [0, 0.01, 0] } },\n {\n id: 'glass_bottle',\n group: 'items',\n spec: bottle,\n colors: { bottle_body: 0x7fd6b0, bottle_neck: 0x7fd6b0 },\n fluid: { container: { capacity: 0.5, liquid: 'water', liters: 0.5, temperature: 18, shape: { kind: 'cylinder', radius: 0.034, height: 0.14 }, opening: 0.012 }, part: 'bottle_body', uses: ['drink', 'sip', 'pour'], offset: [0, 0.015, 0] },\n },\n { id: 'wooden_crate', group: 'containers', spec: crate },\n { id: 'steel_drum', group: 'containers', spec: drum, colors: { drum_body: 0x2b5f9e, drum_top: 0x2b5f9e, drum_bottom: 0x2b5f9e } },\n { id: 'plastic_bucket', group: 'containers', spec: bucket, colors: { bucket_body: 0xd9482b, handle: 0x8a8a8a } },\n {\n id: 'jerrycan',\n group: 'containers',\n spec: jerrycan,\n colors: { tank: 0xc23b22, cap: 0xf2c230, handle: 0xc23b22 },\n fluid: { container: { capacity: 20, liquid: 'fuel', liters: 20, temperature: 20, shape: { kind: 'box', size: [0.33, 0.44, 0.13] }, opening: 0.025, closed: true }, part: 'tank', uses: ['pour', 'open', 'close'], offset: [0, 0.008, 0] },\n },\n { id: 'gas_bottle', group: 'containers', spec: gasBottle, colors: { cylinder: 0xd8d8d0, valve: 0x777777, foot_ring: 0x555555 } },\n]\n\n/**\n * The generic demo catalogue, names and groups translated for `locale` (`en` or `pt-BR`). Every item is a procedural low-poly build (one mesh per\n * destruction part, drawn by `buildFromSpec`) plus an explicit destruction spec. Containers carry a fluid container where it makes sense.\n */\nexport function demoItems(locale = 'en', extra: TestRoomItem[] = []): TestRoomItem[] {\n const s = resolveStrings(locale)\n const out: TestRoomItem[] = DEFS.map((d) => ({\n id: d.id,\n name: s.items[d.id] ?? d.id,\n group: s.groups[d.group] ?? d.group,\n build: (THREE: typeof THREE_NS) => buildFromSpec(THREE, d.spec(), { colors: d.colors }),\n spec: d.spec,\n movable: d.movable,\n fluid: d.fluid,\n }))\n return [...out, ...extra]\n}\n\n/** The demo catalogue in English (see `demoItems` for other locales). */\nexport const DEMO_ITEMS: TestRoomItem[] = demoItems('en')\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, PartSpec } from '@adatechnology/game-destruction'\n\n/** Default look of each built-in destruction material (`0xRRGGBB`). */\nexport const MATERIAL_COLORS: Record<string, number> = {\n steel: 0x8d949c,\n cast_iron: 0x4a4d52,\n aluminium: 0xc4c9ce,\n copper: 0xb8733a,\n wood_soft: 0xb9854f,\n wood_hard: 0x7a4a26,\n plywood: 0xc9a46a,\n mdf: 0xa88b64,\n glass: 0x9cd6e6,\n tempered_glass: 0x9cd6e6,\n ceramic: 0xe9e4da,\n concrete: 0x9a9a96,\n brick: 0xa5472e,\n plaster: 0xe6e1d4,\n stone: 0x77746f,\n plastic: 0x3b78c4,\n rubber: 0x1f1f22,\n fabric: 0x8a4b5e,\n foam: 0xe3c458,\n leather: 0x5b3a26,\n paper: 0xeeeadf,\n foliage: 0x3f8f3a,\n green_wood: 0x6b4a2b,\n cactus: 0x3e7d4a,\n flesh_fruit: 0xd24b32,\n wax: 0xefe2b5,\n soil: 0x4a3322,\n}\n\nexport interface BuildFromSpecOptions {\n /** Colour per part id, then per material id (falls back to `MATERIAL_COLORS`, then grey). */\n colors?: Record<string, number>\n /** Segments of cylinders and spheres (default 12: low poly on purpose). */\n segments?: number\n /** Cast and receive shadows (default true). */\n shadows?: boolean\n}\n\nconst TRANSPARENT: Record<string, number> = { glass: 0.38, tempered_glass: 0.38 }\n\n/**\n * Draw any `DestructibleSpec` as plain meshes: one mesh per part (box, cylinder or sphere) with `name` and `userData.destructionPart` set to the\n * part id and `userData.destructionMaterial` to its material, so `renderer.bind` and `specFromObject3D` find them. Useful for teams that describe\n * objects as specs and want something to look at while they tune them.\n */\nexport function buildFromSpec(THREE: typeof THREE_NS, spec: DestructibleSpec, options: BuildFromSpecOptions = {}): THREE_NS.Group {\n const root = new THREE.Group()\n root.name = spec.name ?? 'object'\n const seg = options.segments ?? 12\n const shadows = options.shadows !== false\n const mats = new Map<string, THREE_NS.Material>()\n const materialFor = (p: PartSpec): THREE_NS.Material => {\n const color = options.colors?.[p.id] ?? options.colors?.[p.material] ?? MATERIAL_COLORS[p.material] ?? 0x888888\n const key = `${p.material}:${color}`\n let m = mats.get(key)\n if (!m) {\n const alpha = TRANSPARENT[p.material]\n const metal = p.material === 'steel' || p.material === 'aluminium' || p.material === 'copper' || p.material === 'cast_iron'\n m = new THREE.MeshStandardMaterial({\n color,\n roughness: alpha ? 0.1 : metal ? 0.45 : 0.85,\n metalness: metal ? 0.7 : 0,\n transparent: !!alpha,\n opacity: alpha ?? 1,\n depthWrite: !alpha,\n })\n mats.set(key, m)\n }\n return m\n }\n for (const p of spec.parts) {\n let geo: THREE_NS.BufferGeometry\n const s = p.shape\n if (s.kind === 'box') geo = new THREE.BoxGeometry(s.size[0], s.size[1], s.size[2])\n else if (s.kind === 'cylinder') geo = new THREE.CylinderGeometry(s.radius, s.radius, s.height, seg)\n else geo = new THREE.SphereGeometry(s.radius, seg, Math.max(6, seg - 4))\n const mesh = new THREE.Mesh(geo, materialFor(p))\n mesh.name = p.id\n mesh.userData.destructionPart = p.id\n mesh.userData.destructionMaterial = p.material\n mesh.position.set(p.position[0], p.position[1], p.position[2])\n if (p.rotation) mesh.rotation.set(p.rotation[0], p.rotation[1], p.rotation[2], 'XYZ')\n mesh.castShadow = shadows && !TRANSPARENT[p.material]\n mesh.receiveShadow = shadows\n root.add(mesh)\n }\n return root\n}\n","/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type TestRoomLocale = 'en' | 'pt-BR'\n\nexport interface RoomStrings {\n /** Display name per demo item id (see `DEMO_ITEMS`). */\n items: Record<string, string>\n /** Display name per demo catalogue group. */\n groups: Record<string, string>\n /** Every other text: UI, log lines, scenario names and checks. `{name}` placeholders are replaced. */\n text: Record<string, string>\n}\n\nconst en: RoomStrings = {\n items: {\n chair: 'Wooden chair',\n sofa: 'Sofa',\n shelf: 'Shelf with boards',\n old_tv: 'Old TV',\n steel_sheet: 'Steel sheet on a stand',\n glass_pane: 'Glass pane',\n concrete_block: 'Concrete block',\n brick_column: 'Brick column',\n building_frame: 'Building frame',\n car_door: 'Car door',\n small_tree: 'Small tree',\n potted_plant: 'Potted plant',\n coffee_cup: 'Cup of coffee',\n glass_bottle: 'Glass bottle',\n wooden_crate: 'Wooden crate',\n steel_drum: 'Steel drum',\n plastic_bucket: 'Plastic bucket',\n jerrycan: 'Jerrycan',\n gas_bottle: 'Gas bottle',\n },\n groups: { furniture: 'Furniture', structure: 'Structure', vehicles: 'Vehicles', plants: 'Plants', items: 'Items', containers: 'Containers' },\n text: {\n 'locale.decimal': '.',\n yes: 'yes',\n no: 'no',\n piece: 'piece',\n coords: 'x {x} · z {z}',\n 'count.piece.one': '1 piece',\n 'count.piece.other': '{n} pieces',\n 'count.joint.one': '1 joint',\n 'count.joint.other': '{n} joints',\n 'count.dent.one': '1 dent',\n 'count.dent.other': '{n} dents',\n 'count.hole.one': '1 hole',\n 'count.hole.other': '{n} holes',\n 'count.crack.one': '1 crack',\n 'count.crack.other': '{n} cracks',\n 'joint.generic': 'joint',\n 'lost.broken': 'broke',\n 'lost.melted': 'melted away',\n 'lost.ashes': 'burned to ash',\n 'tool.none': 'by hand only',\n 'arena.target_wall': 'Target wall',\n 'arena.table': 'Table',\n 'arena.shelf': 'Shelf',\n 'surface.floor': 'on the floor',\n 'surface.ground': 'on the floor',\n 'surface.table': 'on the table',\n 'by.break': 'broken loose',\n 'by.tool': 'undone with a tool',\n 'by.part_lost': 'the part next to it was lost',\n 'dmg.ballistic': 'ballistic',\n 'dmg.blunt': 'blunt',\n 'dmg.slash': 'slash',\n 'dmg.explosive': 'blast',\n 'dmg.fire': 'fire',\n 'dmg.heat': 'heat',\n 'effect.caffeine': 'caffeine',\n 'effect.alcohol': 'alcohol',\n 'effect.poison': 'poison',\n 'effect.disgust': 'disgust',\n\n 'ev.dent': '{where}: dent of {mm} mm, {hp}',\n 'ev.hole.through': '{where}: {mm} mm hole went through, {hp}',\n 'ev.hole.stuck': '{where}: {mm} mm hole, did not go through, {hp}',\n 'ev.dents': '{where}: {n} dents, deepest {mm} mm, {hp}',\n 'ev.holes': '{where}: {n} holes of {mm} mm, {thr} went through, {hp}',\n 'ev.leak.tail': ', leaking {liquid} at {rate} l/s',\n 'ev.leak.alone': '{where}: leaking {liquid} at {rate} l/s',\n 'ev.crack': '{where}: cracked, {rays} rays up to {cm} cm, {hp}',\n 'ev.ricochet': '{where}: bullet ricocheted, {energy} J left',\n 'ev.fracture.shatter': '{where}: shattered into {n} shards',\n 'ev.fracture.crumble': '{where}: crumbled into {n} chunks',\n 'ev.fracture.splinter': '{where}: splintered into {n} pieces',\n 'ev.fracture.tear': '{where}: torn into {n} scraps',\n 'ev.fracture.snap': '{where}: snapped into {n} pieces',\n 'ev.fracture.none': '{where}: broke into {n} pieces',\n 'ev.detach': '{obj}: {a} came off {b} ({by}); the object now has {pieces}',\n 'ev.detach.many.break': '{obj}: {joints} broke loose; the object now has {pieces}',\n 'ev.detach.many.tool': '{obj}: {joints} undone with a tool; the object now has {pieces}',\n 'ev.lost.tail': ' and came loose from {joints}; the object now has {pieces}',\n 'ev.lost.alone': '{where}: {verb} and came loose from {joints}; the object now has {pieces}',\n 'ev.cracks': '{where}: cracking under the load, {n} cracks so far, longest {cm} cm, {hp}',\n 'ev.disassemble': '{obj}: undoing the {kind} between {a} and {b} with {tool}: {pct}%',\n 'ev.ignite': '{where}: caught fire at {temp} °C',\n 'ev.ignite.many': '{obj}: {n} parts caught fire at {temp} °C ({parts})',\n 'ev.extinguish': '{where}: fire put out',\n 'ev.extinguish.many': '{obj}: fire put out on {n} parts ({parts})',\n 'ev.burnout': '{where}: burned to ash',\n 'ev.melt': '{where}: melting, {pct}% melted away',\n 'ev.drip': '{where}: dripping molten material',\n 'ev.explode': '{where}: exploded, {energy} J within {radius} m',\n 'ev.destroyed': '{obj}: destroyed',\n 'ev.damage': '{where}: {type} damage {amount}, {hp}',\n 'ev.damage.overload': '{where}: crushed by the weight it carries, lost {amount} hp so far, {hp}',\n 'ev.stress': '{where}: overloaded at {stress}% of its capacity, carrying {load} kg',\n 'ev.collapse': '{obj}: collapsed, {pieces} fell ({mass} kg): {parts}',\n 'ev.stain_ignite': 'The {liquid} stain at x {x} · z {z} caught fire and will burn for about {seconds} s',\n 'ev.stain_burned': 'The burning stain burned itself out',\n 'ev.fire_dries': 'Fire dried the wet stains nearby',\n\n 'fl.fill': '{who}: filled with {liquid} (+{liters} l)',\n 'fl.pour': '{who}: pouring {liquid} at {rate} l/s',\n 'fl.spill': '{who}: spilled {liquid} over the lip at {rate} l/s',\n 'fl.leak': '{who}: leaking {liquid} at {rate} l/s',\n 'fl.drink': '{who}: drank {liters} l, thirst +{thirst}',\n 'fl.burn': 'too hot: burned the mouth',\n 'fl.empty': '{who}: empty',\n 'fl.splash': 'Splash of {liquid}',\n 'fl.stain': 'Stain of {liquid} {surface} at {where}',\n 'fl.stains': '{n} stains of {liquid} {surface}, the latest at {where}',\n 'fl.dried': 'A stain dried up',\n 'fl.dried.mark': 'A stain dried and left a mark',\n 'fl.dried.known': 'The {liquid} stain {surface} at {where} dried up',\n 'fl.dried.known.mark': 'The {liquid} stain {surface} at {where} dried and left a mark',\n 'fl.dried.many': '{n} {liquid} stains dried up',\n 'fl.dried.many.mark': '{n} {liquid} stains dried and left marks',\n 'fl.mix': '{who}: {from} mixed into {into}',\n\n 'act.anim_start': '{name}: animation \"{clip}\" ({seconds} s)',\n 'act.anim_event': '{name}: \"{clip}\" event {type}',\n 'act.anim_end': '{name}: animation \"{clip}\" finished',\n 'act.module_loaded': 'Module \"{name}\" loaded: {items} item(s), {scenarios} scenario(s), contract checks: {result}',\n 'mod.all_ok': 'all passed',\n 'mod.some_failed': 'some FAILED',\n 'mod.destructible_ok': '{name}: destructible contract ok ({parts} parts, hit and state well-formed)',\n 'mod.destructible_fail': '{name}: destructible contract broken: {problems}',\n 'mod.animation_ok': '{name}: animation \"{clip}\" ok ({seconds} s)',\n 'mod.spec_ok': '{name}: spec ok ({parts} parts)',\n 'mod.spec_fail': '{name}: spec broken: {problems}',\n 'mod.spec_warn': '{name}: spec warning: {warning}',\n 'mod.animation_fail': '{name}: animation \"{clip}\" broken: {problems}',\n 'ui.animations': 'Animations',\n 'ui.animations_aim': 'Aim at an item or hold it to see its animations.',\n 'ui.animations_none': 'This item brings no animations.',\n 'mod.bench_ok': '{name}: bench ok ({controls} controls, {layers} layers, {metrics} metrics)',\n 'mod.bench_fail': '{name}: bench broken: {problems}',\n 'mod.metric_failed': '{name}: metric \"{metric}\" threw and shows n/a: {error}',\n 'mod.listener_failed': '{name}: a bench listener threw: {error}',\n 'ui.bench': 'Bench',\n 'ui.layers': 'Layers',\n 'ui.metrics': 'Counters',\n 'metric.fps': 'FPS',\n 'metric.frame_ms': 'ms/frame',\n 'metric.draw_calls': 'Draw calls',\n 'metric.triangles': 'Triangles',\n 'metric.objects': 'Objects',\n 'metric.fragments': 'Fragments',\n 'metric.particles': 'Particles',\n 'metric.decals': 'Decals',\n 'act.spawn': 'Spawned {name} at x {x} · z {z}',\n 'act.clear': 'Cleared the room',\n 'act.reset': 'Repaired every object',\n 'act.tool': 'Equipped {weapon}',\n 'act.shoot.hit': '{weapon}: shot, {energy} J, hit {where} at {dist} m',\n 'act.shoot.miss': '{weapon}: shot, {energy} J, hit nothing',\n 'act.shoot.pellets': '{weapon}: shot, {n} projectiles of up to {energy} J, {hits} hit {where} at {dist} m',\n 'act.melee.hit': '{weapon}: strike, {energy} J, hit {where} at {dist} m',\n 'act.melee.miss': '{weapon}: struck the air',\n 'act.flame.hit': '{weapon}: flame at {temp} °C on {where}',\n 'act.flame.air': '{weapon}: flame, nothing in range',\n 'act.heat.hit': '{weapon}: heating {where} at {temp} °C',\n 'act.heat.air': '{weapon}: nothing in range',\n 'act.throw.grenade': '{weapon}: thrown, fuse {fuse} s',\n 'act.throw.molotov': '{weapon}: thrown, breaks on impact',\n 'act.explode': '{weapon}: exploded, {energy} J within {radius} m, {n} objects in range',\n 'act.molotov_fire': '{weapon}: fire on the ground, radius {radius} m for {seconds} s',\n 'act.tool.none': '{weapon}: nothing in reach',\n 'act.tool.nojoint': '{weapon}: no joint near {where}',\n 'act.tool.refused': '{weapon} cannot undo the {kind} of {obj}; it needs: {need}',\n 'act.extinguish.hit': '{weapon}: foam on {what}',\n 'act.extinguish.air': '{weapon}: foam, nothing in range',\n 'act.grab': 'Grabbed {name} ({kg} kg)',\n 'act.drop': 'Dropped {name}',\n 'act.throw': 'Threw {name} at {speed} m/s',\n 'act.landing': '{name} landed at {speed} m/s: {energy} J',\n 'act.impact': '{name} hit {where} at {speed} m/s: {energy} J of blunt damage',\n 'act.use_item': '{name}: {use}',\n 'act.tap.on': 'Tap opened',\n 'act.tap.off': 'Tap closed',\n\n 'use.drink': 'drink',\n 'use.sip': 'sip',\n 'use.chug': 'chug',\n 'use.pour': 'pour',\n 'use.pour_out': 'pour out',\n 'use.open': 'open',\n 'use.close': 'close',\n\n 'hud.reloading': 'Reloading...',\n 'hud.empty': 'Empty',\n 'hud.no_fuel': 'Out of fuel',\n 'hud.nothing_to_grab': 'Nothing to grab here',\n 'hud.cannot_grab': '{name} cannot be picked up',\n 'hud.too_heavy': '{name} is too heavy ({kg} kg)',\n 'hud.empty_container': '{name} is empty',\n 'hud.refused': 'Wrong tool for the {kind}',\n 'hud.drop': 'drop',\n 'hud.rotate': 'rotate',\n 'hud.throw': 'throw',\n 'hud.tilt': 'tilt (hold)',\n 'hud.equip': 'equip {weapon}',\n\n 'ui.help': 'Click: look · WASD: walk · Shift: run · Space: jump · 1-0 / wheel: tool · LMB: use · E: grab/drop · G or RMB: throw · Tab: panels · Esc: free the mouse',\n 'ui.log': 'Behaviour log',\n 'ui.filter.action': 'actions',\n 'ui.filter.event': 'events',\n 'ui.filter.check': 'checks',\n 'ui.autoscroll': 'autoscroll',\n 'log.export_cancelled': 'export cancelled',\n 'ui.copy_json': 'Copy JSON',\n 'ui.download_ndjson': 'Download NDJSON',\n 'ui.download_txt': 'Download TXT',\n 'ui.clear_log': 'Clear',\n 'ui.catalog': 'Catalogue',\n 'ui.clear': 'Clear',\n 'ui.reset_all': 'Reset all',\n 'ui.slow': 'Slow motion 0.25×',\n 'ui.fast': 'Time ×10',\n 'ui.tap': 'Tap',\n 'ui.quality': 'Quality',\n 'ui.quality.low': 'low',\n 'ui.quality.medium': 'medium',\n 'ui.quality.high': 'high',\n 'ui.equip': 'Equip as a tool',\n 'ui.search_items': 'Search items (all groups)',\n 'ui.search_tests': 'Search tests',\n 'ui.no_results': 'Nothing found',\n 'ui.objects': '{n} objects',\n 'ui.tests': 'Tests',\n 'ui.run_all': 'Run all',\n 'ui.running': 'Running...',\n 'ui.report': '{passed} passed, {failed} failed',\n 'ui.panel': 'Panels',\n 'ui.inspector': 'Inspector',\n 'ui.aim_at_something': 'Aim at an object',\n 'ins.material': 'Material',\n 'ins.status': 'Status',\n 'ins.burning': 'burning',\n 'ins.hp': 'Hit points',\n 'ins.temperature': 'Temperature',\n 'ins.char': 'Charred',\n 'ins.melt': 'Melted',\n 'ins.liters': 'Liquid',\n 'ins.damage': 'Marks',\n 'ins.damage_counts': '{dents}, {holes}, {cracks}',\n 'ins.mass': 'Mass',\n 'ins.load': 'Load',\n 'ins.stress': 'Stress',\n 'ins.joints': 'Joints',\n 'ins.open': 'open',\n\n 'sc.start': 'Scenario: {name}',\n 'sc.pass': 'Scenario passed: {name}',\n 'sc.fail': 'Scenario FAILED: {name}',\n 'sc.error': 'the scenario threw an error: {msg}',\n 'leg.still': 'leg_1 still attached',\n 'leg.gone': 'leg_1 came off',\n\n 'sc.steel_through_hole': '9 mm into a steel sheet makes a through hole',\n 'sc.steel_through_hole.check': '9 mm into 3 mm steel: {holes} hole(s) of {mm} mm, went through: {through}, sheet {hp} hp (expected: through)',\n 'sc.concrete_stops_bullet': '9 mm into a concrete block does not go through',\n 'sc.concrete_stops_bullet.check': '9 mm into 40 cm of concrete: went through: {through}, {dents}, {holes}, {cracks}, block {hp} hp (expected: stopped, wall behind untouched)',\n 'sc.hammer_dents_drum': 'Hammer dents a steel drum',\n 'sc.hammer_dents_drum.check': 'Hammer on the drum: {swings} swing(s), {dents} dent(s), first {depth} mm deep, body {hp} hp (expected: dented, not broken)',\n 'sc.glass_shatters': 'Glass pane shatters on the first 9 mm shot',\n 'sc.glass_shatters.check': 'Glass pane: broken after {shots} shot(s) into {n} shards (expected: broken on the first shot, at least 4 shards)',\n 'sc.shotgun_splinters_crate': 'Shotgun splinters a wooden crate',\n 'sc.shotgun_splinters_crate.check': '12 ga on the crate: {shots} shot(s), {splinters} board(s) splintered, {holes} holes (expected: at least one splintered)',\n 'sc.kick_chair_leg': 'A kick takes a chair leg off',\n 'sc.kick_chair_leg.check': 'Chair: {kicks} kick(s), {groups} group(s), loose pieces {before} → {after}, {leg} (expected: a loose piece appears)',\n 'sc.kick_detaches_leg_via_tool': 'The kick tool (hotbar) takes a chair leg off',\n 'sc.kick_detaches_leg_via_tool.check': 'Chair, kick tool: {kicks} kick(s), loose pieces {before} → {after}, {leg} (expected: a loose piece appears)',\n 'sc.screwdriver_shelf_board': 'Screwdriver takes a screwed shelf board off in about 2.5 s',\n 'sc.screwdriver_shelf_board.check': 'Screwdriver on the shelf board: took {secs} s, expected about {want} s, the shelf is now in {pieces}',\n 'sc.wrong_tool_refused': 'The wrong tool is refused',\n 'sc.wrong_tool_refused.check': 'Screwdriver on a weld: refused {refused} time(s), joints opened {opened} (expected: refused, none opened)',\n 'sc.lighter_burns_crate': 'A lighter ignites a wooden crate and it ends as ash',\n 'sc.lighter_burns_crate.lit': 'Lighter on the crate: burning: {lit} (expected: yes)',\n 'sc.lighter_burns_crate.ash': 'After burning for 500 s: {ash} of {total} boards are ash, most charred {char}% (expected: all ash or charred)',\n 'sc.torch_melts_steel': 'Wood fire does not melt a steel drum, the cutting torch does',\n 'sc.torch_melts_steel.wood': 'Burning crate next to the drum: drum peaked at {peak} °C, melted {melt}%, crate still burning: {crate} (expected: no melt)',\n 'sc.torch_melts_steel.torch': 'Cutting torch on the drum: {temp} °C, melted {melt}% (expected: melting)',\n 'sc.bucket_melts_drips': 'A plastic bucket melts and drips near fire',\n 'sc.bucket_melts_drips.check': 'Bucket in flames: melted {melt}%, {temp} °C, {drips} drip line(s) (expected: melting)',\n 'sc.gas_bottle_explodes': 'A gas bottle in a fire explodes and pushes a crate',\n 'sc.gas_bottle_explodes.explode': 'Gas bottle in fire: exploded after {seconds} s (expected: explodes)',\n 'sc.gas_bottle_explodes.push': 'Crate 1.3 m away: moved {moved} m, lost {lost} (expected: pushed or broken)',\n 'sc.bottle_drop_shatters': 'A glass bottle dropped from 1.5 m shatters',\n 'sc.bottle_drop_shatters.check': 'Bottle dropped from 1.5 m: status {status}, {cracks} cracks, water stain: {stain} (expected: broken, water on the floor)',\n 'sc.throw_chair_at_wall': 'A chair thrown at the wall deals blunt damage',\n 'sc.throw_chair_at_wall.check': 'Chair thrown at the wall: {impacts} impact(s), first {energy} J, {wall} damage line(s) on the wall (expected: impact and damage)',\n 'sc.coffee_three_sips': 'Three sips of coffee lower the level and log caffeine',\n 'sc.coffee_three_sips.check': 'Coffee: {sips} sip(s), level {before} → {after} l, caffeine logged: {caffeine}, burned the mouth: {burn} (expected: 3 sips, caffeine)',\n 'sc.tilt_cup_spills': 'Tilting the cup spills coffee and leaves a stain',\n 'sc.tilt_cup_spills.check': 'Cup tilted: level {before} → {after} l, {stains} coffee stain(s) (expected: spilled with a stain)',\n 'sc.jerrycan_leaks_fuel': 'Shooting the jerrycan makes a leak and a fuel stain',\n 'sc.jerrycan_leaks_fuel.check': 'Jerrycan shot: {streams} leak stream(s), fuel stain: {stain}, {left} l left of 20, hole line mentions the leak: {leak} (expected: leaking, stain)',\n 'sc.fuel_stain_burns': 'A lit fuel stain burns',\n 'sc.fuel_stain_burns.stain': 'Fuel stain on the floor after the leak: {stain} (expected: yes)',\n 'sc.fuel_stain_burns.ignite': 'Lighter on the stain: {ignited} ignition(s), fire reached nearby objects: {near} (expected: ignited)',\n 'sc.fuel_stain_burns.out': 'After 30 s the stain burned out: {burned} (expected: yes)',\n 'roof.standing': 'roof standing',\n 'roof.fell': 'roof fell',\n 'sc.one_column_roof_stands': 'One column destroyed: the roof stays up',\n 'sc.one_column_roof_stands.check': 'Frame with one column gone: {roof}, heaviest collapse {heavy} kg, peak stress {stress}% (expected: standing, no big collapse)',\n 'sc.two_columns_roof_collapses': 'Two columns destroyed: the roof collapses',\n 'sc.two_columns_roof_collapses.check': 'Frame with two columns gone: the others at {stress}% right away, then heavy loose pieces: {pieces} ({kg} kg), collapse event logged: {logged} (expected: the roof comes down)',\n 'sc.extinguisher_puts_out_fire': 'The extinguisher puts out a burning crate',\n 'sc.extinguisher_puts_out_fire.burning': 'Crate set on fire: burning: {burning} (expected: yes)',\n 'sc.extinguisher_puts_out_fire.out': 'After the extinguisher: still burning: {burning}, {events} extinguish event(s) (expected: out)',\n },\n}\n\nconst ptBR: RoomStrings = {\n items: {\n chair: 'Cadeira de madeira',\n sofa: 'Sofá',\n shelf: 'Estante com prateleiras',\n old_tv: 'TV antiga',\n steel_sheet: 'Chapa de aço com suporte',\n glass_pane: 'Vidro de janela',\n concrete_block: 'Bloco de concreto',\n brick_column: 'Coluna de tijolos',\n building_frame: 'Estrutura de prédio',\n car_door: 'Porta de carro',\n small_tree: 'Árvore pequena',\n potted_plant: 'Vaso de planta',\n coffee_cup: 'Copo de café',\n glass_bottle: 'Garrafa de vidro',\n wooden_crate: 'Caixote de madeira',\n steel_drum: 'Tambor de aço',\n plastic_bucket: 'Balde de plástico',\n jerrycan: 'Galão',\n gas_bottle: 'Botijão de gás',\n },\n groups: { furniture: 'Móveis', structure: 'Estrutura', vehicles: 'Veículos', plants: 'Plantas', items: 'Itens', containers: 'Recipientes' },\n text: {\n 'locale.decimal': ',',\n yes: 'sim',\n no: 'não',\n piece: 'peça',\n coords: 'x {x} · z {z}',\n 'count.piece.one': '1 peça',\n 'count.piece.other': '{n} peças',\n 'count.joint.one': '1 encaixe',\n 'count.joint.other': '{n} encaixes',\n 'count.dent.one': '1 amassado',\n 'count.dent.other': '{n} amassados',\n 'count.hole.one': '1 furo',\n 'count.hole.other': '{n} furos',\n 'count.crack.one': '1 trinca',\n 'count.crack.other': '{n} trincas',\n 'joint.generic': 'junta',\n 'lost.broken': 'quebrou',\n 'lost.melted': 'derreteu',\n 'lost.ashes': 'virou cinza',\n 'tool.none': 'só com a mão',\n 'arena.target_wall': 'Parede de alvo',\n 'arena.table': 'Mesa',\n 'arena.shelf': 'Estante',\n 'surface.floor': 'no chão',\n 'surface.ground': 'no chão',\n 'surface.table': 'na mesa',\n 'by.break': 'arrebentou',\n 'by.tool': 'desmontado com ferramenta',\n 'by.part_lost': 'a peça ao lado se perdeu',\n 'dmg.ballistic': 'de tiro',\n 'dmg.blunt': 'de impacto',\n 'dmg.slash': 'de corte',\n 'dmg.explosive': 'de explosão',\n 'dmg.fire': 'de fogo',\n 'dmg.heat': 'de calor',\n 'effect.caffeine': 'cafeína',\n 'effect.alcohol': 'álcool',\n 'effect.poison': 'veneno',\n 'effect.disgust': 'nojo',\n\n 'ev.dent': '{where}: amassado de {mm} mm, {hp}',\n 'ev.hole.through': '{where}: furo de {mm} mm atravessou, {hp}',\n 'ev.hole.stuck': '{where}: furo de {mm} mm não atravessou, {hp}',\n 'ev.dents': '{where}: {n} amassados, o mais fundo com {mm} mm, {hp}',\n 'ev.holes': '{where}: {n} furos de {mm} mm, {thr} atravessaram, {hp}',\n 'ev.leak.tail': ', vazando {liquid} a {rate} l/s',\n 'ev.leak.alone': '{where}: vazando {liquid} a {rate} l/s',\n 'ev.crack': '{where}: trincou, {rays} raios de até {cm} cm, {hp}',\n 'ev.ricochet': '{where}: a bala ricocheteou, sobraram {energy} J',\n 'ev.fracture.shatter': '{where}: estilhaçou em {n} cacos',\n 'ev.fracture.crumble': '{where}: esfarelou em {n} pedaços',\n 'ev.fracture.splinter': '{where}: lascou em {n} pedaços',\n 'ev.fracture.tear': '{where}: rasgou em {n} retalhos',\n 'ev.fracture.snap': '{where}: partiu em {n} pedaços',\n 'ev.fracture.none': '{where}: quebrou em {n} pedaços',\n 'ev.detach': '{obj}: {a} soltou de {b} ({by}); o objeto agora tem {pieces}',\n 'ev.detach.many.break': '{obj}: {joints} arrebentaram; o objeto agora tem {pieces}',\n 'ev.detach.many.tool': '{obj}: {joints} soltos com ferramenta; o objeto agora tem {pieces}',\n 'ev.lost.tail': ' e se soltou de {joints}; o objeto agora tem {pieces}',\n 'ev.lost.alone': '{where}: {verb} e se soltou de {joints}; o objeto agora tem {pieces}',\n 'ev.cracks': '{where}: rachando sob o peso, {n} trincas até agora, a maior com {cm} cm, {hp}',\n 'ev.disassemble': '{obj}: soltando {kind} entre {a} e {b} com {tool}: {pct}%',\n 'ev.ignite': '{where}: pegou fogo a {temp} °C',\n 'ev.ignite.many': '{obj}: {n} peças pegaram fogo a {temp} °C ({parts})',\n 'ev.extinguish': '{where}: fogo apagado',\n 'ev.extinguish.many': '{obj}: fogo apagado em {n} peças ({parts})',\n 'ev.burnout': '{where}: virou cinza',\n 'ev.melt': '{where}: derretendo, {pct}% já derreteu',\n 'ev.drip': '{where}: pingando material derretido',\n 'ev.explode': '{where}: explodiu, {energy} J em {radius} m',\n 'ev.destroyed': '{obj}: destruído',\n 'ev.damage': '{where}: dano {type} de {amount}, {hp}',\n 'ev.damage.overload': '{where}: esmagado pelo peso que sustenta, perdeu {amount} hp até agora, {hp}',\n 'ev.stress': '{where}: sobrecarregado a {stress}% da capacidade, sustentando {load} kg',\n 'ev.collapse': '{obj}: desabou, caíram {pieces} ({mass} kg): {parts}',\n 'ev.stain_ignite': 'A mancha de {liquid} em x {x} · z {z} pegou fogo e vai queimar por uns {seconds} s',\n 'ev.stain_burned': 'A mancha em chamas se consumiu',\n 'ev.fire_dries': 'O fogo secou as manchas molhadas por perto',\n\n 'fl.fill': '{who}: encheu de {liquid} (+{liters} l)',\n 'fl.pour': '{who}: despejando {liquid} a {rate} l/s',\n 'fl.spill': '{who}: derramou {liquid} pela borda a {rate} l/s',\n 'fl.leak': '{who}: vazando {liquid} a {rate} l/s',\n 'fl.drink': '{who}: bebeu {liters} l, sede +{thirst}',\n 'fl.burn': 'quente demais: queimou a boca',\n 'fl.empty': '{who}: vazio',\n 'fl.splash': 'Respingo de {liquid}',\n 'fl.stain': 'Mancha de {liquid} {surface} em {where}',\n 'fl.stains': '{n} manchas de {liquid} {surface}, a última em {where}',\n 'fl.dried': 'Uma mancha secou',\n 'fl.dried.mark': 'Uma mancha secou e deixou marca',\n 'fl.dried.known': 'A mancha de {liquid} {surface} em {where} secou',\n 'fl.dried.known.mark': 'A mancha de {liquid} {surface} em {where} secou e deixou marca',\n 'fl.dried.many': '{n} manchas de {liquid} secaram',\n 'fl.dried.many.mark': '{n} manchas de {liquid} secaram e deixaram marca',\n 'fl.mix': '{who}: {from} misturou em {into}',\n\n 'act.anim_start': '{name}: animação \"{clip}\" ({seconds} s)',\n 'act.anim_event': '{name}: \"{clip}\" evento {type}',\n 'act.anim_end': '{name}: animação \"{clip}\" terminou',\n 'act.module_loaded': 'Módulo \"{name}\" carregado: {items} item(ns), {scenarios} cenário(s), verificações do contrato: {result}',\n 'mod.all_ok': 'todas passaram',\n 'mod.some_failed': 'algumas FALHARAM',\n 'mod.destructible_ok': '{name}: contrato de destruição ok ({parts} peças, golpe e estado bem formados)',\n 'mod.destructible_fail': '{name}: contrato de destruição quebrado: {problems}',\n 'mod.animation_ok': '{name}: animação \"{clip}\" ok ({seconds} s)',\n 'mod.spec_ok': '{name}: spec ok ({parts} peças)',\n 'mod.spec_fail': '{name}: spec quebrada: {problems}',\n 'mod.spec_warn': '{name}: aviso na spec: {warning}',\n 'mod.animation_fail': '{name}: animação \"{clip}\" quebrada: {problems}',\n 'ui.animations': 'Animações',\n 'ui.animations_aim': 'Mire num item ou segure-o para ver as animações.',\n 'ui.animations_none': 'Este item não traz animações.',\n 'mod.bench_ok': '{name}: bancada ok ({controls} controles, {layers} camadas, {metrics} contadores)',\n 'mod.bench_fail': '{name}: bancada quebrada: {problems}',\n 'mod.metric_failed': '{name}: o contador \"{metric}\" lançou erro e mostra n/a: {error}',\n 'mod.listener_failed': '{name}: um ouvinte da bancada lançou erro: {error}',\n 'ui.bench': 'Bancada',\n 'ui.layers': 'Camadas',\n 'ui.metrics': 'Contadores',\n 'metric.fps': 'FPS',\n 'metric.frame_ms': 'ms/quadro',\n 'metric.draw_calls': 'Chamadas de desenho',\n 'metric.triangles': 'Triângulos',\n 'metric.objects': 'Objetos',\n 'metric.fragments': 'Fragmentos',\n 'metric.particles': 'Partículas',\n 'metric.decals': 'Decalques',\n 'act.spawn': 'Criou {name} em x {x} · z {z}',\n 'act.clear': 'Limpou a sala',\n 'act.reset': 'Consertou todos os objetos',\n 'act.tool': 'Equipou {weapon}',\n 'act.shoot.hit': '{weapon}: disparo, {energy} J, acertou {where} a {dist} m',\n 'act.shoot.miss': '{weapon}: disparo, {energy} J, não acertou nada',\n 'act.shoot.pellets': '{weapon}: disparo, {n} projéteis de até {energy} J, {hits} acertaram {where} a {dist} m',\n 'act.melee.hit': '{weapon}: golpe, {energy} J, acertou {where} a {dist} m',\n 'act.melee.miss': '{weapon}: golpe no ar',\n 'act.flame.hit': '{weapon}: chama a {temp} °C em {where}',\n 'act.flame.air': '{weapon}: chama, nada ao alcance',\n 'act.heat.hit': '{weapon}: esquentando {where} a {temp} °C',\n 'act.heat.air': '{weapon}: nada ao alcance',\n 'act.throw.grenade': '{weapon}: arremessada, pavio de {fuse} s',\n 'act.throw.molotov': '{weapon}: arremessado, quebra no impacto',\n 'act.explode': '{weapon}: explodiu, {energy} J em {radius} m, {n} objetos ao alcance',\n 'act.molotov_fire': '{weapon}: fogo no chão, raio de {radius} m por {seconds} s',\n 'act.tool.none': '{weapon}: nada ao alcance',\n 'act.tool.nojoint': '{weapon}: nenhuma junta perto de {where}',\n 'act.tool.refused': '{weapon} não solta {kind} de {obj}; precisa de: {need}',\n 'act.extinguish.hit': '{weapon}: espuma em {what}',\n 'act.extinguish.air': '{weapon}: espuma, nada ao alcance',\n 'act.grab': 'Pegou {name} ({kg} kg)',\n 'act.drop': 'Soltou {name}',\n 'act.throw': 'Arremessou {name} a {speed} m/s',\n 'act.landing': '{name} caiu a {speed} m/s: {energy} J',\n 'act.impact': '{name} bateu em {where} a {speed} m/s: {energy} J de dano de impacto',\n 'act.use_item': '{name}: {use}',\n 'act.tap.on': 'Abriu a torneira',\n 'act.tap.off': 'Fechou a torneira',\n\n 'use.drink': 'beber',\n 'use.sip': 'golinho',\n 'use.chug': 'virar',\n 'use.pour': 'despejar',\n 'use.pour_out': 'esvaziar',\n 'use.open': 'abrir',\n 'use.close': 'fechar',\n\n 'hud.reloading': 'Recarregando...',\n 'hud.empty': 'Sem munição',\n 'hud.no_fuel': 'Sem combustível',\n 'hud.nothing_to_grab': 'Nada para pegar aqui',\n 'hud.cannot_grab': '{name} não dá para pegar',\n 'hud.too_heavy': '{name} é pesado demais ({kg} kg)',\n 'hud.empty_container': '{name} está vazio',\n 'hud.refused': 'Ferramenta errada para {kind}',\n 'hud.drop': 'soltar',\n 'hud.rotate': 'girar',\n 'hud.throw': 'arremessar',\n 'hud.tilt': 'inclinar (segurar)',\n 'hud.equip': 'equipar {weapon}',\n\n 'ui.help': 'Clique: olhar · WASD: andar · Shift: correr · Espaço: pular · 1-0 / roda: ferramenta · botão esquerdo: usar · E: pegar/soltar · G ou botão direito: arremessar · Tab: painéis · Esc: soltar o mouse',\n 'ui.log': 'Registro de comportamento',\n 'ui.filter.action': 'ações',\n 'ui.filter.event': 'eventos',\n 'ui.filter.check': 'testes',\n 'ui.autoscroll': 'rolar sozinho',\n 'log.export_cancelled': 'exportação cancelada',\n 'ui.copy_json': 'Copiar JSON',\n 'ui.download_ndjson': 'Baixar NDJSON',\n 'ui.download_txt': 'Baixar TXT',\n 'ui.clear_log': 'Limpar',\n 'ui.catalog': 'Catálogo',\n 'ui.clear': 'Limpar',\n 'ui.reset_all': 'Consertar tudo',\n 'ui.slow': 'Câmera lenta 0,25×',\n 'ui.fast': 'Tempo ×10',\n 'ui.tap': 'Torneira',\n 'ui.quality': 'Qualidade',\n 'ui.quality.low': 'baixa',\n 'ui.quality.medium': 'média',\n 'ui.quality.high': 'alta',\n 'ui.equip': 'Equipar como ferramenta',\n 'ui.search_items': 'Buscar item (todas as abas)',\n 'ui.search_tests': 'Buscar teste',\n 'ui.no_results': 'Nada encontrado',\n 'ui.objects': '{n} objetos',\n 'ui.tests': 'Testes',\n 'ui.run_all': 'Rodar todos',\n 'ui.running': 'Rodando...',\n 'ui.report': '{passed} passaram, {failed} falharam',\n 'ui.panel': 'Painéis',\n 'ui.inspector': 'Inspetor',\n 'ui.aim_at_something': 'Mire em um objeto',\n 'ins.material': 'Material',\n 'ins.status': 'Estado',\n 'ins.burning': 'em chamas',\n 'ins.hp': 'Pontos de vida',\n 'ins.temperature': 'Temperatura',\n 'ins.char': 'Carbonizado',\n 'ins.melt': 'Derretido',\n 'ins.liters': 'Líquido',\n 'ins.damage': 'Marcas',\n 'ins.damage_counts': '{dents}, {holes}, {cracks}',\n 'ins.mass': 'Massa',\n 'ins.load': 'Carga',\n 'ins.stress': 'Tensão',\n 'ins.joints': 'Juntas',\n 'ins.open': 'aberta',\n\n 'sc.start': 'Cenário: {name}',\n 'sc.pass': 'Cenário passou: {name}',\n 'sc.fail': 'Cenário FALHOU: {name}',\n 'sc.error': 'o cenário lançou um erro: {msg}',\n 'leg.still': 'leg_1 continua presa',\n 'leg.gone': 'leg_1 soltou',\n\n 'sc.steel_through_hole': 'Tiro de 9 mm em chapa de aço faz furo que atravessa',\n 'sc.steel_through_hole.check': '9 mm em aço de 3 mm: {holes} furo(s) de {mm} mm, atravessou: {through}, chapa com {hp} hp (esperado: atravessar)',\n 'sc.concrete_stops_bullet': 'Tiro de 9 mm em bloco de concreto não atravessa',\n 'sc.concrete_stops_bullet.check': '9 mm em 40 cm de concreto: atravessou: {through}, {dents}, {holes}, {cracks}, bloco com {hp} hp (esperado: parou, parede atrás intacta)',\n 'sc.hammer_dents_drum': 'Martelo amassa um tambor de aço',\n 'sc.hammer_dents_drum.check': 'Martelo no tambor: {swings} golpe(s), {dents} amassado(s), o primeiro com {depth} mm, corpo com {hp} hp (esperado: amassado, sem quebrar)',\n 'sc.glass_shatters': 'Vidro estilhaça no primeiro tiro de 9 mm',\n 'sc.glass_shatters.check': 'Vidro: quebrou depois de {shots} tiro(s) em {n} cacos (esperado: quebrado no primeiro tiro, pelo menos 4 cacos)',\n 'sc.shotgun_splinters_crate': 'Escopeta lasca um caixote de madeira',\n 'sc.shotgun_splinters_crate.check': 'Calibre 12 no caixote: {shots} tiro(s), {splinters} tábua(s) lascada(s), {holes} furos (esperado: pelo menos uma lascada)',\n 'sc.kick_chair_leg': 'Um chute solta a perna da cadeira',\n 'sc.kick_chair_leg.check': 'Cadeira: {kicks} chute(s), {groups} grupo(s), peças soltas {before} → {after}, {leg} (esperado: aparece uma peça solta)',\n 'sc.kick_detaches_leg_via_tool': 'A ferramenta chute (barra de atalhos) solta a perna da cadeira',\n 'sc.kick_detaches_leg_via_tool.check': 'Cadeira, ferramenta chute: {kicks} chute(s), peças soltas {before} → {after}, {leg} (esperado: aparece uma peça solta)',\n 'sc.screwdriver_shelf_board': 'Chave de fenda solta a prateleira parafusada em cerca de 2,5 s',\n 'sc.screwdriver_shelf_board.check': 'Chave de fenda na prateleira: levou {secs} s, esperado cerca de {want} s, a estante agora está em {pieces}',\n 'sc.wrong_tool_refused': 'A ferramenta errada é recusada',\n 'sc.wrong_tool_refused.check': 'Chave de fenda numa solda: recusou {refused} vez(es), juntas abertas {opened} (esperado: recusar, nenhuma aberta)',\n 'sc.lighter_burns_crate': 'Isqueiro acende o caixote de madeira e ele vira cinza',\n 'sc.lighter_burns_crate.lit': 'Isqueiro no caixote: pegou fogo: {lit} (esperado: sim)',\n 'sc.lighter_burns_crate.ash': 'Depois de queimar por 500 s: {ash} de {total} tábuas viraram cinza, a mais queimada {char}% (esperado: tudo cinza ou carbonizado)',\n 'sc.torch_melts_steel': 'Fogo de madeira não derrete o tambor de aço, o maçarico derrete',\n 'sc.torch_melts_steel.wood': 'Caixote em chamas ao lado do tambor: o tambor chegou a {peak} °C, derreteu {melt}%, caixote ainda queimando: {crate} (esperado: sem derreter)',\n 'sc.torch_melts_steel.torch': 'Maçarico no tambor: {temp} °C, derreteu {melt}% (esperado: derretendo)',\n 'sc.bucket_melts_drips': 'Balde de plástico derrete e pinga perto do fogo',\n 'sc.bucket_melts_drips.check': 'Balde nas chamas: derreteu {melt}%, {temp} °C, {drips} linha(s) de pingos (esperado: derretendo)',\n 'sc.gas_bottle_explodes': 'Botijão de gás no fogo explode e empurra um caixote',\n 'sc.gas_bottle_explodes.explode': 'Botijão no fogo: explodiu depois de {seconds} s (esperado: explode)',\n 'sc.gas_bottle_explodes.push': 'Caixote a 1,3 m: andou {moved} m, perdeu {lost} (esperado: empurrado ou quebrado)',\n 'sc.bottle_drop_shatters': 'Garrafa de vidro solta de 1,5 m estilhaça',\n 'sc.bottle_drop_shatters.check': 'Garrafa solta de 1,5 m: estado {status}, {cracks} trincas, mancha de água: {stain} (esperado: quebrada, água no chão)',\n 'sc.throw_chair_at_wall': 'Cadeira arremessada na parede causa dano de impacto',\n 'sc.throw_chair_at_wall.check': 'Cadeira na parede: {impacts} impacto(s), o primeiro com {energy} J, {wall} linha(s) de dano na parede (esperado: impacto e dano)',\n 'sc.coffee_three_sips': 'Três goles de café baixam o nível e registram cafeína',\n 'sc.coffee_three_sips.check': 'Café: {sips} gole(s), nível {before} → {after} l, cafeína registrada: {caffeine}, queimou a boca: {burn} (esperado: 3 goles, cafeína)',\n 'sc.tilt_cup_spills': 'Inclinar o copo derrama café e deixa mancha',\n 'sc.tilt_cup_spills.check': 'Copo inclinado: nível {before} → {after} l, {stains} mancha(s) de café (esperado: derramou com mancha)',\n 'sc.jerrycan_leaks_fuel': 'Tiro no galão faz vazamento e mancha de combustível',\n 'sc.jerrycan_leaks_fuel.check': 'Galão baleado: {streams} jato(s) de vazamento, mancha de combustível: {stain}, restam {left} l de 20, a linha do furo cita o vazamento: {leak} (esperado: vazando, mancha)',\n 'sc.fuel_stain_burns': 'Mancha de combustível acesa queima',\n 'sc.fuel_stain_burns.stain': 'Mancha de combustível no chão depois do vazamento: {stain} (esperado: sim)',\n 'sc.fuel_stain_burns.ignite': 'Isqueiro na mancha: {ignited} ignição(ões), o fogo alcançou objetos por perto: {near} (esperado: acendeu)',\n 'sc.fuel_stain_burns.out': 'Depois de 30 s a mancha se consumiu: {burned} (esperado: sim)',\n 'roof.standing': 'laje de pé',\n 'roof.fell': 'laje caiu',\n 'sc.one_column_roof_stands': 'Pilar destruído: a laje fica de pé',\n 'sc.one_column_roof_stands.check': 'Estrutura sem um pilar: {roof}, maior desabamento {heavy} kg, tensão máxima {stress}% (esperado: de pé, sem desabamento grande)',\n 'sc.two_columns_roof_collapses': 'Dois pilares destruídos: a laje desaba',\n 'sc.two_columns_roof_collapses.check': 'Estrutura sem dois pilares: os outros logo a {stress}%, depois peças pesadas soltas: {pieces} ({kg} kg), evento de desabamento registrado: {logged} (esperado: a laje desaba)',\n 'sc.extinguisher_puts_out_fire': 'Extintor apaga um caixote em chamas',\n 'sc.extinguisher_puts_out_fire.burning': 'Caixote incendiado: queimando: {burning} (esperado: sim)',\n 'sc.extinguisher_puts_out_fire.out': 'Depois do extintor: ainda queimando: {burning}, {events} evento(s) de apagar (esperado: apagado)',\n },\n}\n\nexport const locales: Record<TestRoomLocale, RoomStrings> = { en, 'pt-BR': ptBR }\n\nexport const resolveStrings = (locale: string | undefined): RoomStrings => locales[(locale as TestRoomLocale) ?? 'en'] ?? locales.en\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-destruction'\nimport type { SurfaceSpec } from '@adatechnology/game-fluids'\nimport { brickWallSpec } from './items'\n\nexport interface ArenaObject {\n id: string\n spec: DestructibleSpec\n position: Vec3\n colors?: Record<string, number>\n}\n\n/** The static part of the room: lights, floor, grid, ruler and the destructible scenery. */\nexport interface Arena {\n group: THREE_NS.Group\n /** Objects to register in the world (target wall, table, shelf). */\n objects: ArenaObject[]\n surfaces: SurfaceSpec[]\n /** `[minX, minZ, maxX, maxZ]` boxes the player cannot walk into. */\n colliders: Array<[number, number, number, number]>\n playerStart: Vec3\n wallZ: number\n /** Rectangle and height of the table top (pieces rest on it while the table stands). */\n table: { minX: number; maxX: number; minZ: number; maxZ: number; top: number; id: string; topPart: string }\n tapSpout: Vec3\n sun: THREE_NS.DirectionalLight\n}\n\nconst tableSpec = (): DestructibleSpec => {\n const parts: PartSpec[] = [{ id: 'top', material: 'wood_hard', shape: { kind: 'box', size: [1.6, 0.05, 0.8] }, position: [0, 0.755, 0] }]\n const joints: JointSpec[] = []\n for (const [i, [x, z]] of [\n [-0.72, -0.32],\n [0.72, -0.32],\n [-0.72, 0.32],\n [0.72, 0.32],\n ].entries()) {\n parts.push({ id: `leg_${i + 1}`, material: 'wood_hard', shape: { kind: 'box', size: [0.06, 0.73, 0.06] }, position: [x, 0.365, z], anchored: true })\n joints.push({ a: `leg_${i + 1}`, b: 'top', kind: 'screw' })\n }\n return { name: 'table', parts, joints, tags: ['furniture'] }\n}\n\nconst shelfSpec = (): DestructibleSpec => {\n const parts: PartSpec[] = []\n const joints: JointSpec[] = []\n for (const [i, x] of [-0.6, 0.6].entries()) {\n parts.push({ id: `upright_${i + 1}`, material: 'wood_hard', shape: { kind: 'box', size: [0.04, 1.7, 0.4] }, position: [x, 0.85, 0], anchored: true })\n }\n for (const [i, y] of [0.4, 0.9, 1.4].entries()) {\n parts.push({ id: `board_${i + 1}`, material: 'wood_soft', shape: { kind: 'box', size: [1.2, 0.03, 0.4] }, position: [0, y, 0] })\n joints.push({ a: `board_${i + 1}`, b: 'upright_1', kind: 'screw' }, { a: `board_${i + 1}`, b: 'upright_2', kind: 'screw' })\n }\n return { name: 'shelf', parts, joints, tags: ['furniture'] }\n}\n\nexport function createArena(THREE: typeof THREE_NS, size: number, scene: THREE_NS.Scene): Arena {\n const group = new THREE.Group()\n group.name = 'test-room-arena'\n scene.background = new THREE.Color(0x9fb4c8)\n\n group.add(new THREE.HemisphereLight(0xcfe3ff, 0x6b6257, 0.75))\n const sun = new THREE.DirectionalLight(0xffffff, 2.1)\n sun.position.set(7, 13, 8)\n sun.castShadow = true\n sun.shadow.mapSize.set(1024, 1024)\n const sc = sun.shadow.camera\n sc.left = -16\n sc.right = 16\n sc.top = 16\n sc.bottom = -16\n sc.near = 1\n sc.far = 40\n sun.shadow.bias = -0.0006\n group.add(sun)\n\n const floor = new THREE.Mesh(new THREE.PlaneGeometry(size * 2, size * 2), new THREE.MeshStandardMaterial({ color: 0x8e8e8a, roughness: 0.95 }))\n floor.rotation.x = -Math.PI / 2\n floor.receiveShadow = true\n floor.name = 'floor'\n group.add(floor)\n\n const grid = new THREE.GridHelper(size * 2, size * 2, 0x4c4c52, 0x77777b)\n grid.position.y = 0.004\n group.add(grid)\n\n const wallZ = -11\n const playerStart: Vec3 = [0, 1.7, 5]\n\n // distance ruler along the left of the lane: a tick every metre (taller every 5 m) and a label every 5 m\n const pts: number[] = []\n const rx = -1.6\n for (let z = Math.round(playerStart[2]); z >= wallZ; z--) {\n const d = playerStart[2] - z\n const len = d % 5 === 0 ? 0.5 : 0.2\n pts.push(rx, 0.01, z, rx + len, 0.01, z)\n }\n pts.push(rx, 0.01, playerStart[2], rx, 0.01, wallZ)\n const rg = new THREE.BufferGeometry()\n rg.setAttribute('position', new THREE.Float32BufferAttribute(pts, 3))\n group.add(new THREE.LineSegments(rg, new THREE.LineBasicMaterial({ color: 0xffd23f })))\n for (let d = 5; playerStart[2] - d >= wallZ; d += 5) {\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 128\n canvas.height = 64\n const ctx = canvas.getContext('2d')\n if (!ctx) break\n ctx.fillStyle = '#ffd23f'\n ctx.font = 'bold 44px sans-serif'\n ctx.textAlign = 'center'\n ctx.fillText(`${d} m`, 64, 48)\n const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(canvas), transparent: true, depthWrite: false }))\n sprite.scale.set(1.2, 0.6, 1)\n sprite.position.set(rx - 0.8, 0.45, playerStart[2] - d)\n group.add(sprite)\n } catch {\n break\n }\n }\n\n // tap on a post at the end of the table, spout over the tabletop\n const tableX = 3.5\n const tapMat = new THREE.MeshStandardMaterial({ color: 0xb9bec4, metalness: 0.8, roughness: 0.35 })\n const post = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 1.4, 10), tapMat)\n post.position.set(tableX + 1.15, 0.7, 0)\n const arm = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.025, 1.15 - 0.3, 10), tapMat)\n arm.rotation.z = Math.PI / 2\n arm.position.set(tableX + (1.15 + 0.3) / 2, 1.38, 0)\n const spoutMesh = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.025, 0.1, 10), tapMat)\n spoutMesh.position.set(tableX + 0.3, 1.33, 0)\n for (const m of [post, arm, spoutMesh]) {\n m.castShadow = true\n group.add(m)\n }\n const tapSpout: Vec3 = [tableX + 0.3, 1.28, 0]\n\n const objects: ArenaObject[] = [\n { id: 'target_wall', spec: brickWallSpec(), position: [0, 0, wallZ], colors: { brick: 0xa5472e } },\n { id: 'table', spec: tableSpec(), position: [tableX, 0, 0] },\n { id: 'shelf', spec: shelfSpec(), position: [-3.5, 0, 0], colors: { wood_soft: 0xc79a62 } },\n ]\n\n return {\n group,\n objects,\n surfaces: [\n { id: 'floor', point: [0, 0, 0], normal: [0, 1, 0], halfSize: [size, size], porosity: 0.05 },\n { id: 'table', point: [tableX, 0.78, 0], normal: [0, 1, 0], halfSize: [0.8, 0.4], porosity: 0.3 },\n ],\n colliders: [\n [tableX - 0.8, -0.4, tableX + 0.8, 0.4],\n [tableX + 1.1, -0.1, tableX + 1.2, 0.1],\n [-3.5 - 0.62, -0.2, -3.5 + 0.62, 0.2],\n [-size, wallZ - 1, size, wallZ + 0.2],\n ],\n playerStart,\n wallZ,\n table: { minX: tableX - 0.8, maxX: tableX + 0.8, minZ: -0.4, maxZ: 0.4, top: 0.78, id: 'table', topPart: 'top' },\n tapSpout,\n sun,\n }\n}\n","import type { BenchChange, ControlPatch, ControlValue, ModuleControl, ModuleLayer, ModuleMetric, TestableModule } from '@adatechnology/game-contracts'\nimport type { BenchControl, BenchHandle, BenchLayer } from './types'\n\n/** What the room keeps per module bench: the declarations, the module's patches, the values and the layers. Pure: no DOM, no three.js. */\nexport interface BenchStore extends BenchHandle {\n readonly moduleId: string\n readonly metrics: readonly ModuleMetric[]\n readonly declared: { readonly controls: readonly ModuleControl[]; readonly layers: readonly ModuleLayer[]; readonly metrics: readonly ModuleMetric[] }\n /** Changes for the module (the `ModuleBench.onChange` listeners). */\n onChange(listener: (change: BenchChange) => void): () => void\n /** Any change of state, the module's patches included (the panel and the URL follow it). */\n watch(listener: () => void): () => void\n patch(id: string, patch: ControlPatch): void\n /** One change per control (not actions) and per layer, in declaration order. */\n sendInitial(): void\n /** Apply an encoded state without emitting. */\n restore(encoded: string): void\n /** Drops every listener and watcher (the room is gone). */\n dispose(): void\n}\n\ntype ControlState = ModuleControl & { disabled: boolean }\n\nconst snap = (control: Extract<ModuleControl, { kind: 'number' }>, value: number): number => {\n const clamped = Math.min(control.max, Math.max(control.min, value))\n if (!control.step) return clamped\n const stepped = control.min + Math.round((clamped - control.min) / control.step) * control.step\n return Number(Math.min(control.max, stepped).toFixed(10))\n}\n\n/** The value a control takes for `value`, or undefined when it does not fit (wrong type, option not offered, action). */\nfunction fitValue(control: ModuleControl, value: unknown): ControlValue | undefined {\n if (control.kind === 'number') return typeof value === 'number' && Number.isFinite(value) ? snap(control, value) : undefined\n if (control.kind === 'boolean') return typeof value === 'boolean' ? value : undefined\n if (control.kind === 'choice') return typeof value === 'string' && control.options.some((option) => option.id === value) ? value : undefined\n return undefined\n}\n\nconst fromText = (control: ModuleControl, text: string): unknown => {\n if (control.kind === 'number') return text.trim() === '' ? Number.NaN : Number(text)\n if (control.kind === 'boolean') return text === '1' ? true : text === '0' ? false : undefined\n return text\n}\n\nconst toText = (value: ControlValue): string => (typeof value === 'boolean' ? (value ? '1' : '0') : String(value))\n\n/** `id=value;id=value`, values with `encodeURIComponent`, booleans and layers as `1` / `0`. */\nexport function encodeBenchState(controls: readonly BenchControl[], layers: readonly BenchLayer[]): string {\n const pairs: string[] = []\n for (const control of controls) if (control.value !== undefined) pairs.push(`${control.id}=${encodeURIComponent(toText(control.value))}`)\n for (const layer of layers) pairs.push(`${layer.id}=${layer.on ? '1' : '0'}`)\n return pairs.join(';')\n}\n\n/** Reads an encoded state as hostile input: unknown ids, NaN, options not offered and malformed pairs are dropped; numbers are clamped. */\nexport function decodeBenchState(encoded: string, controls: readonly ModuleControl[], layers: readonly ModuleLayer[]): Map<string, ControlValue> {\n const out = new Map<string, ControlValue>()\n for (const pair of encoded.split(';')) {\n const at = pair.indexOf('=')\n if (at <= 0) continue\n const id = pair.slice(0, at)\n let text: string\n try {\n text = decodeURIComponent(pair.slice(at + 1))\n } catch {\n continue\n }\n const control = controls.find((c) => c.id === id)\n if (control) {\n const value = fitValue(control, fromText(control, text))\n if (value !== undefined) out.set(id, value)\n continue\n }\n if (layers.some((layer) => layer.id === id) && (text === '1' || text === '0')) out.set(id, text === '1')\n }\n return out\n}\n\nexport function createBenchStore(module: TestableModule<unknown>, locale: string, onListenerError?: (error: unknown) => void): BenchStore {\n const declared = { controls: module.controls?.(locale) ?? [], layers: module.layers?.(locale) ?? [], metrics: module.metrics?.(locale) ?? [] }\n const controls: ControlState[] = declared.controls.map((control) => ({ ...control, disabled: false }))\n const values = new Map<string, ControlValue>()\n for (const control of controls) if (control.kind !== 'action') values.set(control.id, control.default)\n const layers = new Map<string, boolean>(declared.layers.map((layer) => [layer.id, layer.default !== false]))\n const listeners = new Set<(change: BenchChange) => void>()\n const watchers = new Set<() => void>()\n const emit = (change: BenchChange): void => {\n for (const listener of listeners) {\n try {\n listener(change)\n } catch (error) {\n onListenerError?.(error)\n }\n }\n }\n const changed = (): void => {\n for (const watcher of watchers) watcher()\n }\n const controlOf = (id: string): ControlState | undefined => controls.find((control) => control.id === id)\n\n const store: BenchStore = {\n moduleId: module.id,\n metrics: declared.metrics,\n declared,\n controls: () => controls.map((control) => ({ ...control, value: values.get(control.id) })),\n layers: () => declared.layers.map((layer) => ({ ...layer, on: layers.get(layer.id) === true })),\n value: (id) => values.get(id),\n layer: (id) => layers.get(id) === true,\n set(id, value) {\n const control = controlOf(id)\n if (!control || control.disabled) return false\n const fitted = fitValue(control, value)\n if (fitted === undefined) return false\n values.set(id, fitted)\n emit({ kind: 'control', id, value: fitted })\n changed()\n return true\n },\n setLayer(id, on) {\n if (!layers.has(id)) return false\n layers.set(id, on)\n emit({ kind: 'layer', id, on })\n changed()\n return true\n },\n act(id) {\n const control = controlOf(id)\n if (!control || control.kind !== 'action' || control.disabled) return false\n emit({ kind: 'action', id })\n return true\n },\n encode: () => encodeBenchState(store.controls(), store.layers()),\n onChange(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n watch(listener) {\n watchers.add(listener)\n return () => watchers.delete(listener)\n },\n patch(id, patch) {\n const index = controls.findIndex((control) => control.id === id)\n if (index < 0) return\n let control = controls[index]\n if (patch.hidden !== undefined) control = { ...control, hidden: patch.hidden }\n if (patch.disabled !== undefined) control = { ...control, disabled: patch.disabled }\n if (patch.options && control.kind === 'choice' && patch.options.length > 0) {\n control = { ...control, options: [...patch.options] }\n const offered = control.options\n if (!offered.some((option) => option.id === values.get(id))) values.set(id, offered[0].id)\n }\n controls[index] = control\n if (patch.value !== undefined) {\n const fitted = fitValue(control, patch.value)\n if (fitted !== undefined) values.set(id, fitted)\n }\n changed()\n },\n sendInitial() {\n for (const control of controls) {\n const value = values.get(control.id)\n if (value !== undefined) emit({ kind: 'control', id: control.id, value })\n }\n for (const layer of declared.layers) emit({ kind: 'layer', id: layer.id, on: layers.get(layer.id) === true })\n changed()\n },\n restore(encoded) {\n for (const [id, value] of decodeBenchState(encoded, controls, declared.layers)) {\n if (typeof value === 'boolean' && layers.has(id)) layers.set(id, value)\n else values.set(id, value)\n }\n },\n dispose() {\n listeners.clear()\n watchers.clear()\n },\n }\n return store\n}\n","import type { LogEntry, NewLogEntry, TestRoomLog } from './types'\n\nexport type NewEntry = NewLogEntry\n\n/** The log the room writes to (a `TestRoomLog` plus the write side). */\nexport interface WritableLog extends TestRoomLog {\n /** Called before every read, so pending work (the room batches events per frame) is flushed first. */\n setBeforeRead(fn: (() => void) | null): void\n setClock(fn: () => number): void\n}\n\nconst MAX_ENTRIES = 5000\n\nconst pad = (n: number, w = 2): string => String(n).padStart(w, '0')\n\n/** `00:03.21` style clock for the text export. */\nexport const formatTime = (t: number): string => {\n const m = Math.floor(t / 60)\n const s = t - m * 60\n return `${pad(m)}:${s.toFixed(2).padStart(5, '0')}`\n}\n\n/** Minimal shape of the `downloads` capability a claude.ai Artifact page gets from `claude.use('downloads')`. */\ninterface DownloadsApi {\n save(request: { filename: string; data: string }): Promise<unknown>\n}\n\nexport interface LogOptions {\n /** Text of the `action` line written when the viewer declines (or fails) an export from an Artifact page. */\n exportCancelled?: () => string\n}\n\nexport function createLog(options: LogOptions = {}): WritableLog {\n // In a claude.ai Artifact the page cannot use <a download> / blob links: it asks the host for the `downloads` capability. The promise is\n // created once, never awaited here (`use` may take up to 10 s and resolve null); `download` awaits it when somebody actually exports.\n const host = (globalThis as { claude?: { use?: (name: string) => Promise<unknown> } }).claude\n let downloadsP: Promise<DownloadsApi | null> | null = null\n if (host && typeof host.use === 'function') {\n try {\n downloadsP = Promise.resolve(host.use('downloads')).then((d) => (d as DownloadsApi | null) ?? null, () => null)\n } catch {\n downloadsP = null\n }\n }\n let list: LogEntry[] = []\n let seq = 0\n let clock = (): number => 0\n let beforeRead: (() => void) | null = null\n const listeners = new Set<(entry: LogEntry, updated: boolean) => void>()\n const keyed = new Map<string, { entry: LogEntry; last: number; count: number }>()\n\n const read = (): LogEntry[] => {\n beforeRead?.()\n return list\n }\n const emit = (e: LogEntry, updated: boolean): void => {\n for (const fn of listeners) {\n try {\n fn(e, updated)\n } catch {\n // a broken listener must not break the room\n }\n }\n }\n\n const add = (entry: NewEntry): LogEntry => {\n const { t, ...rest } = entry\n const e: LogEntry = { seq: seq++, t: Math.round((t ?? clock()) * 1000) / 1000, ...rest }\n list.push(e)\n if (list.length > MAX_ENTRIES) list = list.slice(list.length - MAX_ENTRIES)\n emit(e, false)\n return e\n }\n\n const log: WritableLog = {\n add,\n coalesce(key, entry, windowS = 1) {\n const now = entry.t ?? clock()\n const k = keyed.get(key)\n if (k && now - k.last <= windowS && list.includes(k.entry)) {\n const { t: _t, ...rest } = entry\n k.count++\n Object.assign(k.entry, rest)\n k.entry.data = { ...(rest.data ?? {}), updates: k.count }\n k.last = now\n emit(k.entry, true)\n return k.entry\n }\n const e = add(entry)\n keyed.set(key, { entry: e, last: now, count: 1 })\n return e\n },\n setBeforeRead(fn) {\n beforeRead = fn\n },\n setClock(fn) {\n clock = fn\n },\n entries(filter) {\n const all = read()\n if (!filter) return all.slice()\n return all.filter(\n (e) =>\n (!filter.channel || e.channel === filter.channel) && (!filter.type || e.type === filter.type) && (!filter.objectId || e.objectId === filter.objectId),\n )\n },\n clear() {\n beforeRead?.()\n list = []\n keyed.clear()\n },\n toJSON: () => JSON.stringify(read(), null, 2),\n toNDJSON: () => read().map((e) => JSON.stringify(e)).join('\\n') + (list.length ? '\\n' : ''),\n toText: () => read().map((e) => `[${formatTime(e.t)}] ${e.channel.padEnd(6)} ${e.text}`).join('\\n'),\n async download(format = 'ndjson') {\n const body = format === 'json' ? log.toJSON() : format === 'txt' ? log.toText() : log.toNDJSON()\n const downloads = downloadsP ? await downloadsP : null\n if (downloads) {\n // the Artifact allowlist has no `.ndjson`: it goes out as text\n const filename = format === 'ndjson' ? 'test-room-log.ndjson.txt' : `test-room-log.${format}`\n try {\n await downloads.save({ filename, data: body })\n } catch (err) {\n const code = (err as { code?: unknown } | null)?.code\n log.add({ channel: 'action', type: 'export_cancelled', text: options.exportCancelled?.() ?? 'export cancelled', data: { format, ...(typeof code === 'string' ? { code } : {}) } })\n }\n return\n }\n if (typeof document === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL) return\n const mime = format === 'json' ? 'application/json' : 'text/plain'\n const url = URL.createObjectURL(new Blob([body], { type: mime }))\n const a = document.createElement('a')\n a.href = url\n a.download = `test-room-log.${format}`\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n },\n summary() {\n const byType: Record<string, number> = {}\n const byMaterial: Record<string, number> = {}\n const objects = new Set<string>()\n let destroyed = 0\n for (const e of read()) {\n byType[e.type] = (byType[e.type] ?? 0) + 1\n if (e.material) byMaterial[e.material] = (byMaterial[e.material] ?? 0) + 1\n if (e.objectId) objects.add(e.objectId)\n if (e.type === 'destroyed') destroyed++\n }\n return { byType, byMaterial, objects: objects.size, destroyed }\n },\n on(fn) {\n listeners.add(fn)\n return () => listeners.delete(fn)\n },\n }\n return log\n}\n","import type { RoomMetricId } from './types'\n\nexport const ROOM_METRICS: readonly RoomMetricId[] = ['fps', 'frame_ms', 'draw_calls', 'triangles', 'objects', 'fragments', 'particles', 'decals']\n\nconst WINDOW_S = 0.5\n\ninterface RenderInfo {\n info?: { render?: { calls: number; triangles: number } }\n}\n\nexport interface RoomMetricsSources {\n readonly gl: unknown\n readonly destruction: { stats(): { fragments: number; particles: number; pieces: number; decals: number } }\n readonly fluids: { stats(): { particles: number; stains: number } }\n readonly ids: readonly RoomMetricId[]\n}\n\nexport interface RoomMetrics {\n /** Every frame with the real `dt`, before the time scale. */\n frame(dt: number): void\n /** Right after the room renders (only when it owns the loop). */\n rendered(): void\n sample(): Partial<Record<RoomMetricId, number>>\n}\n\nexport function createRoomMetrics(sources: RoomMetricsSources): RoomMetrics {\n const wanted = new Set(sources.ids)\n const gl = sources.gl as RenderInfo\n let windowS = 0\n let frames = 0\n let fps: number | undefined\n let frameMs: number | undefined\n let calls: number | undefined\n let triangles: number | undefined\n let ownsRender = false\n return {\n frame(dt) {\n frames++\n windowS += dt\n if (windowS < WINDOW_S) return\n fps = frames / windowS\n frameMs = (windowS / frames) * 1000\n frames = 0\n windowS = 0\n },\n rendered() {\n ownsRender = true\n calls = gl.info?.render?.calls\n triangles = gl.info?.render?.triangles\n },\n sample() {\n const out: Partial<Record<RoomMetricId, number>> = {}\n const put = (id: RoomMetricId, value: number | undefined): void => {\n if (wanted.has(id) && value !== undefined) out[id] = value\n }\n put('fps', fps)\n put('frame_ms', frameMs)\n const render = ownsRender ? { calls, triangles } : gl.info?.render\n put('draw_calls', render?.calls)\n put('triangles', render?.triangles)\n if (!['objects', 'fragments', 'particles', 'decals'].some((id) => wanted.has(id as RoomMetricId))) return out\n const destruction = sources.destruction.stats()\n const fluids = sources.fluids.stats()\n put('objects', destruction.pieces)\n put('fragments', destruction.fragments)\n put('particles', destruction.particles + fluids.particles)\n put('decals', destruction.decals + fluids.stains)\n return out\n },\n }\n}\n","import type { DestructionEvent, DestructionWorld, PartState, ToolKind } from '@adatechnology/game-destruction'\nimport type { FluidEvent, FluidWorld } from '@adatechnology/game-fluids'\nimport type { WritableLog } from './log'\nimport type { LogEntry } from './types'\n\ntype Vars = Record<string, string | number>\n\n/** What the narrator needs to know about the room. */\nexport interface NarrateContext {\n world: DestructionWorld\n fluids: FluidWorld\n log: WritableLog\n /** Current room time in seconds. */\n now: () => number\n t: (key: string, vars?: Vars) => string\n /** Locale number: `1.5` -> `1,5` in pt-BR. */\n num: (n: number, digits?: number) => string\n /** Item display name of an object id (also loose pieces). */\n nameOf: (objectId: string) => string\n itemIdOf: (objectId: string) => string | undefined\n materialName: (id: string) => string\n liquidName: (id: string) => string\n jointKind: (kind: string) => string\n toolName: (tool: string) => string\n /** Display name of the item that carries a fluid container. */\n containerName: (containerId: string) => { name: string; objectId?: string; itemId?: string } | undefined\n /** Where a part lives now: its object, or the loose piece it broke off into. */\n locatePart?: (objectId: string, partId: string) => { objectId: string; part: PartState } | null\n}\n\nconst SKIP_DAMAGE: ReadonlySet<string> = new Set(['fire', 'heat'])\n\n/**\n * Turns destruction and fluid events into plain log lines in the room locale. Events of one frame arrive as a batch: a `damage` event is merged\n * into the dent, hole or crack it caused, a `leak` event into the hole that opened it, and the noisy ones (melt, drip, disassembly) become one\n * line that is updated while it goes on.\n */\nexport function createNarrator(c: NarrateContext) {\n const { t, num } = c\n\n /** Materials seen per `object|part`, so a line about a part that already broke off its object still names the material. */\n const materialMemo = new Map<string, string>()\n const findPart = (objectId: string, partId: string): PartState | null => {\n const p = c.world.part(objectId, partId) ?? c.locatePart?.(objectId, partId)?.part ?? null\n if (p) materialMemo.set(`${objectId}|${partId}`, p.material)\n return p\n }\n const plural = (key: string, n: number): string => t(`${key}.${n === 1 ? 'one' : 'other'}`, { n })\n const pieces = (n: number): string => plural('count.piece', n)\n const joints = (n: number): string => plural('count.joint', n)\n const xz = (x: number, z: number): string => t('coords', { x: num(x, 1), z: num(z, 1) })\n\n const where = (objectId: string, partId: string): string => {\n const p = findPart(objectId, partId)\n const m = p?.material ?? materialMemo.get(`${objectId}|${partId}`)\n return `${c.nameOf(objectId)} › ${partId}${m ? ` (${c.materialName(m)})` : ''}`\n }\n\n const stateOf = (objectId: string, partId: string): LogEntry['state'] => {\n const p = findPart(objectId, partId)\n if (!p) return undefined\n const s: Record<string, number | string | boolean> = {\n status: p.status,\n hp: Math.round(p.hp * 10) / 10,\n maxHp: Math.round(p.maxHp * 10) / 10,\n temperature: Math.round(p.temperature),\n char: Math.round(p.char * 100) / 100,\n melt: Math.round(p.melt * 100) / 100,\n }\n if (p.liters !== undefined) s.liters = Math.round(p.liters * 1000) / 1000\n return s\n }\n\n const base = (ev: DestructionEvent, part?: string): Pick<LogEntry, 'channel' | 'objectId' | 'itemId' | 'part' | 'material' | 'state'> => ({\n channel: 'event',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n part,\n material: part ? (findPart(ev.object, part)?.material ?? materialMemo.get(`${ev.object}|${part}`)) : undefined,\n state: part ? stateOf(ev.object, part) : undefined,\n })\n\n const hpText = (obj: string, part: string): string => {\n const p = findPart(obj, part)\n return p ? `hp ${num(p.hp, 0)}/${num(p.maxHp, 0)}` : ''\n }\n\n const isLost = (obj: string, part: string): boolean => {\n const st = findPart(obj, part)?.status\n return st === 'broken' || st === 'melted' || st === 'ashes'\n }\n\n /** Per-part running totals for lines that repeat while something goes on (cracks under load, overload damage). */\n const crackAcc = new Map<string, { n: number; cm: number; last: number }>()\n const damageAcc = new Map<string, { total: number; last: number }>()\n const stressAt = new Map<string, number>()\n const leakAt = new Map<string, number>()\n const list = (names: string[]): string => (names.length > 6 ? `${names.slice(0, 6).join(', ')}…` : names.join(', '))\n\n const events = (batch: DestructionEvent[]): void => {\n const now = c.now()\n const damage = new Map<string, { amount: number; type: string }>()\n const holes = new Map<string, LogEntry>()\n const dents = new Map<string, LogEntry>()\n for (const ev of batch) {\n if (ev.type !== 'damage') continue\n const k = `${ev.object}|${ev.part}`\n const prev = damage.get(k)\n damage.set(k, { amount: (prev?.amount ?? 0) + ev.amount, type: ev.damageType })\n }\n\n // A part that breaks, melts or burns away opens every joint it had: those `detach` events become part of ONE line about the part\n // (appended to its fracture or burnout line, or standing alone), instead of one line per joint.\n const lostJoints = new Map<string, { obj: string; part: string; joints: number; groups: number; merged: boolean }>()\n // Joints that open for another reason (a blow, a tool) are counted per object.\n const openJoints = new Map<string, { obj: string; by: string; list: Array<{ joint: string; a: string; b: string }>; groups: number; done: boolean }>()\n // Several parts of one object catching fire or being put out at once are one line.\n const fireParts = new Map<string, { obj: string; parts: string[]; temp: number; done: boolean }>()\n const outParts = new Map<string, { obj: string; parts: string[]; done: boolean }>()\n for (const ev of batch) {\n if (ev.type === 'detach') {\n if (ev.by === 'part_lost') {\n const [a, b] = ev.parts\n const lost = isLost(ev.object, a) && !isLost(ev.object, b) ? a : isLost(ev.object, b) && !isLost(ev.object, a) ? b : isLost(ev.object, a) ? a : b\n const key = `${ev.object}|${lost}`\n const g = lostJoints.get(key) ?? { obj: ev.object, part: lost, joints: 0, groups: 0, merged: false }\n g.joints++\n g.groups = ev.groups.length\n lostJoints.set(key, g)\n } else {\n const key = `${ev.object}|${ev.by}`\n const g = openJoints.get(key) ?? { obj: ev.object, by: ev.by, list: [], groups: 0, done: false }\n const [a, b] = ev.parts\n g.list.push({ joint: ev.joint, a, b })\n g.groups = ev.groups.length\n openJoints.set(key, g)\n }\n } else if (ev.type === 'ignite') {\n const g = fireParts.get(ev.object) ?? { obj: ev.object, parts: [], temp: 0, done: false }\n g.parts.push(ev.part)\n g.temp = Math.max(g.temp, findPart(ev.object, ev.part)?.temperature ?? 0)\n fireParts.set(ev.object, g)\n } else if (ev.type === 'extinguish') {\n const g = outParts.get(ev.object) ?? { obj: ev.object, parts: [], done: false }\n g.parts.push(ev.part)\n outParts.set(ev.object, g)\n }\n }\n const lostTail = (key: string): string => {\n const g = lostJoints.get(key)\n if (!g) return ''\n g.merged = true\n return t('ev.lost.tail', { joints: joints(g.joints), pieces: pieces(g.groups) })\n }\n const lostData = (key: string): Record<string, unknown> => {\n const g = lostJoints.get(key)\n return g ? { jointsOpened: g.joints, pieces: g.groups } : {}\n }\n\n for (const ev of batch) {\n switch (ev.type) {\n case 'damage':\n break\n case 'dent': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n const mm = ev.dent.depth * 1000\n const prev = dents.get(k)\n if (prev) {\n const n = Number(prev.data?.count ?? 1) + 1\n const deepest = Math.max(Number(prev.data?.depthMm ?? 0), mm)\n prev.text = t('ev.dents', { where: where(ev.object, ev.part), n, mm: num(deepest, 0), hp: hpText(ev.object, ev.part) })\n prev.data = { ...prev.data, count: n, depthMm: Math.round(deepest * 10) / 10 }\n break\n }\n dents.set(\n k,\n c.log.add({\n ...base(ev, ev.part),\n type: 'dent',\n text: t('ev.dent', { where: where(ev.object, ev.part), mm: num(mm, 0), hp: hpText(ev.object, ev.part) }),\n data: { count: 1, depthMm: Math.round(mm * 10) / 10, radius: ev.dent.radius, damage: d?.amount, point: ev.worldPoint, source: ev.source },\n }),\n )\n break\n }\n case 'hole': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n const mm = ev.hole.diameter * 1000\n const prev = holes.get(k)\n if (prev) {\n const n = Number(prev.data?.count ?? 1) + 1\n const through = Number(prev.data?.throughCount ?? 0) + (ev.hole.through ? 1 : 0)\n prev.text = t('ev.holes', { where: where(ev.object, ev.part), n, mm: num(mm, 0), thr: through, hp: hpText(ev.object, ev.part) })\n prev.data = { ...prev.data, count: n, throughCount: through, through: through > 0 }\n break\n }\n holes.set(\n k,\n c.log.add({\n ...base(ev, ev.part),\n type: 'hole',\n text: t(ev.hole.through ? 'ev.hole.through' : 'ev.hole.stuck', { where: where(ev.object, ev.part), mm: num(mm, 0), hp: hpText(ev.object, ev.part) }),\n data: { count: 1, throughCount: ev.hole.through ? 1 : 0, diameterMm: Math.round(mm * 10) / 10, through: ev.hole.through, damage: d?.amount, point: ev.worldPoint, source: ev.source },\n }),\n )\n break\n }\n case 'crack': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n // a part under load cracks again and again: that is one line that counts them (a cracking shot or blow stays its own line)\n const loaded = (findPart(ev.object, ev.part)?.stress ?? 0) > 0.8 && ev.source === undefined\n const cm = ev.crack.length * 100\n if (loaded) {\n const acc = crackAcc.get(k)\n const n = acc && now - acc.last <= 1 ? acc.n + 1 : 1\n const longest = acc && n > 1 ? Math.max(acc.cm, cm) : cm\n crackAcc.set(k, { n, cm: longest, last: now })\n c.log.coalesce(\n `crack:${k}`,\n {\n ...base(ev, ev.part),\n type: 'crack',\n text: t('ev.cracks', { where: where(ev.object, ev.part), n, cm: num(longest, 0), hp: hpText(ev.object, ev.part) }),\n data: { rays: ev.crack.rays, lengthM: ev.crack.length, count: n, underLoad: true },\n },\n 1,\n )\n break\n }\n c.log.add({\n ...base(ev, ev.part),\n type: 'crack',\n text: t('ev.crack', { where: where(ev.object, ev.part), rays: ev.crack.rays, cm: num(cm, 0), hp: hpText(ev.object, ev.part) }),\n data: { rays: ev.crack.rays, lengthM: ev.crack.length, damage: d?.amount, source: ev.source },\n })\n break\n }\n case 'ricochet':\n c.log.add({\n ...base(ev, ev.part),\n type: 'ricochet',\n text: t('ev.ricochet', { where: where(ev.object, ev.part), energy: num(ev.energy, 0) }),\n data: { energy: ev.energy, direction: ev.direction },\n })\n break\n case 'leak': {\n const k = `${ev.object}|${ev.part}`\n const liquid = c.liquidName(ev.fluid)\n const hole = holes.get(k)\n const rate = num(ev.rate, 2)\n leakAt.set(ev.object, now)\n if (hole) {\n hole.text += t('ev.leak.tail', { liquid, rate })\n hole.data = { ...hole.data, leak: { fluid: ev.fluid, ratePerS: ev.rate, pressurized: ev.pressurized } }\n } else {\n c.log.add({ ...base(ev, ev.part), type: 'leak', text: t('ev.leak.alone', { where: where(ev.object, ev.part), liquid, rate }), data: { fluid: ev.fluid, ratePerS: ev.rate } })\n }\n break\n }\n case 'fracture': {\n const k = `${ev.object}|${ev.part}`\n const d = damage.get(k)\n damage.delete(k)\n c.log.add({\n ...base(ev, ev.part),\n type: 'fracture',\n text: t(`ev.fracture.${ev.style}`, { where: where(ev.object, ev.part), n: ev.fragments.length }) + lostTail(k),\n data: { style: ev.style, fragments: ev.fragments.length, damage: d?.amount, point: ev.point, source: ev.source, ...lostData(k) },\n })\n break\n }\n case 'detach': {\n if (ev.by === 'part_lost') {\n // the part's own line (fracture, burnout) already says it; with none in this batch, say it here, once\n const [a, b] = ev.parts\n const lost = isLost(ev.object, a) && !isLost(ev.object, b) ? a : isLost(ev.object, b) && !isLost(ev.object, a) ? b : isLost(ev.object, a) ? a : b\n const key = `${ev.object}|${lost}`\n const g = lostJoints.get(key)\n if (!g || g.merged) break\n const hasOwnLine = batch.some((e) => (e.type === 'fracture' || e.type === 'burnout') && e.object === ev.object && e.part === lost)\n if (hasOwnLine) break\n g.merged = true\n const status = findPart(ev.object, lost)?.status\n const verb = t(`lost.${status === 'ashes' ? 'ashes' : status === 'melted' ? 'melted' : 'broken'}`)\n c.log.add({\n ...base(ev, lost),\n type: 'detach',\n text: t('ev.lost.alone', { where: where(ev.object, lost), verb, joints: joints(g.joints), pieces: pieces(g.groups) }),\n data: { parts: [a, b], by: ev.by, ...lostData(key) },\n })\n break\n }\n const key = `${ev.object}|${ev.by}`\n const g = openJoints.get(key)\n if (!g || g.done) break\n g.done = true\n const [a, b] = ev.parts\n const many = g.list.length > 1\n c.log.add({\n channel: 'event',\n type: 'detach',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: many\n ? t(`ev.detach.many.${ev.by === 'tool' ? 'tool' : 'break'}`, { obj: c.nameOf(ev.object), joints: joints(g.list.length), pieces: pieces(g.groups) })\n : t('ev.detach', { obj: c.nameOf(ev.object), a, b, by: t(`by.${ev.by}`), pieces: pieces(g.groups) }),\n data: { joint: ev.joint, joints: g.list.map((j) => j.joint), parts: ev.parts, by: ev.by, groups: g.groups },\n })\n break\n }\n case 'disassemble_progress': {\n const pct = Math.round(ev.progress * 100)\n const kind = kindOf(ev.object, ev.joint)\n const [a, b] = ev.joint.split('~')\n c.log.coalesce(\n `dis:${ev.object}:${ev.joint}`,\n {\n channel: 'event',\n type: 'disassemble_progress',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: t('ev.disassemble', { obj: c.nameOf(ev.object), a: a ?? ev.joint, b: b ?? '', kind: kind ? c.jointKind(kind) : t('joint.generic'), tool: c.toolName(ev.tool as ToolKind), pct }),\n data: { joint: ev.joint, tool: ev.tool, progress: ev.progress },\n },\n 1.5,\n )\n break\n }\n case 'ignite': {\n const g = fireParts.get(ev.object)\n if (g && g.parts.length >= 3) {\n if (g.done) break\n g.done = true\n c.log.add({\n channel: 'event',\n type: 'ignite',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: t('ev.ignite.many', { obj: c.nameOf(ev.object), n: g.parts.length, temp: num(g.temp, 0), parts: list(g.parts) }),\n data: { parts: g.parts, temperature: Math.round(g.temp) },\n })\n break\n }\n c.log.add({ ...base(ev, ev.part), type: 'ignite', text: t('ev.ignite', { where: where(ev.object, ev.part), temp: num(findPart(ev.object, ev.part)?.temperature ?? 0, 0) }) })\n break\n }\n case 'extinguish': {\n const g = outParts.get(ev.object)\n if (g && g.parts.length >= 3) {\n if (g.done) break\n g.done = true\n c.log.add({\n channel: 'event',\n type: 'extinguish',\n objectId: ev.object,\n itemId: c.itemIdOf(ev.object),\n text: t('ev.extinguish.many', { obj: c.nameOf(ev.object), n: g.parts.length, parts: list(g.parts) }),\n data: { parts: g.parts },\n })\n break\n }\n c.log.add({ ...base(ev, ev.part), type: 'extinguish', text: t('ev.extinguish', { where: where(ev.object, ev.part) }) })\n break\n }\n case 'burnout': {\n const k = `${ev.object}|${ev.part}`\n c.log.add({ ...base(ev, ev.part), type: 'burnout', text: t('ev.burnout', { where: where(ev.object, ev.part) }) + lostTail(k), data: lostData(k) })\n break\n }\n case 'melt':\n c.log.coalesce(\n `melt:${ev.object}:${ev.part}`,\n { ...base(ev, ev.part), type: 'melt', text: t('ev.melt', { where: where(ev.object, ev.part), pct: Math.round(ev.melt * 100) }), data: { melt: ev.melt } },\n 2,\n )\n break\n case 'drip':\n c.log.coalesce(`drip:${ev.object}:${ev.part}`, { ...base(ev, ev.part), type: 'drip', text: t('ev.drip', { where: where(ev.object, ev.part) }), data: { point: ev.point } }, 2)\n break\n case 'explode':\n c.log.add({\n ...base(ev, ev.part),\n type: 'explode',\n text: t('ev.explode', { where: where(ev.object, ev.part), energy: num(ev.energy, 0), radius: num(ev.radius, 1) }),\n data: { energy: ev.energy, radius: ev.radius, point: ev.point },\n })\n break\n case 'destroyed':\n c.log.add({ channel: 'event', type: 'destroyed', objectId: ev.object, itemId: c.itemIdOf(ev.object), text: t('ev.destroyed', { obj: c.nameOf(ev.object) }) })\n break\n default: {\n // structural events (`stress`, `collapse`) come from newer versions of the core\n const x = ev as unknown as Record<string, unknown> & { type: string; object: string; time: number }\n if (x.type === 'stress') {\n const part = String(x.part ?? '')\n stressAt.set(`${x.object}|${part}`, now)\n c.log.coalesce(\n `stress:${x.object}:${part}`,\n {\n ...base(ev, part),\n type: 'stress',\n text: t('ev.stress', { where: where(x.object, part), stress: num(Number(x.stress ?? 0) * 100, 0), load: num(Number(x.load ?? 0), 0) }),\n data: { stress: x.stress, load: x.load },\n },\n 1,\n )\n } else if (x.type === 'collapse') {\n const parts = Array.isArray(x.parts) ? (x.parts as unknown[]).map(String) : []\n c.log.add({\n channel: 'event',\n type: 'collapse',\n objectId: x.object,\n itemId: c.itemIdOf(x.object),\n text: t('ev.collapse', { obj: c.nameOf(x.object), pieces: pieces(parts.length), mass: num(Number(x.mass ?? 0), 0), parts: list(parts) }),\n data: { parts: parts.length, partIds: parts, massKg: x.mass, cause: x.cause },\n })\n }\n }\n }\n }\n // damage that no dent, hole, crack or fracture explained (blunt thuds, blast, absorbed bullets, a structure carrying too much)\n for (const [k, d] of damage) {\n if (SKIP_DAMAGE.has(d.type) || d.amount < 0.5) continue\n const [obj, part] = k.split('|')\n const overload = d.type === 'blunt' && now - (stressAt.get(k) ?? -99) <= 3\n const entry = {\n channel: 'event' as const,\n type: 'damage',\n objectId: obj,\n itemId: c.itemIdOf(obj),\n part,\n material: findPart(obj, part)?.material ?? materialMemo.get(k),\n state: stateOf(obj, part),\n }\n if (!overload) {\n c.log.add({ ...entry, text: t('ev.damage', { where: where(obj, part), type: t(`dmg.${d.type}`), amount: num(d.amount, 0), hp: hpText(obj, part) }), data: { amount: d.amount, damageType: d.type } })\n continue\n }\n // a structure carrying too much loses hit points every tick: one line with the running total\n const acc = damageAcc.get(k)\n const total = acc && now - acc.last <= 1 ? acc.total + d.amount : d.amount\n damageAcc.set(k, { total, last: now })\n c.log.coalesce(\n `damage:${k}`,\n { ...entry, text: t('ev.damage.overload', { where: where(obj, part), amount: num(total, 0), hp: hpText(obj, part) }), data: { amount: total, damageType: d.type, overload: true } },\n 1,\n )\n }\n }\n\n const kindMemo = new Map<string, string>()\n const kindOf = (objectId: string, jointId: string): string => {\n const key = `${objectId}|${jointId}`\n const own = c.world.state(objectId)?.joints.find((j) => j.id === jointId)?.kind\n if (own) {\n kindMemo.set(key, own)\n return own\n }\n const known = kindMemo.get(key)\n if (known) return known\n for (const id of c.world.ids()) {\n const k = c.world.state(id)?.joints.find((j) => j.id === jointId)?.kind\n if (k) return k\n }\n return ''\n }\n\n const stainInfo = new Map<string, { liquid: string; surface: string; x: number; z: number }>()\n const stainAcc = new Map<string, { n: number; last: number }>()\n const driedAcc = new Map<string, { n: number; last: number }>()\n const drinkAcc = new Map<string, { liters: number; thirst: number; burn: boolean; effects: Set<string>; last: number; start: number }>()\n const fluid = (ev: FluidEvent): void => {\n const who = (id: string): string => c.containerName(id)?.name ?? id\n const meta = (id: string): { objectId?: string; itemId?: string } => {\n const m = c.containerName(id)\n return { objectId: m?.objectId, itemId: m?.itemId }\n }\n const f = 'fluid.'\n switch (ev.type) {\n case 'fill':\n c.log.coalesce(`fill:${ev.container}`, { channel: 'event', type: f + 'fill', ...meta(ev.container), text: t('fl.fill', { who: who(ev.container), liquid: c.liquidName(ev.liquid), liters: num(ev.liters, 2) }), data: { liters: ev.liters } }, 1.5)\n break\n case 'pour':\n c.log.coalesce(`pour:${ev.container}`, { channel: 'event', type: f + 'pour', ...meta(ev.container), text: t('fl.pour', { who: who(ev.container), liquid: c.liquidName(ev.liquid), rate: num(ev.rate, 2) }), data: { rate: ev.rate } }, 2)\n break\n case 'spill':\n c.log.coalesce(`spill:${ev.container}`, { channel: 'event', type: f + 'spill', ...meta(ev.container), text: t('fl.spill', { who: who(ev.container), liquid: c.liquidName(ev.liquid), rate: num(ev.rate, 2) }), data: { rate: ev.rate } }, 2)\n break\n case 'leak': {\n // the hole line of the destruction event already says the object is leaking\n const owner = meta(ev.container).objectId\n if (owner && c.now() - (leakAt.get(owner) ?? -99) <= 2) break\n c.log.coalesce(`fleak:${ev.container}`, { channel: 'event', type: f + 'leak', ...meta(ev.container), text: t('fl.leak', { who: who(ev.container), liquid: c.liquidName(ev.liquid), rate: num(ev.rate, ev.rate < 0.01 ? 3 : 2) }), data: { rate: ev.rate, point: ev.point } }, 2)\n break\n }\n case 'drink': {\n // a sip arrives as many small drink events: one line per sip, updated while it goes on\n const now = c.now()\n let acc = drinkAcc.get(ev.container)\n if (!acc || now - acc.last > 0.5) acc = { liters: 0, thirst: 0, burn: false, effects: new Set<string>(), last: now, start: now }\n acc.liters += ev.liters\n acc.thirst += ev.thirst\n acc.burn = acc.burn || ev.burn\n for (const e of ev.effects) acc.effects.add(e)\n acc.last = now\n drinkAcc.set(ev.container, acc)\n const effects = [...acc.effects].map((e) => t(`effect.${e}`)).join(', ')\n c.log.coalesce(\n `drink:${ev.container}:${acc.start}`,\n {\n channel: 'event',\n type: f + 'drink',\n ...meta(ev.container),\n text:\n t('fl.drink', { who: who(ev.container), liters: num(acc.liters, 2), thirst: num(acc.thirst, 0) }) +\n (effects ? `, ${effects}` : '') +\n (acc.burn ? `, ${t('fl.burn')}` : ''),\n data: { liters: acc.liters, temperature: ev.temperature, thirst: acc.thirst, effects: [...acc.effects], burn: acc.burn },\n },\n 0.5,\n )\n break\n }\n case 'empty':\n c.log.add({ channel: 'event', type: f + 'empty', ...meta(ev.container), text: t('fl.empty', { who: who(ev.container) }) })\n break\n case 'splash':\n c.log.coalesce(`splash:${ev.liquid}`, { channel: 'event', type: f + 'splash', text: t('fl.splash', { liquid: c.liquidName(ev.liquid) }), data: { point: ev.point, intensity: ev.intensity } }, 1)\n break\n case 'stain': {\n const surface = t(`surface.${ev.surface}`)\n const liquid = c.liquidName(ev.liquid)\n stainInfo.set(ev.stain, { liquid: ev.liquid, surface, x: ev.point[0], z: ev.point[2] })\n // a leak or a spill makes several stains in a row: one line that counts them\n const key = `stain:${ev.liquid}:${ev.surface}`\n const acc = stainAcc.get(key)\n const n = acc && c.now() - acc.last <= 1 ? acc.n + 1 : 1\n stainAcc.set(key, { n, last: c.now() })\n c.log.coalesce(\n key,\n {\n channel: 'event',\n type: f + 'stain',\n text: n > 1 ? t('fl.stains', { n, liquid, surface, where: xz(ev.point[0], ev.point[2]) }) : t('fl.stain', { liquid, surface, where: xz(ev.point[0], ev.point[2]) }),\n data: { stain: ev.stain, surface: ev.surface, liquid: ev.liquid, point: ev.point, count: n },\n },\n 1,\n )\n break\n }\n case 'dried': {\n const info = stainInfo.get(ev.stain)\n const key = `dried:${info?.liquid ?? '?'}:${ev.mark}`\n const acc = driedAcc.get(key)\n const n = acc && c.now() - acc.last <= 1.5 ? acc.n + 1 : 1\n driedAcc.set(key, { n, last: c.now() })\n const vars = { liquid: info ? c.liquidName(info.liquid) : '', surface: info?.surface ?? '', where: info ? xz(info.x, info.z) : '', n }\n const text = !info\n ? t(ev.mark ? 'fl.dried.mark' : 'fl.dried')\n : n > 1\n ? t(ev.mark ? 'fl.dried.many.mark' : 'fl.dried.many', vars)\n : t(ev.mark ? 'fl.dried.known.mark' : 'fl.dried.known', vars)\n c.log.coalesce(key, { channel: 'event', type: f + 'dried', text, data: { stain: ev.stain, mark: ev.mark, count: n } }, 1.5)\n break\n }\n case 'mix':\n c.log.add({ channel: 'event', type: f + 'mix', ...meta(ev.container), text: t('fl.mix', { who: who(ev.container), from: c.liquidName(ev.from), into: c.liquidName(ev.into) }) })\n break\n default:\n break\n }\n }\n\n return { events, fluid }\n}\n","import type * as THREE_NS from 'three'\nimport type { Vec3 } from '@adatechnology/game-destruction'\n\nexport interface PlayerHooks {\n /** Primary button pressed / released (use the tool). `click` is a press without a drag, for the no-pointer-lock fallback. */\n primaryDown(): void\n primaryUp(): void\n secondary(): void\n key(code: string, down: boolean, event: KeyboardEvent): void\n wheel(direction: 1 | -1): void\n}\n\nexport interface PlayerOptions {\n camera: THREE_NS.PerspectiveCamera\n dom: HTMLElement\n /** `[minX, minZ, maxX, maxZ]` boxes to stay out of. */\n colliders: Array<[number, number, number, number]>\n /** Half size of the arena. */\n limit: number\n start: Vec3\n hooks: PlayerHooks\n}\n\nexport interface Player {\n readonly yaw: number\n readonly pitch: number\n readonly locked: boolean\n /** Held keys, by `KeyboardEvent.code`. */\n keys: ReadonlySet<string>\n update(dt: number): void\n setPose(position: Vec3, yaw: number, pitch: number): void\n /** Put the eye at `position` looking at `target`. */\n look(position: Vec3, target: Vec3): void\n /** Camera kick in degrees. */\n kick(pitchDeg: number, yawDeg: number): void\n /** Move the player by a world offset on the floor plane, stopped by the colliders and the arena limit (scripted walks). */\n moveBy(dx: number, dz: number): void\n /** Walk by hand (tests): moves the player `forward` and `right` metres along its facing. */\n walk(forward: number, right: number): void\n dispose(): void\n}\n\nconst EYE = 1.7\nconst RADIUS = 0.3\nconst WALK = 3.4\nconst RUN = 6.2\nconst JUMP = 4.6\nconst GRAVITY = 13\nconst LOOK = 0.0022\n\n/**\n * First-person controller: WASD, Shift, Space, mouse look with pointer lock, and a drag-to-look fallback for pages where the lock is not\n * available (iframes, headless browsers, touch). In the fallback a press that does not move is a click (tool use), a drag looks around.\n */\nexport function createPlayer(THREE: typeof THREE_NS, o: PlayerOptions): Player {\n const cam = o.camera\n let yaw = 0\n let pitch = 0\n let y = 0\n let eye = EYE\n let vy = 0\n const px = { x: o.start[0], z: o.start[2] }\n let locked = false\n const keys = new Set<string>()\n const euler = new THREE.Euler(0, 0, 0, 'YXZ')\n\n const apply = (): void => {\n euler.set(pitch, yaw, 0, 'YXZ')\n cam.quaternion.setFromEuler(euler)\n cam.position.set(px.x, eye + y, px.z)\n cam.updateMatrixWorld(true)\n }\n apply()\n\n const blocked = (x: number, z: number): boolean => {\n if (Math.abs(x) > o.limit - RADIUS || Math.abs(z) > o.limit - RADIUS) return true\n for (const c of o.colliders) if (x > c[0] - RADIUS && x < c[2] + RADIUS && z > c[1] - RADIUS && z < c[3] + RADIUS) return true\n return false\n }\n const move = (dx: number, dz: number): void => {\n if (!blocked(px.x + dx, px.z)) px.x += dx\n if (!blocked(px.x, px.z + dz)) px.z += dz\n }\n\n let dragging = false\n let moved = 0\n let downAt = 0\n let useStarted = false\n let holdTimer: ReturnType<typeof setTimeout> | null = null\n\n const look = (dx: number, dy: number): void => {\n yaw -= dx * LOOK\n pitch = Math.max(-1.5, Math.min(1.5, pitch - dy * LOOK))\n }\n const onLockChange = (): void => {\n locked = document.pointerLockElement === o.dom\n }\n const onMouseDown = (e: MouseEvent): void => {\n o.dom.focus?.()\n if (e.button === 2) {\n e.preventDefault()\n o.hooks.secondary()\n return\n }\n if (e.button !== 0) return\n if (!locked) {\n try {\n const r = (o.dom.requestPointerLock as unknown as (() => Promise<void> | void) | undefined)?.call(o.dom)\n if (r && typeof (r as Promise<void>).catch === 'function') (r as Promise<void>).catch(() => undefined)\n } catch {\n // no pointer lock here: drag to look\n }\n dragging = true\n moved = 0\n downAt = performance.now()\n useStarted = false\n holdTimer = setTimeout(() => {\n if (dragging && moved < 4 && !useStarted) {\n useStarted = true\n o.hooks.primaryDown()\n }\n }, 220)\n return\n }\n useStarted = true\n o.hooks.primaryDown()\n }\n const onMouseUp = (e: MouseEvent): void => {\n if (e.button !== 0) return\n if (holdTimer) clearTimeout(holdTimer)\n if (dragging) {\n dragging = false\n if (!useStarted && moved < 4 && performance.now() - downAt < 400) {\n o.hooks.primaryDown()\n o.hooks.primaryUp()\n } else if (useStarted) o.hooks.primaryUp()\n useStarted = false\n return\n }\n if (useStarted) o.hooks.primaryUp()\n useStarted = false\n }\n const onMouseMove = (e: MouseEvent): void => {\n if (locked) look(e.movementX, e.movementY)\n else if (dragging) {\n moved += Math.abs(e.movementX) + Math.abs(e.movementY)\n if (moved >= 4) {\n if (useStarted) {\n useStarted = false\n o.hooks.primaryUp()\n }\n look(e.movementX, e.movementY)\n }\n }\n }\n const onWheel = (e: WheelEvent): void => {\n e.preventDefault()\n o.hooks.wheel(e.deltaY > 0 ? 1 : -1)\n }\n const typing = (e: Event): boolean => {\n const t = e.target as HTMLElement | null\n return !!t && (t.tagName === 'INPUT' || t.tagName === 'SELECT' || t.tagName === 'TEXTAREA')\n }\n const onKeyDown = (e: KeyboardEvent): void => {\n if (typing(e)) return\n if (e.code === 'Space' || e.code === 'Tab') e.preventDefault()\n if (!e.repeat) keys.add(e.code)\n o.hooks.key(e.code, true, e)\n }\n const onKeyUp = (e: KeyboardEvent): void => {\n keys.delete(e.code)\n if (typing(e)) return\n o.hooks.key(e.code, false, e)\n }\n const onContext = (e: Event): void => e.preventDefault()\n const onBlur = (): void => keys.clear()\n\n o.dom.addEventListener('mousedown', onMouseDown)\n window.addEventListener('mouseup', onMouseUp)\n window.addEventListener('mousemove', onMouseMove)\n o.dom.addEventListener('wheel', onWheel, { passive: false })\n o.dom.addEventListener('contextmenu', onContext)\n document.addEventListener('pointerlockchange', onLockChange)\n window.addEventListener('keydown', onKeyDown)\n window.addEventListener('keyup', onKeyUp)\n window.addEventListener('blur', onBlur)\n\n return {\n get yaw() {\n return yaw\n },\n get pitch() {\n return pitch\n },\n get locked() {\n return locked\n },\n keys,\n update(dt) {\n const run = keys.has('ShiftLeft') || keys.has('ShiftRight')\n const speed = run ? RUN : WALK\n let f = 0\n let r = 0\n if (keys.has('KeyW') || keys.has('ArrowUp')) f += 1\n if (keys.has('KeyS') || keys.has('ArrowDown')) f -= 1\n if (keys.has('KeyD') || keys.has('ArrowRight')) r += 1\n if (keys.has('KeyA') || keys.has('ArrowLeft')) r -= 1\n if ((f || r || keys.has('Space')) && eye !== EYE) eye = EYE\n if (f || r) {\n const len = Math.hypot(f, r)\n const fx = -Math.sin(yaw)\n const fz = -Math.cos(yaw)\n const rx = Math.cos(yaw)\n const rz = -Math.sin(yaw)\n move(((fx * f + rx * r) / len) * speed * dt, ((fz * f + rz * r) / len) * speed * dt)\n }\n if (y <= 0 && keys.has('Space')) vy = JUMP\n if (y > 0 || vy > 0) {\n vy -= GRAVITY * dt\n y += vy * dt\n if (y <= 0) {\n y = 0\n vy = 0\n }\n }\n apply()\n },\n setPose(position, yw, pt) {\n px.x = position[0]\n px.z = position[2]\n eye = position[1]\n y = 0\n vy = 0\n yaw = yw\n pitch = pt\n apply()\n },\n look(position, target) {\n px.x = position[0]\n px.z = position[2]\n eye = position[1]\n y = 0\n vy = 0\n const dx = target[0] - position[0]\n const dy = target[1] - position[1]\n const dz = target[2] - position[2]\n yaw = Math.atan2(-dx, -dz)\n pitch = Math.atan2(dy, Math.hypot(dx, dz))\n apply()\n },\n kick(pitchDeg, yawDeg) {\n pitch = Math.max(-1.5, Math.min(1.5, pitch + (pitchDeg * Math.PI) / 180))\n yaw += (yawDeg * Math.PI) / 180\n apply()\n },\n moveBy(dx, dz) {\n move(dx, dz)\n apply()\n },\n walk(forward, right) {\n move(-Math.sin(yaw) * forward + Math.cos(yaw) * right, -Math.cos(yaw) * forward - Math.sin(yaw) * right)\n apply()\n },\n dispose() {\n if (holdTimer) clearTimeout(holdTimer)\n o.dom.removeEventListener('mousedown', onMouseDown)\n window.removeEventListener('mouseup', onMouseUp)\n window.removeEventListener('mousemove', onMouseMove)\n o.dom.removeEventListener('wheel', onWheel)\n o.dom.removeEventListener('contextmenu', onContext)\n document.removeEventListener('pointerlockchange', onLockChange)\n window.removeEventListener('keydown', onKeyDown)\n window.removeEventListener('keyup', onKeyUp)\n window.removeEventListener('blur', onBlur)\n if (document.pointerLockElement === o.dom) document.exitPointerLock?.()\n },\n }\n}\n","import { JOINT_DEFAULTS, rotateVec, toWorld } from '@adatechnology/game-destruction'\nimport type { Vec3 } from '@adatechnology/game-destruction'\nimport { resolveStrings } from './locale'\nimport type { ScenarioContext, TestRoom, TestRoomScenario } from './types'\n\ntype T = (key: string, vars?: Record<string, string | number>) => string\ntype Num = (n: number, digits?: number) => string\n\n/** Built-in scripted checks over the generic `DEMO_ITEMS`. Names and check texts come from the room locale. */\nexport function makeScenarios(t: T, num: Num, _locale = 'en'): TestRoomScenario[] {\n const yn = (b: boolean): string => t(b ? 'yes' : 'no')\n const cn = (what: string, n: number): string => t(`count.${what}.${n === 1 ? 'one' : 'other'}`, { n })\n const pc = (n: number): string => t(n === 1 ? 'count.piece.one' : 'count.piece.other', { n })\n const sc = (id: string, run: (c: ScenarioContext) => void | Promise<void>): TestRoomScenario => ({ id, name: t(`sc.${id}`), run })\n\n const at = (room: TestRoom, itemId: string, x: number, z: number, y = 0, rot = 0): string => room.spawn(itemId, [x, y, z], rot).objectId\n const look = (room: TestRoom, from: Vec3, to: Vec3): void => room.look(from, to)\n const part = (room: TestRoom, id: string, p: string) => room.world.part(id, p)\n const count = (room: TestRoom, type: string, objectId?: string): number => room.log.entries({ type, objectId }).length\n const anyBurning = (room: TestRoom, id: string): boolean => (room.world.state(id)?.parts ?? []).some((p) => p.burning)\n const igniteHit = (room: TestRoom, id: string, point: Vec3, temperature = 900, seconds = 3): void => {\n room.world.hit(id, { type: 'fire', point, temperature, radius: 0.6, duration: seconds })\n }\n\n // columns of the demo `building_frame` placed at (0, 0, -6): x = -2 / 2, z = -8 / -4\n const COLUMN: Record<string, Vec3> = { column_0_0_0: [-2, 1.4, -8], column_0_1_0: [2, 1.4, -8], column_0_0_1: [-2, 1.4, -4], column_0_1_1: [2, 1.4, -4] }\n const killColumns = (room: TestRoom, id: string, ids: string[]): void => {\n for (const c of ids) room.world.hitPart(id, c, { type: 'blunt', point: COLUMN[c], energy: 3e6, radius: 0.05, source: 'test' })\n }\n const heavyCollapse = (room: TestRoom): number => room.log.entries({ type: 'collapse' }).reduce((m, e) => Math.max(m, Number(e.data?.massKg ?? 0)), 0)\n\n return [\n sc('steel_through_hole', ({ room, step, expect }) => {\n const id = at(room, 'steel_sheet', 0, -4)\n room.setTool('pistol_9mm')\n look(room, [0, 1.1, -1.5], [0, 1.1, -4])\n room.use()\n step(0.2)\n const p = part(room, id, 'sheet')\n const hole = p?.holes[0]\n expect(\n !!hole?.through,\n t('sc.steel_through_hole.check', { mm: num((hole?.diameter ?? 0) * 1000, 0), through: yn(!!hole?.through), holes: p?.holes.length ?? 0, hp: `${num(p?.hp ?? 0, 0)}/${num(p?.maxHp ?? 0, 0)}` }),\n { holes: p?.holes.length, through: hole?.through },\n )\n }),\n\n sc('concrete_stops_bullet', ({ room, step, expect }) => {\n const id = at(room, 'concrete_block', 0, -4)\n room.setTool('pistol_9mm')\n look(room, [0, 0.5, -1.5], [0, 0.2, -3.8])\n room.use()\n step(0.2)\n const p = part(room, id, 'block')\n const wall = part(room, 'target_wall', 'brick_1_4')\n const through = p?.holes.some((h) => h.through) ?? true\n expect(\n !through && (p?.holes.length ?? 0) + (p?.dents.length ?? 0) + (p?.cracks.length ?? 0) > 0 && (wall?.holes.length ?? 0) === 0,\n t('sc.concrete_stops_bullet.check', { through: yn(through), dents: cn('dent', p?.dents.length ?? 0), holes: cn('hole', p?.holes.length ?? 0), cracks: cn('crack', p?.cracks.length ?? 0), hp: `${num(p?.hp ?? 0, 0)}/${num(p?.maxHp ?? 0, 0)}` }),\n { through },\n )\n }),\n\n sc('hammer_dents_drum', ({ room, step, expect }) => {\n const id = at(room, 'steel_drum', 0, -4)\n room.setTool('hammer')\n look(room, [0, 0.6, -3.35], [0, 0.5, -4])\n let swings = 0\n for (; swings < 8 && (part(room, id, 'drum_body')?.dents.length ?? 0) === 0; swings++) {\n room.use()\n step(1)\n }\n const p = part(room, id, 'drum_body')\n expect(\n (p?.dents.length ?? 0) > 0 && p?.status !== 'broken',\n t('sc.hammer_dents_drum.check', { swings, dents: p?.dents.length ?? 0, depth: num((p?.dents[0]?.depth ?? 0) * 1000, 1), hp: `${num(p?.hp ?? 0, 0)}/${num(p?.maxHp ?? 0, 0)}` }),\n { swings },\n )\n }),\n\n sc('glass_shatters', ({ room, step, expect }) => {\n const id = at(room, 'glass_pane', 0, -4)\n room.setTool('pistol_9mm')\n look(room, [0, 1.3, -1.5], [0, 1.05, -4])\n let shots = 0\n for (; shots < 10 && part(room, id, 'pane')?.status !== 'broken'; shots++) {\n room.use()\n step(0.25)\n }\n step(0.5)\n const fr = room.log.entries({ type: 'fracture', objectId: id }).find((e) => e.part === 'pane')\n const n = Number(fr?.data?.fragments ?? 0)\n expect(part(room, id, 'pane')?.status === 'broken' && shots === 1 && n >= 4, t('sc.glass_shatters.check', { shots, n }), { shots, fragments: n })\n }),\n\n sc('shotgun_splinters_crate', ({ room, step, expect }) => {\n const id = at(room, 'wooden_crate', 0, -4)\n room.setTool('shotgun_pump_12')\n look(room, [0, 0.6, -1.8], [0, 0.25, -3.77])\n let shots = 0\n const splinters = (): number => room.log.entries({ type: 'fracture', objectId: id }).filter((e) => e.data?.style === 'splinter').length\n for (; shots < 4 && splinters() === 0; shots++) {\n room.use()\n step(1.1)\n }\n const holes = (room.world.state(id)?.parts ?? []).reduce((n, p) => n + p.holes.length, 0)\n expect(splinters() > 0, t('sc.shotgun_splinters_crate.check', { shots, splinters: splinters(), holes }), { shots })\n }),\n\n sc('kick_chair_leg', ({ room, step, expect }) => {\n const id = at(room, 'chair', 0, -4)\n const before = room.renderer.pieces().length\n const leg = part(room, id, 'leg_1')\n void leg\n let kicks = 0\n for (; kicks < 6 && room.renderer.pieces().length <= before && part(room, id, 'leg_1'); kicks++) {\n room.world.hitPart(id, 'leg_1', { type: 'blunt', point: [-0.18, 0.2, -4.18], direction: [1, 0, 0], energy: 220, radius: 0.05, source: 'kick' })\n step(0.3)\n }\n step(0.5)\n const after = room.renderer.pieces().length\n const groups = room.world.state(id)?.groups.length ?? 1\n expect(\n after > before,\n t('sc.kick_chair_leg.check', { kicks, groups, before, after, leg: part(room, id, 'leg_1') ? t('leg.still') : t('leg.gone') }),\n { kicks, before, after },\n )\n }),\n\n sc('kick_detaches_leg_via_tool', ({ room, step, expect }) => {\n const id = at(room, 'chair', 0, -4)\n const before = room.renderer.pieces().length\n room.setTool('kick')\n let kicks = 0\n for (; kicks < 8 && room.renderer.pieces().length <= before && part(room, id, 'leg_1'); kicks++) {\n // the chair moves when it is kicked: aim at the leg where it is now, from the side\n const st = room.world.state(id)!\n const leg = toWorld(st.position, st.rotation, [-0.18, 0.2, -0.18])\n const side = rotateVec(st.rotation, [-0.8, 0, 0])\n look(room, [leg[0] + side[0], leg[1] + side[1], leg[2] + side[2]], leg)\n room.use()\n step(1.05)\n }\n step(0.5)\n const after = room.renderer.pieces().length\n expect(after > before, t('sc.kick_detaches_leg_via_tool.check', { kicks, before, after, leg: part(room, id, 'leg_1') ? t('leg.still') : t('leg.gone') }), { kicks, before, after })\n }),\n\n sc('screwdriver_shelf_board', ({ room, step, expect }) => {\n const id = at(room, 'shelf', 0, -4)\n room.setTool('screwdriver')\n look(room, [0, 0.8, -3.5], [0, 0.75, -3.86])\n const t0 = room.log.entries().length ? room.log.entries().slice(-1)[0].t : 0\n room.use(5)\n const done = room.log.entries({ type: 'detach', objectId: id })[0]\n const elapsed = done ? done.t - t0 : 5\n const want = JOINT_DEFAULTS.screw.seconds\n const groups = room.renderer.pieces().length\n expect(!!done && Math.abs(elapsed - want) < 0.6 && groups >= 1, t('sc.screwdriver_shelf_board.check', { secs: num(elapsed, 1), want: num(want, 1), pieces: pc(groups) }), { elapsed, want })\n step(0.2)\n }),\n\n sc('wrong_tool_refused', ({ room, expect }) => {\n const id = at(room, 'steel_sheet', 0, -4)\n room.setTool('screwdriver')\n look(room, [0.2, 1.05, -3.6], [0.34, 1.0, -4])\n room.use(0.5)\n const refused = count(room, 'tool_refused')\n const opened = (room.world.state(id)?.joints ?? []).filter((j) => j.open).length\n expect(refused > 0 && opened === 0, t('sc.wrong_tool_refused.check', { refused, opened }), { refused, opened })\n }),\n\n sc('lighter_burns_crate', ({ room, step, expect }) => {\n const id = at(room, 'wooden_crate', 0, -4)\n room.setTool('lighter')\n look(room, [0, 0.3, -3.65], [0, 0.25, -3.76])\n room.use(5)\n const lit = anyBurning(room, id)\n expect(lit, t('sc.lighter_burns_crate.lit', { lit: yn(lit) }))\n step(500)\n const parts = room.world.state(id)?.parts ?? []\n const ash = parts.filter((p) => p.status === 'ashes').length\n const charred = Math.max(...parts.map((p) => p.char))\n expect(ash === parts.length || (ash > 0 && parts.every((p) => p.status === 'ashes' || p.status === 'broken' || p.char > 0.8)), t('sc.lighter_burns_crate.ash', { ash, total: parts.length, char: num(charred * 100, 0) }), { ash, total: parts.length })\n }),\n\n sc('torch_melts_steel', ({ room, step, expect }) => {\n const drum = at(room, 'steel_drum', 0, -4)\n const crate = at(room, 'wooden_crate', 0.7, -4)\n igniteHit(room, crate, [0.7, 0.25, -3.8], 900, 2)\n let peak = 0\n for (let i = 0; i < 40; i++) {\n step(1)\n peak = Math.max(peak, part(room, drum, 'drum_body')?.temperature ?? 0)\n }\n const melt0 = part(room, drum, 'drum_body')?.melt ?? 0\n expect(melt0 === 0 && peak < 1450, t('sc.torch_melts_steel.wood', { peak: num(peak, 0), melt: num(melt0 * 100, 0), crate: yn(anyBurning(room, crate)) }), { peak })\n room.setTool('cutting_torch')\n look(room, [-0.15, 0.55, -3.55], [-0.15, 0.5, -3.72])\n room.use(20)\n const p = part(room, drum, 'drum_body')\n expect((p?.melt ?? 0) > 0.02 || p?.status === 'melted' || (p?.holes.length ?? 0) > 0, t('sc.torch_melts_steel.torch', { temp: num(p?.temperature ?? 0, 0), melt: num((p?.melt ?? 0) * 100, 0) }), { temperature: p?.temperature, melt: p?.melt })\n }),\n\n sc('bucket_melts_drips', ({ room, step, expect }) => {\n const id = at(room, 'plastic_bucket', 0, -4)\n room.setTool('flamethrower')\n look(room, [0, 0.5, -2.4], [0, 0.15, -4])\n room.use(2.5)\n step(10)\n const p = part(room, id, 'bucket_body')\n const drips = count(room, 'drip', id)\n expect((p?.melt ?? 0) > 0.05 || p?.status === 'melted', t('sc.bucket_melts_drips.check', { melt: num((p?.melt ?? 0) * 100, 0), drips, temp: num(p?.temperature ?? 0, 0) }), { melt: p?.melt, drips })\n }),\n\n sc('gas_bottle_explodes', ({ room, step, expect }) => {\n const bottle = at(room, 'gas_bottle', 0, -4)\n const crate = at(room, 'wooden_crate', 1.3, -4)\n const c0 = room.spawned().find((s) => s.objectId === crate)?.root.position.clone()\n let seconds = 0\n for (; seconds < 60 && count(room, 'explode', bottle) === 0; seconds++) {\n igniteHit(room, bottle, [0, 0.4, -3.9], 1000, 1)\n step(1)\n }\n step(1.5)\n const c1 = room.spawned().find((s) => s.objectId === crate)?.root.position\n const moved = c0 && c1 ? c0.distanceTo(c1) : 0\n const state = room.world.state(crate)\n const lost = (state?.parts ?? []).filter((p) => p.status === 'broken').length + (state && state.groups.length > 1 ? 1 : 0)\n expect(count(room, 'explode', bottle) > 0, t('sc.gas_bottle_explodes.explode', { seconds }), { seconds })\n expect(moved > 0.3 || lost > 0, t('sc.gas_bottle_explodes.push', { moved: num(moved, 1), lost: pc(lost) }), { moved, lost })\n }),\n\n sc('bottle_drop_shatters', ({ room, step, expect }) => {\n const id = at(room, 'glass_bottle', 0, -3, 1.5)\n step(2)\n const p = part(room, id, 'bottle_body')\n const stain = room.fluids.stains().find((s) => s.liquid === 'water')\n expect(p?.status === 'broken', t('sc.bottle_drop_shatters.check', { status: p?.status ?? '?', cracks: p?.cracks.length ?? 0, stain: yn(!!stain) }), { status: p?.status })\n }),\n\n sc('throw_chair_at_wall', ({ room, step, expect }) => {\n const id = at(room, 'chair', 0, -5.2)\n look(room, [0, 1.7, -4.2], [0, 0.35, -5.2])\n room.grab()\n look(room, [0, 1.7, -4.2], [0, 2.3, -11])\n step(0.3)\n room.throwHeld(16)\n step(2.5)\n const hits = room.log.entries({ type: 'impact' })\n const wallDamage = room.log.entries().filter((e) => e.objectId === 'target_wall' && (e.type === 'dent' || e.type === 'damage' || e.type === 'crack' || e.type === 'fracture')).length\n expect(hits.length > 0 && wallDamage > 0, t('sc.throw_chair_at_wall.check', { impacts: hits.length, wall: wallDamage, energy: num(Number(hits[0]?.data?.energyJ ?? 0), 0) }), { id })\n }),\n\n sc('coffee_three_sips', ({ room, step, expect }) => {\n const id = at(room, 'coffee_cup', 0, -3)\n look(room, [0, 1.0, -1.8], [0, 0.05, -3])\n const cid = `${id}_fluid`\n const before = room.fluids.container(cid)?.liters ?? 0\n room.grab()\n for (let i = 0; i < 3; i++) {\n room.useItem('sip')\n step(1.4)\n }\n const after = room.fluids.container(cid)?.liters ?? 0\n const drinks = room.log.entries().filter((e) => e.type === 'fluid.drink')\n const caffeine = drinks.some((e) => Array.isArray(e.data?.effects) && (e.data?.effects as string[]).includes('caffeine'))\n expect(drinks.length === 3 && before - after > 0.06 && caffeine, t('sc.coffee_three_sips.check', { sips: drinks.length, before: num(before, 2), after: num(after, 2), caffeine: yn(caffeine), burn: yn(drinks.some((e) => !!e.data?.burn)) }), { before, after })\n }),\n\n sc('tilt_cup_spills', ({ room, step, expect }) => {\n const id = at(room, 'coffee_cup', 0, -3)\n look(room, [0, 1.0, -1.8], [0, 0.05, -3])\n const cid = `${id}_fluid`\n const before = room.fluids.container(cid)?.liters ?? 0\n room.grab()\n step(0.6)\n room.tilt(2.0)\n step(2.5)\n const after = room.fluids.container(cid)?.liters ?? 0\n const stains = room.fluids.stains().filter((s) => s.liquid === 'coffee').length\n expect(before - after > 0.03 && stains > 0, t('sc.tilt_cup_spills.check', { before: num(before, 2), after: num(after, 2), stains }), { before, after })\n }),\n\n sc('jerrycan_leaks_fuel', ({ room, step, expect }) => {\n const id = at(room, 'jerrycan', 0, -3.5)\n room.setTool('pistol_9mm')\n look(room, [0, 0.4, -1.5], [0, 0.12, -3.43])\n room.use()\n step(1.5)\n const streams = room.fluids.streams().filter((s) => s.cause === 'leak' && s.liquid === 'fuel')\n step(5)\n const stain = room.fluids.stains().find((s) => s.liquid === 'fuel')\n const left = room.fluids.container(`${id}_fluid`)?.liters ?? 20\n const hole = room.log.entries({ type: 'hole', objectId: id })[0]\n expect(streams.length > 0 && !!stain && left < 20, t('sc.jerrycan_leaks_fuel.check', { streams: streams.length, stain: yn(!!stain), left: num(left, 2), leak: hole?.data?.leak ? yn(true) : yn(false) }), { left })\n }),\n\n sc('fuel_stain_burns', ({ room, step, expect }) => {\n const id = at(room, 'jerrycan', 0, -3.5)\n const crate = at(room, 'wooden_crate', 0.9, -3.2)\n room.setTool('pistol_9mm')\n look(room, [0, 0.4, -1.5], [0, 0.12, -3.43])\n room.use()\n step(6)\n const stain = room.fluids.stains().find((s) => s.liquid === 'fuel')\n expect(!!stain, t('sc.fuel_stain_burns.stain', { stain: yn(!!stain) }))\n if (!stain) return\n room.setTool('lighter')\n look(room, [stain.center[0], 0.1, stain.center[2] + 0.06], [stain.center[0], 0, stain.center[2]])\n room.use(1)\n step(4)\n const ignited = count(room, 'stain_ignite')\n const fireHits = (room.world.state(id)?.parts ?? []).some((p) => p.burning || p.temperature > 100) || anyBurning(room, crate)\n expect(ignited > 0, t('sc.fuel_stain_burns.ignite', { ignited, near: yn(fireHits) }), { ignited })\n step(30)\n expect(count(room, 'stain_burned') > 0 || room.fluids.stains().filter((s) => s.liquid === 'fuel' && s.wetness > 0.05).length === 0, t('sc.fuel_stain_burns.out', { burned: count(room, 'stain_burned') }))\n }),\n\n sc('one_column_roof_stands', ({ room, step, expect }) => {\n const id = at(room, 'building_frame', 0, -6)\n killColumns(room, id, ['column_0_0_0'])\n step(40)\n const roof = part(room, id, 'roof')\n const neighbour = (part(room, id, 'column_0_0_1') as unknown as { stress?: number } | null)?.stress ?? 0\n const heavy = Math.max(heavyCollapse(room), ...room.renderer.pieces().map((p) => p.mass))\n expect(!!roof && roof.status !== 'broken' && heavy < 2000, t('sc.one_column_roof_stands.check', { roof: roof ? t('roof.standing') : t('roof.fell'), heavy: num(heavy, 0), stress: num(neighbour * 100, 0) }), { heavy, neighbour })\n }),\n\n sc('two_columns_roof_collapses', ({ room, step, expect }) => {\n const id = at(room, 'building_frame', 0, -6)\n killColumns(room, id, ['column_0_0_0', 'column_0_1_0'])\n const stress0 = (room.world.part(id, 'column_0_0_1') as unknown as { stress?: number } | null)?.stress ?? 0\n step(40)\n const pieces = room.renderer.pieces().filter((p) => p.mass >= 2000)\n const logged = heavyCollapse(room) >= 2000\n const kg = pieces.reduce((m, p) => m + p.mass, 0)\n expect(!part(room, id, 'roof') && pieces.length > 0, t('sc.two_columns_roof_collapses.check', { stress: num(stress0 * 100, 0), pieces: pc(pieces.length), kg: num(kg, 0), logged: yn(logged) }), { kg, logged })\n }),\n\n sc('extinguisher_puts_out_fire', ({ room, step, expect }) => {\n const id = at(room, 'wooden_crate', 0, -4)\n igniteHit(room, id, [0, 0.25, -3.8], 900, 4)\n step(6)\n const before = anyBurning(room, id)\n expect(before, t('sc.extinguisher_puts_out_fire.burning', { burning: yn(before) }))\n room.setTool('extinguisher')\n look(room, [0, 0.9, -2.2], [0, 0.25, -4])\n room.use(2.5)\n step(1)\n const after = anyBurning(room, id)\n expect(!after, t('sc.extinguisher_puts_out_fire.out', { burning: yn(after), events: count(room, 'extinguish', id) }), { events: count(room, 'extinguish', id) })\n }),\n ]\n}\n\nconst makeT =\n (locale: string): T =>\n (key, vars) => {\n let s = resolveStrings(locale).text[key] ?? key\n if (vars) for (const k of Object.keys(vars)) s = s.split(`{${k}}`).join(String(vars[k]))\n return s\n }\n\n/** The built-in scenarios for a locale (`en` or `pt-BR`), standalone: no room needed to list them. */\nexport function scenariosFor(locale = 'en'): TestRoomScenario[] {\n const pt = locale.toLowerCase().startsWith('pt')\n return makeScenarios(makeT(locale), (n, d = 1) => (pt ? (Math.round(n * 10 ** d) / 10 ** d).toFixed(d).replace('.', ',') : (Math.round(n * 10 ** d) / 10 ** d).toFixed(d)), locale)\n}\n\n/** The built-in scenarios in English. The room offers them in its own locale. */\nexport const SCENARIOS: TestRoomScenario[] = scenariosFor('en')\n","import type { ControlValue } from '@adatechnology/game-contracts'\nimport type { BenchControl, BenchLayer } from './types'\n\n/** What the bench panel shows: the active module's bench, or only the room counters. */\nexport interface BenchView {\n readonly title: string\n readonly controls: readonly BenchControl[]\n readonly layers: readonly BenchLayer[]\n}\n\nexport interface MetricRow {\n readonly id: string\n readonly name: string\n readonly text: string\n /** Value over the budget, when the metric has one. */\n readonly ratio?: number\n}\n\nexport interface BenchPanelOptions {\n t: (key: string, vars?: Record<string, string | number>) => string\n num: (n: number, digits?: number) => string\n onControl: (id: string, value: ControlValue) => void\n onLayer: (id: string, on: boolean) => void\n onAction: (id: string) => void\n}\n\nexport interface BenchPanel {\n readonly element: HTMLElement\n show(view: BenchView | null): void\n metrics(rows: { room: readonly MetricRow[]; module: readonly MetricRow[] }): void\n readonly visible: boolean\n}\n\nconst SEGMENTED_MAX = 4\n\nconst mk = <K extends keyof HTMLElementTagNameMap>(tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] => {\n const e = document.createElement(tag)\n if (cls) e.className = cls\n if (text !== undefined) e.textContent = text\n return e\n}\n\n// the shape of the panel without the values: when it is unchanged the values are updated in place (a range being dragged keeps its focus)\nconst shapeOf = (view: BenchView): string =>\n JSON.stringify([view.title, view.controls.map((c) => ({ ...c, value: undefined })), view.layers.map((l) => [l.id, l.name])])\n\nexport function createBenchPanel(o: BenchPanelOptions): BenchPanel {\n const { t } = o\n const element = mk('div', 'tr-panel tr-bench')\n element.style.display = 'none'\n element.addEventListener('keydown', (e) => e.stopPropagation())\n const roomLine = mk('div', 'sub tr-bench-room')\n const body = mk('div')\n const metricTitle = mk('div', 'sub', t('ui.metrics'))\n metricTitle.style.display = 'none'\n const metricList = mk('dl', 'tr-metrics')\n element.append(mk('h3', undefined, t('ui.bench')), roomLine, body, metricTitle, metricList)\n\n let shape = ''\n let hasRoom = false\n let hasBench = false\n const refreshers: Array<(view: BenchView) => void> = []\n const metricNodes = new Map<string, { text: HTMLElement; bar: HTMLElement | null }>()\n let metricKey = ''\n\n const syncDisplay = (): void => {\n element.style.display = hasRoom || hasBench ? '' : 'none'\n }\n\n const numberControl = (control: Extract<BenchControl, { kind: 'number' }>): HTMLElement => {\n const wrap = mk('label', 'tr-ctl')\n const input = mk('input')\n input.type = 'range'\n input.min = String(control.min)\n input.max = String(control.max)\n input.step = control.step ? String(control.step) : 'any'\n input.disabled = control.disabled\n const reading = mk('output')\n input.oninput = () => o.onControl(control.id, Number(input.value))\n wrap.append(mk('span', undefined, control.name), input, reading)\n refreshers.push((view) => {\n const value = view.controls.find((c) => c.id === control.id)?.value\n if (typeof value !== 'number') return\n if (Number(input.value) !== value) input.value = String(value)\n reading.textContent = `${o.num(value, control.step && control.step >= 1 ? 0 : 2)}${control.unit ? ` ${control.unit}` : ''}`\n })\n return wrap\n }\n\n const booleanControl = (control: BenchControl): HTMLElement => {\n const wrap = mk('label', 'tr-ctl')\n const box = mk('input')\n box.type = 'checkbox'\n box.disabled = control.disabled\n box.onchange = () => o.onControl(control.id, box.checked)\n wrap.append(box, document.createTextNode(` ${control.name}`))\n refreshers.push((view) => {\n box.checked = view.controls.find((c) => c.id === control.id)?.value === true\n })\n return wrap\n }\n\n const choiceControl = (control: Extract<BenchControl, { kind: 'choice' }>): HTMLElement => {\n const wrap = mk('div', 'tr-ctl')\n wrap.appendChild(mk('span', undefined, control.name))\n if (control.options.length <= SEGMENTED_MAX) {\n const group = mk('div', 'tr-seg')\n group.setAttribute('role', 'group')\n const buttons = control.options.map((option) => {\n const b = mk('button', 'tr-btn', option.name)\n b.type = 'button'\n b.disabled = control.disabled\n b.onclick = () => o.onControl(control.id, option.id)\n group.appendChild(b)\n return { b, id: option.id }\n })\n wrap.appendChild(group)\n refreshers.push((view) => {\n const value = view.controls.find((c) => c.id === control.id)?.value\n for (const { b, id } of buttons) {\n b.setAttribute('aria-pressed', String(id === value))\n b.classList.toggle('on', id === value)\n }\n })\n return wrap\n }\n const select = mk('select')\n select.disabled = control.disabled\n for (const option of control.options) {\n const op = mk('option', undefined, option.name)\n op.value = option.id\n select.appendChild(op)\n }\n select.onchange = () => o.onControl(control.id, select.value)\n wrap.appendChild(select)\n refreshers.push((view) => {\n const value = view.controls.find((c) => c.id === control.id)?.value\n if (typeof value === 'string') select.value = value\n })\n return wrap\n }\n\n const actionControl = (control: BenchControl): HTMLElement => {\n const b = mk('button', 'tr-btn', control.name)\n b.type = 'button'\n b.disabled = control.disabled\n b.onclick = () => o.onAction(control.id)\n return b\n }\n\n const controlElement = (control: BenchControl): HTMLElement => {\n const el = control.kind === 'number' ? numberControl(control) : control.kind === 'boolean' ? booleanControl(control) : control.kind === 'choice' ? choiceControl(control) : actionControl(control)\n if (control.hint) el.title = control.hint\n return el\n }\n\n const layerList = (layers: readonly BenchLayer[]): HTMLElement => {\n const wrap = mk('div', 'tr-layers')\n wrap.appendChild(mk('div', 'sub', t('ui.layers')))\n for (const layer of layers) {\n const label = mk('label', 'tr-ctl')\n const box = mk('input')\n box.type = 'checkbox'\n box.onchange = () => o.onLayer(layer.id, box.checked)\n label.append(box, document.createTextNode(` ${layer.name}`))\n wrap.appendChild(label)\n refreshers.push((view) => {\n box.checked = view.layers.find((l) => l.id === layer.id)?.on === true\n })\n }\n return wrap\n }\n\n const rebuild = (view: BenchView): void => {\n body.textContent = ''\n refreshers.length = 0\n body.appendChild(mk('div', 'sub', view.title))\n const list = mk('div', 'tr-ctls')\n for (const control of view.controls) if (!control.hidden) list.appendChild(controlElement(control))\n body.appendChild(list)\n if (view.layers.length) body.appendChild(layerList(view.layers))\n }\n\n const renderMetrics = (rows: readonly MetricRow[]): void => {\n metricList.textContent = ''\n metricNodes.clear()\n metricTitle.style.display = rows.length ? '' : 'none'\n for (const row of rows) {\n const dd = mk('dd')\n const text = mk('span', undefined, row.text)\n dd.appendChild(text)\n let bar: HTMLElement | null = null\n if (row.ratio !== undefined) {\n bar = mk('div', 'tr-bar')\n bar.appendChild(mk('i'))\n dd.appendChild(bar)\n }\n metricList.append(mk('dt', undefined, row.name), dd)\n metricNodes.set(row.id, { text, bar })\n }\n }\n\n const fillBar = (bar: HTMLElement, ratio: number): void => {\n bar.className = `tr-bar${ratio > 1 ? ' bad' : ratio >= 0.8 ? ' warn' : ''}`\n const fill = bar.firstElementChild as HTMLElement\n fill.style.width = `${Math.round(Math.max(0, Math.min(1, ratio)) * 100)}%`\n }\n\n return {\n element,\n show(view) {\n hasBench = view !== null\n syncDisplay()\n if (!view) {\n shape = ''\n body.textContent = ''\n refreshers.length = 0\n renderMetrics([])\n metricKey = ''\n return\n }\n const next = shapeOf(view)\n if (next !== shape) {\n shape = next\n rebuild(view)\n }\n for (const refresh of refreshers) refresh(view)\n },\n metrics(rows) {\n hasRoom = rows.room.length > 0\n syncDisplay()\n roomLine.textContent = rows.room.map((row) => `${row.name} ${row.text}`).join(' · ')\n const key = rows.module.map((row) => `${row.id}:${row.ratio !== undefined}`).join('|')\n if (key !== metricKey) {\n metricKey = key\n renderMetrics(rows.module)\n }\n for (const row of rows.module) {\n const node = metricNodes.get(row.id)\n if (!node) continue\n node.text.textContent = row.text\n if (node.bar && row.ratio !== undefined) fillBar(node.bar, row.ratio)\n }\n },\n get visible() {\n if (element.style.display === 'none') return false\n const parent = element.parentElement\n return !parent || getComputedStyle(parent).display !== 'none'\n },\n }\n}\n","import type { ControlValue } from '@adatechnology/game-contracts'\nimport { createBenchPanel } from './bench-panel'\nimport type { BenchView, MetricRow } from './bench-panel'\nimport type { WritableLog } from './log'\nimport type { RoomStrings } from './locale'\nimport type { AnimationInfo, LogEntry, ScenarioReport, TestRoomItem, TestRoomScenario } from './types'\n\nexport interface InspectInfo {\n object: string\n objectId: string\n part: string\n material: string\n status: string\n hp: number\n maxHp: number\n temperature: number\n burning: boolean\n char: number\n melt: number\n liters?: number\n dents: number\n holes: number\n cracks: number\n mass: number\n /** Structural load in kg and stress (load / capacity) when the core reports them. */\n load?: number\n stress?: number\n joints: Array<{ id: string; kind: string; tools: string[]; open: boolean; progress: number }>\n note?: string\n distance: number\n}\n\nexport interface HudState {\n toolName: string\n toolId: string\n ammo: string\n slots: string[]\n slot: number\n page: number\n pages: number\n status: string\n progress: { label: string; value: number } | null\n held: { name: string; uses: Array<{ key: string; label: string }>; weapon?: string; using: string } | null\n inspect: InspectInfo | null\n /** Animations of the aimed or held item. */\n animations: AnimationInfo | null\n locked: boolean\n timeScale: number\n fast: boolean\n tap: boolean\n quality: string\n objects: number\n}\n\nexport interface UiOptions {\n container: HTMLElement\n strings: RoomStrings\n t: (key: string, vars?: Record<string, string | number>) => string\n log: WritableLog\n groups: () => Map<string, TestRoomItem[]>\n loadout: () => Array<{ id: string; name: string }>\n onSpawn: (itemId: string) => void\n onEquip: (itemId: string) => void\n onClear: () => void\n onResetAll: () => void\n onSlow: (on: boolean) => void\n onFast: (on: boolean) => void\n onQuality: (q: 'low' | 'medium' | 'high') => void\n quality: 'low' | 'medium' | 'high'\n scenarios: () => TestRoomScenario[]\n onRun: (s: TestRoomScenario) => Promise<ScenarioReport | void>\n onRunAll: () => Promise<ScenarioReport | void>\n onTool: (index: number) => void\n onTap: () => void\n onPlay: (objectId: string, clipId: string) => void\n onResize: () => void\n onControl: (id: string, value: ControlValue) => void\n onLayer: (id: string, on: boolean) => void\n onAction: (id: string) => void\n}\n\nexport interface RoomUi {\n hud(state: HudState): void\n toast(text: string): void\n /** Re-read the catalogue and the scenarios (after `loadModule`). */\n refresh(): void\n /** Open the catalogue on a group tab (its translated name), clearing the search. */\n showGroup(group: string): void\n togglePanels(): void\n /** The active module's bench (null: none). */\n bench(view: BenchView | null): void\n /** Room counters and the active module's metrics, text only. */\n metrics(rows: { room: readonly MetricRow[]; module: readonly MetricRow[] }): void\n /** The bench panel has something to show and is on screen (the room samples its counters only then). */\n readonly benchVisible: boolean\n dispose(): void\n}\n\nconst CSS = `\n.tr-root{position:absolute;inset:0;pointer-events:none;font:12px/1.35 system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;color:#e8eaee;overflow:hidden}\n.tr-root *{box-sizing:border-box}\n.tr-root button,.tr-root select,.tr-root label,.tr-root input{pointer-events:auto}\n.tr-search{width:100%;margin:0 0 6px;padding:5px 8px;border-radius:5px;border:1px solid #3a404c;background:#0f1116;color:#e8eaee;font:inherit}\n.tr-search::placeholder{color:#7d8594}\n.tr-item small{color:#7d8594;margin-left:4px}\n.tr-empty{color:#9aa3b2;padding:4px 2px;grid-column:1/-1}\n.tr-cross{position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-9px 0 0 -9px}\n.tr-cross:before,.tr-cross:after{content:\"\";position:absolute;background:#fff;opacity:.85;box-shadow:0 0 2px #000}\n.tr-cross:before{left:8px;top:0;width:2px;height:18px}.tr-cross:after{top:8px;left:0;height:2px;width:18px}\n.tr-cross i{position:absolute;left:6px;top:6px;width:6px;height:6px;background:#0b0c0e;border-radius:50%;z-index:1}\n.tr-top{position:absolute;top:8px;left:50%;transform:translateX(-50%);text-align:center;max-width:46vw}\n.tr-tool{display:inline-block;background:rgba(10,12,16,.72);padding:4px 12px;border-radius:6px;font-size:14px;font-weight:600}\n.tr-tool small{font-weight:400;opacity:.8;margin-left:8px}\n.tr-status{margin-top:4px;min-height:16px;color:#ffd23f;text-shadow:0 1px 2px #000}\n.tr-prog{margin:4px auto 0;width:260px;background:rgba(10,12,16,.72);border-radius:6px;padding:4px 8px;display:none}\n.tr-prog b{display:block;font-weight:500;margin-bottom:3px}\n.tr-bar{height:7px;background:#2a2e36;border-radius:4px;overflow:hidden}\n.tr-bar i{display:block;height:100%;background:#4fc3f7;width:0}\n.tr-bar.hp i{background:#66bb6a}.tr-bar.warn i{background:#ffb300}.tr-bar.bad i{background:#ef5350}\n.tr-bottom{position:absolute;bottom:8px;left:50%;transform:translateX(-50%);text-align:center;max-width:56vw}\n.tr-held{margin-bottom:6px;background:rgba(10,12,16,.72);padding:4px 10px;border-radius:6px;display:none}\n.tr-held kbd,.tr-help kbd{background:#2a2e36;border:1px solid #4a505c;border-radius:3px;padding:0 4px;font:inherit;font-weight:700}\n.tr-hotbar{display:inline-flex;gap:3px;flex-wrap:wrap;justify-content:center}\n.tr-slot{pointer-events:auto;min-width:64px;max-width:92px;padding:3px 5px;background:rgba(10,12,16,.68);border:1px solid #3a404c;border-radius:5px;color:#cfd3da;cursor:pointer;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.tr-slot b{color:#ffd23f;margin-right:3px}\n.tr-slot.on{border-color:#ffd23f;color:#fff;background:rgba(60,50,10,.8)}\n.tr-help{position:absolute;left:8px;bottom:8px;max-width:360px;opacity:.75;font-size:11px;background:rgba(10,12,16,.55);padding:4px 8px;border-radius:6px}\n.tr-left{position:absolute;top:8px;left:8px;bottom:70px;width:min(400px,36vw);display:flex;flex-direction:column;gap:8px}\n.tr-right{position:absolute;top:8px;right:8px;bottom:8px;width:min(310px,34vw);display:flex;flex-direction:column;gap:8px}\n.tr-panel{background:rgba(12,14,19,.82);border:1px solid #2c313b;border-radius:8px;padding:8px;pointer-events:auto;overflow:auto}\n.tr-panel h3{margin:0 0 6px;font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:#9aa3b2;font-weight:600}\n.tr-insp{flex:0 0 auto;max-height:46%;min-height:60px}\n.tr-insp .r{display:flex;justify-content:space-between;gap:8px}.tr-insp .r span:first-child{color:#9aa3b2}\n.tr-insp .t{font-weight:600;font-size:13px;margin-bottom:3px}\n.tr-log{flex:1 1 auto;display:flex;flex-direction:column;min-height:120px;overflow:hidden}\n.tr-logbar{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:5px;align-items:center}\n.tr-logbody{flex:1;overflow:auto;font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;background:#090a0d;border-radius:5px;padding:4px 6px}\n.tr-logbody div{white-space:pre-wrap;word-break:break-word;border-bottom:1px solid #15171c}\n.tr-logbody .action{color:#8fd3ff}.tr-logbody .event{color:#dfe3ea}.tr-logbody .check{color:#c8e6c9}.tr-logbody .check.fail{color:#ff8a80;font-weight:700}.tr-logbody .check.pass{color:#9be59f}\n.tr-logbody time{color:#6b7280;margin-right:6px}\n.tr-btn,.tr-root button.tr-btn{background:#232831;border:1px solid #3a404c;color:#e8eaee;border-radius:5px;padding:3px 8px;cursor:pointer;font:inherit}\n.tr-btn:hover{background:#2d3440}.tr-btn.on{background:#3b3a14;border-color:#ffd23f;color:#fff}\n.tr-btn.pass{border-color:#4caf50}.tr-btn.fail{border-color:#ef5350;background:#3a1d1d}\n.tr-tabs{display:flex;flex-wrap:wrap;gap:3px;margin-bottom:6px}\n.tr-items{display:grid;grid-template-columns:1fr 1fr;gap:4px}\n.tr-item{display:flex;gap:2px}.tr-item .tr-btn:first-child{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.tr-cat{flex:0 1 auto;max-height:40%}\n.tr-anim{flex:0 0 auto;max-height:18%}\n.tr-anim .list{display:flex;flex-wrap:wrap;gap:4px}.tr-anim .sub{color:#9aa3b2;margin-bottom:4px}\n.tr-bench{flex:0 1 auto;max-height:34%}\n.tr-bench .sub{color:#9aa3b2;margin-bottom:4px}\n.tr-ctls{display:flex;flex-direction:column;gap:5px}\n.tr-ctl{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.tr-ctl input[type=range]{flex:1;min-width:90px}.tr-ctl output{min-width:48px;text-align:right;color:#cfd3da}\n.tr-seg{display:inline-flex;flex-wrap:wrap;gap:2px}\n.tr-layers{margin-top:6px;display:flex;flex-direction:column;gap:2px}\n.tr-metrics{display:grid;grid-template-columns:auto 1fr;gap:2px 8px;margin:6px 0 0}.tr-metrics dt{color:#9aa3b2}.tr-metrics dd{margin:0}\n.tr-tests{flex:1 1 auto;min-height:100px}\n.tr-tests .list{display:flex;flex-direction:column;gap:3px;margin-top:6px}.tr-tests .list .tr-btn{text-align:left}\n.tr-row{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px;align-items:center}\n.tr-toggle{position:absolute;top:8px;right:8px;display:none}\n.tr-summary{margin-top:6px;color:#9aa3b2}\n@media (max-width:980px){.tr-left,.tr-right{display:none}.tr-root.open .tr-left,.tr-root.open .tr-right{display:flex}.tr-toggle{display:block;pointer-events:auto}.tr-root.open .tr-toggle{right:min(310px,34vw)}.tr-left{width:min(400px,46vw)}.tr-help{display:none}}\n`\n\n// accents are dropped on both sides of a search, so \"gas\" finds \"gás\"\nconst fold = (text: string): string => text.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '').toLowerCase()\n\nconst mk = <K extends keyof HTMLElementTagNameMap>(tag: K, cls?: string, text?: string): HTMLElementTagNameMap[K] => {\n const e = document.createElement(tag)\n if (cls) e.className = cls\n if (text !== undefined) e.textContent = text\n return e\n}\n\nexport function createUi(o: UiOptions): RoomUi {\n const { t } = o\n const style = mk('style')\n style.textContent = CSS\n const root = mk('div', 'tr-root')\n const pos = getComputedStyle?.(o.container)?.position\n if (!pos || pos === 'static') o.container.style.position = 'relative'\n root.appendChild(style)\n o.container.appendChild(root)\n\n // crosshair, top bar\n const cross = mk('div', 'tr-cross')\n cross.appendChild(mk('i'))\n const top = mk('div', 'tr-top')\n const toolBox = mk('div', 'tr-tool')\n const status = mk('div', 'tr-status')\n const prog = mk('div', 'tr-prog')\n const progLabel = mk('b')\n const progBar = mk('div', 'tr-bar')\n const progFill = mk('i')\n progBar.appendChild(progFill)\n prog.append(progLabel, progBar)\n top.append(toolBox, status, prog)\n\n // bottom: held hint and hotbar\n const bottom = mk('div', 'tr-bottom')\n const held = mk('div', 'tr-held')\n const hotbar = mk('div', 'tr-hotbar')\n bottom.append(held, hotbar)\n const help = mk('div', 'tr-help')\n help.textContent = t('ui.help')\n\n // left: inspector + log\n const left = mk('div', 'tr-left')\n const insp = mk('div', 'tr-panel tr-insp')\n const logPanel = mk('div', 'tr-panel tr-log')\n left.append(insp, logPanel)\n\n // log panel\n const logTitle = mk('h3', undefined, t('ui.log'))\n const logBar = mk('div', 'tr-logbar')\n const logBody = mk('div', 'tr-logbody')\n const filters: Record<LogEntry['channel'], boolean> = { action: true, event: true, check: true }\n const filterBtns: HTMLButtonElement[] = []\n for (const ch of ['action', 'event', 'check'] as const) {\n const b = mk('button', 'tr-btn on', t(`ui.filter.${ch}`))\n b.type = 'button'\n b.onclick = () => {\n filters[ch] = !filters[ch]\n b.classList.toggle('on', filters[ch])\n rebuildLog()\n }\n filterBtns.push(b)\n logBar.appendChild(b)\n }\n let autoscroll = true\n const asLabel = mk('label')\n const asBox = mk('input')\n asBox.type = 'checkbox'\n asBox.checked = true\n asBox.onchange = () => {\n autoscroll = asBox.checked\n }\n asLabel.append(asBox, document.createTextNode(' ' + t('ui.autoscroll')))\n logBar.appendChild(asLabel)\n const logBtn = (label: string, fn: () => void): void => {\n const b = mk('button', 'tr-btn', label)\n b.type = 'button'\n b.onclick = fn\n logBar.appendChild(b)\n }\n logBtn(t('ui.copy_json'), () => {\n const text = o.log.toJSON()\n // no clipboard API (an Artifact iframe, file://): select the text in a textarea and ask the browser to copy it, leaving it selected\n const select = (): void => {\n const ta = mk('textarea')\n ta.value = text\n ta.setAttribute('readonly', '')\n ta.style.cssText = 'position:fixed;left:8px;bottom:8px;width:min(480px,80vw);height:120px;z-index:99999'\n document.body.appendChild(ta)\n ta.focus()\n ta.select()\n let copied = false\n try {\n copied = !!document.execCommand?.('copy')\n } catch {\n copied = false\n }\n if (copied) ta.remove()\n else ta.onblur = () => ta.remove()\n }\n if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) navigator.clipboard.writeText(text).catch(select)\n else select()\n })\n logBtn(t('ui.download_ndjson'), () => o.log.download('ndjson'))\n logBtn(t('ui.download_txt'), () => o.log.download('txt'))\n logBtn(t('ui.clear_log'), () => {\n o.log.clear()\n logBody.textContent = ''\n nodes.clear()\n })\n logPanel.append(logTitle, logBar, logBody)\n\n const MAX_LINES = 200\n const nodes = new Map<number, HTMLElement>()\n const fmtTime = (s: number): string => `${Math.floor(s / 60)\n .toString()\n .padStart(2, '0')}:${(s % 60).toFixed(1).padStart(4, '0')}`\n const lineClass = (e: LogEntry): string => `${e.channel}${e.type === 'fail' || e.type === 'scenario_fail' ? ' fail' : e.type === 'pass' || e.type === 'scenario_pass' ? ' pass' : ''}`\n const fill = (n: HTMLElement, e: LogEntry): void => {\n n.className = lineClass(e)\n n.textContent = ''\n const tm = mk('time', undefined, fmtTime(e.t))\n n.append(tm, document.createTextNode(e.text))\n }\n const addNode = (e: LogEntry): void => {\n if (!filters[e.channel]) return\n const n = mk('div')\n fill(n, e)\n nodes.set(e.seq, n)\n logBody.appendChild(n)\n while (logBody.childElementCount > MAX_LINES) {\n const first = logBody.firstElementChild as HTMLElement\n for (const [k, v] of nodes) if (v === first) nodes.delete(k)\n first.remove()\n }\n if (autoscroll) logBody.scrollTop = logBody.scrollHeight\n }\n function rebuildLog(): void {\n logBody.textContent = ''\n nodes.clear()\n for (const e of o.log.entries().slice(-MAX_LINES * 3)) addNode(e)\n }\n const offLog = o.log.on((e, updated) => {\n if (updated) {\n const n = nodes.get(e.seq)\n if (n) fill(n, e)\n } else addNode(e)\n })\n\n // right: catalogue and tests\n const right = mk('div', 'tr-right')\n const cat = mk('div', 'tr-panel tr-cat')\n const anim = mk('div', 'tr-panel tr-anim')\n const tests = mk('div', 'tr-panel tr-tests')\n const benchPanel = createBenchPanel({ t, num: (n, d) => num(n, d), onControl: o.onControl, onLayer: o.onLayer, onAction: o.onAction })\n right.append(cat, anim, benchPanel.element, tests)\n\n cat.appendChild(mk('h3', undefined, t('ui.catalog')))\n const itemSearch = mk('input', 'tr-search')\n itemSearch.type = 'search'\n itemSearch.placeholder = t('ui.search_items')\n const tabs = mk('div', 'tr-tabs')\n const items = mk('div', 'tr-items')\n cat.append(itemSearch, tabs, items)\n let activeGroup = ''\n // a search looks in every group, so an item is found without knowing its tab\n const visibleItems = (): Array<{ item: TestRoomItem; group: string }> => {\n const term = fold(itemSearch.value.trim())\n if (!term) return (o.groups().get(activeGroup) ?? []).map((item) => ({ item, group: activeGroup }))\n return [...o.groups()].flatMap(([group, list]) => list.filter((item) => fold(`${item.name} ${item.id} ${group}`).includes(term)).map((item) => ({ item, group })))\n }\n const renderItems = (): void => {\n items.textContent = ''\n const searching = itemSearch.value.trim() !== ''\n const found = visibleItems()\n if (!found.length) items.appendChild(mk('div', 'tr-empty', t('ui.no_results')))\n for (const { item: it, group } of found) {\n const wrap = mk('div', 'tr-item')\n const b = mk('button', 'tr-btn', it.name)\n if (searching) b.appendChild(mk('small', undefined, group))\n b.type = 'button'\n b.title = it.note ?? it.name\n b.onclick = () => o.onSpawn(it.id)\n wrap.appendChild(b)\n if (it.weapon) {\n const w = mk('button', 'tr-btn', '⚔')\n w.type = 'button'\n w.title = t('ui.equip')\n w.onclick = () => o.onEquip(it.id)\n wrap.appendChild(w)\n }\n items.appendChild(wrap)\n }\n }\n const renderTabs = (): void => {\n tabs.textContent = ''\n const groupNames = [...o.groups().keys()]\n if (!groupNames.includes(activeGroup)) activeGroup = groupNames[0] ?? ''\n for (const g of groupNames) {\n const b = mk('button', g === activeGroup ? 'tr-btn on' : 'tr-btn', g)\n b.type = 'button'\n b.onclick = () => {\n activeGroup = g\n renderTabs()\n }\n tabs.appendChild(b)\n }\n renderItems()\n }\n renderTabs()\n itemSearch.oninput = renderItems\n // typing in a search box must not move the player or switch tools\n for (const box of [itemSearch]) box.addEventListener('keydown', (e) => e.stopPropagation())\n\n const controls = mk('div', 'tr-row')\n const ctl = (label: string, fn: (b: HTMLButtonElement) => void): HTMLButtonElement => {\n const b = mk('button', 'tr-btn', label)\n b.type = 'button'\n b.onclick = () => fn(b)\n controls.appendChild(b)\n return b\n }\n ctl(t('ui.clear'), () => o.onClear())\n ctl(t('ui.reset_all'), () => o.onResetAll())\n let slow = false\n ctl(t('ui.slow'), (b) => {\n slow = !slow\n b.classList.toggle('on', slow)\n o.onSlow(slow)\n })\n let fast = false\n ctl(t('ui.fast'), (b) => {\n fast = !fast\n b.classList.toggle('on', fast)\n o.onFast(fast)\n })\n const tapBtn = ctl(t('ui.tap'), () => o.onTap())\n const qSel = mk('select')\n for (const q of ['low', 'medium', 'high'] as const) {\n const op = mk('option', undefined, t(`ui.quality.${q}`))\n op.value = q\n qSel.appendChild(op)\n }\n qSel.value = o.quality\n qSel.onchange = () => o.onQuality(qSel.value as 'low' | 'medium' | 'high')\n const qLabel = mk('label', undefined, t('ui.quality') + ' ')\n qLabel.appendChild(qSel)\n controls.appendChild(qLabel)\n const count = mk('span')\n controls.appendChild(count)\n cat.appendChild(controls)\n\n // tests\n tests.appendChild(mk('h3', undefined, t('ui.tests')))\n const runAll = mk('button', 'tr-btn', t('ui.run_all'))\n runAll.type = 'button'\n const summary = mk('div', 'tr-summary')\n const testSearch = mk('input', 'tr-search')\n testSearch.type = 'search'\n testSearch.placeholder = t('ui.search_tests')\n testSearch.addEventListener('keydown', (e) => e.stopPropagation())\n const list = mk('div', 'list')\n tests.append(runAll, summary, testSearch, list)\n testSearch.oninput = () => {\n const term = fold(testSearch.value.trim())\n for (const b of scBtns.values()) b.style.display = !term || fold(b.textContent ?? '').includes(term) ? '' : 'none'\n }\n const scBtns = new Map<string, HTMLButtonElement>()\n let busy = false\n const mark = (rep: ScenarioReport | void): void => {\n if (!rep) return\n for (const r of rep.results) {\n const b = scBtns.get(r.id)\n if (!b) continue\n b.classList.remove('pass', 'fail')\n b.classList.add(r.ok ? 'pass' : 'fail')\n b.textContent = `${r.ok ? '✓' : '✗'} ${r.name}`\n }\n summary.textContent = t('ui.report', { passed: rep.passed, failed: rep.failed })\n }\n const renderScenarios = (): void => {\n list.textContent = ''\n scBtns.clear()\n for (const s of o.scenarios()) {\n const b = mk('button', 'tr-btn', s.name)\n b.type = 'button'\n b.onclick = async () => {\n if (busy) return\n busy = true\n try {\n mark(await o.onRun(s))\n } finally {\n busy = false\n }\n }\n scBtns.set(s.id, b)\n list.appendChild(b)\n }\n }\n renderScenarios()\n runAll.onclick = async () => {\n if (busy) return\n busy = true\n summary.textContent = t('ui.running')\n try {\n mark(await o.onRunAll())\n } finally {\n busy = false\n }\n }\n\n const toggle = mk('button', 'tr-btn tr-toggle', t('ui.panel'))\n toggle.type = 'button'\n const togglePanels = (): void => {\n root.classList.toggle('open')\n o.onResize()\n }\n toggle.onclick = togglePanels\n\n root.append(cross, top, bottom, help, left, right, toggle)\n\n // inspector\n const bar = (value: number, max: number, cls: string): HTMLElement => {\n const b = mk('div', `tr-bar ${cls}`)\n const i = mk('i')\n i.style.width = `${Math.max(0, Math.min(100, (value / Math.max(1e-9, max)) * 100))}%`\n b.appendChild(i)\n return b\n }\n const row = (k: string, v: string): HTMLElement => {\n const r = mk('div', 'r')\n r.append(mk('span', undefined, k), mk('span', undefined, v))\n return r\n }\n const num = (n: number, d = 1): string => {\n const s = (Math.round(n * 10 ** d) / 10 ** d).toFixed(d)\n return t('locale.decimal') === ',' ? s.replace('.', ',') : s\n }\n const renderInspector = (i: InspectInfo | null): void => {\n insp.textContent = ''\n insp.appendChild(mk('h3', undefined, t('ui.inspector')))\n if (!i) {\n insp.appendChild(mk('div', undefined, t('ui.aim_at_something')))\n return\n }\n insp.appendChild(mk('div', 't', `${i.object} › ${i.part}`))\n insp.appendChild(row(t('ins.material'), i.material))\n insp.appendChild(row(t('ins.status'), i.status + (i.burning ? ` · ${t('ins.burning')}` : '')))\n insp.appendChild(row(t('ins.hp'), `${num(i.hp, 0)} / ${num(i.maxHp, 0)}`))\n const frac = i.hp / Math.max(1e-9, i.maxHp)\n insp.appendChild(bar(i.hp, i.maxHp, frac < 0.25 ? 'bad' : frac < 0.6 ? 'warn' : 'hp'))\n insp.appendChild(row(t('ins.temperature'), `${num(i.temperature, 0)} °C`))\n if (i.char > 0.01) insp.appendChild(row(t('ins.char'), `${num(i.char * 100, 0)} %`))\n if (i.melt > 0.01) insp.appendChild(row(t('ins.melt'), `${num(i.melt * 100, 0)} %`))\n if (i.liters !== undefined) insp.appendChild(row(t('ins.liters'), `${num(i.liters, 2)} l`))\n const cn = (what: string, n: number): string => t(`count.${what}.${n === 1 ? 'one' : 'other'}`, { n })\n insp.appendChild(row(t('ins.damage'), t('ins.damage_counts', { dents: cn('dent', i.dents), holes: cn('hole', i.holes), cracks: cn('crack', i.cracks) })))\n insp.appendChild(row(t('ins.mass'), `${num(i.mass, 1)} kg`))\n if (i.load !== undefined) insp.appendChild(row(t('ins.load'), `${num(i.load, 0)} kg`))\n if (i.stress !== undefined) {\n insp.appendChild(row(t('ins.stress'), `${num(i.stress * 100, 0)} %`))\n insp.appendChild(bar(Math.min(i.stress, 1.2), 1.2, i.stress > 1 ? 'bad' : i.stress > 0.7 ? 'warn' : 'hp'))\n }\n if (i.joints.length) {\n insp.appendChild(mk('div', undefined, t('ins.joints') + ':'))\n for (const j of i.joints) {\n const tools = j.tools.length ? j.tools.join(', ') : t('tool.none')\n insp.appendChild(mk('div', undefined, `• ${j.kind} (${j.id})${j.open ? ` · ${t('ins.open')}` : ` → ${tools}`}`))\n }\n }\n if (i.note) insp.appendChild(mk('div', undefined, i.note))\n }\n\n let lastAnim = ''\n const renderAnimations = (a: AnimationInfo | null): void => {\n anim.textContent = ''\n anim.appendChild(mk('h3', undefined, t('ui.animations')))\n if (!a) {\n anim.appendChild(mk('div', 'sub', t('ui.animations_aim')))\n return\n }\n anim.appendChild(mk('div', 'sub', a.name))\n if (a.clips.length === 0) {\n anim.appendChild(mk('div', 'sub', t('ui.animations_none')))\n return\n }\n const l = mk('div', 'list')\n for (const c of a.clips) {\n const b = mk('button', a.playing === c.id ? 'tr-btn on' : 'tr-btn', `▶ ${t(`anim.${c.id}`) === `anim.${c.id}` ? c.id : t(`anim.${c.id}`)} (${num(c.duration, 1)} s)`)\n b.type = 'button'\n b.onclick = () => o.onPlay(a.objectId, c.id)\n l.appendChild(b)\n }\n anim.appendChild(l)\n }\n renderAnimations(null)\n\n let toastTimer: ReturnType<typeof setTimeout> | null = null\n const slotsEl: HTMLButtonElement[] = []\n let lastSlotsKey = ''\n let lastInspect = ''\n let hudPage = 0\n\n const api: RoomUi = {\n hud(s) {\n toolBox.textContent = ''\n toolBox.append(document.createTextNode(s.toolName))\n if (s.ammo) toolBox.append(mk('small', undefined, s.ammo))\n if (s.status) status.textContent = s.status\n else if (!toastTimer) status.textContent = ''\n if (s.progress) {\n prog.style.display = 'block'\n progLabel.textContent = s.progress.label\n progFill.style.width = `${Math.round(s.progress.value * 100)}%`\n } else prog.style.display = 'none'\n if (s.held) {\n held.style.display = 'block'\n held.textContent = ''\n held.append(document.createTextNode(`${s.held.name} · `))\n const keys: Array<[string, string]> = [\n ['E', t('hud.drop')],\n ['R', t('hud.rotate')],\n ['G', t('hud.throw')],\n ['Z', t('hud.tilt')],\n ...s.held.uses.map((u) => [u.key, u.label] as [string, string]),\n ]\n if (s.held.weapon) keys.push(['H', t('hud.equip', { weapon: s.held.weapon })])\n for (const [k, label] of keys) {\n held.append(mk('kbd', undefined, k), document.createTextNode(` ${label} `))\n }\n } else held.style.display = 'none'\n const key = s.slots.join('|') + s.page\n if (key !== lastSlotsKey) {\n lastSlotsKey = key\n hotbar.textContent = ''\n slotsEl.length = 0\n hudPage = s.page - 1\n s.slots.forEach((name, i) => {\n const b = mk('button', 'tr-slot')\n b.type = 'button'\n b.append(mk('b', undefined, String((i + 1) % 10)), document.createTextNode(name))\n b.title = name\n b.onclick = () => o.onTool(hudPage * 10 + i)\n hotbar.appendChild(b)\n slotsEl.push(b)\n })\n }\n slotsEl.forEach((b, i) => b.classList.toggle('on', i === s.slot))\n tapBtn.classList.toggle('on', s.tap)\n count.textContent = t('ui.objects', { n: s.objects })\n const ak = JSON.stringify(s.animations)\n if (ak !== lastAnim) {\n lastAnim = ak\n renderAnimations(s.animations)\n }\n const ik = JSON.stringify(s.inspect)\n if (ik !== lastInspect) {\n lastInspect = ik\n renderInspector(s.inspect)\n }\n },\n toast(text) {\n status.textContent = text\n if (toastTimer) clearTimeout(toastTimer)\n toastTimer = setTimeout(() => {\n toastTimer = null\n }, 2000)\n },\n refresh() {\n renderTabs()\n renderScenarios()\n },\n showGroup(group) {\n activeGroup = group\n itemSearch.value = ''\n renderTabs()\n },\n togglePanels,\n bench: benchPanel.show,\n metrics: benchPanel.metrics,\n get benchVisible() {\n return benchPanel.visible\n },\n dispose() {\n offLog()\n if (toastTimer) clearTimeout(toastTimer)\n root.remove()\n },\n }\n rebuildLog()\n return api\n}\n"],"mappings":"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","names":["JOINT_DEFAULTS","control","a","b","key","g","drum","crate","bottle","box","mk","list","box","host","box","JOINT_DEFAULTS","step","update","grab","room"]}
|