@adatechnology/game-audio 0.0.0-stage → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anderson Fernandes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,87 @@
1
- # Temporary Holding Version
1
+ # @adatechnology/game-audio
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Sound as data for games. A **recipe** says which nodes a sound has (seeded noise, oscillators, the art scene's formant voice, serial or parallel
4
+ filters, LFOs, an envelope) and which numbers drive them; `planSound` turns it into a **`SoundPlan`** with every number decided by a seeded stream,
5
+ and the WebAudio layer builds the plan. Nothing here knows any game: the sounds live in each subject's bank (weapons, materials, voices, animals,
6
+ weather), and this package holds the machinery plus the two team mixing chains.
7
+
8
+ - **Recipes are data**, with `sources` for every number (`"jogo:L62128"`, `"cena:L1342"`, `"sdk"`).
9
+ - **Plans are pure** and run in Node: the same seed gives the same plan, which is what goldens and the bench sheet read.
10
+ - **Distance curves of the teams** (`DISTANCE_CURVES`): the game's `vol / (1 + d² × k)` with k 0.004, 0.006, 0.01, 0.002 and its cutoff muffling
11
+ `/ (1 + d × 0.01)`; the art scene's 0.008; the animals' linear 70 m.
12
+ - **Pan** like the art scene (right ear from the listener yaw, ±0.85, at least 2 m), distance on the ground or in 3D.
13
+ - **Occlusion** only when the host passes a callback: gain × (1 − 0.5 × o), lowpass cutoffs × (1 − 0.6 × o).
14
+ - **Voice limiter**: groups with `maxConcurrent`, `cooldown`, `maxDistance` and `steal`; a global cap of 32 that drops the lowest `priority × gain`
15
+ (weapons > voices > world > ambience).
16
+ - **Loops**: nodes only once the volume reaches 0.002, then `setTargetAtTime` with 0.15 s (volume) and 0.08 s (frequency), as in the game.
17
+
18
+ ## Install
19
+
20
+ ```sh
21
+ pnpm add @adatechnology/game-audio
22
+ ```
23
+
24
+ Browser without a bundler (the global is `GameAudio`):
25
+
26
+ ```html
27
+ <script src="https://unpkg.com/@adatechnology/game-audio/dist/index.global.js"></script>
28
+ ```
29
+
30
+ ## Recipes
31
+
32
+ ```ts
33
+ import { planSound, createRng } from '@adatechnology/game-audio'
34
+ import type { SoundRecipe } from '@adatechnology/game-audio'
35
+
36
+ const scream: SoundRecipe = {
37
+ id: 'scream_hoarse',
38
+ bus: 'voices',
39
+ order: 'scream',
40
+ duration: [1, 1.4], // drawn first
41
+ layers: [
42
+ {
43
+ source: { kind: 'noise', offset: 'random' }, // the start point is drawn last in its layer
44
+ filters: { mode: 'parallel', bank: [{ type: 'bandpass', q: 6, level: 1, frequency: { from: 805, to: 560, curve: 'linear', over: 'duration' } }] },
45
+ modulators: [{ target: 'gain', wave: 'square', rate: [31, 40], depth: 0.35 }],
46
+ envelope: [[0, 0, 'set'], [0.06, 0.9, 'linear'], ['0.6d', 0.9, 'set'], ['1d', 0.001, 'exp', 'fixed']],
47
+ },
48
+ ],
49
+ falloff: { model: 'inverse_square', k: 0.006, minGain: 0.02 },
50
+ group: 'undead_voice',
51
+ sources: ['jogo:L62128'],
52
+ }
53
+
54
+ const plan = planSound(scream, { random: createRng(7), distance: 12 }) // null when too far to hear
55
+ ```
56
+
57
+ - `Range` is a number, `[min, max]` (drawn as `min + random × (max − min)`) or `{ param, scale?, add? }`.
58
+ - **Draw order** (so a recipe draws exactly what the team routine drew): `vars` in the order written, then `duration`, then each layer in the order
59
+ its fields are written, the noise start point last in its layer. A sound below `minGain` draws nothing.
60
+ - Envelope points are `[time, value, 'set' | 'linear' | 'exp']`; `'0.6d'` is 0.6 × the layer duration; values are multiplied by the level unless
61
+ the fourth item is `'fixed'`.
62
+ - `order` names the node-creation order the realizer uses, each taken from the team routine it reproduces (`layered` is the art scene's and the
63
+ default; `burst`, `scream`, `groan`, `boom`, `static`, `chord`, `calls` are the game's; `siren` is the art scene's siren).
64
+
65
+ ## Engine
66
+
67
+ `createAudioEngine({ seed, mix, banks, maxVoices, distance, occlusion, createContext })` plans a recipe, admits it through the voice limiter and builds it
68
+ on a lazily created `AudioContext` through one of the team chains (`game` or `art_scene`). Without a context (Node, workers) every call but `plan` does
69
+ nothing. `channel({ seed })` gives a subject its own random stream; `createAudioSink(engine)` lends the engine as a host's `audio` (`@adatechnology/game-contracts`).
70
+ `weapons-three` plays on it (`createWeaponAudio(volume, { engine })`) with the `weapon` build order.
71
+
72
+ ## Shipped data
73
+
74
+ | Data | What it is | Source |
75
+ |---|---|---|
76
+ | `GAME_SFX_CLASSES`, `GAME_SFX_FALLBACK`, `noiseClassRecipe`, `GAME_SFX_BANK` (`src/data/game-sfx.json`) | The game's 12 noise classes (pistol to explosion) and its fallback, as rows and as `burst` recipes `sfx_<id>` | jogo L62089–62107 |
77
+ | `MIX_PROFILES` (`src/data/mix-profiles.json`), `DEFAULT_MIX` | `game` (master 0.5, noise 1.5 s made on demand) and `art_scene` (compressor −12 dB ratio 5, master 0.85, reverb 2.2 s with decay 3.4 and wet 0.4, noise 2 s made with the chain). The kit default is `art_scene` (Q1) | jogo L62077–62088, cena L1305–1313 |
78
+ | `VOICE_GROUPS` (`src/data/voice-groups.json`) | `undead_voice`: five at once, one every 0.25 s, nearer than 40 m | cena L1342, jogo L66986, L70472 |
79
+ | `LIBRARY_BANK` (`src/library/*.json`) | Sounds whose subject has no package yet (Q12): loops `engine_saw`, `rotor_blades`, `crowd_rumble`; sounds `horn`, `radio_static`, `siren` | jogo L62109–62127, L69998–70004, L70272–70276; cena L1369 |
80
+
81
+ The subject banks (weapons, destruction, characters, animals, weather) live in their own packages.
82
+
83
+ ## Português
84
+
85
+ Som como dados: a receita diz quais nós o som tem e quais números o movem; `planSound` sorteia tudo com semente na ordem em que a receita está
86
+ escrita e devolve o plano que a camada WebAudio constrói. Curvas de distância dos times, pan da Cena de Arte, limite de vozes, laços e as cadeias de
87
+ mixagem do jogo e da Cena. Os sons em si ficam no banco de cada assunto (armas, materiais, vozes, bichos, clima).