@adatechnology/game-crowd-three 0.4.0 → 0.5.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/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  createHerdView,
12
12
  crowdBenchTextOf,
13
13
  lookOfAgent
14
- } from "./chunk-PXT6DYGJ.js";
14
+ } from "./chunk-LP4CFGD7.js";
15
15
 
16
16
  // src/variety/signature.ts
17
17
  import { unpackIdentity } from "@adatechnology/game-characters-three";
package/dist/testing.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  DENSE_WALL,
7
7
  createCrowdTestModule,
8
8
  crowdBenchTextOf
9
- } from "./chunk-PXT6DYGJ.js";
9
+ } from "./chunk-LP4CFGD7.js";
10
10
  export {
11
11
  BUILTIN_SCENES,
12
12
  CHAIN_LINE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adatechnology/game-crowd-three",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "license": "MIT",
5
5
  "description": "three.js drawing for @adatechnology/game-crowd: every agent, body on the ground and civilian as instances (a literal port of the team game's hordeRender and npcRender: view culling, LOD with hysteresis, attack pose, the pose by state), the renderer on the baked variants of game-characters-three, the herd on the animals' own rigs, the crowd's sound bank and the crowd test area.",
6
6
  "keywords": [
@@ -42,13 +42,13 @@
42
42
  "dist"
43
43
  ],
44
44
  "dependencies": {
45
- "@adatechnology/game-audio": "^0.4.0",
46
- "@adatechnology/game-characters": "^0.2.8",
47
- "@adatechnology/game-characters-three": "^0.8.0",
48
- "@adatechnology/game-contracts": "^0.22.0",
49
- "@adatechnology/game-crowd": "^0.3.0",
50
- "@adatechnology/game-player": "^0.5.0",
51
- "@adatechnology/game-shapes-three": "^0.3.0"
45
+ "@adatechnology/game-audio": "^0.5.0",
46
+ "@adatechnology/game-characters": "^0.2.9",
47
+ "@adatechnology/game-characters-three": "^0.8.1",
48
+ "@adatechnology/game-contracts": "^0.23.0",
49
+ "@adatechnology/game-crowd": "^0.4.0",
50
+ "@adatechnology/game-player": "^0.5.1",
51
+ "@adatechnology/game-shapes-three": "^0.3.1"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "three": "^0.160.0"
@@ -63,7 +63,7 @@
63
63
  "vitest": "^3.2.4",
64
64
  "@adatechnology/game-animals": "^0.1.0",
65
65
  "@adatechnology/game-animals-species": "^0.1.0",
66
- "@adatechnology/game-animals-three": "^0.4.0",
66
+ "@adatechnology/game-animals-three": "^0.4.1",
67
67
  "@adatechnology/game-characters-undead": "^0.3.0",
68
68
  "@adatechnology/game-infection": "^0.1.0",
69
69
  "@adatechnology/golden-tool": "^0.0.0"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/bench/module.ts","../src/audio/bank.ts","../src/herd-view.ts","../src/instances.ts","../src/data/render.json","../src/variety/look.ts","../src/renderer.ts","../src/gpu-cost.ts","../src/bench/locale.ts","../src/bench/scenes.ts"],"sourcesContent":["import { CROWD_PHYSICS_DEFAULTS, HERD_ROLES, STATE, bindInfection, carrionCenter, createCivilians, createCrowd, createFlock, createHerd, createRng } from '@adatechnology/game-crowd'\nimport type { CivilianBuilding, CivilianSpec, Civilians, Crowd, CrowdEventMap, CrowdPack, CrowdPhysicsOptions, CrowdType, Flock, Herd, InfectionBinding, InfectionModelLike } from '@adatechnology/game-crowd'\nimport type { BakeBuilders, BakeSpec, Three } from '@adatechnology/game-characters-three'\nimport type { BenchChange, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableModule } from '@adatechnology/game-contracts'\nimport { createPlayer } from '@adatechnology/game-player'\nimport type { Player, PlayerAction } from '@adatechnology/game-player'\nimport type * as THREE_NS from 'three'\n\nimport { CROWD_SOUND_BANK, HERD_SOUND_IDS } from '../audio/bank'\nimport { createHerdView } from '../herd-view'\nimport type { AnimalDrawer, HerdView } from '../herd-view'\nimport { createCrowdInstances } from '../instances'\nimport type { CrowdInstance } from '../instances'\nimport { createCrowdRenderer } from '../renderer'\nimport type { CrowdRenderer, CrowdRendererVariety } from '../renderer'\nimport { crowdBenchTextOf } from './locale'\nimport type { CrowdBenchText } from './locale'\nimport { BUILTIN_SCENES } from './scenes'\nimport type { CrowdBenchScene, CrowdSceneProps } from './scenes'\n\nexport const CROWD_AREA_ID = 'crowd_area'\n\n/** The species card the bench reads: the gait rates (`game-animals-species` cards are these). */\nexport type CrowdBenchSpecies = { readonly walkHz: number; readonly runHz: number }\n\n/** What a crowd effect is in the host's effect catalogue (`host.effects`): its id and, optionally, the option it plays with. */\nexport type CrowdEffectMap = Readonly<Record<string, { readonly effect: string; readonly param?: number | string } | null>>\n\n/** The room's effects for the crowd's (the Oficina de VFX recipes of `game-vfx`): blood on a hit, a severed limb, the bloater's cloud, a spark, dust. */\nexport const CROWD_EFFECTS: CrowdEffectMap = {\n blood: { effect: 'blood_hit' },\n limb: { effect: 'dismember' },\n cloud: { effect: 'bloater_cloud' },\n spark: { effect: 'impact', param: 'metal' },\n dust: { effect: 'impact', param: 'concrete' },\n}\n\nexport type CrowdTestModuleOptions = {\n readonly locale?: string\n /** The bodies the crowd draws from (types, ages, outfits): the host's content (`game-characters-undead` `undeadCrowdPack()`, or a game's own). */\n readonly pack: CrowdPack\n /** The rich builders the bodies are baked from, made once three.js is lent. Without it the crowd runs and nothing is drawn. */\n readonly builders?: (three: Three) => BakeBuilders\n /** The name the rich builder knows a type by (default its id). */\n readonly typeName?: (type: CrowdType, index: number) => string\n /** The bench's name of a type (default its id). */\n readonly typeLabel?: (type: CrowdType, locale: string) => string\n /** The bodies of the civilians (baked human specs), one per civilian, in order; without them the civilians run but are not drawn. */\n readonly civilianBodies?: readonly BakeSpec[]\n /** The animals: the species card of an id, its size (`game-animals` `quadrupedLayout(body).size`, `birdSize(body)`) and, optionally, what draws them. */\n readonly animals?: {\n readonly species: (id: string) => CrowdBenchSpecies | undefined\n readonly size: (species: CrowdBenchSpecies) => number\n readonly drawer?: (three: Three) => AnimalDrawer<CrowdBenchSpecies>\n }\n /** A region model to bring agents from (`game-infection` `create(...)`) and the region the area is in. */\n readonly infection?: { readonly create: () => InfectionModelLike; readonly region: string; readonly active?: (model: InfectionModelLike) => number }\n /** The effect ids of the host for the crowd's effects (default `CROWD_EFFECTS`; null leaves one out). */\n readonly effects?: CrowdEffectMap\n readonly seed?: number\n /** Variety for the drawing (identity, accessories, near shadows, blobs): see `CrowdRendererVariety`. Default off. */\n readonly variety?: CrowdRendererVariety\n /** The physics options of the crowd (personality, contact, balance...): see `CrowdPhysicsOptions`. Default off; the bench's `physics` control turns on the package defaults when this is absent. */\n readonly crowdPhysics?: CrowdPhysicsOptions\n /** Scenes the bench can be born in, by id, over the built-in `dense_wall` and `chain_line`. */\n readonly scenes?: Readonly<Record<string, CrowdBenchScene>>\n /** What the scenes draw with: the host project's wall piece and catalogue item ids. */\n readonly props?: CrowdSceneProps\n /** Bake every type and make the drawing as soon as the module is on a frame, so the first play frame pays no bake and the room's warm-up draws the batches. Default off. */\n readonly eager?: boolean\n /** Agents when the area opens (default 0, so a room that only carries the module stays calm). */\n readonly startCount?: number\n /** Where the crowd is born around (default 0, -45: in front of the room's start). */\n readonly center?: readonly [number, number]\n}\n\n/** What the scenarios use of the context the test room passes. */\nexport interface CrowdScenarioLike {\n expect(condition: boolean, label: string, data?: Record<string, unknown>): void\n}\n\nexport type CrowdTestModule = TestableModule<CrowdScenarioLike> & {\n readonly crowd: Crowd\n readonly player: Player\n readonly renderer: CrowdRenderer | null\n}\n\ntype CameraLike = { position: { x: number; y: number; z: number }; rotation?: { y: number }; getWorldDirection?(target: unknown): { x: number; z: number } }\ntype ThreeLike = Three & { Vector3: new () => { x: number; y: number; z: number } }\n\nconst CAPACITY = 4000\nconst FRAME = 1 / 30\n/** Crowd step times kept for the p99 the bench shows. */\nconst STEP_WINDOW = 600\n/** The lethal radius of a blast the host reports with its reach only (`ModuleHost` `explosion`): the grenade's 5 m inside its 15 m. */\nconst LETHAL_SHARE = 1 / 3\n/** The renderer's default level budgets (`CrowdRendererVariety.budget`: 160, 320 and 600 bodies at the near, middle and far levels), scaled by a fixed horde detail. */\nconst HORDE_BUDGET_LEVELS = [160, 320, 600] as const\nconst RING = [10, 90] as const\n/** Two lots of the area for the civilians (a house and a shop) and the way out of the area: the test area's own ground, not a delivery's. */\nconst LOTS: Readonly<Record<string, CivilianBuilding>> = { home: { x: -14, z: -14, w: 8, d: 10, house: true, front: 1 }, shop: { x: 8, z: -14, w: 10, d: 10, front: 1 } }\n/** Four civilians with the shirts of the game's block (G 69947-69953: an adult and a child at home, two more next door), without names. */\nconst CIVILIANS: readonly CivilianSpec[] = [\n { id: 'civilian_1', home: 'home', color: 0x3e6a8a },\n { id: 'civilian_2', home: 'home', color: 0xd0a030, child: true },\n { id: 'civilian_3', home: 'shop', color: 0x6a5a3a },\n { id: 'civilian_4', home: 'shop', color: 0x8a3a5a },\n]\nconst WAY_OUT: readonly (readonly [number, number])[] = [\n [0, 4],\n [30, 4],\n [60, 20],\n]\n/** The yard and the farm of the herd golden scene (`bichosPovoar` G 66607-66623 laid out round one point): offsets, the species and its role. */\nconst FARM: readonly (readonly [string, number, number, { companion?: boolean; dead?: boolean }?])[] = [\n ['dog', 2, 3, { companion: true }],\n ['cat', 12, -6],\n ['chicken', -8, 4],\n ['chicken', -8.5, 5],\n ['chicken', -7.5, 4.6],\n ['southern_lapwing', 8, 5],\n ['cow', -20, -10],\n ['cow', -24, -12],\n ['horse', -26, -4],\n ['pig', -14, -16],\n ['capybara', 18, 14],\n ['cow', -18, -24, { dead: true }],\n ['vulture', 0, 0],\n ['vulture', 0, 0],\n ['vulture', 0, 0],\n]\n\nconst messageText = (text: CrowdBenchText, id: string): string => (text.messages as Readonly<Record<string, string>>)[id] ?? id\n\n/**\n * The crowd area of a test room, against the generic contracts only: a horde of any pack drawn on the instanced path (the baked variants of\n * `game-characters-three`), the room's camera as the `game-player` body it hunts, civilians, the herd and the vultures, and a bridge to a region\n * model. Sounds go to `host.audio` (the crowd's bank is registered there), effects to `host.effects`. The pack and the bodies come in by option:\n * this package knows no game.\n */\nexport function createCrowdTestModule(options: CrowdTestModuleOptions): CrowdTestModule {\n const locale = options.locale ?? 'pt-BR'\n const text = crowdBenchTextOf(locale)\n const effects = options.effects ?? CROWD_EFFECTS\n const [cx, cz] = options.center ?? [0, -45]\n const settings = { count: options.startCount ?? 0, type: 'mix', night: false, seed: options.seed ?? 1, scene: 'open', physics: options.crowdPhysics !== undefined }\n const scenes = { ...BUILTIN_SCENES, ...options.scenes }\n const sceneOf = (): CrowdBenchScene | undefined => (settings.scene === 'open' ? undefined : scenes[settings.scene])\n const layers = { corpses: true, civilians: true, animals: true }\n let host: ModuleHost | null = null\n let three: Three | null = null\n let renderer: CrowdRenderer | null = null\n let herdView: HerdView | null = null\n let lastMessage = ''\n let isDirty = false\n let removeProps: (() => void) | null = null\n const stepTimes: number[] = []\n const peaks = { climbers: 0, moundMax: 0, maxOverlap: 0 }\n let isBaked = false\n let frameStepMs = 0\n let pending: Partial<Record<PlayerAction, boolean>> = {}\n let last: { x: number; z: number } | null = null\n const offs: (() => void)[] = []\n\n const typeOfSetting = (crowd: Crowd): number => (settings.type === 'mix' ? -1 : crowd.typeIndex(settings.type))\n type World = { crowd: Crowd; player: Player; civilians: Civilians; herd: Herd; flock: Flock; vultures: number; binding: InfectionBinding | null; model: InfectionModelLike | null; place: () => number; physics: boolean; sceneUnit: () => number }\n const build = (seed: number): World => {\n const player = createPlayer({ seed })\n const physics = settings.physics ? (options.crowdPhysics ?? CROWD_PHYSICS_DEFAULTS) : undefined\n const crowd = createCrowd({ pack: options.pack, seed, capacity: CAPACITY, target: player, ...(physics ? { physics } : {}) })\n sceneOf()?.layout(crowd, { cx, cz })\n const civilians = createCivilians(crowd, { people: CIVILIANS.map((c) => ({ ...c })), buildings: LOTS })\n const herd = createHerd(crowd, { view: () => ({ x: player.state.x, z: player.state.z }) })\n const flock = createFlock({ count: 0, mode: 'carrion' })\n const model = options.infection?.create() ?? null\n const spot = createRng(seed + 7)\n const binding = model ? bindInfection(crowd, model, { place: () => [cx + (spot() - 0.5) * 40, cz - 20 - spot() * 40], civilians, regionOf: () => options.infection!.region }) : null\n const place = (): number => {\n const a = spot() * Math.PI * 2\n const r = RING[0] + spot() * (RING[1] - RING[0])\n const type = typeOfSetting(crowd)\n return crowd.spawn(cx + Math.cos(a) * r, cz + Math.sin(a) * r, type)\n }\n return { crowd, player, civilians, herd, flock, vultures: 0, binding, model, place, physics: physics !== undefined, sceneUnit: createRng(seed + 13) }\n }\n let world = build(settings.seed)\n\n const wire = (): void => {\n for (const off of offs.splice(0)) off()\n const { crowd, herd, civilians } = world\n offs.push(crowd.on('sound', (e) => void host?.audio?.play({ sound: e.sound, volume: e.volume, position: e.position })))\n offs.push(herd.on('sound', (e) => void host?.audio?.play({ sound: HERD_SOUND_IDS[e.sound] ?? e.sound, volume: e.volume, position: e.position })))\n offs.push(crowd.on('effect', (e: CrowdEventMap['effect']) => playEffect(e)))\n offs.push(crowd.on('message', (e) => void (lastMessage = messageText(text, e.id))))\n offs.push(herd.on('message', (e) => void (lastMessage = messageText(text, e.id))))\n offs.push(civilians.on('bitten', () => void (lastMessage = text.messages.bitten)))\n offs.push(civilians.on('turned', () => void (lastMessage = text.messages.turned)))\n offs.push(civilians.on('died', () => void (lastMessage = text.messages.died)))\n offs.push(crowd.on('kill', (e) => host?.log(`crowd kill: ${e.type}`, { agent: e.agent, headshot: e.headshot })))\n }\n const playEffect = (e: CrowdEventMap['effect']): void => {\n const map = effects[e.effect]\n if (!map || !host?.effects) return\n host.effects.play({ effect: map.effect, point: e.point, ...(map.param !== undefined ? { param: map.param } : {}), ...(e.amount !== undefined ? { scale: Math.max(0.3, Math.min(2, e.amount / 30)) } : {}) })\n }\n\n const fit = (): void => {\n settle()\n const { crowd } = world\n const scene = sceneOf()\n if (scene) {\n const missing = Math.min(settings.count, CAPACITY) - crowd.store.n\n if (missing > 0) scene.spawn(crowd, { first: crowd.store.n, count: missing, type: typeOfSetting(crowd), unit: world.sceneUnit }, { cx, cz })\n } else {\n while (crowd.store.n < settings.count && world.place() >= 0) {\n /* born in the ring */\n }\n }\n while (crowd.store.n > settings.count) crowd.remove(crowd.store.n - 1)\n }\n\n const bringHerd = (): void => {\n const animals = options.animals\n if (!animals || world.herd.list.length) return\n for (const [id, dx, dz, extra] of FARM) {\n const species = animals.species(id)\n if (!species) continue\n world.herd.add({ ...HERD_ROLES[id], ...extra, species: id, x: cx + dx, z: cz + 30 + dz, walkHz: species.walkHz, runHz: species.runHz, size: animals.size(species) })\n }\n world.vultures = world.herd.list.filter((E) => E.spec.sky).length\n world.flock = createFlock({ count: world.vultures, mode: 'carrion' })\n herdView?.clear()\n herdView = null\n }\n\n const sceneView = (): ModuleArea['view'] | undefined => {\n const view = sceneOf()?.view({ cx, cz })\n return view ? { eye: [...view.eye], target: [...view.target] } : undefined\n }\n\n const settle = (): void => {\n if (isDirty) reset()\n }\n\n const reset = (): void => {\n isDirty = false\n stepTimes.length = 0\n peaks.climbers = peaks.moundMax = peaks.maxOverlap = 0\n removeProps?.()\n removeProps = null\n world.binding?.unbind()\n renderer?.dispose()\n if (renderer) (host?.scene as THREE_NS.Object3D | undefined)?.remove(renderer.group)\n renderer = null\n herdView?.clear()\n if (herdView) (host?.scene as THREE_NS.Object3D | undefined)?.remove(herdView.group)\n herdView = null\n world = build(settings.seed)\n wire()\n if (host) removeProps = sceneOf()?.props?.(host, { cx, cz }, options.props ?? {}) ?? null\n fit()\n lastMessage = ''\n const view = sceneView()\n if (view) host?.bench?.look?.(view.eye, view.target)\n }\n\n const view = (): { x: number; z: number; yaw: number } | null => {\n const camera = host?.camera as CameraLike | undefined\n if (!camera?.position) return null\n const Vector3 = (host?.THREE as ThreeLike | undefined)?.Vector3\n if (camera.getWorldDirection && Vector3) {\n const look = camera.getWorldDirection(new Vector3())\n return { x: camera.position.x, z: camera.position.z, yaw: Math.atan2(-look.x, -look.z) }\n }\n return { x: camera.position.x, z: camera.position.z, yaw: camera.rotation?.y ?? 0 }\n }\n\n // the player's horde detail (host.graphics, Gráficos → Detalhe da horda): auto keeps the renderer's own budget.adapt; a share fixes the level budgets at that share\n const varietyFor = (detail: 'auto' | number): CrowdRendererVariety | undefined => {\n const variety = options.variety\n if (!variety || detail === 'auto' || variety.budget === false) return variety\n const levels = (variety.budget?.levels ?? HORDE_BUDGET_LEVELS).map((n) => Math.max(1, Math.round(n * detail)))\n return { ...variety, budget: { ...variety.budget, levels, adapt: false } }\n }\n const ensureDrawing = (): void => {\n if (!host || !three) return\n const scene = host.scene as THREE_NS.Object3D\n if (!renderer && options.builders) {\n const bodies = options.civilianBodies ?? []\n const variety = varietyFor(host.graphics?.hordeDetail() ?? 'auto')\n renderer = createCrowdRenderer(three, {\n crowd: world.crowd,\n builders: options.builders(three),\n ...(options.typeName ? { typeName: options.typeName } : {}),\n drawCorpses: () => layers.corpses,\n ...(variety ? { variety } : {}),\n ...(bodies.length ? { civilians: { list: () => (layers.civilians ? world.civilians.list : []), body: (n) => bodies[n.k % bodies.length]! } } : {}),\n })\n scene.add(renderer.group)\n isBaked = false\n }\n if (!herdView && options.animals?.drawer && world.herd.list.length) {\n herdView = createHerdView(three, { herd: world.herd, flock: world.flock, drawer: options.animals.drawer(three), species: options.animals.species })\n scene.add(herdView.group)\n }\n }\n\n const updateContext = (): { viewYaw: number; nightFactor: number; bandCentre?: readonly [number, number]; flowTarget?: readonly [number, number] } => ({\n viewYaw: view()?.yaw ?? 0,\n nightFactor: settings.night ? 1 : 0,\n ...sceneOf()?.context?.({ cx, cz }),\n })\n const stepCrowd = (dt: number): void => {\n const started = performance.now()\n world.crowd.update(dt, updateContext())\n frameStepMs += performance.now() - started\n }\n const recordPeaks = (): void => {\n const physics = world.crowd.stats.physics\n peaks.climbers = Math.max(peaks.climbers, physics.climbers)\n peaks.moundMax = Math.max(peaks.moundMax, physics.moundMax)\n peaks.maxOverlap = Math.max(peaks.maxOverlap, physics.maxOverlap)\n if (frameStepMs <= 0) return\n stepTimes.push(frameStepMs)\n if (stepTimes.length > STEP_WINDOW) stepTimes.shift()\n frameStepMs = 0\n }\n const stepMsP99 = (): number => {\n if (stepTimes.length === 0) return 0\n const sorted = [...stepTimes].sort((a, b) => a - b)\n return sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * 0.99))]!\n }\n\n const prepareDrawing = (): void => {\n if (!host) return\n settle()\n ensureDrawing()\n if (!renderer || isBaked) return\n renderer.prepare()\n isBaked = true\n }\n\n const frame = (dt: number): void => {\n settle()\n const { crowd, player, civilians, herd, flock } = world\n const here = view()\n const speed = here && last && dt > 0 ? Math.hypot(here.x - last.x, here.z - last.z) / dt : 0\n if (here) {\n player.state.x = here.x\n player.state.z = here.z\n }\n player.update(dt, { forward: speed > 0.2 ? 1 : 0, run: speed > 3.4, yaw: here?.yaw ?? 0, pressed: pending }, { crowd: crowd.asPlayerCrowd() })\n pending = {}\n if (here) {\n player.state.x = here.x\n player.state.z = here.z\n last = { x: here.x, z: here.z }\n }\n crowd.updateTrail(dt)\n civilians.update(dt)\n if (herd.list.length) {\n herd.update(dt)\n const carcass = herd.list.find((E) => E.dead)\n flock.update(herd.time, dt, carrionCenter(crowd.corpses.entries.map((e) => e.data), carcass ? [carcass.x, carcass.z] : null), [player.state.x, player.state.z])\n }\n if (!world.physics) stepCrowd(dt)\n recordPeaks()\n crowd.updateCorpses(dt)\n if (options.eager) prepareDrawing()\n else ensureDrawing()\n if (renderer && (crowd.store.n || crowd.corpses.count || civilians.list.length)) {\n renderer.update(dt, { camera: { x: player.state.x, z: player.state.z }, viewYaw: here?.yaw ?? 0, target: { x: player.state.x, z: player.state.z, alive: player.state.alive } })\n // what the horde draws now, for the settings screen (under auto it is the adaptive share; fixed, the share chosen)\n const detail = host?.graphics?.hordeDetail() ?? 'auto'\n host?.graphics?.report('hordeDetail', detail === 'auto' ? renderer.detailScale : detail)\n }\n if (herdView) {\n herdView.group.visible = layers.animals\n herdView.update(dt)\n }\n }\n const hitNearest = (): void => {\n const { crowd, player } = world\n const Z = crowd.store\n let best = -1\n let bd = Infinity\n for (let i = 0; i < Z.n; i++) {\n const d = Math.hypot(Z.x[i]! - player.state.x, Z.z[i]! - player.state.z)\n if (d < bd) [best, bd] = [i, d]\n }\n if (best >= 0) crowd.damage(best, { region: 0, amount: 200, distance: bd, cut: 0, caliber: null })\n }\n\n const onChange = (change: BenchChange): void => {\n if (change.kind === 'layer') {\n if (change.id in layers) layers[change.id as keyof typeof layers] = change.on\n return\n }\n if (change.kind === 'action') {\n const id = change.id\n if (id === 'spawn') {\n settings.count = Math.min(CAPACITY, world.crowd.store.n + 100)\n host?.bench?.patch('count', { value: settings.count })\n fit()\n } else if (id === 'noise') world.crowd.emitNoise(world.player.state.x, world.player.state.z, 80)\n else if (id === 'hit') hitNearest()\n else if (id === 'kill_all') for (let i = world.crowd.store.n - 1; i >= 0; i--) world.crowd.kill(i)\n else if (id === 'join') for (const n of world.civilians.list) world.civilians.join(n.id)\n else if (id === 'flee') for (const n of world.civilians.list) world.civilians.flee(n.id, WAY_OUT.map(([x, z]) => [cx + x, cz + 40 + z] as const))\n else if (id === 'herd') bringHerd()\n else if (id === 'materialize' && world.binding && options.infection) world.binding.materialize(options.infection.region, 50)\n else if (id === 'push') pending = { ...pending, push: true }\n else if (id === 'reset') reset()\n return\n }\n const { id, value } = change\n if (id === 'count' && typeof value === 'number') {\n settings.count = value\n fit()\n } else if (id === 'scene' && typeof value === 'string' && value !== settings.scene) {\n settings.scene = value\n isDirty = true\n } else if (id === 'physics' && typeof value === 'boolean' && value !== settings.physics) {\n settings.physics = value\n isDirty = true\n } else if (id === 'type' && typeof value === 'string') settings.type = value\n else if (id === 'night' && typeof value === 'boolean') settings.night = value\n else if (id === 'seed' && typeof value === 'number' && value !== settings.seed) {\n settings.seed = value\n isDirty = true\n }\n }\n\n const typeOptions = () => [{ id: 'mix', name: text.mix }, ...options.pack.types.map((type) => ({ id: type.id, name: options.typeLabel?.(type, locale) ?? type.id }))]\n const sceneOptions = () => [{ id: 'open', name: text.sceneNames.open }, ...Object.keys(scenes).map((id) => ({ id, name: (text.sceneNames as Readonly<Record<string, string>>)[id] ?? id }))]\n const controls = (): ModuleControl[] => [\n // the order is the order the bench state is applied in (`sendInitial`): the seed makes the world, the scene writes its grid, the physics rebuilds the crowd, the count bears the agents\n { kind: 'number', id: 'seed', name: text.controls.seed, min: 1, max: 9999, step: 1, default: settings.seed },\n { kind: 'choice', id: 'scene', name: text.controls.scene, hint: text.hints.scene, options: sceneOptions(), default: settings.scene },\n { kind: 'boolean', id: 'physics', name: text.controls.physics, hint: text.hints.physics, default: settings.physics },\n { kind: 'number', id: 'count', name: text.controls.count, hint: text.hints.count, min: 0, max: CAPACITY, step: 100, default: settings.count },\n { kind: 'choice', id: 'type', name: text.controls.type, hint: text.hints.type, options: typeOptions(), default: 'mix' },\n { kind: 'boolean', id: 'night', name: text.controls.night, hint: text.hints.night, default: false },\n { kind: 'action', id: 'spawn', name: text.controls.spawn, slow: true },\n { kind: 'action', id: 'noise', name: text.controls.noise, hint: text.hints.noise },\n { kind: 'action', id: 'hit', name: text.controls.hit, hint: text.hints.hit },\n { kind: 'action', id: 'kill_all', name: text.controls.kill_all },\n { kind: 'action', id: 'join', name: text.controls.join, hint: text.hints.join },\n { kind: 'action', id: 'flee', name: text.controls.flee, hint: text.hints.flee },\n ...(options.animals ? [{ kind: 'action', id: 'herd', name: text.controls.herd, hint: text.hints.herd } as const] : []),\n ...(options.infection ? [{ kind: 'action', id: 'materialize', name: text.controls.materialize, hint: text.hints.materialize } as const] : []),\n { kind: 'action', id: 'push', name: text.controls.push, hint: text.hints.push },\n { kind: 'action', id: 'reset', name: text.controls.reset, slow: true },\n ]\n const benchLayers = (): ModuleLayer[] => [\n { id: 'corpses', name: text.layers.corpses },\n { id: 'civilians', name: text.layers.civilians },\n { id: 'animals', name: text.layers.animals },\n ]\n const metrics = (): ModuleMetric[] => [\n { id: 'agents', name: text.metrics.agents, digits: 0, max: CAPACITY, read: () => world.crowd.store.n },\n { id: 'drawn', name: text.metrics.drawn, digits: 0, read: () => (renderer ? renderer.lodCounts[0] + renderer.lodCounts[1] + renderer.lodCounts[2] : 0) },\n { id: 'lod_near', name: text.metrics.lod_near, digits: 0, read: () => renderer?.lodCounts[0] ?? 0 },\n { id: 'lod_middle', name: text.metrics.lod_middle, digits: 0, read: () => renderer?.lodCounts[1] ?? 0 },\n { id: 'lod_far', name: text.metrics.lod_far, digits: 0, read: () => renderer?.lodCounts[2] ?? 0 },\n { id: 'draw_calls', name: text.metrics.draw_calls, digits: 0, read: () => renderer?.drawCalls ?? 0 },\n { id: 'bake_ms', name: text.metrics.bake_ms, unit: 'ms', digits: 0, read: () => renderer?.bakeMs ?? 0 },\n { id: 'detail_scale', name: text.metrics.detail_scale, digits: 2, read: () => renderer?.detailScale ?? 1 },\n { id: 'crowd_gpu_ms', name: text.metrics.crowd_gpu_ms, unit: 'ms', digits: 1, read: () => renderer?.gpuMs ?? 0 },\n { id: 'active', name: text.metrics.active, digits: 0, read: () => world.crowd.stats.bands[0] },\n { id: 'kills', name: text.metrics.kills, digits: 0, read: () => world.crowd.stats.kills },\n { id: 'bodies', name: text.metrics.corpses, digits: 0, read: () => world.crowd.corpses.count },\n { id: 'civilians_alive', name: text.metrics.civilians, digits: 0, read: () => world.civilians.list.filter((n) => n.state !== 'dead' && n.state !== 'undead' && n.state !== 'gone').length },\n { id: 'health', name: text.metrics.health, digits: 0, read: () => Math.max(0, world.player.state.health) },\n { id: 'grabbed', name: text.metrics.grabbed, read: () => (world.player.state.grabbedBy >= 0 ? text.yes : text.no) },\n { id: 'message', name: text.metrics.message, read: () => lastMessage },\n { id: 'falls_pressure', name: text.metrics.falls_pressure, digits: 0, read: () => world.crowd.stats.physics.falls[0] },\n { id: 'falls_chain', name: text.metrics.falls_chain, digits: 0, read: () => world.crowd.stats.physics.fallsBeyondBlast },\n { id: 'falls_landing', name: text.metrics.falls_landing, digits: 0, read: () => world.crowd.stats.physics.falls[3] },\n { id: 'climbers', name: text.metrics.climbers, digits: 0, read: () => peaks.climbers },\n { id: 'mound_max', name: text.metrics.mound_max, unit: 'm', digits: 2, read: () => peaks.moundMax },\n { id: 'thrown_peak', name: text.metrics.thrown_peak, digits: 0, read: () => world.crowd.stats.physics.thrownPeak },\n { id: 'max_overlap', name: text.metrics.max_overlap, unit: 'm', digits: 2, read: () => peaks.maxOverlap },\n { id: 'chain_links', name: text.metrics.chain_links, digits: 0, read: () => world.crowd.stats.physics.chainLinks },\n { id: 'crowd_ms_p99', name: text.metrics.crowd_ms_p99, unit: 'ms', digits: 2, read: () => stepMsP99() },\n ]\n\n // each scenario runs its own crowd, so the bench's live one is not touched\n const fresh = (seed = 1, capacity = 600): { crowd: Crowd; player: Player } => {\n const player = createPlayer({ seed })\n return { crowd: createCrowd({ pack: options.pack, seed, capacity, flow: { clock: () => 0 }, target: player }), player }\n }\n const run = (crowd: Crowd, seconds: number): void => {\n for (let t = 0; t < seconds; t += FRAME) {\n crowd.update(FRAME)\n crowd.updateCorpses(FRAME)\n }\n }\n const eyes = options.pack.types.map((type) => type.eye ?? null)\n const sizes = Array.from({ length: options.pack.types.reduce((sum, type) => sum + (type.variants ?? 1), 0) }, () => ({ s: 1.7, bulk: 1 }))\n const drawOnce = (crowd: Crowd, player: Player): { level: number; pose: number }[] => {\n const out: { level: number; pose: number }[] = []\n createCrowdInstances({ eyes }).agents(crowd.store, sizes, { camera: { x: player.state.x, z: player.state.z }, viewYaw: 0, target: { x: player.state.x, z: player.state.z, alive: true } }, (_v, level, instance: CrowdInstance) => out.push({ level, pose: instance.b[3] }))\n return out\n }\n const scenarios = (): Array<ModuleScenario<CrowdScenarioLike>> => [\n {\n id: 'crowd_relevance',\n name: text.scenarios.relevance,\n run: ({ expect }) => {\n const { crowd } = fresh(3)\n const spot = createRng(3)\n for (let k = 0; k < 500; k++) crowd.spawn((spot() - 0.5) * 600, (spot() - 0.5) * 600)\n run(crowd, 1)\n const [near, , mid, far] = crowd.stats.bands\n expect(crowd.store.n === 500, '500 agents', { n: crowd.store.n })\n expect(near < 50 && mid + far > 400, 'few think every frame, most are far and slow', { bands: [...crowd.stats.bands] })\n },\n },\n {\n id: 'crowd_lod',\n name: text.scenarios.lod,\n run: ({ expect }) => {\n const { crowd, player } = fresh(1, 4)\n player.state.x = 0\n player.state.z = 0\n const i = crowd.spawn(0, -17, 0)\n const levels: number[] = []\n for (const z of [-17, -19, -19.6, -17.5, -16]) {\n crowd.store.z[i] = z\n levels.push(drawOnce(crowd, player)[0]!.level)\n }\n expect(levels.join() === '0,0,1,1,0', 'in at 19.5 m, back under 16.5 m', { levels })\n },\n },\n {\n id: 'crowd_attack_pose',\n name: text.scenarios.attack_pose,\n run: ({ expect }) => {\n const { crowd, player } = fresh(1, 4)\n const i = crowd.spawn(0, -1.5, 0)\n crowd.store.state[i] = STATE.CHASE\n const poses: number[] = []\n for (const z of [-1.5, -2, -2.3, -1.9]) {\n crowd.store.z[i] = z\n poses.push(drawOnce(crowd, player)[0]!.pose)\n }\n expect(poses.join() === '3,3,0,0', 'the attack pose holds to 2.2 m and comes back under 1.6 m', { poses })\n },\n },\n {\n id: 'crowd_corpse_darkens',\n name: text.scenarios.corpse_darkens,\n run: ({ expect }) => {\n const { crowd, player } = fresh(1, 4)\n crowd.kill(crowd.spawn(0, -5, 0))\n const life = crowd.numbers.corpseSeconds\n crowd.updateCorpses(life / 2)\n const shades: number[] = []\n const heights: number[] = []\n const take = (_v: number, _l: number, instance: CrowdInstance): void => {\n shades.push(instance.shade)\n heights.push(instance.b[0])\n }\n const instances = createCrowdInstances({ eyes })\n const frameOf = { camera: { x: player.state.x, z: player.state.z }, viewYaw: 0 }\n instances.corpses(crowd.corpses.entries, sizes, frameOf, life, take, (i) => take(-1, 1, i))\n crowd.updateCorpses(life / 2 - 30)\n instances.corpses(crowd.corpses.entries, sizes, frameOf, life, take, (i) => take(-1, 1, i))\n expect(Math.abs(shades[0]! - 0.65) < 1e-9, 'half its life: 65% of the colour', { shades })\n expect(Math.abs(heights[1]! / heights[0]! - 0.5) < 1e-6, '30 s before the end: half its height', { heights })\n },\n },\n {\n id: 'crowd_civilians_flee',\n name: text.scenarios.civilians_flee,\n run: ({ expect }) => {\n const { crowd, player } = fresh(2, 4)\n player.state.x = 0\n player.state.z = 6\n const civilians = createCivilians(crowd, { people: [{ id: 'c', home: 'home' }], buildings: LOTS })\n civilians.join('c')\n for (let t = 0; t < 10; t += 0.05) civilians.update(0.05)\n const c = civilians.get('c')!\n expect(Math.hypot(c.x - 0, c.z - 6) < 2.5, 'it follows', { x: c.x, z: c.z })\n civilians.flee('c', [[5, 6], [10, 6]])\n for (let t = 0; t < 20; t += 0.05) civilians.update(0.05)\n expect(c.state === 'gone', 'it ran off and is gone', { state: c.state })\n },\n },\n {\n id: 'crowd_herd_calls',\n name: text.scenarios.herd_calls,\n run: ({ expect }) => {\n const { crowd } = fresh(4, 4)\n const herd = createHerd(crowd)\n const hen = herd.add({ ...HERD_ROLES.chicken, species: 'chicken', x: 20, z: 0, walkHz: 2.2, runHz: 4, size: 0.4 })\n herd.add({ ...HERD_ROLES.southern_lapwing, species: 'southern_lapwing', x: 5, z: 0, walkHz: 2.5, runHz: 1.6, size: 0.35 })\n crowd.spawn(21.5, 0, 0)\n const sounds: string[] = []\n herd.on('sound', (e) => sounds.push(HERD_SOUND_IDS[e.sound] ?? e.sound))\n for (let f = 0; f < 40; f++) herd.update(0.05)\n expect(sounds.includes('hen_cluck') && sounds.includes('lapwing_call'), 'the hen clucks, the lapwing calls', { sounds })\n expect(hen.x < 20, 'the hen ran', { x: hen.x })\n },\n },\n {\n id: 'crowd_vultures',\n name: text.scenarios.vultures,\n run: ({ expect }) => {\n const centre = carrionCenter([{ x: 0, z: 0 }, { x: 3, z: 0 }, { x: 0, z: 3 }], null)\n const vultures = createFlock({ count: 3, mode: 'carrion' })\n vultures.update(10, 0.05, centre, [0, 0])\n const r = vultures.birds.map((U) => Math.hypot(U.x - centre[0], U.z - centre[1]))\n expect(r.every((d, i) => Math.abs(d - (7 + i * 2)) < 1e-9), 'each at its radius over the centre of the bodies', { r })\n },\n },\n ...(options.infection\n ? [\n {\n id: 'crowd_infection',\n name: text.scenarios.infection,\n run: ({ expect }: CrowdScenarioLike) => {\n const infection = options.infection!\n const model = infection.create()\n const { crowd } = fresh(6, 64)\n const binding = bindInfection(crowd, model, { place: (_r, seed, k) => [(seed % 100) - 50 + k * 0.01, 500 + k] })\n const before = infection.active?.(model)\n const born = binding.materialize(infection.region, 10)\n crowd.update(0.1)\n const back = binding.giveBack(infection.region)\n expect(born.length > 0 && back === born.length && crowd.store.n === 0, 'brought out, given back', { born: born.length, back })\n if (before !== undefined) expect(infection.active!(model) === before, 'the region keeps its numbers', { before, after: infection.active!(model) })\n binding.unbind()\n },\n },\n ]\n : []),\n {\n id: 'crowd_determinism',\n name: text.scenarios.determinism,\n run: ({ expect }) => {\n const trace = (seed: number): string => {\n const { crowd } = fresh(seed, 40)\n for (let k = 0; k < 30; k++) crowd.spawn((k % 6) * 3 - 8, -10 - Math.floor(k / 6) * 3)\n run(crowd, 3)\n return Array.from({ length: crowd.store.n }, (_, i) => `${crowd.store.x[i]!.toFixed(4)},${crowd.store.z[i]!.toFixed(4)}`).join(';')\n }\n expect(trace(9) === trace(9), 'the same seed gives the same crowd')\n expect(trace(9) !== trace(10), 'another seed gives another')\n },\n },\n ]\n\n wire()\n fit()\n\n const module: CrowdTestModule = {\n id: CROWD_AREA_ID,\n name: text.name,\n ground: { surface: 'road' },\n group: text.group,\n get crowd() {\n return world.crowd\n },\n get player() {\n return world.player\n },\n get renderer() {\n return renderer\n },\n items: () => [],\n area: (): ModuleArea => ({ placements: [], view: sceneView() ?? { eye: [0, 1.7, 6], target: [cx, 1.2, cz] } }),\n controls: () => controls(),\n layers: () => benchLayers(),\n metrics: () => metrics(),\n scenarios: () => scenarios(),\n attach(lent) {\n host = lent\n three = lent.THREE as Three\n last = null\n lent.audio?.register?.(CROWD_SOUND_BANK)\n const off = lent.bench?.onChange(onChange)\n const offFrame = lent.onFrame(frame)\n // a new horde detail rebuilds the drawing with the new budget (the next frame makes it again)\n const offGraphics = lent.graphics?.onChange(() => {\n if (!renderer) return\n ;(lent.scene as THREE_NS.Object3D).remove(renderer.group)\n renderer.dispose()\n renderer = null\n isBaked = false\n })\n // with the physics the crowd steps in the fixed phase of the host's scheduler: one fixed step per call, the same whatever the frame rate\n const offFixed = lent.onFrame((step) => (world.physics ? stepCrowd(step) : undefined), { phase: 'fixedSimulate' })\n const offBlast = lent.on((event) => {\n if (event.type !== 'explosion') return\n world.crowd.blast({ point: event.point, energy: event.energy, radius: event.radius, lethalRadius: event.radius * LETHAL_SHARE, source: event.source, ...(event.cause === 'part' ? { chain: event.source } : {}) })\n })\n if (host) removeProps = sceneOf()?.props?.(host, { cx, cz }, options.props ?? {}) ?? null\n // the bench state arrives right after `attach`: once it has been applied the drawing is made and every batch with it, before the host's warm-up draws the scene\n if (options.eager) queueMicrotask(() => prepareDrawing())\n return () => {\n off?.()\n offFrame()\n offGraphics?.()\n offFixed()\n offBlast()\n removeProps?.()\n removeProps = null\n if (renderer) (lent.scene as THREE_NS.Object3D).remove(renderer.group)\n if (herdView) (lent.scene as THREE_NS.Object3D).remove(herdView.group)\n renderer?.dispose()\n renderer = null\n herdView = null\n host = null\n }\n },\n }\n return module\n}\n","// The crowd's sounds as recipes of @adatechnology/game-audio, ported literally from the team game: the hoarse scream (`grito`, jogo L62128-62142), the groan\n// and the runner's groan (`voz`, jogo L62143-62155) and the animal calls of the herd (`bichoSom`, jogo L66625-66639). The same recipes are checked against the\n// team traces in game-audio's tests (tests/support/team-game-recipes.ts), which keeps its own copy so it does not depend on this package.\nimport { DISTANCE_CURVES } from '@adatechnology/game-audio'\nimport type { Layer, SoundBank, SoundRecipe } from '@adatechnology/game-audio'\n\nconst scream: SoundRecipe = {\n id: 'scream_hoarse',\n bus: 'voices',\n order: 'scream',\n duration: [1, 1.4],\n layers: [\n {\n source: { kind: 'noise', offset: 'random' },\n filters: {\n mode: 'parallel',\n bank: [\n { type: 'bandpass', q: 6, frequency: { from: 700 * 1.15, to: 700 * 0.8, curve: 'linear', over: 'duration' }, level: 1 },\n { type: 'bandpass', q: 8, frequency: { from: 1150 * 1.15, to: 1150 * 0.8, curve: 'linear', over: 'duration' }, level: 0.7 },\n { type: 'bandpass', q: 10, frequency: { from: 2600 * 1.15, to: 2600 * 0.8, curve: 'linear', over: 'duration' }, level: 0.35 },\n ],\n },\n modulators: [{ target: 'gain', wave: 'square', rate: [31, 40], depth: 0.35 }],\n envelope: [\n [0, 0, 'set'],\n [0.06, 0.9, 'linear'],\n ['0.6d', 0.9, 'set'],\n ['1d', 0.001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.game_scream,\n sources: ['jogo:L62128-62142'],\n}\n\nconst groanLayer = (base: number | { readonly param: string }): Layer => ({\n source: {\n kind: 'osc',\n wave: 'sawtooth',\n frequency: typeof base === 'number' ? { from: base, to: base * 0.7, curve: 'linear', over: 'duration' } : { from: base, to: { ...base, scale: 0.7 }, curve: 'linear', over: 'duration' },\n },\n filters: { mode: 'serial', bank: [{ type: 'bandpass', q: 3, frequency: { set: typeof base === 'number' ? base * 3 : { ...base, scale: 3 } } }] },\n envelope: [\n [0, 0, 'set'],\n [0.15, 0.25, 'linear'],\n ['1d', 0.001, 'exp', 'fixed'],\n ],\n})\n\nconst groan: SoundRecipe = {\n id: 'groan',\n bus: 'voices',\n order: 'groan',\n vars: { base: [95, 135], dur: [0.9, 1.5] },\n duration: { param: 'dur' },\n layers: [groanLayer({ param: 'base' })],\n falloff: DISTANCE_CURVES.game_voice,\n sources: ['jogo:L62143-62155 gemido'],\n}\n\nconst runnerGroan: SoundRecipe = {\n id: 'runner_groan',\n bus: 'voices',\n order: 'groan',\n vars: { dur: [0.9, 1.5] },\n duration: { param: 'dur' },\n layers: [groanLayer(300)],\n falloff: DISTANCE_CURVES.game_voice,\n sources: ['jogo:L62143-62155 corredor'],\n}\n\nconst call = (id: string, options: { count: number; spacing: number; seconds: number; wave: OscillatorType; frequency: number; drop: number }): SoundRecipe => ({\n id,\n bus: 'world',\n order: 'calls',\n duration: options.seconds,\n tail: 0.02,\n keepSilent: true,\n layers: [\n {\n repeat: { count: options.count, spacing: options.spacing },\n source: { kind: 'osc', wave: options.wave, frequency: { from: options.frequency, to: options.frequency * options.drop, curve: 'exp', over: 'duration' } },\n filters: { mode: 'serial', bank: [{ type: 'bandpass', frequency: { set: options.frequency * 1.2 }, q: 3 }] },\n envelope: [\n [0, 0.0001, 'set', 'fixed'],\n [0.015, 1, 'exp'],\n ['1d', 0.0001, 'exp', 'fixed'],\n ],\n },\n ],\n falloff: DISTANCE_CURVES.animals,\n sources: ['jogo:L66625-66639'],\n})\n\n/** The crowd's sound bank: register it in the host's engine (`host.audio.register`) and the crowd's and the herd's sound ids play. */\nexport const CROWD_SOUND_BANK: SoundBank = {\n id: 'crowd',\n sounds: [\n scream,\n groan,\n runnerGroan,\n call('dog_bark', { count: 2, spacing: 0.22, seconds: 0.12, wave: 'square', frequency: 520, drop: 0.6 }),\n call('lapwing_call', { count: 3, spacing: 0.14, seconds: 0.09, wave: 'square', frequency: 2400, drop: 0.6 }),\n call('hen_cluck', { count: 4, spacing: 0.14, seconds: 0.09, wave: 'square', frequency: 900, drop: 0.6 }),\n call('cow_moo', { count: 1, spacing: 0.14, seconds: 1.2, wave: 'sawtooth', frequency: 140, drop: 0.8 }),\n ],\n}\n\n/** The herd's sound ids (`HERD_ROLES`) to the bank's recipes; the crowd's own ids (`groan`, `runner_groan`, `scream_hoarse`) are the recipes' ids already. */\nexport const HERD_SOUND_IDS: Readonly<Record<string, string>> = { bark: 'dog_bark', lapwing: 'lapwing_call', cluck: 'hen_cluck', moo: 'cow_moo' }\n","import type { Flock, Herd, HerdAnimal } from '@adatechnology/game-crowd'\nimport type * as THREE_NS from 'three'\n\n/** One drawn animal, as `game-animals-three` builds it (structural: this package does not depend on it). */\nexport type DrawnAnimal = {\n readonly root: THREE_NS.Object3D\n readonly wings: readonly { readonly shoulder: THREE_NS.Object3D; readonly elbow: THREE_NS.Object3D; readonly side: number }[]\n phase: number\n}\n\n/** What draws the animals: `game-animals-three`'s `createAnimalsThree(THREE)` is one as it is. */\nexport type AnimalDrawer<TSpecies = unknown> = {\n build(species: TSpecies, options?: { readonly phase?: number }): DrawnAnimal\n animate(rig: DrawnAnimal, params: { readonly time: number; readonly delta: number; readonly clip: string }): void\n setVisualState?(rig: DrawnAnimal, state: 'alive' | 'infected' | 'dead'): void\n}\n\nexport type HerdViewOptions<TSpecies> = {\n readonly herd: Herd\n readonly drawer: AnimalDrawer<TSpecies>\n /** The species card of an animal's species id (`game-animals-species` `getSpecies`). */\n readonly species: (id: string) => TSpecies | undefined\n /** The vultures: the flock that moves the herd's sky animals, in the order they were added. */\n readonly flock?: Flock\n}\n\nexport type HerdView = {\n readonly group: THREE_NS.Group\n /** Builds what is new in the herd and moves every drawn animal to its place this frame (G 66697-66708). */\n update(dt: number): void\n readonly count: number\n clear(): void\n}\n\n/**\n * The herd drawn with the animals' own rigs: each animal where `game-crowd`'s herd put it, turned to its heading and animated with its clip (G 66697\n * `E.pele.mesh.position.set(E.x, 0, E.z)`, `animQuad`); the vultures where the flock puts them, gliding with the wings half open (G 66704-66708).\n */\nexport function createHerdView<TSpecies>(three: { readonly Group: new () => THREE_NS.Group }, options: HerdViewOptions<TSpecies>): HerdView {\n const group = new three.Group()\n group.name = 'herd'\n const drawn = new Map<HerdAnimal, DrawnAnimal>()\n const sky: HerdAnimal[] = []\n const build = (E: HerdAnimal): DrawnAnimal | null => {\n const species = options.species(E.spec.species)\n if (!species) return null\n const rig = options.drawer.build(species)\n rig.root.position.set(E.x, 0, E.z)\n if (E.dead) options.drawer.setVisualState?.(rig, 'dead')\n group.add(rig.root)\n drawn.set(E, rig)\n if (E.spec.sky) sky.push(E)\n return rig\n }\n return {\n group,\n update(dt) {\n for (const E of options.herd.list) if (!drawn.has(E)) build(E)\n const time = options.herd.time\n for (const [E, rig] of drawn) {\n if (E.spec.sky) continue\n rig.root.position.set(E.x, 0, E.z)\n rig.root.rotation.y = E.yaw\n options.drawer.animate(rig, { time, delta: dt, clip: E.clip })\n }\n sky.forEach((E, i) => {\n const rig = drawn.get(E)\n const U = options.flock?.birds[i]\n if (!rig || !U) return\n rig.root.position.set(U.x, U.y, U.z)\n rig.root.rotation.set(0, U.yaw, U.roll)\n rig.root.visible = U.visible\n if (!U.visible) return\n rig.phase = U.wing\n for (const w of rig.wings) {\n w.shoulder.rotation.y = 0\n w.elbow.rotation.y = 0\n w.shoulder.rotation.z = w.side * (0.18 + Math.sin(U.wing * 0.4) * 0.05)\n }\n })\n },\n get count() {\n return drawn.size\n },\n clear() {\n for (const rig of drawn.values()) group.remove(rig.root)\n drawn.clear()\n sky.length = 0\n },\n }\n}\n","import { INSTANCE_POSES, walkGait } from '@adatechnology/game-characters'\nimport type { InstancePose } from '@adatechnology/game-characters'\nimport { STAGGER_POSE } from '@adatechnology/game-characters-three'\nimport { MISSING, STATE } from '@adatechnology/game-crowd'\nimport type { Civilian, Corpse, CrowdStore } from '@adatechnology/game-crowd'\n\nimport defaults from './data/render.json'\nimport { VARIETY_DEFAULTS, isStaggering, lookOfAgent, packLook } from './variety/look'\nimport type { CrowdVarietyNumbers } from './variety/look'\n\nexport type CrowdRenderNumbers = typeof defaults.numbers\nexport type CrowdPoseMap = { readonly [K in keyof typeof defaults.poses]: InstancePose }\n\n/** The game's numbers for the drawing (G 67098 `hordeRender`, G 70177 `npcRender`) and the instance pose of each state. */\nexport const CROWD_RENDER_DEFAULTS: { readonly sources: Readonly<Record<string, string>>; readonly numbers: CrowdRenderNumbers; readonly poses: CrowdPoseMap } = {\n sources: defaults.sources,\n numbers: defaults.numbers,\n poses: defaults.poses as CrowdPoseMap,\n}\n\n/**\n * One body for a batch: the 12 numbers of the shader's `iA`, `iB` and `iC` (`a`: x, z, yaw, phase; `b`: height and build over the variant's,\n * stride, pose; `c`: missing parts, age look, arms, skin), the shirt colour as hex with the shade it is multiplied by, the eye colour (none:\n * no glow) and the ground height.\n */\nexport type CrowdInstance = {\n readonly a: readonly [number, number, number, number]\n readonly b: readonly [number, number, number, number]\n readonly c: readonly [number, number, number, number]\n readonly color: number\n readonly shade: number\n readonly eye: number | null\n readonly y: number\n /** The identity `iD` (with `variety`): wounds, trousers, gait style, accessories, clips, lean. See `packIdentity`. */\n readonly d?: readonly [number, number, number, number]\n /** The accessory bits of the look (with `variety`), so a renderer routes the instance to the accessory batches. */\n readonly accessories?: number\n /** The crowd type index of the agent (with `variety`). */\n readonly type?: number\n}\n\n/** A baked variant as the drawing reads it: its own height and build (the instance scales the agent's against them). */\nexport type VariantSize = { readonly s: number; readonly bulk: number }\n\n/** Where the frame is seen from. `target` is who the agents attack (the attack pose); `hidden` leaves an agent out (a floor the viewer is not on). */\nexport type CrowdFrame = {\n readonly camera: { readonly x: number; readonly z: number }\n /** The view's yaw: forward is `(-sin, -cos)`. */\n readonly viewYaw: number\n readonly target?: { readonly x: number; readonly z: number; readonly alive: boolean } | null\n readonly hidden?: (i: number) => boolean\n /** How much of the level budget to use this frame, 0..1 (default 1); the renderer lowers it when the frames run long. */\n readonly detailScale?: number\n}\n\n/** Takes one instance for the batch of `variant` at level `level` (0 near, 1 middle, 2 far). */\nexport type CrowdInstanceSink = (variant: number, level: number, instance: CrowdInstance) => void\n/** Takes one body on the ground that was not an agent (a civilian killed outright): the plain body batch. */\nexport type PlainCorpseSink = (instance: CrowdInstance) => void\n\n/** The level of detail after the three meshes: the impostor (with `variety.impostorFrom`). */\nexport const IMPOSTOR_LEVEL = 3\n\n/** The width of a distance bin when a level budget fits the edges, and the most an edge moves in a frame (in, out). */\nconst BUDGET_BIN = 0.25\n/** The distance bins the bodies are ordered by (half a metre each), the last one holding everything past them; the culled bodies (distance -1) go first and are skipped. */\nconst SORT_BINS = 130\nconst sortBin = (distance: number): number => (distance < 0 ? 0 : Math.min(SORT_BINS - 1, 1 + Math.floor(distance * 2)))\n/** The distance out to which the bodies on the ground are counted when a budget fits their levels. */\nconst CORPSE_REACH = 60\nconst EDGE_SHRINK = 0.3\nconst EDGE_GROW = 0.15\n\nconst poseIndex = (pose: InstancePose): number => INSTANCE_POSES.indexOf(pose)\n\n/** The clip family of a gait style (the order of `SEGMENT_CLIPS`: walk, limp left, limp right, drag, lurch, shamble) and the stagger after them. */\nconst STAGGER_FAMILY = 6\n\n/** The clips of an agent: its family's arms-down and arms-up clips, blended by how far it has raised its arms. */\nconst clipsOf = (store: CrowdStore, i: number, staggering: boolean): { readonly clips: true; readonly clipA: number; readonly clipB: number; readonly clipBlend: number } => {\n const family = staggering ? STAGGER_FAMILY : Math.min(store.gaitStyle[i]!, STAGGER_FAMILY - 1)\n return { clips: true, clipA: family * 2, clipB: family * 2 + 1, clipBlend: Math.min(1, Math.max(0, store.arms[i]!)) }\n}\n\nconst lookFields = (store: CrowdStore, i: number, numbers: CrowdVarietyNumbers, clips: boolean, staggering: boolean): Pick<CrowdInstance, 'd' | 'accessories' | 'type'> => {\n const look = lookOfAgent(store, i, numbers, clips ? clipsOf(store, i, staggering) : {})\n return { d: packLook(look), accessories: look.accessories, type: store.type[i]! }\n}\n\nexport type CrowdInstancesOptions = {\n readonly numbers?: Partial<CrowdRenderNumbers>\n readonly poses?: Partial<CrowdPoseMap>\n /** The eye colour of each crowd type, by type index (G `_eye`); null for a type that has none. */\n readonly eyes: readonly (number | null)[]\n /** Identity for every agent (T4b.7), default off: each instance carries `d`, `accessories` and `type`, and the stagger pose; the game's numbers do not change. */\n readonly variety?: { readonly numbers?: Partial<CrowdVarietyNumbers>; readonly impostorFrom?: number; readonly segmentClips?: boolean; readonly budget?: readonly number[] }\n}\n\nexport type CrowdInstances = {\n readonly numbers: CrowdRenderNumbers\n /** Writes the agents seen this frame, keeps each one's level of detail and attack pose in the store (`lod`, `attackPose`) and returns how many went out. */\n agents(store: CrowdStore, variants: readonly VariantSize[], frame: CrowdFrame, sink: CrowdInstanceSink): number\n /** Writes the bodies on the ground: an agent's on its variant, the others on the plain batch. `life` is the seconds a body lasts (the crowd's `corpseSeconds`). */\n corpses(entries: readonly { readonly age: number; readonly data: Corpse }[], variants: readonly VariantSize[], frame: CrowdFrame, life: number, sink: CrowdInstanceSink, plain: PlainCorpseSink): void\n /** Writes the civilians that are still people (not dead, turned or gone); `colorOf` gives each one's shirt. */\n civilians(list: readonly Civilian[], colorOf: (civilian: Civilian) => number, sink: (civilian: Civilian, instance: CrowdInstance) => void): void\n}\n\n/**\n * The drawing of a crowd as instances, without three.js: a literal port of the team game's `hordeRender` (G 67098-67136) and `npcRender`\n * (G 70177-70184). The renderer of `game-crowd-three` hands each instance to a `BodyBatch` of `game-characters-three`; any other drawing can take them.\n */\nexport function createCrowdInstances(options: CrowdInstancesOptions): CrowdInstances {\n const N: CrowdRenderNumbers = { ...defaults.numbers, ...options.numbers }\n const P: CrowdPoseMap = { ...(defaults.poses as CrowdPoseMap), ...options.poses }\n const pose = {\n dormant: poseIndex(P.dormant),\n airborne: poseIndex(P.airborne),\n eating: poseIndex(P.eating),\n pileStep: poseIndex(P.pileStep),\n swing: poseIndex(P.swing),\n crawl: poseIndex(P.crawl),\n grab: poseIndex(P.grab),\n calling: poseIndex(P.calling),\n walk: poseIndex(P.default),\n corpse: poseIndex(P.corpse),\n civilian: poseIndex(P.civilian),\n }\n const [near, middle] = N.lodDistances as unknown as [number, number]\n const variety = options.variety ? { ...VARIETY_DEFAULTS, ...options.variety.numbers } : null\n const impostorFrom = options.variety?.impostorFrom\n const segmentClips = options.variety?.segmentClips === true\n const lodEdges = impostorFrom === undefined ? [near, middle] : [near, middle, impostorFrom]\n const lastLevel = lodEdges.length\n const budget = options.variety?.budget\n // the edges a crowd packed near the camera is drawn with: the nominal ones pulled in until each level holds the bodies its budget allows\n const edges = [...lodEdges]\n const bands = lodEdges.map(() => N.lodHysteresis)\n const histogram = new Uint32Array(budget ? Math.max(1, Math.ceil(lodEdges[lastLevel - 1]! / BUDGET_BIN) + 1) : 0)\n let distances = new Float32Array(0)\n let order = new Uint32Array(0)\n const sortStarts = new Uint32Array(SORT_BINS + 1)\n const behindFrom = N.behindFrom\n const farSquared = N.farCull * N.farCull\n\n /** Pulls each edge in to the distance inside which the levels up to it hold their budget (scaled), and lets it move a few centimetres a frame so a body does not flip levels at once. */\n const fitEdges = (scale: number): void => {\n let allowed = 0\n let seen = 0\n let bin = 0\n let previous = 0\n for (let level = 0; level < lastLevel; level++) {\n allowed += Math.round((budget![level] ?? Infinity) * scale)\n while (bin < histogram.length && seen + histogram[bin]! <= allowed) seen += histogram[bin++]!\n const reach = bin < histogram.length ? bin * BUDGET_BIN : lodEdges[level]!\n const target = Math.max(previous, Math.min(lodEdges[level]!, reach))\n edges[level] = Math.min(edges[level]! + EDGE_GROW, Math.max(edges[level]! - EDGE_SHRINK, target))\n // an edge pulled in close keeps a proportional band, or the bodies inside the nominal band would never leave the level\n bands[level] = N.lodHysteresis * Math.min(1, edges[level]! / lodEdges[level]!)\n previous = target\n }\n }\n\n /** Orders the agents by distance into `order` (a counting sort), so a batch draws its nearest bodies first and the depth test throws the hidden fragments away before they are shaded. */\n const nearestFirst = (count: number): void => {\n sortStarts.fill(0)\n for (let i = 0; i < count; i++) sortStarts[sortBin(distances[i]!) + 1]!++\n for (let b = 0; b < SORT_BINS; b++) sortStarts[b + 1]! += sortStarts[b]!\n for (let i = 0; i < count; i++) order[sortStarts[sortBin(distances[i]!)]!++] = i\n }\n const corpseHistogram = new Uint32Array(budget ? Math.ceil(CORPSE_REACH / BUDGET_BIN) + 1 : 0)\n /** The two distances that split the bodies on the ground into the near mesh, the middle one and the far one: the nominal edge and none, pulled in until each level holds no more than its share of the budget (the fourth and fifth numbers, default half the near and the middle). */\n const fitCorpseEdges = (entries: readonly { readonly data: Corpse }[], cx: number, cz: number, scale: number): readonly [number, number] => {\n if (!budget) return [N.corpseNear, Infinity]\n corpseHistogram.fill(0)\n for (const { data } of entries) {\n const distance = Math.hypot(data.x - cx, data.z - cz)\n if (distance < CORPSE_REACH) corpseHistogram[Math.floor(distance / BUDGET_BIN)]!++\n }\n let seen = 0\n let bin = 0\n const edgeFor = (allowed: number, nominal: number): number => {\n while (bin < corpseHistogram.length && seen + corpseHistogram[bin]! <= allowed) seen += corpseHistogram[bin++]!\n return bin < corpseHistogram.length ? Math.min(nominal, bin * BUDGET_BIN) : nominal\n }\n const near = edgeFor(Math.round((budget[3] ?? (budget[0] ?? Infinity) / 2) * scale), N.corpseNear)\n const middle = edgeFor(Math.round(((budget[3] ?? (budget[0] ?? Infinity) / 2) + (budget[4] ?? (budget[1] ?? Infinity) / 2)) * scale), Infinity)\n return [near, Math.max(near, middle)]\n }\n\n return {\n numbers: N,\n agents(Z, variants, frame, sink) {\n const cx = frame.camera.x\n const cz = frame.camera.z\n const fx = -Math.sin(frame.viewYaw)\n const fz = -Math.cos(frame.viewYaw)\n const target = frame.target\n let written = 0\n if (distances.length < Z.n) distances = new Float32Array(Math.max(Z.n, distances.length * 2))\n if (budget) histogram.fill(0)\n for (let i = 0; i < Z.n; i++) {\n const dx = Z.x[i]! - cx\n const dz = Z.z[i]! - cz\n const d2 = dx * dx + dz * dz\n distances[i] = -1\n if (d2 > behindFrom && dx * fx + dz * fz < -Math.sqrt(d2) * N.behindFactor - N.behindMargin) continue // behind the view\n if (d2 > farSquared) continue\n if (frame.hidden?.(i)) continue\n const seen = Math.sqrt(d2)\n distances[i] = seen\n if (budget && seen < lodEdges[lastLevel - 1]!) histogram[Math.floor(seen / BUDGET_BIN)]!++\n }\n if (budget) fitEdges(frame.detailScale ?? 1)\n if (budget) {\n if (order.length < Z.n) order = new Uint32Array(distances.length)\n nearestFirst(Z.n)\n }\n for (let k = 0; k < Z.n; k++) {\n const i = budget ? order[k]! : k\n const dd = distances[i]!\n if (dd < 0) continue\n // the level of detail with hysteresis: a body does not keep switching meshes on the edge\n let l = Z.lod[i]!\n while (l > 0 && dd < edges[l - 1]! - bands[l - 1]!) l--\n while (l < lastLevel && dd > edges[l]! + bands[l]!) l++\n Z.lod[i] = l\n const sp = Z.renderSpeed[i]!\n const gait = Math.min(N.gaitMax, walkGait(sp, Z.height[i]!))\n const st = Z.state[i]!\n // the attack pose by distance with hysteresis (in at 1.6 m, out at 2.2 m): it does not flicker between walking and striking\n if (st === STATE.CHASE && target?.alive) {\n const px = Z.x[i]! - target.x\n const pz = Z.z[i]! - target.z\n const p2 = px * px + pz * pz\n Z.attackPose[i] = p2 < (Z.attackPose[i] ? N.attackLeave : N.attackEnter) ? 1 : 0\n } else Z.attackPose[i] = 0\n const p =\n st === STATE.DORMANT\n ? pose.dormant\n : st === STATE.AIRBORNE\n ? pose.airborne\n : st === STATE.EATING\n ? pose.eating\n : st === STATE.PILE_STEP\n ? pose.pileStep\n : st === STATE.SWING\n ? pose.swing\n : Z.crawl[i]\n ? pose.crawl\n : st === STATE.GRAB || Z.attackPose[i]\n ? pose.grab\n : st === STATE.CALLING\n ? pose.calling\n : pose.walk\n const staggering = variety !== null && p === pose.walk && isStaggering(Z, i)\n const bb = st === STATE.SWELLING ? Z.build[i]! * (1 + (N.swellPivot - Z.stateTimer[i]!) * N.swell) : Z.build[i]!\n const eyeOn = !(Z.missing[i]! & MISSING.SKULL)\n const V = variants[Z.variant[i]!]!\n // the impostor only draws a body that walks (the atlas holds the walk); any other pose stays on the far mesh\n const level = l === IMPOSTOR_LEVEL && p !== pose.walk ? IMPOSTOR_LEVEL - 1 : l\n sink(Z.variant[i]!, level, {\n a: [Z.x[i]!, Z.z[i]!, Z.renderYaw[i]!, Z.phase[i]!],\n b: [Z.height[i]! / V.s, bb / V.bulk, gait, staggering ? STAGGER_POSE : p],\n c: [Z.missing[i]!, N.ageBase + Z.age[i]! * N.agePer, N.armBase + N.armPer * Z.arms[i]!, Z.skin[i]!],\n color: Z.color[i]!,\n shade: 1,\n eye: eyeOn && st !== STATE.DORMANT ? (options.eyes[Z.type[i]!] ?? null) : null,\n y: Z.y[i]!,\n ...(variety ? lookFields(Z, i, variety, segmentClips, staggering) : {}),\n })\n written++\n }\n return written\n },\n corpses(entries, variants, frame, life, sink, plain) {\n const cx = frame.camera.x\n const cz = frame.camera.z\n const [nearEdge, middleEdge] = fitCorpseEdges(entries, cx, cz, frame.detailScale ?? 1)\n for (const { age: t, data: C } of entries) {\n const dark = Math.min(1, t / life)\n const shade = 1 - dark * N.corpseDarken\n const fade = t > life - N.corpseFade ? (life - t) / N.corpseFade : 1\n const c: CrowdInstance['c'] = [C.missing, N.corpseAgeBase + dark * N.corpseAgeDark, 1, C.skin]\n if (C.variant >= 0) {\n // an agent's body: the same mesh as its variant, lying down\n const V = variants[C.variant]!\n const dx = C.x - cx\n const dz = C.z - cz\n const distance = Math.hypot(dx, dz)\n const l = distance < nearEdge ? 0 : distance < middleEdge ? 1 : 2\n sink(C.variant, l, { a: [C.x, C.z, C.yaw, C.seed], b: [(C.height / V.s) * fade, C.build / V.bulk, Math.min(1, t * N.corpseRise), pose.corpse], c, color: C.color, shade, eye: null, y: 0 })\n continue\n }\n plain({ a: [C.x, C.z, C.yaw, C.seed], b: [C.height * fade, C.build, Math.min(1, t * N.corpseRise), pose.corpse], c, color: C.color, shade, eye: null, y: 0 })\n }\n },\n civilians(list, colorOf, sink) {\n for (const n of list) {\n if (n.state === 'undead' || n.state === 'gone' || n.state === 'dead') continue\n const sp = Math.hypot(n.vx, n.vz)\n const child = !!n.spec.child\n sink(n, {\n a: [n.x, n.z, n.yaw, n.phase],\n b: [child ? N.childHeight : 1, child ? N.childBuild : 1, Math.min(N.gaitMax, walkGait(sp, child ? N.childHeight : 1)), pose.civilian],\n c: [0, n.biteTimer > 0 ? N.bittenLook : 0, 0, n.k * N.civilianSkinStep],\n color: colorOf(n),\n shade: 1,\n eye: null,\n y: 0,\n })\n }\n },\n }\n}\n","{\n \"sources\": {\n \"agents\": \"jogo.js G 67098-67121 hordeRender: view cull (behind beyond 0.35·d + 3 m once past √30 m, nothing past 200 m), LOD [18, 55] m with 1.5 m of hysteresis, attack pose in at 1.6 m and out at 2.2 m, the pose by state, the bloater's swelling, the eye only with the skull and awake\",\n \"corpses\": \"jogo.js G 67122-67131 hordeRender: an agent's body on its variant at the near level within 18 m (else the middle), the fallen pose, the colour darkening 70% over the body's life, the last 60 s shrinking it; a body that was not an agent on the plain body batch\",\n \"civilians\": \"jogo.js G 70177-70184 npcRender: one baked body per survivor, a child 0.66 high and 0.75 wide, the bite showing as 0.3 of age\",\n \"batches\": \"jogo.js G 67079-67094 ZVAR, CB: each variant at 1, 0.5 and 0.28 of detail in batches of 160, 700 and 2600; the plain corpse batch at the middle body (BODY_LOD[1]) for 400; G 68469 PB: survivors baked at 0.8 in batches of 4\"\n },\n \"numbers\": {\n \"lodDistances\": [18, 55],\n \"lodHysteresis\": 1.5,\n \"behindFrom\": 30,\n \"behindFactor\": 0.35,\n \"behindMargin\": 3,\n \"farCull\": 200,\n \"gaitMax\": 1.4,\n \"attackEnter\": 2.56,\n \"attackLeave\": 4.84,\n \"swell\": 0.9,\n \"swellPivot\": 0.5,\n \"ageBase\": 0.75,\n \"agePer\": 0.08,\n \"armBase\": 1,\n \"armPer\": 0.4,\n \"corpseNear\": 18,\n \"corpseFade\": 60,\n \"corpseDarken\": 0.7,\n \"corpseRise\": 1.8,\n \"corpseAgeBase\": 0.8,\n \"corpseAgeDark\": 0.2,\n \"childHeight\": 0.66,\n \"childBuild\": 0.75,\n \"bittenLook\": 0.3,\n \"civilianSkinStep\": 0.25,\n \"civilianBake\": 0.8,\n \"civilianBatch\": 4\n },\n \"poses\": {\n \"dormant\": \"fallen\",\n \"airborne\": \"leap\",\n \"eating\": \"eat\",\n \"pileStep\": \"attack\",\n \"swing\": \"scream\",\n \"crawl\": \"crawl\",\n \"grab\": \"attack\",\n \"calling\": \"scream\",\n \"default\": \"walk\",\n \"corpse\": \"fallen\",\n \"civilian\": \"walk\"\n }\n}\n","import { BALANCE, unit } from '@adatechnology/game-crowd'\nimport type { CrowdStore } from '@adatechnology/game-crowd'\nimport { ACCESSORY_BIT, packIdentity } from '@adatechnology/game-characters-three'\nimport type { IdentityLook } from '@adatechnology/game-characters-three'\n\n/** The numbers of the look a body is given from its identity (T4b.7, D11). Every one is a default a game can change. */\nexport const VARIETY_DEFAULTS = {\n capChance: 0.16,\n backpackChance: 0.2,\n hoodChance: 0.1,\n /** Chance of a wound in a region at the youngest infection age, and how much each age step adds. */\n woundBase: 0.05,\n woundPerAge: 0.12,\n /** Share of the wounds that are severe. */\n severeShare: 0.35,\n /** Steps of the infection age of the pack (0 .. ageSteps). */\n ageSteps: 3,\n /** How much of a shove's push (0..1) tilts the body. */\n leanScale: 0.3,\n} as const\n\nexport type CrowdVarietyNumbers = { readonly [K in keyof typeof VARIETY_DEFAULTS]: number }\n\n/** One salt per use, so the draws of the same agent stay independent (the physics salts of `game-crowd` are its own). */\nexport const LOOK_SALT = { TROUSERS: 0x7a101, CAP: 0x7a202, BACKPACK: 0x7a303, HOOD: 0x7a404, WOUND: 0x7a505, FRESH: 0x7a606 } as const\n\nconst REGIONS = 6\nconst TROUSER_COUNT = 16\nconst WOUND_BITS = 2\nconst FRESHEST = 15\nconst FRESH_STEPS = 12\nconst LEAN_MIN = 0.02\n\n/** The wound bits of the six regions: the game's own (`store.wounds`) or, where it has none, a draw that grows with the infection age. */\nconst woundsOf = (store: CrowdStore, i: number, identity: number, ageNorm: number, N: CrowdVarietyNumbers): number => {\n const own = store.wounds[i]!\n const chance = N.woundBase + N.woundPerAge * ageNorm\n let wounds = 0\n for (let region = 0; region < REGIONS; region++) {\n const draw = unit(identity, region, LOOK_SALT.WOUND)\n const drawn = draw < chance * N.severeShare ? 2 : draw < chance ? 1 : 0\n wounds |= Math.max((own >> (region * WOUND_BITS)) & 3, drawn) << (region * WOUND_BITS)\n }\n return wounds\n}\n\nconst accessoriesOf = (store: CrowdStore, i: number, identity: number, N: CrowdVarietyNumbers): number => {\n let bits = store.helmet[i] ? ACCESSORY_BIT.HELMET : unit(identity, 0, LOOK_SALT.CAP) < N.capChance ? ACCESSORY_BIT.CAP : 0\n if (!bits && unit(identity, 0, LOOK_SALT.HOOD) < N.hoodChance) bits |= ACCESSORY_BIT.EXTRA\n if (unit(identity, 0, LOOK_SALT.BACKPACK) < N.backpackChance) bits |= ACCESSORY_BIT.BACKPACK\n return bits\n}\n\n/** Lean toward the push, in the body's own frame, from the store's lean (the push over its cap). */\nconst leanOf = (store: CrowdStore, i: number, N: CrowdVarietyNumbers): { readonly leanAngle: number; readonly leanAmount: number } => {\n const lx = store.leanX[i]!\n const lz = store.leanZ[i]!\n const size = Math.min(1, Math.hypot(lx, lz))\n if (size < LEAN_MIN) return { leanAngle: 0, leanAmount: 0 }\n const yaw = store.renderYaw[i]!\n const cos = Math.cos(yaw)\n const sin = Math.sin(yaw)\n return { leanAngle: Math.atan2(cos * lx - sin * lz, sin * lx + cos * lz), leanAmount: size * N.leanScale }\n}\n\n/** The whole look of an agent, all of it from its identity and its state in the store: it never changes with the level of detail. */\nexport const lookOfAgent = (store: CrowdStore, i: number, N: CrowdVarietyNumbers, extra: Pick<IdentityLook, 'clipA' | 'clipB' | 'clipBlend' | 'clipSpeed' | 'clips'> = {}): IdentityLook => {\n const identity = store.identity[i]!\n const ageNorm = Math.min(1, store.age[i]! / N.ageSteps)\n const wounds = woundsOf(store, i, identity, ageNorm, N)\n const fresh = store.wounds[i]! ? FRESHEST : Math.max(0, Math.min(FRESHEST, FRESHEST - Math.round(ageNorm * FRESH_STEPS) + Math.floor(unit(identity, 0, LOOK_SALT.FRESH) * 4)))\n return {\n wounds,\n freshness: fresh,\n trousers: Math.floor(unit(identity, 0, LOOK_SALT.TROUSERS) * TROUSER_COUNT),\n gaitStyle: store.gaitStyle[i]!,\n accessories: accessoriesOf(store, i, identity, N),\n ...leanOf(store, i, N),\n ...extra,\n }\n}\n\nexport const isStaggering = (store: CrowdStore, i: number): boolean => store.balance[i] === BALANCE.STAGGERING\n\nexport const packLook = (look: IdentityLook): readonly [number, number, number, number] => packIdentity(look)\n","import { variantDecay, variantSeed } from '@adatechnology/game-characters'\nimport type { Civilian, Crowd, CrowdType } from '@adatechnology/game-crowd'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport { KIT_ACCESSORIES, createSegmentClipUniforms, LOD_BAKE, LOD_SEGMENTS, accessoryPlacement, bakeBody, bakeImpostorAtlas, buildInstancedBody, buildKitAccessory, createBlobShadowBatch, createBodyBatch, createImpostorBatch, createVariantBatches } from '@adatechnology/game-characters-three'\nimport type { BakeBuilders, BakeSpec, BakedBody, BlobShadowBatch, BodyBatch, BodyVariant, ImpostorAtlas, ImpostorBatch, KitAccessory, SegmentClipUniforms, Three } from '@adatechnology/game-characters-three'\nimport type * as THREE_NS from 'three'\n\nimport { createGpuCostProbe } from './gpu-cost'\nimport { IMPOSTOR_LEVEL, createCrowdInstances } from './instances'\nimport type { CrowdFrame, CrowdInstance, CrowdInstances, CrowdPoseMap, CrowdRenderNumbers } from './instances'\nimport type { CrowdVarietyNumbers } from './variety/look'\n\n/** Variety on the instanced path (T4b.7, D11 and D12): identity for every body, accessories, real shadows only near and blobs beyond. Absent, the renderer is the game's. */\nexport type CrowdRendererVariety = {\n readonly numbers?: Partial<CrowdVarietyNumbers>\n /** The accessory batches, drawn by the kit's builders (default `KIT_ACCESSORIES`); `false` for none. */\n readonly accessories?: readonly KitAccessory[] | false\n /** Instances an accessory batch holds at the near and the middle level (default 480 and 1400). */\n readonly accessoryCapacity?: readonly [number, number]\n /** Only the nearest level casts a real shadow (default true). */\n readonly nearShadows?: boolean\n /** Draws the depth of the near level first so its lit pass shades each pixel once (default true): the room's lights make an overdrawn fragment the dearest part of a crowd close to the camera. */\n readonly nearDepthPrepass?: boolean\n /** One dark disc under each body beyond the nearest level (default true). */\n readonly blobShadows?: boolean\n /** Walk the bodies of the near and middle levels from the clip texture (12 bones, 24 texels, nearest filtered; step 3 of the ladder). Default off: the shader's own walk. */\n readonly segmentClips?: boolean\n /**\n * How many bodies each mesh level may draw (default 160, 320 and 600 for the near, middle and far levels, and half of the near budget for the bodies on the ground that keep the near mesh; `false` for the nominal distances only). A crowd packed near the camera pulls the edges in,\n * so the bodies past a level's budget draw at the next one, and the last go to the impostor. Under `adapt` the budget shrinks while the crowd takes the GPU longer than `gpuHighMs` and grows back under `gpuLowMs` (timer queries; where the\n * GPU has none, while the frames run longer than `highMs` and back under `lowMs`).\n */\n readonly budget?: false | { readonly levels?: readonly number[]; readonly adapt?: false | { readonly gpuHighMs?: number; readonly gpuLowMs?: number; readonly highMs?: number; readonly lowMs?: number; readonly minScale?: number } }\n /** The far tier (default on, from 90 m): one atlas for every type, one draw call; `false` keeps the far mesh to the cull distance. */\n readonly impostor?: false | { readonly from?: number; readonly capacity?: number; readonly light?: { readonly r: number; readonly g: number; readonly b: number } }\n}\n\nexport type CrowdRendererOptions = {\n readonly crowd: Crowd\n /** The rich builders the bodies are baked from (`game-characters-three`: the Bestiário builder, optionally the survivors'). */\n readonly builders: BakeBuilders\n /** The name the rich builder knows a crowd type by (default its id). */\n readonly typeName?: (type: CrowdType, index: number) => string\n /** The civilians to draw and the body each one is baked from (G 68469 `PB`: a human spec or a portrait). Without it no civilian is drawn. */\n readonly civilians?: { readonly list: () => readonly Civilian[]; readonly body: (civilian: Civilian) => BakeSpec; readonly color?: (civilian: Civilian) => number }\n /** The plain body for bodies on the ground that were not agents (default the instanced body at the middle level, G `BODY_LOD[1]`). */\n readonly plainBody?: THREE_NS.BufferGeometry\n /** Whether the bodies on the ground are drawn this frame (default always). */\n readonly drawCorpses?: () => boolean\n readonly numbers?: Partial<CrowdRenderNumbers>\n readonly poses?: Partial<CrowdPoseMap>\n readonly variety?: CrowdRendererVariety\n}\n\nexport type CrowdRenderer = {\n /** Holds every batch; add it to the scene. */\n readonly group: THREE_NS.Group\n readonly instances: CrowdInstances\n /** Bakes every type's variants now (otherwise a type is baked the first time one of its bodies is drawn). */\n bake(): void\n /**\n * Bakes and makes every batch the frame would make on demand (the bodies on the ground, the blob shadows, the impostors, the accessories of the near and middle levels), so that a host that compiles\n * its scene (`ProgramWarmup`) links the body, accessory, blob and impostor programs and their depth and distance materials before play, and no batch is made during it.\n */\n prepare(): void\n /** Draws the frame: the agents, the bodies on the ground and the civilians. */\n update(dt: number, frame: CrowdFrame): void\n /** Agents drawn at each level of detail in the last frame (G `lodCounts`). */\n readonly lodCounts: readonly [number, number, number]\n /** The share of the level budget in use, 1 down to the adaptive floor. */\n readonly detailScale: number\n /** The smoothed GPU time of the crowd's draws in milliseconds (0 until the timer answers, or without one). */\n readonly gpuMs: number\n /** Agents drawn as impostors in the last frame. */\n readonly impostorCount: number\n /** Batches with something to draw. */\n readonly drawCalls: number\n readonly bakeMs: number\n readonly variants: readonly BodyVariant[]\n dispose(): void\n}\n\nconst ACCESSORY_CAPACITY = [480, 1400] as const\nconst BLOB_CAPACITY = 4000\nconst IMPOSTOR_FROM = 90\nconst IMPOSTOR_CAPACITY = 4000\nconst NEAR_SHADOWS = [true, false, false] as const\nconst NEAR_PREPASS = [true, false, false] as const\nconst BUDGET_LEVELS = [160, 320, 600] as const\nconst ADAPT = { gpuHighMs: 3.5, gpuLowMs: 2.2, highMs: 24, lowMs: 19, minScale: 0.1, shrinkPerSecond: 1.2, growPerSecond: 0.5, smoothing: 0.1 } as const\n\nconst now = (): number => (typeof performance === 'undefined' ? Date.now() : performance.now())\n\n/**\n * The crowd drawn on the instanced path: every type's variants baked at the three levels of detail (G 67079 `ZVAR`, the variants and seeds of\n * `game-characters`), a few draw calls for thousands of agents, the bodies on the ground and the civilians. The instances are `createCrowdInstances`\n * (the port of `hordeRender` and `npcRender`); the batches are `game-characters-three`'s.\n */\nexport function createCrowdRenderer(three: Three, options: CrowdRendererOptions): CrowdRenderer {\n const { crowd } = options\n const group = markKitOrigin(new three.Group(), { owner: 'game-crowd-three', kind: 'person' })\n group.name = 'crowd'\n const time = { value: 0 }\n const eyes = crowd.pack.types.map((type) => type.eye ?? null)\n const variety = options.variety\n const accessoryKinds = variety ? (variety.accessories === false ? [] : (variety.accessories ?? KIT_ACCESSORIES)) : []\n const accessoryCapacity = variety?.accessoryCapacity ?? ACCESSORY_CAPACITY\n const nearShadows = variety ? (variety.nearShadows ?? true) : false\n const impostorOptions = variety && variety.impostor !== false ? (variety.impostor ?? {}) : null\n const budgetOptions = variety && variety.budget !== false ? (variety.budget ?? {}) : null\n const adaptOptions = budgetOptions && budgetOptions.adapt !== false ? { ...ADAPT, ...budgetOptions.adapt } : null\n let detailScale = 1\n let frameMs = 0\n let gpuMs = 0\n const probe = adaptOptions ? createGpuCostProbe() : null\n const tracked = new WeakSet<THREE_NS.Object3D>()\n const track = (mesh: THREE_NS.Object3D): void => {\n if (!probe || tracked.has(mesh)) return\n tracked.add(mesh)\n probe.attach(mesh)\n }\n const instances = createCrowdInstances({\n eyes,\n ...(options.numbers ? { numbers: options.numbers } : {}),\n ...(options.poses ? { poses: options.poses } : {}),\n ...(variety ? { variety: { ...(variety.numbers ? { numbers: variety.numbers } : {}), ...(impostorOptions ? { impostorFrom: impostorOptions.from ?? IMPOSTOR_FROM } : {}), ...(variety.segmentClips ? { segmentClips: true } : {}), ...(budgetOptions ? { budget: budgetOptions.levels ?? BUDGET_LEVELS } : {}) } } : {}),\n })\n const N = instances.numbers\n const variants: BodyVariant[] = []\n const batches: (readonly BodyBatch[])[] = []\n let plain: BodyBatch | null = null\n const people = new Map<string, BodyBatch>()\n const accessoryBatches = new Map<string, BodyBatch>()\n const accessoryGeometry = new Map<string, THREE_NS.BufferGeometry>()\n const placements = new Map<string, readonly [number, number, number, number]>()\n let blobs: BlobShadowBatch | null = null\n let atlas: ImpostorAtlas | null = null\n let impostors: ImpostorBatch | null = null\n let impostorCount = 0\n const clipUniforms: SegmentClipUniforms | null = variety?.segmentClips ? createSegmentClipUniforms(three) : null\n let bakeMs = 0\n const lodCounts: [number, number, number] = [0, 0, 0]\n const shirt = new three.Color()\n const eyeColors = new Map<number, THREE_NS.Color>()\n const eyeOf = (hex: number): THREE_NS.Color => {\n let color = eyeColors.get(hex)\n if (!color) eyeColors.set(hex, (color = new three.Color(hex)))\n return color\n }\n const push = (batch: BodyBatch | undefined, instance: CrowdInstance): void => {\n if (!batch) return\n shirt.setHex(instance.color).multiplyScalar(instance.shade)\n batch.push({ a: instance.a, b: instance.b, c: instance.c, color: shirt, ...(instance.eye !== null ? { eye: eyeOf(instance.eye) } : {}), y: instance.y, ...(instance.d ? { d: instance.d } : {}) })\n }\n const pushAccessories = (variant: number, level: number, instance: CrowdInstance): void => {\n const bits = instance.accessories ?? 0\n if (!bits || level > 1) return\n shirt.setHex(instance.color).multiplyScalar(instance.shade)\n for (const accessory of accessoryKinds) {\n if (!(bits & accessory.bit)) continue\n accessoryBatch(accessory, level).push({ a: instance.a, b: instance.b, c: instance.c, color: shirt, y: instance.y, ...(instance.d ? { d: instance.d } : {}), acc: placementOf(variant, level, accessory) })\n }\n }\n\n const accessoryBatch = (accessory: KitAccessory, level: number): BodyBatch => {\n const key = `${accessory.id}|${level}`\n const made = accessoryBatches.get(key)\n if (made) return made\n let geometry = accessoryGeometry.get(accessory.id)\n if (!geometry) accessoryGeometry.set(accessory.id, (geometry = buildKitAccessory(three, accessory)))\n const batch = createBodyBatch(three, geometry, { max: accessoryCapacity[level] ?? ACCESSORY_CAPACITY[1], castShadow: level === 0, time, accessory: true, ...(clipUniforms ? { segmentClips: clipUniforms } : {}) })\n accessoryBatches.set(key, batch)\n group.add(batch.mesh)\n return batch\n }\n const placementOf = (variant: number, level: number, accessory: KitAccessory): readonly [number, number, number, number] => {\n const key = `${variant}|${level}|${accessory.attach}`\n let placed = placements.get(key)\n if (!placed) placements.set(key, (placed = accessoryPlacement(variants[variant]!.geometries[level]!, accessory.attach)))\n return placed\n }\n /** The atlas holds one silhouette per type, from the far mesh of its first variant: every type is baked the first time a body is drawn as an impostor. */\n const ensureImpostors = (): ImpostorBatch => {\n if (impostors) return impostors\n bake()\n const bodies = crowd.pack.types.map((_, c) => {\n const variant = variants[crowd.variantsOf[c]![0]!]!\n return { geometry: variant.geometries[2]! }\n })\n atlas = bakeImpostorAtlas(three, bodies)\n impostors = createImpostorBatch(three, atlas, { max: impostorOptions?.capacity ?? IMPOSTOR_CAPACITY, ...(impostorOptions?.light ? { light: impostorOptions.light } : {}) })\n group.add(impostors.mesh)\n return impostors\n }\n const pushImpostor = (instance: CrowdInstance): void => {\n shirt.setHex(instance.color).multiplyScalar(instance.shade)\n ensureImpostors().push({ a: instance.a, scale: [instance.b[0], instance.b[1]], silhouette: instance.type ?? 0, y: instance.y, c: instance.c, color: shirt, ...(instance.d ? { d: instance.d } : {}) })\n impostorCount++\n }\n const ensureBlobs = (): BlobShadowBatch => {\n if (!blobs) {\n blobs = createBlobShadowBatch(three, { max: BLOB_CAPACITY })\n group.add(blobs.mesh)\n }\n return blobs\n }\n\n // the type of each global variant (G `ZVAR_OF` turned around), so a body is baked the first time one of its type is drawn\n const typeOfVariant: number[] = []\n crowd.variantsOf.forEach((list, c) => list.forEach((g) => (typeOfVariant[g] = c)))\n const baked = new Set<number>()\n const ensurePlain = (): BodyBatch => {\n if (!plain) {\n plain = createBodyBatch(three, options.plainBody ?? buildInstancedBody(three, { segments: LOD_SEGMENTS[1] }), { max: crowd.numbers.corpsesMax, castShadow: false, time })\n group.add(plain.mesh)\n }\n return plain\n }\n /** Bakes the variants of type `c` (G 67079: decay 1, 2, 1, 2 and the seed `7000 + c·101 + v·13`, at 1, 0.5 and 0.28 of detail). */\n const bakeType = (c: number): void => {\n if (baked.has(c)) return\n baked.add(c)\n const type = crowd.pack.types[c]!\n const name = options.typeName?.(type, c) ?? type.id\n const started = now()\n crowd.variantsOf[c]!.forEach((g, v) => {\n const decay = variantDecay(v)\n const seed = variantSeed(c, v)\n const bodies: BakedBody[] = LOD_BAKE.map((lod) => bakeBody(three, options.builders, { type: name, decay, seed }, lod))\n const variant: BodyVariant = { typeId: type.id, variant: v, seed, decay, s: bodies[0]!.s, bulk: bodies[0]!.bulk, verts: bodies.map((body) => body.verts), geometries: bodies.map((body) => body.geo) }\n variants[g] = variant\n batches[g] = createVariantBatches(three, variant, time, variety ? { identity: true, ...(clipUniforms ? { segmentClips: clipUniforms } : {}), ...(nearShadows ? { castsShadow: NEAR_SHADOWS } : {}), ...(variety.nearDepthPrepass ?? true ? { depthPrepass: NEAR_PREPASS } : {}) } : {})\n for (const batch of batches[g]!) group.add(batch.mesh, ...(batch.prepass ? [batch.prepass] : []))\n })\n bakeMs += now() - started\n }\n const bake = (): void => crowd.pack.types.forEach((_, c) => bakeType(c))\n const bakeSeen = (): void => {\n const Z = crowd.store\n for (let i = 0; i < Z.n; i++) if (!baked.has(Z.type[i]!)) bakeType(Z.type[i]!)\n for (const { data } of crowd.corpses.entries) if (data.variant >= 0 && !baked.has(typeOfVariant[data.variant]!)) bakeType(typeOfVariant[data.variant]!)\n }\n\n const personBatch = (civilian: Civilian): BodyBatch | undefined => {\n const made = people.get(civilian.id)\n if (made) return made\n const spec = options.civilians?.body(civilian)\n if (!spec) return undefined\n const batch = createBodyBatch(three, bakeBody(three, options.builders, spec, N.civilianBake).geo, { max: N.civilianBatch, time })\n people.set(civilian.id, batch)\n group.add(batch.mesh)\n return batch\n }\n\n const all = (): BodyBatch[] => [...batches.flatMap((set) => set ?? []), ...(plain ? [plain] : []), ...people.values(), ...accessoryBatches.values()]\n\n return {\n group,\n instances,\n bake,\n prepare() {\n bake()\n ensurePlain()\n if (!variety) return\n if (variety.blobShadows ?? true) ensureBlobs()\n if (impostorOptions) ensureImpostors()\n for (const accessory of accessoryKinds) for (const level of [0, 1]) accessoryBatch(accessory, level)\n },\n update(dt, frame) {\n if (adaptOptions && probe && dt > 0) {\n const measured = probe.poll()\n if (measured !== undefined) gpuMs += (measured - gpuMs) * (gpuMs === 0 ? 1 : adaptOptions.smoothing)\n frameMs += (dt * 1000 - frameMs) * (frameMs === 0 ? 1 : adaptOptions.smoothing)\n const [high, low, load] = measured === undefined ? ([adaptOptions.highMs, adaptOptions.lowMs, frameMs] as const) : ([adaptOptions.gpuHighMs, adaptOptions.gpuLowMs, gpuMs] as const)\n if (load > high) detailScale = Math.max(adaptOptions.minScale, detailScale * (1 - adaptOptions.shrinkPerSecond * dt))\n else if (load < low) detailScale = Math.min(1, detailScale * (1 + adaptOptions.growPerSecond * dt))\n }\n if (budgetOptions) frame = { ...frame, detailScale }\n bakeSeen()\n time.value += dt\n for (const batch of all()) batch.begin()\n blobs?.begin()\n impostors?.begin()\n impostorCount = 0\n const drawBlobs = variety ? (variety.blobShadows ?? true) : false\n instances.agents(crowd.store, variants, frame, (v, l, instance) => {\n if (l === IMPOSTOR_LEVEL) pushImpostor(instance)\n else push(batches[v]?.[l], instance)\n if (!variety) return\n pushAccessories(v, l, instance)\n if (drawBlobs && l > 0) ensureBlobs().push(instance.a[0], instance.y, instance.a[1], instance.b[0] * (variants[v]?.s ?? 1))\n })\n if (options.drawCorpses?.() !== false) instances.corpses(crowd.corpses.entries, variants, frame, crowd.numbers.corpseSeconds, (v, l, instance) => push(batches[v]?.[l], instance), (instance) => push(ensurePlain(), instance))\n // as the game counts them: the variant batches after the bodies on the ground went in\n for (let l = 0; l < 3; l++) lodCounts[l] = batches.reduce((sum, set) => sum + (set?.[l]?.count ?? 0), 0)\n const list = options.civilians?.list()\n if (list) instances.civilians(list, options.civilians?.color ?? ((n) => n.spec.color ?? 0x808080), (n, instance) => push(personBatch(n), instance))\n for (const batch of all()) batch.end()\n blobs?.end()\n impostors?.end()\n if (probe) {\n for (const batch of all()) {\n track(batch.mesh)\n if (batch.prepass) track(batch.prepass)\n }\n if (blobs) track(blobs.mesh)\n if (impostors) track(impostors.mesh)\n }\n },\n get detailScale() {\n return detailScale\n },\n get gpuMs() {\n return gpuMs\n },\n get impostorCount() {\n return impostorCount\n },\n get lodCounts() {\n return lodCounts\n },\n get drawCalls() {\n return all().filter((batch) => batch.count > 0).length + (blobs && blobs.count > 0 ? 1 : 0) + (impostors && impostors.count > 0 ? 1 : 0)\n },\n get bakeMs() {\n return bakeMs\n },\n get variants() {\n return variants\n },\n dispose() {\n for (const batch of all()) {\n batch.mesh.geometry.dispose()\n group.remove(batch.mesh)\n if (batch.prepass) group.remove(batch.prepass)\n }\n variants.length = 0\n batches.length = 0\n baked.clear()\n plain = null\n people.clear()\n accessoryBatches.clear()\n accessoryGeometry.clear()\n placements.clear()\n blobs?.mesh.geometry.dispose()\n if (blobs) group.remove(blobs.mesh)\n blobs = null\n impostors?.mesh.geometry.dispose()\n if (impostors) group.remove(impostors.mesh)\n atlas?.dispose()\n clipUniforms?.uClips.value.dispose()\n impostors = null\n atlas = null\n },\n }\n}\n","import type * as THREE_NS from 'three'\n\nconst NANOSECONDS_PER_MILLISECOND = 1e6\nconst MAX_PENDING = 512\n\ntype Timer = {\n readonly TIME_ELAPSED_EXT: number\n readonly GPU_DISJOINT_EXT: number\n}\n\ntype PendingQuery = { readonly query: WebGLQuery; readonly frame: number }\n\nexport type GpuCostProbe = {\n /** Times every draw of `mesh` on the GPU (the time of its depth pass included). */\n attach(mesh: THREE_NS.Object3D): void\n /** Reads the finished queries; the milliseconds the attached meshes took in the last frame whose queries are all back, or undefined while there is none (or no timer on this GPU). */\n poll(): number | undefined\n}\n\n/**\n * The GPU time the attached meshes take, from `EXT_disjoint_timer_query_webgl2` (one query around each of their draws, summed per frame). The crowd renderer reads it to size\n * its level budget on the machine it runs on. Without the extension `poll` stays undefined and the caller falls back to the frame time.\n */\nexport function createGpuCostProbe(): GpuCostProbe {\n let context: WebGL2RenderingContext | null = null\n let timer: Timer | null = null\n let isReady = false\n let active: WebGLQuery | null = null\n let drawFrame = 0\n let lastRenderFrame = -1\n const pending: PendingQuery[] = []\n const free: WebGLQuery[] = []\n let sumFrame = -1\n let sum = 0\n let last: number | undefined\n\n const begin = (renderer: THREE_NS.WebGLRenderer): void => {\n if (!isReady) {\n isReady = true\n const gl = renderer.getContext() as WebGL2RenderingContext\n const extension = gl.getExtension('EXT_disjoint_timer_query_webgl2') as Timer | null\n if (extension) {\n context = gl\n timer = extension\n }\n }\n if (!context || !timer || active || pending.length >= MAX_PENDING) return\n const frame = renderer.info.render.frame\n if (frame !== lastRenderFrame) {\n lastRenderFrame = frame\n drawFrame++\n }\n active = free.pop() ?? context.createQuery()\n context.beginQuery(timer.TIME_ELAPSED_EXT, active)\n }\n\n const end = (): void => {\n if (!context || !timer || !active) return\n context.endQuery(timer.TIME_ELAPSED_EXT)\n pending.push({ query: active, frame: drawFrame })\n active = null\n }\n\n const poll = (): number | undefined => {\n if (!context || !timer) return undefined\n const disjoint = context.getParameter(timer.GPU_DISJOINT_EXT) as boolean\n while (pending.length > 0) {\n const { query, frame } = pending[0]!\n if (!context.getQueryParameter(query, context.QUERY_RESULT_AVAILABLE)) break\n pending.shift()\n free.push(query)\n if (disjoint) continue\n if (frame !== sumFrame) {\n if (sumFrame >= 0) last = sum\n sumFrame = frame\n sum = 0\n }\n sum += (context.getQueryParameter(query, context.QUERY_RESULT) as number) / NANOSECONDS_PER_MILLISECOND\n }\n return last\n }\n\n return {\n attach(mesh) {\n mesh.onBeforeRender = (renderer) => begin(renderer)\n mesh.onAfterRender = () => end()\n },\n poll,\n }\n}\n","type Keys<K extends string> = Readonly<Record<K, string>>\n\nexport type CrowdBenchText = {\n readonly group: string\n readonly name: string\n readonly mix: string\n readonly controls: Keys<'scene' | 'physics' | 'count' | 'type' | 'night' | 'seed' | 'spawn' | 'noise' | 'hit' | 'kill_all' | 'join' | 'flee' | 'herd' | 'materialize' | 'push' | 'reset'>\n readonly hints: Keys<'scene' | 'physics' | 'count' | 'type' | 'night' | 'noise' | 'hit' | 'join' | 'flee' | 'herd' | 'materialize' | 'push'>\n readonly layers: Keys<'corpses' | 'civilians' | 'animals'>\n readonly metrics: Keys<'agents' | 'drawn' | 'lod_near' | 'lod_middle' | 'lod_far' | 'draw_calls' | 'bake_ms' | 'active' | 'kills' | 'corpses' | 'civilians' | 'health' | 'grabbed' | 'message' | 'falls_pressure' | 'falls_chain' | 'falls_landing' | 'climbers' | 'mound_max' | 'thrown_peak' | 'max_overlap' | 'chain_links' | 'crowd_ms_p99' | 'detail_scale' | 'crowd_gpu_ms'>\n readonly sceneNames: Keys<'open' | 'dense_wall' | 'chain_line'>\n readonly scenarios: Keys<'relevance' | 'lod' | 'attack_pose' | 'corpse_darkens' | 'civilians_flee' | 'herd_calls' | 'vultures' | 'infection' | 'determinism'>\n readonly messages: Keys<'called' | 'burst_hit' | 'swing_knock' | 'pounce_knock' | 'migration' | 'door_broken' | 'alarm' | 'bark' | 'growl' | 'bitten' | 'turned' | 'died'>\n readonly yes: string\n readonly no: string\n}\n\nconst EN: CrowdBenchText = {\n group: 'Crowd',\n name: 'Crowd area',\n mix: 'Mixed (by weight)',\n controls: {\n scene: 'Scene',\n physics: 'Crowd physics',\n count: 'Agents',\n type: 'Type of the new ones',\n night: 'Night',\n seed: 'Seed',\n spawn: 'Add 100',\n noise: 'Noise here (80 m)',\n hit: 'Shoot the nearest in the head',\n kill_all: 'Kill all',\n join: 'Civilians join you',\n flee: 'Civilians run away',\n herd: 'Bring the animals',\n materialize: 'Bring 50 from the region',\n push: 'Push (break a grab)',\n reset: 'Start again',\n },\n hints: {\n scene: 'Where the crowd is born: the open ring, a horde pressed against a wall and a door, or a horde coming down a street at a row of gas cylinders and a car. Applied before the physics and the count.',\n physics: 'Contact, pressure, falls, mounds, thrown bodies and blasts (the crowd is rebuilt with them).',\n count: 'The crowd grows or shrinks to this many, born 10 to 90 m from the area centre. Only the near ones think every frame (relevance bands).',\n type: 'The type of the agents added from now on; mixed draws them by the weights of the pack.',\n night: 'At night sight drops by 40%.',\n noise: 'A noise heard 80 m around you: the ones that hear it come.',\n hit: 'A headshot to the nearest agent: a body on the ground, blood through the room effects.',\n join: 'The civilians follow you; bitten, they turn after the bite time.',\n flee: 'The civilians run off along a path out of the area and are gone.',\n herd: 'A companion dog, hens, a lapwing, cows, a horse, a pig, a capybara, a carcass and the vultures over it.',\n materialize: 'The region model turns 50 of its numbers into agents near you; the far ones go back.',\n push: 'What holds you lets go after six pushes.',\n },\n layers: { corpses: 'Bodies on the ground', civilians: 'Civilians', animals: 'Animals' },\n metrics: {\n agents: 'Agents',\n drawn: 'Drawn',\n lod_near: 'Near level',\n lod_middle: 'Middle level',\n lod_far: 'Far level',\n draw_calls: 'Draw calls',\n bake_ms: 'Bake',\n detail_scale: 'Detail budget',\n crowd_gpu_ms: 'Crowd GPU time',\n active: 'Thinking every frame',\n kills: 'Kills',\n corpses: 'Bodies',\n civilians: 'Civilians alive',\n health: 'Your health',\n grabbed: 'Grabbed',\n message: 'Last message',\n falls_pressure: 'Falls by pressure',\n falls_chain: 'Chain falls beyond a blast',\n falls_landing: 'Falls by a landing body',\n climbers: 'On the mound, peak',\n mound_max: 'Highest mound, peak',\n thrown_peak: 'Thrown bodies, peak',\n max_overlap: 'Largest overlap, peak',\n chain_links: 'Chain links',\n crowd_ms_p99: 'Crowd step, p99',\n },\n sceneNames: { open: 'Open ring', dense_wall: 'Dense wall', chain_line: 'Chain line' },\n scenarios: {\n relevance: 'Relevance: 500 agents, only the near ones every frame',\n lod: 'Level of detail with 1.5 m of hysteresis',\n attack_pose: 'Attack pose in at 1.6 m, out at 2.2 m',\n corpse_darkens: 'A body darkens and shrinks at the end of its life',\n civilians_flee: 'Civilians follow, then run away and are gone',\n herd_calls: 'The hen flees and clucks, the lapwing raises the alarm',\n vultures: 'The vultures circle the bodies',\n infection: 'Region numbers become agents and go back',\n determinism: 'The same seed, the same crowd',\n },\n messages: {\n called: 'A screamer called the crowd',\n burst_hit: 'Hit by a bloater burst',\n swing_knock: 'A brute knocked you down',\n pounce_knock: 'A leaper knocked you down',\n migration: 'A crowd is on the move',\n door_broken: 'A door gave way',\n alarm: 'A bird raises the alarm',\n bark: 'The dog is barking',\n growl: 'The dog is growling',\n bitten: 'A civilian was bitten',\n turned: 'A civilian turned',\n died: 'A civilian died',\n },\n yes: 'yes',\n no: 'no',\n}\n\nconst PT_BR: CrowdBenchText = {\n group: 'Multidão',\n name: 'Área da multidão',\n mix: 'Misturado (pelo peso)',\n controls: {\n scene: 'Cena',\n physics: 'Física da multidão',\n count: 'Agentes',\n type: 'Tipo dos novos',\n night: 'Noite',\n seed: 'Semente',\n spawn: 'Mais 100',\n noise: 'Barulho aqui (80 m)',\n hit: 'Tiro na cabeça do mais perto',\n kill_all: 'Matar todos',\n join: 'Civis vêm com você',\n flee: 'Civis fogem',\n herd: 'Trazer os bichos',\n materialize: 'Trazer 50 da região',\n push: 'Empurrar (soltar-se)',\n reset: 'Recomeçar',\n },\n hints: {\n scene: 'Onde a multidão nasce: o anel aberto, uma horda espremida contra um muro e uma porta, ou uma horda descendo uma rua em direção a uma fileira de botijões e um carro. Vale antes da física e da contagem.',\n physics: 'Contato, pressão, quedas, montes, corpos arremessados e explosões (a multidão é refeita com elas).',\n count: 'A multidão cresce ou diminui até esse número, nascendo de 10 a 90 m do centro da área. Só os de perto pensam todo quadro (faixas de relevância).',\n type: 'O tipo dos agentes acrescentados daqui em diante; misturado sorteia pelos pesos do pacote.',\n night: 'À noite a visão cai 40%.',\n noise: 'Um barulho ouvido a 80 m de você: quem ouve vem.',\n hit: 'Um tiro na cabeça do agente mais perto: um corpo no chão, sangue pelos efeitos da sala.',\n join: 'Os civis seguem você; mordidos, viram depois do tempo da mordida.',\n flee: 'Os civis fogem por um caminho para fora da área e somem.',\n herd: 'Um cão companheiro, galinhas, um quero-quero, vacas, um cavalo, um porco, uma capivara, uma carcaça e os urubus sobre ela.',\n materialize: 'O modelo da região transforma 50 dos seus números em agentes perto de você; os de longe voltam.',\n push: 'Quem segura você solta depois de seis empurrões.',\n },\n layers: { corpses: 'Corpos no chão', civilians: 'Civis', animals: 'Bichos' },\n metrics: {\n agents: 'Agentes',\n drawn: 'Desenhados',\n lod_near: 'Nível perto',\n lod_middle: 'Nível meio',\n lod_far: 'Nível longe',\n draw_calls: 'Chamadas de desenho',\n bake_ms: 'Cozimento',\n detail_scale: 'Orçamento de detalhe',\n crowd_gpu_ms: 'Tempo de GPU da horda',\n active: 'Pensando todo quadro',\n kills: 'Mortes',\n corpses: 'Corpos',\n civilians: 'Civis vivos',\n health: 'Sua vida',\n grabbed: 'Agarrado',\n message: 'Última mensagem',\n falls_pressure: 'Quedas por pressão',\n falls_chain: 'Quedas em cadeia além da explosão',\n falls_landing: 'Quedas por corpo que pousa',\n climbers: 'No monte, pico',\n mound_max: 'Maior monte, pico',\n thrown_peak: 'Arremessados, pico',\n max_overlap: 'Maior sobreposição, pico',\n chain_links: 'Elos da cadeia',\n crowd_ms_p99: 'Passo da multidão, p99',\n },\n sceneNames: { open: 'Anel aberto', dense_wall: 'Muro denso', chain_line: 'Rua em cadeia' },\n scenarios: {\n relevance: 'Relevância: 500 agentes, só os de perto todo quadro',\n lod: 'Nível de detalhe com 1,5 m de histerese',\n attack_pose: 'Pose de ataque entra a 1,6 m e sai a 2,2 m',\n corpse_darkens: 'O corpo escurece e encolhe no fim da vida',\n civilians_flee: 'Civis seguem, depois fogem e somem',\n herd_calls: 'A galinha foge e cacareja, o quero-quero dá o alarme',\n vultures: 'Os urubus circulam os corpos',\n infection: 'Números da região viram agentes e voltam',\n determinism: 'A mesma semente, a mesma multidão',\n },\n messages: {\n called: 'Um gritador chamou a multidão',\n burst_hit: 'Atingido pelo estouro de um inchado',\n swing_knock: 'Um brutamonte derrubou você',\n pounce_knock: 'Um saltador derrubou você',\n migration: 'Uma multidão está migrando',\n door_broken: 'Uma porta cedeu',\n alarm: 'Um pássaro dá o alarme',\n bark: 'O cão está latindo',\n growl: 'O cão está rosnando',\n bitten: 'Um civil foi mordido',\n turned: 'Um civil virou',\n died: 'Um civil morreu',\n },\n yes: 'sim',\n no: 'não',\n}\n\nconst TEXT: Readonly<Record<string, CrowdBenchText>> = { en: EN, 'pt-BR': PT_BR }\n\nexport const crowdBenchTextOf = (locale: string): CrowdBenchText => TEXT[locale] ?? PT_BR\n","import { STATE, CELL } from '@adatechnology/game-crowd'\nimport type { Crowd, CrowdUpdateContext } from '@adatechnology/game-crowd'\nimport type { ModuleHost } from '@adatechnology/game-contracts'\nimport type * as THREE_NS from 'three'\nimport { discardObject3D } from '@adatechnology/game-shapes-three'\n\n/** The ground a scene lays out its things on: the crowd area centre. */\nexport type CrowdScenePlace = { readonly cx: number; readonly cz: number }\n\n/** What the host project lends the scenes to draw with: its wall piece and the ids of the catalogue items it has (`ModuleHost.addObject`). Without them a scene only writes the grid. */\nexport type CrowdSceneProps = {\n /** An Object3D wall of this length and height, base at the origin along x (the kit's `wallPiece`). */\n readonly wall?: (three: typeof THREE_NS, size: { readonly length: number; readonly height: number }) => THREE_NS.Object3D | undefined\n /** Item ids of the host's catalogue: the gas cylinder, the car and the car's fuel tank. */\n readonly items?: { readonly gasCylinder?: string; readonly car?: string; readonly carTank?: string }\n}\n\n/** A place for the crowd to be born in, with the walls and doors of its own. The bench applies it after the seed and before the physics and the count. */\nexport interface CrowdBenchScene {\n readonly id: string\n /** Writes the walls and the doors of the scene to the crowd's grid. */\n layout(crowd: Crowd, place: CrowdScenePlace): void\n /** Bears `count` agents of `type` (-1: the pack's mix), the `first`-th of the scene onwards; `unit` is the seeded stream of the scene. */\n spawn(crowd: Crowd, request: { readonly first: number; readonly count: number; readonly type: number; readonly unit: () => number }, place: CrowdScenePlace): void\n /** The context of `crowd.update`: where the bands are centred and where the flow converges. */\n context?(place: CrowdScenePlace): Pick<CrowdUpdateContext, 'bandCentre' | 'flowTarget'>\n /** Where the camera stands to see the scene. */\n view(place: CrowdScenePlace): { readonly eye: readonly [number, number, number]; readonly target: readonly [number, number, number] }\n /** Puts the scene's things in the host's world; returns what takes them away. */\n props?(host: ModuleHost, place: CrowdScenePlace, props: CrowdSceneProps): () => void\n}\n\nconst WALL_LENGTH = 30\nconst WALL_HEIGHT = 3\nconst WALL_THICKNESS = 0.5\nconst DOOR_WIDTH = 1.2\nconst BODY_COLUMNS = 50\nconst COLUMN_GAP = 0.6\nconst ROW_GAP = 0.55\nconst STREET_HALF_WIDTH = 6\nconst STREET_COLUMNS = 18\nconst STREET_LENGTH = 90\nconst CYLINDERS = 6\nconst CYLINDER_GAP = 1.5\n\nconst bear = (crowd: Crowd, x: number, z: number, type: number): void => {\n const i = crowd.spawn(x, z, type)\n if (i >= 0) crowd.store.state[i] = STATE.CHASE\n}\n\nconst removers = (list: readonly (() => void)[]): (() => void) => () => {\n for (const remove of list) remove()\n}\n\n/** A horde pressed against a wall of 30 m with a door of 1.2 m, born behind it; the player stands on the other side. */\nexport const DENSE_WALL: CrowdBenchScene = {\n id: 'dense_wall',\n layout(crowd, { cx, cz }) {\n const half = WALL_LENGTH / 2\n crowd.grid.fillRect(cx - half, cz - WALL_THICKNESS / 2, cx - DOOR_WIDTH / 2, cz + WALL_THICKNESS / 2, CELL.SOLID, WALL_HEIGHT)\n crowd.grid.fillRect(cx + DOOR_WIDTH / 2, cz - WALL_THICKNESS / 2, cx + half, cz + WALL_THICKNESS / 2, CELL.SOLID, WALL_HEIGHT)\n crowd.doors.add(cx, cz, 'x', DOOR_WIDTH)\n },\n spawn(crowd, { first, count, type }, { cx, cz }) {\n for (let k = first; k < first + count; k++) {\n const row = Math.floor(k / BODY_COLUMNS)\n bear(crowd, cx + ((k % BODY_COLUMNS) - BODY_COLUMNS / 2 + (row % 2) * 0.5) * COLUMN_GAP, cz - 1.5 - row * ROW_GAP, type)\n }\n },\n context: ({ cx, cz }) => ({ bandCentre: [cx, cz - 8] }),\n view: ({ cx, cz }) => ({ eye: [cx, 1.7, cz + 9], target: [cx, 1.2, cz - 10] }),\n props(host, { cx, cz }, props) {\n const three = host.THREE as typeof THREE_NS\n const side = (WALL_LENGTH - DOOR_WIDTH) / 2\n const made: THREE_NS.Object3D[] = []\n for (const sign of [-1, 1]) {\n const wall = props.wall?.(three, { length: side, height: WALL_HEIGHT })\n if (!wall) continue\n wall.position.set(cx + sign * (DOOR_WIDTH / 2 + side / 2), 0, cz)\n ;(host.scene as THREE_NS.Object3D).add(wall)\n made.push(wall)\n }\n // the walls are built for this scene: freed when it goes, keeping what the scene still draws (the house palette)\n return () => {\n discardObject3D(made)\n }\n },\n}\n\n/** A horde coming down a street of 12 m at a row of six gas cylinders and a car; the player stands at the end of the street. */\nexport const CHAIN_LINE: CrowdBenchScene = {\n id: 'chain_line',\n layout(crowd, { cx, cz }) {\n for (const sign of [-1, 1]) crowd.grid.fillRect(cx + sign * STREET_HALF_WIDTH, cz - STREET_LENGTH, cx + sign * (STREET_HALF_WIDTH + WALL_THICKNESS), cz + 20, CELL.SOLID, WALL_HEIGHT)\n },\n spawn(crowd, { first, count, type }, { cx, cz }) {\n for (let k = first; k < first + count; k++) {\n const row = Math.floor(k / STREET_COLUMNS)\n bear(crowd, cx + ((k % STREET_COLUMNS) - STREET_COLUMNS / 2 + (row % 2) * 0.5) * COLUMN_GAP, cz - 10 - row * ROW_GAP, type)\n }\n },\n context: ({ cx, cz }) => ({ bandCentre: [cx, cz - 14] }),\n view: ({ cx, cz }) => ({ eye: [cx, 1.7, cz + 14], target: [cx, 1.2, cz - 10] }),\n props(host, { cx, cz }, props) {\n const items = props.items\n const placed: (() => void)[] = []\n if (!host.addObject || !items) return removers(placed)\n if (items.gasCylinder) {\n for (let k = 0; k < CYLINDERS; k++) {\n const object = host.addObject(items.gasCylinder, { position: [cx + (k - (CYLINDERS - 1) / 2) * CYLINDER_GAP, 0, cz - 4] })\n if (object) placed.push(() => object.remove())\n }\n }\n for (const id of [items.car, items.carTank]) {\n const object = id ? host.addObject(id, { position: [cx, 0, cz + 2], rotationY: Math.PI / 2 }) : null\n if (object) placed.push(() => object.remove())\n }\n return removers(placed)\n },\n}\n\nexport const BUILTIN_SCENES: Readonly<Record<string, CrowdBenchScene>> = { dense_wall: DENSE_WALL, chain_line: CHAIN_LINE }\n"],"mappings":"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","names":["STATE","near","middle","STATE","view","id","STATE"]}