@adatechnology/game-crowd-three 0.3.0 → 0.3.2
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.global.js +20 -3
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -168,11 +168,12 @@ function createCrowdInstances(options) {
|
|
|
168
168
|
|
|
169
169
|
// src/renderer.ts
|
|
170
170
|
import { variantDecay, variantSeed } from "@adatechnology/game-characters";
|
|
171
|
+
import { markKitOrigin } from "@adatechnology/game-contracts";
|
|
171
172
|
import { LOD_BAKE, LOD_SEGMENTS, bakeBody, buildInstancedBody, createBodyBatch, createVariantBatches } from "@adatechnology/game-characters-three";
|
|
172
173
|
var now = () => typeof performance === "undefined" ? Date.now() : performance.now();
|
|
173
174
|
function createCrowdRenderer(three, options) {
|
|
174
175
|
const { crowd } = options;
|
|
175
|
-
const group = new three.Group();
|
|
176
|
+
const group = markKitOrigin(new three.Group(), { owner: "game-crowd-three", kind: "person" });
|
|
176
177
|
group.name = "crowd";
|
|
177
178
|
const time = { value: 0 };
|
|
178
179
|
const eyes = crowd.pack.types.map((type) => type.eye ?? null);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/instances.ts","../src/data/render.json","../src/renderer.ts","../src/herd-view.ts","../src/audio/bank.ts","../src/bench/module.ts","../src/bench/locale.ts"],"sourcesContent":["import { INSTANCE_POSES, walkGait } from '@adatechnology/game-characters'\nimport type { InstancePose } from '@adatechnology/game-characters'\nimport { MISSING, STATE } from '@adatechnology/game-crowd'\nimport type { Civilian, Corpse, CrowdStore } from '@adatechnology/game-crowd'\n\nimport defaults from './data/render.json'\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}\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}\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\nconst poseIndex = (pose: InstancePose): number => INSTANCE_POSES.indexOf(pose)\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}\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 lodEdges = [near, middle]\n const behindFrom = N.behindFrom\n const farSquared = N.farCull * N.farCull\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 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 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 // the level of detail with hysteresis: a body does not keep switching meshes on the edge\n let l = Z.lod[i]!\n const dd = Math.sqrt(d2)\n while (l > 0 && dd < lodEdges[l - 1]! - N.lodHysteresis) l--\n while (l < 2 && dd > lodEdges[l]! + N.lodHysteresis) 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 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 sink(Z.variant[i]!, l, {\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, 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 })\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 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 l = dx * dx + dz * dz < N.corpseNear * N.corpseNear ? 0 : 1\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 { variantDecay, variantSeed } from '@adatechnology/game-characters'\nimport type { Civilian, Crowd, CrowdType } from '@adatechnology/game-crowd'\nimport { LOD_BAKE, LOD_SEGMENTS, bakeBody, buildInstancedBody, createBodyBatch, createVariantBatches } from '@adatechnology/game-characters-three'\nimport type { BakeBuilders, BakeSpec, BakedBody, BodyBatch, BodyVariant, Three } from '@adatechnology/game-characters-three'\nimport type * as THREE_NS from 'three'\n\nimport { createCrowdInstances } from './instances'\nimport type { CrowdFrame, CrowdInstance, CrowdInstances, CrowdPoseMap, CrowdRenderNumbers } from './instances'\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}\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 /** 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 /** Batches with something to draw. */\n readonly drawCalls: number\n readonly bakeMs: number\n readonly variants: readonly BodyVariant[]\n dispose(): void\n}\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 = new three.Group()\n group.name = 'crowd'\n const time = { value: 0 }\n const eyes = crowd.pack.types.map((type) => type.eye ?? null)\n const instances = createCrowdInstances({ eyes, ...(options.numbers ? { numbers: options.numbers } : {}), ...(options.poses ? { poses: options.poses } : {}) })\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 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 })\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)\n for (const batch of batches[g]!) group.add(batch.mesh)\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()]\n\n return {\n group,\n instances,\n bake,\n update(dt, frame) {\n bakeSeen()\n time.value += dt\n for (const batch of all()) batch.begin()\n instances.agents(crowd.store, variants, frame, (v, l, instance) => push(batches[v]?.[l], instance))\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 },\n get lodCounts() {\n return lodCounts\n },\n get drawCalls() {\n return all().filter((batch) => batch.count > 0).length\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 }\n variants.length = 0\n batches.length = 0\n baked.clear()\n plain = null\n people.clear()\n },\n }\n}\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","// 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 { HERD_ROLES, STATE, bindInfection, carrionCenter, createCivilians, createCrowd, createFlock, createHerd, createRng } from '@adatechnology/game-crowd'\nimport type { CivilianBuilding, CivilianSpec, Civilians, Crowd, CrowdEventMap, CrowdPack, 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 } from '../renderer'\nimport { crowdBenchTextOf } from './locale'\nimport type { CrowdBenchText } from './locale'\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 /** 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\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 }\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 pending: Partial<Record<PlayerAction, boolean>> = {}\n let last: { x: number; z: number } | null = null\n const offs: (() => void)[] = []\n\n type World = { crowd: Crowd; player: Player; civilians: Civilians; herd: Herd; flock: Flock; vultures: number; binding: InfectionBinding | null; model: InfectionModelLike | null; place: () => number }\n const build = (seed: number): World => {\n const player = createPlayer({ seed })\n const crowd = createCrowd({ pack: options.pack, seed, capacity: CAPACITY, target: player })\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 = settings.type === 'mix' ? -1 : crowd.typeIndex(settings.type)\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 }\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 const { crowd } = world\n while (crowd.store.n < settings.count && world.place() >= 0) {\n /* born in the ring */\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 reset = (): void => {\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 fit()\n lastMessage = ''\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 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 renderer = createCrowdRenderer(three, {\n crowd: world.crowd,\n builders: options.builders(three),\n ...(options.typeName ? { typeName: options.typeName } : {}),\n drawCorpses: () => layers.corpses,\n ...(bodies.length ? { civilians: { list: () => (layers.civilians ? world.civilians.list : []), body: (n) => bodies[n.k % bodies.length]! } } : {}),\n })\n scene.add(renderer.group)\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 frame = (dt: number): void => {\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 crowd.update(dt, { viewYaw: here?.yaw ?? 0, nightFactor: settings.night ? 1 : 0 })\n crowd.updateCorpses(dt)\n 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 }\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 === '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 reset()\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 controls = (): ModuleControl[] => [\n { kind: 'number', id: 'count', name: text.controls.count, hint: text.hints.count, min: 0, max: 3000, 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: 'number', id: 'seed', name: text.controls.seed, min: 1, max: 9999, step: 1, default: settings.seed },\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: '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 ]\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 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: { 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 return () => {\n off?.()\n offFrame()\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","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<'count' | 'type' | 'night' | 'seed' | 'spawn' | 'noise' | 'hit' | 'kill_all' | 'join' | 'flee' | 'herd' | 'materialize' | 'push' | 'reset'>\n readonly hints: Keys<'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'>\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 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 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 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 },\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 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 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 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 },\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"],"mappings":"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","names":["STATE","id","STATE"]}
|
|
1
|
+
{"version":3,"sources":["../src/instances.ts","../src/data/render.json","../src/renderer.ts","../src/herd-view.ts","../src/audio/bank.ts","../src/bench/module.ts","../src/bench/locale.ts"],"sourcesContent":["import { INSTANCE_POSES, walkGait } from '@adatechnology/game-characters'\nimport type { InstancePose } from '@adatechnology/game-characters'\nimport { MISSING, STATE } from '@adatechnology/game-crowd'\nimport type { Civilian, Corpse, CrowdStore } from '@adatechnology/game-crowd'\n\nimport defaults from './data/render.json'\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}\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}\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\nconst poseIndex = (pose: InstancePose): number => INSTANCE_POSES.indexOf(pose)\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}\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 lodEdges = [near, middle]\n const behindFrom = N.behindFrom\n const farSquared = N.farCull * N.farCull\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 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 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 // the level of detail with hysteresis: a body does not keep switching meshes on the edge\n let l = Z.lod[i]!\n const dd = Math.sqrt(d2)\n while (l > 0 && dd < lodEdges[l - 1]! - N.lodHysteresis) l--\n while (l < 2 && dd > lodEdges[l]! + N.lodHysteresis) 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 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 sink(Z.variant[i]!, l, {\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, 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 })\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 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 l = dx * dx + dz * dz < N.corpseNear * N.corpseNear ? 0 : 1\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 { variantDecay, variantSeed } from '@adatechnology/game-characters'\nimport type { Civilian, Crowd, CrowdType } from '@adatechnology/game-crowd'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport { LOD_BAKE, LOD_SEGMENTS, bakeBody, buildInstancedBody, createBodyBatch, createVariantBatches } from '@adatechnology/game-characters-three'\nimport type { BakeBuilders, BakeSpec, BakedBody, BodyBatch, BodyVariant, Three } from '@adatechnology/game-characters-three'\nimport type * as THREE_NS from 'three'\n\nimport { createCrowdInstances } from './instances'\nimport type { CrowdFrame, CrowdInstance, CrowdInstances, CrowdPoseMap, CrowdRenderNumbers } from './instances'\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}\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 /** 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 /** Batches with something to draw. */\n readonly drawCalls: number\n readonly bakeMs: number\n readonly variants: readonly BodyVariant[]\n dispose(): void\n}\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 instances = createCrowdInstances({ eyes, ...(options.numbers ? { numbers: options.numbers } : {}), ...(options.poses ? { poses: options.poses } : {}) })\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 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 })\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)\n for (const batch of batches[g]!) group.add(batch.mesh)\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()]\n\n return {\n group,\n instances,\n bake,\n update(dt, frame) {\n bakeSeen()\n time.value += dt\n for (const batch of all()) batch.begin()\n instances.agents(crowd.store, variants, frame, (v, l, instance) => push(batches[v]?.[l], instance))\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 },\n get lodCounts() {\n return lodCounts\n },\n get drawCalls() {\n return all().filter((batch) => batch.count > 0).length\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 }\n variants.length = 0\n batches.length = 0\n baked.clear()\n plain = null\n people.clear()\n },\n }\n}\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","// 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 { HERD_ROLES, STATE, bindInfection, carrionCenter, createCivilians, createCrowd, createFlock, createHerd, createRng } from '@adatechnology/game-crowd'\nimport type { CivilianBuilding, CivilianSpec, Civilians, Crowd, CrowdEventMap, CrowdPack, 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 } from '../renderer'\nimport { crowdBenchTextOf } from './locale'\nimport type { CrowdBenchText } from './locale'\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 /** 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\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 }\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 pending: Partial<Record<PlayerAction, boolean>> = {}\n let last: { x: number; z: number } | null = null\n const offs: (() => void)[] = []\n\n type World = { crowd: Crowd; player: Player; civilians: Civilians; herd: Herd; flock: Flock; vultures: number; binding: InfectionBinding | null; model: InfectionModelLike | null; place: () => number }\n const build = (seed: number): World => {\n const player = createPlayer({ seed })\n const crowd = createCrowd({ pack: options.pack, seed, capacity: CAPACITY, target: player })\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 = settings.type === 'mix' ? -1 : crowd.typeIndex(settings.type)\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 }\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 const { crowd } = world\n while (crowd.store.n < settings.count && world.place() >= 0) {\n /* born in the ring */\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 reset = (): void => {\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 fit()\n lastMessage = ''\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 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 renderer = createCrowdRenderer(three, {\n crowd: world.crowd,\n builders: options.builders(three),\n ...(options.typeName ? { typeName: options.typeName } : {}),\n drawCorpses: () => layers.corpses,\n ...(bodies.length ? { civilians: { list: () => (layers.civilians ? world.civilians.list : []), body: (n) => bodies[n.k % bodies.length]! } } : {}),\n })\n scene.add(renderer.group)\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 frame = (dt: number): void => {\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 crowd.update(dt, { viewYaw: here?.yaw ?? 0, nightFactor: settings.night ? 1 : 0 })\n crowd.updateCorpses(dt)\n 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 }\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 === '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 reset()\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 controls = (): ModuleControl[] => [\n { kind: 'number', id: 'count', name: text.controls.count, hint: text.hints.count, min: 0, max: 3000, 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: 'number', id: 'seed', name: text.controls.seed, min: 1, max: 9999, step: 1, default: settings.seed },\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: '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 ]\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 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: { 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 return () => {\n off?.()\n offFrame()\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","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<'count' | 'type' | 'night' | 'seed' | 'spawn' | 'noise' | 'hit' | 'kill_all' | 'join' | 'flee' | 'herd' | 'materialize' | 'push' | 'reset'>\n readonly hints: Keys<'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'>\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 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 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 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 },\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 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 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 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 },\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"],"mappings":"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","names":["STATE","id","STATE"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adatechnology/game-crowd-three",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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": [
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"dist"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@adatechnology/game-audio": "0.
|
|
42
|
-
"@adatechnology/game-characters": "0.2.
|
|
43
|
-
"@adatechnology/game-characters-three": "0.
|
|
44
|
-
"@adatechnology/game-contracts": "0.
|
|
45
|
-
"@adatechnology/game-crowd": "0.2.
|
|
46
|
-
"@adatechnology/game-player": "0.2.
|
|
41
|
+
"@adatechnology/game-audio": "0.3.0",
|
|
42
|
+
"@adatechnology/game-characters": "0.2.1",
|
|
43
|
+
"@adatechnology/game-characters-three": "0.4.0",
|
|
44
|
+
"@adatechnology/game-contracts": "0.15.0",
|
|
45
|
+
"@adatechnology/game-crowd": "0.2.2",
|
|
46
|
+
"@adatechnology/game-player": "0.2.2"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"three": "^0.160.0"
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
"typescript": "^5.7.3",
|
|
58
58
|
"vitest": "^3.2.4",
|
|
59
59
|
"@adatechnology/game-animals": "0.1.0",
|
|
60
|
+
"@adatechnology/game-animals-three": "0.3.1",
|
|
61
|
+
"@adatechnology/game-characters-undead": "0.2.2",
|
|
60
62
|
"@adatechnology/game-animals-species": "0.1.0",
|
|
61
|
-
"@adatechnology/game-animals-three": "0.3.0",
|
|
62
|
-
"@adatechnology/game-characters-undead": "0.2.1",
|
|
63
63
|
"@adatechnology/game-infection": "0.1.0",
|
|
64
64
|
"@adatechnology/golden-tool": "0.0.0"
|
|
65
65
|
},
|