@adatechnology/game-weather 0.2.8 → 0.3.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.
@@ -845,90 +845,59 @@ var GameWeather = (() => {
845
845
  };
846
846
  }
847
847
 
848
- // ../game-audio/dist/index.js
849
- var DISTANCE_CURVES = {
850
- /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
851
- game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
852
- /** The game's `grito`: `1 / (1 + d² × 0.006)`, silent below 0.02 (jogo L62129–62130). */
853
- game_scream: { model: "inverse_square", k: 6e-3, minGain: 0.02 },
854
- /** The game's `voz`: `1 / (1 + d² × 0.01)`, silent below 0.02 (jogo L62146–62147). */
855
- game_voice: { model: "inverse_square", k: 0.01, minGain: 0.02 },
856
- /** The game's `boom`: `1.4 / (1 + d² × 0.002)`, never silent (jogo L68280). */
857
- game_boom: { model: "inverse_square", k: 2e-3, scale: 1.4 },
858
- /** The art scene's `outAt`: `vol / (1 + d² × 0.008)` (cena L1320). */
859
- art_scene: { model: "inverse_square", k: 8e-3 },
860
- /** The game's animal calls: `max(0, 1 − d / 70) × 0.25`, silent at or below 0.005 (jogo L66627–66628). */
861
- animals: { model: "linear", range: 70, scale: 0.25, minGain: 5e-3 }
848
+ // ../game-contracts/dist/index.js
849
+ var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
850
+ var DEFERRED_QUEUE_ID = {
851
+ DESTRUCTION_EVENTS: "destruction.events",
852
+ BREACH_PAINT: "floorplan.breach-paint",
853
+ AUDIO_VOICES: "audio.voices",
854
+ VEHICLE_CREASE: "vehicles.crease"
862
855
  };
863
- var mix_profiles_default = [
864
- {
865
- id: "game",
866
- master: 0.5,
867
- noise: { seconds: 1.5, create: "lazy" },
868
- sources: ["jogo:L62077-62081 master 0.5 to the output", "jogo:L62082-62088 noise 1.5 s made by the first sound that needs it"]
869
- },
870
- {
871
- id: "art_scene",
872
- master: 0.85,
873
- compressor: { threshold: -12, ratio: 5 },
874
- reverb: { seconds: 2.2, decay: 3.4, wet: 0.4 },
875
- noise: { seconds: 2, create: "eager" },
876
- sources: [
877
- "cena:L1308 compressor -12 dB, ratio 5",
878
- "cena:L1309 master 0.85",
879
- "cena:L1310 convolver, impulse 2.2 s of (1 - i/len)^3.4",
880
- "cena:L1311 wet 0.4",
881
- "cena:L1312 noise 2 s made with the chain"
882
- ]
883
- }
884
- ];
885
- var MIX_PROFILES = Object.fromEntries(
886
- mix_profiles_default.map((profile) => [profile.id, profile])
887
- );
888
- var game_sfx_default = {
889
- sources: ["jogo:L62089-62107"],
890
- note: "The game's sfx table P: [lowpass cutoff Hz, peak gain, seconds]. Played as a noise burst with the game's distance curve (falloff game_sfx) and a 0.05 s tail. Team names in `team`.",
891
- classes: [
892
- { id: "pistol", team: "pistola", bus: "weapons", cutoff: 1800, gain: 0.9, seconds: 0.18 },
893
- { id: "shotgun", team: "escopeta", bus: "weapons", cutoff: 900, gain: 1.2, seconds: 0.35 },
894
- { id: "rifle", team: "fuzil", bus: "weapons", cutoff: 1400, gain: 1.1, seconds: 0.28 },
895
- { id: "long_rifle", team: "rifle", bus: "weapons", cutoff: 1100, gain: 1.3, seconds: 0.45 },
896
- { id: "impact", team: "impacto", bus: "world", cutoff: 2500, gain: 0.25, seconds: 0.05 },
897
- { id: "flesh", team: "carne", bus: "world", cutoff: 600, gain: 0.35, seconds: 0.08 },
898
- { id: "step", team: "passo", bus: "world", cutoff: 400, gain: 0.08, seconds: 0.05 },
899
- { id: "glass", team: "vidro", bus: "world", cutoff: 5e3, gain: 0.5, seconds: 0.3 },
900
- { id: "wood", team: "madeira", bus: "world", cutoff: 700, gain: 0.5, seconds: 0.2 },
901
- { id: "reload", team: "recarga", bus: "weapons", cutoff: 3e3, gain: 0.15, seconds: 0.06 },
902
- { id: "empty", team: "vazio", bus: "weapons", cutoff: 4e3, gain: 0.12, seconds: 0.03 },
903
- { id: "explosion", team: "explosao", bus: "world", cutoff: 200, gain: 1.6, seconds: 1.4 }
904
- ],
905
- fallback: { id: "unknown", team: "(any other name)", bus: "world", cutoff: 1e3, gain: 0.5, seconds: 0.1 }
856
+ var DEFERRED_PRIORITY = {
857
+ [DEFERRED_QUEUE_ID.DESTRUCTION_EVENTS]: { priority: 300, phase: "present" },
858
+ [DEFERRED_QUEUE_ID.BREACH_PAINT]: { priority: 250, phase: "present" },
859
+ [DEFERRED_QUEUE_ID.AUDIO_VOICES]: { priority: 200, phase: "idle", reserveMs: 1 },
860
+ [DEFERRED_QUEUE_ID.VEHICLE_CREASE]: { priority: 100, phase: "idle" }
906
861
  };
907
- var GAME_SFX = game_sfx_default;
908
- var GAME_SFX_CLASSES = GAME_SFX.classes;
909
- var GAME_SFX_FALLBACK = GAME_SFX.fallback;
910
- function noiseClassRecipe(row, id = `sfx_${row.id}`) {
911
- return {
912
- id,
913
- bus: row.bus,
914
- order: "burst",
915
- duration: row.seconds,
916
- tail: 0.05,
917
- layers: [
918
- {
919
- source: { kind: "noise", offset: "random" },
920
- filters: { mode: "serial", bank: [{ type: "lowpass", frequency: { set: row.cutoff } }] },
921
- envelope: [
922
- [0, row.gain, "set"],
923
- ["1d", 1e-3, "exp", "fixed"]
924
- ]
925
- }
926
- ],
927
- falloff: DISTANCE_CURVES.game_sfx,
928
- sources: [...GAME_SFX.sources.map((source) => `${source} ${row.team}`)]
929
- };
930
- }
931
- var GAME_SFX_BANK = { id: "game_sfx", sounds: [...GAME_SFX_CLASSES, GAME_SFX_FALLBACK].map((row) => noiseClassRecipe(row)) };
862
+ var SURFACE_IDS = ["concrete", "asphalt", "wood", "tile", "dirt", "grass", "gravel", "sand", "metal", "water", "glass", "carpet"];
863
+ var GAIT_IDS = ["walk", "run"];
864
+ var LANDING_IDS = ["light", "heavy"];
865
+ var BODY_SOUND_IDS = [
866
+ "jump",
867
+ "cloth_rustle",
868
+ "body_fall",
869
+ "fall_damage",
870
+ "player_hurt",
871
+ "player_breath_run",
872
+ "player_death",
873
+ "bite",
874
+ "grab",
875
+ "punch_swing",
876
+ "punch_hit_body",
877
+ "punch_hit_face",
878
+ "punch_hit_object",
879
+ "kick_swing",
880
+ "kick_hit",
881
+ "kick_hit_object",
882
+ "shove_two_hands",
883
+ "knife_swing",
884
+ "knife_stab",
885
+ "knife_slash",
886
+ "knife_hit_object",
887
+ "blunt_swing",
888
+ "blunt_hit",
889
+ "blunt_hit_object",
890
+ "axe_swing",
891
+ "axe_chop",
892
+ "axe_hit_object"
893
+ ];
894
+ var footstepSoundId = (surface, gait) => `footstep_${surface}_${gait}`;
895
+ var FOOTSTEP_SOUND_IDS = SURFACE_IDS.flatMap((surface) => GAIT_IDS.map((gait) => footstepSoundId(surface, gait)));
896
+ var LAND_SOUND_IDS = SURFACE_IDS.flatMap((surface) => LANDING_IDS.map((landing2) => `land_${surface}_${landing2}`));
897
+ var BODY_FOLEY_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
898
+ var SWING_LEAD_SECONDS = { punch: 0.07, kick: 0.09, shove: 0, blade: 0.05, blunt: 0.1, chop: 0.11 };
899
+
900
+ // ../game-audio/dist/index.js
932
901
  var ATTACK = 2e-3;
933
902
  function lengthOf(d, attack) {
934
903
  if (typeof d === "number") return attack + d;
@@ -966,51 +935,761 @@ var GameWeather = (() => {
966
935
  envelope: envelope(ATTACK)
967
936
  };
968
937
  }
969
- var BENCH_BANK = {
970
- id: "audio_bench",
971
- sounds: [
972
- {
973
- id: "bench_ping",
974
- bus: "ui",
975
- pan: true,
976
- duration: 0.25,
977
- layers: [
978
- {
979
- gain: 0.5,
980
- wet: 0.3,
981
- source: { kind: "osc", wave: "sine", frequency: { from: 880 } },
982
- envelope: [
983
- [0, 1e-4, "set", "fixed"],
984
- [2e-3, 1, "exp"],
985
- ["1d", 1e-4, "exp", "fixed"]
986
- ]
987
- }
938
+ function sceneVoice(o) {
939
+ return {
940
+ duration: lengthOf(o.d, 0),
941
+ gain: o.vol,
942
+ wet: 0.45,
943
+ source: {
944
+ kind: "formant_voice",
945
+ wave: o.wave ?? "sawtooth",
946
+ frequency: { from: o.f0, to: o.f1, curve: "linear", over: "duration" },
947
+ vibrato: { rate: [4, 10], depth: 0.08 },
948
+ formants: [
949
+ { frequency: o.fA, q: 4 },
950
+ { frequency: o.fB, q: 6 }
988
951
  ],
989
- falloff: DISTANCE_CURVES.art_scene,
990
- sources: ["sdk: bench probe, a 880 Hz ping through the art scene output stage"]
952
+ breath: { frequency: o.fB, q: 1.1, gain: o.noise },
953
+ mix: 3.2
991
954
  },
992
- {
993
- id: "bench_hiss",
994
- bus: "ui",
995
- pan: true,
996
- duration: [0.3, 0.9],
997
- layers: [
998
- {
999
- gain: 0.4,
1000
- source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
1001
- filters: { mode: "serial", bank: [{ type: "highpass", frequency: { set: 3e3 }, q: 0.7 }] },
1002
- envelope: [
1003
- [0, 1e-4, "set", "fixed"],
1004
- [2e-3, 1, "exp"],
1005
- ["1d", 1e-4, "exp", "fixed"]
1006
- ]
1007
- }
1008
- ],
1009
- falloff: DISTANCE_CURVES.art_scene,
1010
- sources: ["sdk: bench probe, a highpass hiss of random length"]
1011
- }
1012
- ]
955
+ envelope: [
956
+ [0, 1e-4, "set", "fixed"],
957
+ [0.1, 1, "exp"],
958
+ ["0.6d", 1, "set"],
959
+ ["1d", 1e-4, "exp", "fixed"]
960
+ ]
961
+ };
962
+ }
963
+ var sceneMany = (count, make) => Array.from({ length: count }, make);
964
+ var FOLEY_FALLOFF = {
965
+ model: "inverse_square",
966
+ k: 0.02,
967
+ cutoffK: 0.04,
968
+ minGain: 4e-3
969
+ };
970
+ var vary = (f, pct = 0.04) => [Math.round(f * (1 - pct)), Math.round(f * (1 + pct))];
971
+ var foley = (id, layers, note) => ({
972
+ id,
973
+ bus: "world",
974
+ pan: true,
975
+ layers,
976
+ falloff: FOLEY_FALLOFF,
977
+ sources: [`sdk: ${note}`]
978
+ });
979
+ var click = (f, vol, delay = 0) => [
980
+ sceneNoise({
981
+ type: "bandpass",
982
+ f: vary(f, 0.08),
983
+ q: 4,
984
+ d: [0.018, 0.03],
985
+ vol: [vol * 0.85, vol * 1.1],
986
+ delay
987
+ }),
988
+ sceneTone({
989
+ f: vary(f * 0.8, 0.06),
990
+ f2: Math.round(f * 0.62),
991
+ d: [0.015, 0.025],
992
+ vol: vol * 0.18,
993
+ delay
994
+ })
995
+ ];
996
+ var meet = (body, panel, vol, latch) => [
997
+ sceneTone({
998
+ f: vary(body),
999
+ f2: Math.round(body * 0.5),
1000
+ d: [0.12, 0.16],
1001
+ vol: [vol * 0.9, vol * 1.1]
1002
+ }),
1003
+ sceneNoise({
1004
+ type: "bandpass",
1005
+ f: vary(panel, 0.06),
1006
+ q: 1.2,
1007
+ d: [0.08, 0.12],
1008
+ vol: [vol * 0.9, vol * 1.1],
1009
+ wet: 0.25
1010
+ }),
1011
+ ...click(latch, vol * 0.45, [0.012, 0.028])
1012
+ ];
1013
+ var LEAF_FOLEY = [
1014
+ // a wooden house door or wardrobe door: latch, a short creak, the leaf on the frame (the hard slam adds the frame rattling)
1015
+ foley("door_wood_open", click(2400, 0.4), "the latch of a wooden door giving"),
1016
+ foley(
1017
+ "door_creak",
1018
+ [
1019
+ sceneTone({ f: [190, 240], f2: 310, d: [0.4, 0.55], vol: [0.04, 0.06] }),
1020
+ sceneNoise({
1021
+ type: "bandpass",
1022
+ f: [480, 560],
1023
+ q: 6,
1024
+ a: 0.05,
1025
+ d: [0.35, 0.5],
1026
+ vol: [0.1, 0.14]
1027
+ })
1028
+ ],
1029
+ "a wooden hinge turning"
1030
+ ),
1031
+ foley("door_wood_close", meet(120, 600, 0.55, 2400), "a wooden leaf meeting its frame"),
1032
+ foley(
1033
+ "door_wood_slam",
1034
+ [
1035
+ ...meet(110, 560, 0.85, 2300),
1036
+ ...sceneMany(
1037
+ 3,
1038
+ () => sceneNoise({
1039
+ type: "bandpass",
1040
+ f: [900, 1500],
1041
+ q: 3,
1042
+ d: 0.03,
1043
+ vol: [0.08, 0.14],
1044
+ delay: [0.05, 0.18]
1045
+ })
1046
+ )
1047
+ ],
1048
+ "a wooden door slammed: the frame and the hinges rattle after the hit"
1049
+ ),
1050
+ // a metal door or gate: a hollow panel that rings a little
1051
+ foley("door_metal_open_close", [...meet(160, 900, 0.55, 2e3), sceneTone({ f: vary(1250), f2: 1150, d: [0.1, 0.16], vol: 0.06, wet: 0.3 })], "a metal door or gate meeting its frame"),
1052
+ foley(
1053
+ "door_creak_metal",
1054
+ [
1055
+ sceneTone({ f: [620, 760], f2: 900, d: [0.3, 0.4], vol: [0.03, 0.045] }),
1056
+ sceneNoise({
1057
+ type: "bandpass",
1058
+ f: [1300, 1500],
1059
+ q: 8,
1060
+ a: 0.04,
1061
+ d: [0.25, 0.35],
1062
+ vol: [0.07, 0.09]
1063
+ })
1064
+ ],
1065
+ "a metal hinge turning"
1066
+ ),
1067
+ // the handle of a locked door shaken: the latch knocking in its keeper, five to seven times in half a second
1068
+ foley(
1069
+ "door_locked_rattle",
1070
+ [
1071
+ ...sceneMany(
1072
+ 6,
1073
+ () => sceneNoise({
1074
+ type: "bandpass",
1075
+ f: [1600, 2600],
1076
+ q: 3,
1077
+ d: [0.025, 0.04],
1078
+ vol: [0.22, 0.34],
1079
+ delay: [0, 0.45]
1080
+ })
1081
+ ),
1082
+ ...sceneMany(
1083
+ 3,
1084
+ () => sceneTone({
1085
+ f: [170, 210],
1086
+ f2: 120,
1087
+ d: 0.05,
1088
+ vol: [0.12, 0.18],
1089
+ delay: [0.02, 0.4]
1090
+ })
1091
+ )
1092
+ ],
1093
+ "the handle of a locked door shaken: latch knocks and the leaf thumping in its frame"
1094
+ ),
1095
+ // a fridge: the rubber seal lets go with a soft suck, the bottles in the door clink; closing it is a soft thump and the seal pulling shut
1096
+ foley(
1097
+ "fridge_open",
1098
+ [
1099
+ sceneNoise({
1100
+ type: "lowpass",
1101
+ f: [320, 380],
1102
+ a: 0.03,
1103
+ d: [0.14, 0.2],
1104
+ vol: [0.32, 0.4]
1105
+ }),
1106
+ sceneNoise({
1107
+ type: "bandpass",
1108
+ f: [800, 950],
1109
+ f2: 1400,
1110
+ q: 2,
1111
+ a: 0.02,
1112
+ d: 0.12,
1113
+ vol: [0.08, 0.12]
1114
+ }),
1115
+ ...sceneMany(
1116
+ 2,
1117
+ () => sceneTone({
1118
+ f: [2600, 4200],
1119
+ d: [0.04, 0.08],
1120
+ vol: [0.015, 0.03],
1121
+ delay: [0.08, 0.22]
1122
+ })
1123
+ )
1124
+ ],
1125
+ "a fridge door: the seal letting go and the bottles in the door"
1126
+ ),
1127
+ foley(
1128
+ "fridge_close",
1129
+ [
1130
+ sceneTone({ f: vary(85), f2: 45, d: [0.1, 0.13], vol: [0.38, 0.46] }),
1131
+ sceneNoise({
1132
+ type: "lowpass",
1133
+ f: [520, 620],
1134
+ d: [0.08, 0.12],
1135
+ vol: [0.3, 0.36]
1136
+ }),
1137
+ sceneNoise({
1138
+ type: "lowpass",
1139
+ f: [260, 320],
1140
+ a: 0.02,
1141
+ d: 0.1,
1142
+ vol: [0.12, 0.18],
1143
+ delay: [0.04, 0.07]
1144
+ }),
1145
+ ...sceneMany(
1146
+ 2,
1147
+ () => sceneTone({
1148
+ f: [2600, 4200],
1149
+ d: [0.04, 0.07],
1150
+ vol: [0.015, 0.03],
1151
+ delay: [0.03, 0.12]
1152
+ })
1153
+ )
1154
+ ],
1155
+ "a fridge door shut: a soft thump, the seal pulling and the bottles"
1156
+ ),
1157
+ // a microwave: the spring catch of the door, plastic on plastic
1158
+ foley(
1159
+ "microwave_open",
1160
+ [
1161
+ ...click(1800, 0.34),
1162
+ sceneTone({
1163
+ f: [3e3, 3400],
1164
+ f2: 2800,
1165
+ d: 0.05,
1166
+ vol: 0.025,
1167
+ delay: [0.01, 0.02]
1168
+ })
1169
+ ],
1170
+ "the spring catch of a microwave door"
1171
+ ),
1172
+ foley(
1173
+ "microwave_close",
1174
+ [
1175
+ sceneNoise({
1176
+ type: "bandpass",
1177
+ f: [1200, 1450],
1178
+ q: 2.5,
1179
+ d: [0.04, 0.06],
1180
+ vol: [0.36, 0.44]
1181
+ }),
1182
+ sceneTone({ f: vary(180), f2: 120, d: 0.05, vol: [0.16, 0.22] }),
1183
+ ...click(2200, 0.2, [8e-3, 0.016])
1184
+ ],
1185
+ "a microwave door clacking shut"
1186
+ ),
1187
+ foley("microwave_beep", [sceneTone({ wave: "square", f: 2e3, d: 0.12, vol: 0.05 })], "the beep of a microwave"),
1188
+ // drawers and sliding leaves: the runners, then the stop
1189
+ foley(
1190
+ "drawer_open",
1191
+ [
1192
+ sceneNoise({
1193
+ type: "bandpass",
1194
+ f: [620, 780],
1195
+ q: 2,
1196
+ a: 0.04,
1197
+ d: [0.28, 0.36],
1198
+ vol: [0.18, 0.24]
1199
+ }),
1200
+ sceneNoise({ type: "bandpass", f: [2e3, 2400], q: 5, d: 0.28, vol: 0.04 }),
1201
+ ...click(1400, 0.16, [0.28, 0.34])
1202
+ ],
1203
+ "a drawer on its runners and its stop"
1204
+ ),
1205
+ foley(
1206
+ "drawer_close",
1207
+ [
1208
+ sceneNoise({
1209
+ type: "bandpass",
1210
+ f: [620, 780],
1211
+ q: 2,
1212
+ a: 0.03,
1213
+ d: [0.2, 0.28],
1214
+ vol: [0.18, 0.24]
1215
+ }),
1216
+ sceneTone({
1217
+ f: vary(150),
1218
+ f2: 90,
1219
+ d: 0.08,
1220
+ vol: [0.22, 0.3],
1221
+ delay: [0.2, 0.26]
1222
+ })
1223
+ ],
1224
+ "a drawer pushed home"
1225
+ )
1226
+ ];
1227
+ var ITEM_FOLEY = [
1228
+ // the hand closing on the item: a touch of skin and cloth, then the item's own small sound
1229
+ foley(
1230
+ "item_pickup_metal",
1231
+ [
1232
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
1233
+ sceneTone({
1234
+ f: [1900, 2600],
1235
+ f2: 1700,
1236
+ d: [0.05, 0.08],
1237
+ vol: [0.06, 0.09],
1238
+ delay: [0.01, 0.03]
1239
+ })
1240
+ ],
1241
+ "picking up a metal thing"
1242
+ ),
1243
+ foley(
1244
+ "item_pickup_plastic",
1245
+ [
1246
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
1247
+ sceneNoise({
1248
+ type: "bandpass",
1249
+ f: [1500, 1900],
1250
+ q: 3,
1251
+ d: 0.03,
1252
+ vol: [0.15, 0.21],
1253
+ delay: [0.01, 0.03]
1254
+ })
1255
+ ],
1256
+ "picking up a plastic thing"
1257
+ ),
1258
+ foley(
1259
+ "item_pickup_glass",
1260
+ [
1261
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.15 }),
1262
+ sceneTone({
1263
+ f: [3200, 4200],
1264
+ d: [0.05, 0.08],
1265
+ vol: [0.038, 0.06],
1266
+ delay: [0.01, 0.03]
1267
+ })
1268
+ ],
1269
+ "picking up a glass thing"
1270
+ ),
1271
+ foley(
1272
+ "item_pickup_paper",
1273
+ [
1274
+ sceneNoise({
1275
+ type: "highpass",
1276
+ f: [2600, 3400],
1277
+ a: 0.01,
1278
+ d: [0.1, 0.14],
1279
+ vol: [0.12, 0.18]
1280
+ }),
1281
+ sceneNoise({ type: "bandpass", f: [800, 1e3], q: 1, d: 0.05, vol: 0.12 })
1282
+ ],
1283
+ "picking up paper or cardboard"
1284
+ ),
1285
+ foley(
1286
+ "item_pickup_fabric",
1287
+ [
1288
+ sceneNoise({
1289
+ type: "bandpass",
1290
+ f: [900, 1300],
1291
+ q: 0.8,
1292
+ a: 0.02,
1293
+ d: [0.12, 0.16],
1294
+ vol: [0.15, 0.21]
1295
+ })
1296
+ ],
1297
+ "picking up cloth"
1298
+ ),
1299
+ foley(
1300
+ "item_pickup_wood",
1301
+ [
1302
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
1303
+ sceneNoise({
1304
+ type: "bandpass",
1305
+ f: [900, 1100],
1306
+ q: 2,
1307
+ d: 0.04,
1308
+ vol: [0.15, 0.21],
1309
+ delay: [0.01, 0.03]
1310
+ })
1311
+ ],
1312
+ "picking up a wooden thing"
1313
+ ),
1314
+ foley(
1315
+ "item_pickup_food",
1316
+ [
1317
+ sceneNoise({ type: "bandpass", f: [700, 900], q: 1, d: 0.06, vol: 0.18 }),
1318
+ sceneNoise({
1319
+ type: "lowpass",
1320
+ f: [500, 650],
1321
+ d: 0.05,
1322
+ vol: 0.12,
1323
+ delay: [0.01, 0.03]
1324
+ })
1325
+ ],
1326
+ "picking up food"
1327
+ ),
1328
+ foley(
1329
+ "item_throw",
1330
+ [
1331
+ sceneNoise({
1332
+ type: "bandpass",
1333
+ f: [450, 650],
1334
+ f2: 1400,
1335
+ q: 1.5,
1336
+ a: 0.05,
1337
+ d: 0.18,
1338
+ vol: [0.1, 0.14]
1339
+ })
1340
+ ],
1341
+ "the arm throwing something: air"
1342
+ ),
1343
+ // a can: the tab cracks, the gas hisses out; drinking is gulps; crushing it crumples the sheet
1344
+ foley(
1345
+ "can_open",
1346
+ [
1347
+ ...click(3200, 0.36),
1348
+ sceneNoise({
1349
+ type: "highpass",
1350
+ f: [3600, 4400],
1351
+ a: 5e-3,
1352
+ d: [0.22, 0.3],
1353
+ vol: [0.16, 0.22],
1354
+ delay: [0.012, 0.02]
1355
+ }),
1356
+ ...sceneMany(5, () => sceneTone({ f: [4e3, 7e3], d: 0.02, vol: 0.01, delay: [0.05, 0.4] }))
1357
+ ],
1358
+ "the tab of a can and the gas hissing out"
1359
+ ),
1360
+ foley(
1361
+ "can_crush",
1362
+ [
1363
+ sceneNoise({
1364
+ type: "bandpass",
1365
+ f: [1600, 2200],
1366
+ q: 1.2,
1367
+ d: [0.18, 0.25],
1368
+ vol: [0.3, 0.38]
1369
+ }),
1370
+ ...sceneMany(
1371
+ 6,
1372
+ () => sceneTone({
1373
+ f: [1200, 3400],
1374
+ f2: 900,
1375
+ d: 0.03,
1376
+ vol: [0.03, 0.06],
1377
+ delay: [0, 0.2]
1378
+ })
1379
+ )
1380
+ ],
1381
+ "a can crushed in the hand"
1382
+ ),
1383
+ foley(
1384
+ "can_puncture_spray",
1385
+ [
1386
+ sceneNoise({
1387
+ type: "highpass",
1388
+ f: [2400, 3e3],
1389
+ a: 5e-3,
1390
+ d: [0.5, 0.7],
1391
+ vol: [0.2, 0.26]
1392
+ }),
1393
+ sceneNoise({ type: "bandpass", f: [600, 800], q: 2, d: 0.4, vol: 0.06 })
1394
+ ],
1395
+ "a can holed: the jet hissing out"
1396
+ ),
1397
+ foley(
1398
+ "bottle_open",
1399
+ [
1400
+ ...sceneMany(
1401
+ 5,
1402
+ () => sceneNoise({
1403
+ type: "bandpass",
1404
+ f: [2200, 3e3],
1405
+ q: 4,
1406
+ d: 8e-3,
1407
+ vol: [0.1, 0.16],
1408
+ delay: [0, 0.18]
1409
+ })
1410
+ ),
1411
+ sceneNoise({
1412
+ type: "highpass",
1413
+ f: 3800,
1414
+ a: 5e-3,
1415
+ d: 0.12,
1416
+ vol: [0.06, 0.1],
1417
+ delay: [0.18, 0.22]
1418
+ })
1419
+ ],
1420
+ "the screw cap of a bottle turning off"
1421
+ ),
1422
+ foley(
1423
+ "drink_gulp",
1424
+ [
1425
+ sceneNoise({
1426
+ type: "lowpass",
1427
+ f: [280, 360],
1428
+ a: 0.02,
1429
+ d: [0.1, 0.14],
1430
+ vol: [0.24, 0.3]
1431
+ }),
1432
+ sceneTone({ f: [140, 170], f2: 85, d: [0.08, 0.11], vol: [0.12, 0.16] })
1433
+ ],
1434
+ "a gulp"
1435
+ ),
1436
+ foley(
1437
+ "eat_crunch",
1438
+ [
1439
+ ...sceneMany(
1440
+ 4,
1441
+ () => sceneNoise({
1442
+ type: "bandpass",
1443
+ f: [1800, 3200],
1444
+ q: 1.5,
1445
+ d: [0.02, 0.04],
1446
+ vol: [0.12, 0.2],
1447
+ delay: [0, 0.12]
1448
+ })
1449
+ )
1450
+ ],
1451
+ "a bite of something crunchy"
1452
+ ),
1453
+ foley(
1454
+ "eat_chew",
1455
+ [
1456
+ sceneNoise({
1457
+ type: "lowpass",
1458
+ f: [450, 600],
1459
+ a: 0.03,
1460
+ d: [0.1, 0.14],
1461
+ vol: [0.12, 0.16]
1462
+ }),
1463
+ sceneNoise({
1464
+ type: "bandpass",
1465
+ f: [1100, 1400],
1466
+ q: 2,
1467
+ d: 0.04,
1468
+ vol: 0.04,
1469
+ delay: [0.03, 0.06]
1470
+ })
1471
+ ],
1472
+ "chewing"
1473
+ ),
1474
+ foley(
1475
+ "bandage_wrap",
1476
+ [
1477
+ sceneNoise({
1478
+ type: "bandpass",
1479
+ f: [1400, 1800],
1480
+ f2: 2400,
1481
+ q: 1,
1482
+ a: 0.04,
1483
+ d: [0.3, 0.4],
1484
+ vol: [0.12, 0.16]
1485
+ })
1486
+ ],
1487
+ "a bandage unrolled round a limb"
1488
+ ),
1489
+ foley(
1490
+ "pills_shake",
1491
+ [
1492
+ ...sceneMany(
1493
+ 8,
1494
+ () => sceneTone({
1495
+ f: [2400, 3600],
1496
+ d: 0.015,
1497
+ vol: [0.03, 0.05],
1498
+ delay: [0, 0.25]
1499
+ })
1500
+ ),
1501
+ sceneNoise({ type: "bandpass", f: [1500, 1900], q: 2, d: 0.25, vol: 0.05 })
1502
+ ],
1503
+ "pills shaken in their bottle"
1504
+ ),
1505
+ foley(
1506
+ "medkit_use",
1507
+ [
1508
+ ...click(1700, 0.24),
1509
+ sceneNoise({
1510
+ type: "bandpass",
1511
+ f: [1e3, 1400],
1512
+ q: 1,
1513
+ a: 0.03,
1514
+ d: [0.25, 0.32],
1515
+ vol: [0.08, 0.12],
1516
+ delay: [0.05, 0.08]
1517
+ })
1518
+ ],
1519
+ "a first aid kit opened and rummaged"
1520
+ ),
1521
+ foley("flashlight_click", click(2600, 0.3), "the switch of a flashlight")
1522
+ ];
1523
+ var FOLEY_BANK = {
1524
+ id: "foley",
1525
+ sounds: [...LEAF_FOLEY, ...ITEM_FOLEY]
1526
+ };
1527
+ var TAKES = [
1528
+ { f: 1, t: 1, v: 1 },
1529
+ { f: 1.08, t: 0.9, v: 0.92 },
1530
+ { f: 0.93, t: 1.12, v: 1.05 },
1531
+ { f: 1.03, t: 1.05, v: 0.88 }
1532
+ ];
1533
+ var FOOTSTEP_FALLOFF = { model: "inverse_square", k: 0.03, cutoffK: 0.03, minGain: 4e-3 };
1534
+ var BODY_FALLOFF = { model: "inverse_square", k: 0.012, cutoffK: 0.015, minGain: 4e-3 };
1535
+ var SURFACES = {
1536
+ concrete: { heel: { f: 95, d: 0.05, vol: 0.55 }, roll: { type: "bandpass", f: 2300, q: 1.1, d: 0.05, vol: 0.38 }, grains: { count: 2, f: 4200, q: 2, spread: 0.04, vol: 0.08 } },
1537
+ asphalt: { heel: { f: 90, d: 0.05, vol: 0.5 }, roll: { type: "bandpass", f: 1700, q: 0.9, d: 0.06, vol: 0.36 }, grains: { count: 4, f: 3600, q: 2.5, spread: 0.06, vol: 0.1 } },
1538
+ wood: { heel: { f: 130, d: 0.08, vol: 0.55 }, roll: { type: "lowpass", f: 1300, q: 0.8, d: 0.06, vol: 0.3 }, ring: [{ f: 210, d: 0.1, vol: 0.18 }, { f: 470, d: 0.06, vol: 0.06 }] },
1539
+ tile: { heel: { f: 110, d: 0.04, vol: 0.45 }, roll: { type: "bandpass", f: 3600, q: 2, d: 0.03, vol: 0.42 }, ring: [{ f: 1900, d: 0.03, vol: 0.05 }] },
1540
+ dirt: { heel: { f: 75, d: 0.06, vol: 0.45 }, roll: { type: "lowpass", f: 750, q: 0.7, d: 0.09, vol: 0.4 }, grains: { count: 3, f: 1800, q: 1.5, spread: 0.07, vol: 0.06 } },
1541
+ grass: { heel: { f: 70, d: 0.05, vol: 0.32 }, roll: { type: "highpass", f: 2600, q: 0.7, d: 0.13, vol: 0.28 }, grains: { count: 4, f: 5200, q: 1.2, spread: 0.1, vol: 0.07 } },
1542
+ gravel: { heel: { f: 80, d: 0.05, vol: 0.4 }, roll: { type: "lowpass", f: 950, q: 0.8, d: 0.1, vol: 0.3 }, grains: { count: 8, f: 2600, q: 3, spread: 0.13, vol: 0.2 } },
1543
+ sand: { heel: { f: 65, d: 0.06, vol: 0.3 }, roll: { type: "bandpass", f: 1500, q: 0.6, d: 0.16, vol: 0.3 }, grains: { count: 5, f: 4800, q: 1.5, spread: 0.12, vol: 0.05 } },
1544
+ metal: { heel: { f: 120, d: 0.05, vol: 0.5 }, roll: { type: "bandpass", f: 2800, q: 1.5, d: 0.03, vol: 0.25 }, ring: [{ f: 420, d: 0.25, vol: 0.16 }, { f: 1130, d: 0.18, vol: 0.09 }, { f: 2470, d: 0.1, vol: 0.04 }] },
1545
+ water: { heel: { f: 70, d: 0.04, vol: 0.25 }, roll: { type: "bandpass", f: 3e3, q: 1.2, d: 0.1, vol: 0.18 }, splash: { f: 1100, f2: 380, d: 0.22, vol: 0.55 }, grains: { count: 4, f: 2400, q: 6, spread: 0.18, vol: 0.12 } },
1546
+ glass: { heel: { f: 90, d: 0.04, vol: 0.4 }, roll: { type: "highpass", f: 4500, q: 0.8, d: 0.06, vol: 0.2 }, grains: { count: 9, f: 6200, q: 5, spread: 0.12, vol: 0.22 }, ring: [{ f: 3900, d: 0.04, vol: 0.04 }, { f: 5300, d: 0.03, vol: 0.03 }] },
1547
+ carpet: { heel: { f: 70, d: 0.05, vol: 0.32 }, roll: { type: "lowpass", f: 420, q: 0.7, d: 0.07, vol: 0.3 } }
1548
+ };
1549
+ var GAITS = {
1550
+ walk: { vol: 1, bright: 1, toe: 0.075, short: 1 },
1551
+ run: { vol: 1.35, bright: 1.25, toe: 0.035, short: 0.75 }
1552
+ };
1553
+ var grainLayers = (g, take, start, scale) => Array.from(
1554
+ { length: g.count },
1555
+ (_, i) => sceneNoise({ type: "bandpass", f: [g.f * take.f * 0.85, g.f * take.f * 1.15], q: g.q, d: [8e-3, 0.02], vol: g.vol * scale * take.v, delay: start + (i + 0.5) / g.count * g.spread * take.t })
1556
+ );
1557
+ var ringLayers = (rings, take, scale, at = 0) => rings.map((r) => sceneTone({ f: r.f * take.f, d: r.d * take.t, vol: r.vol * scale * take.v, delay: at }));
1558
+ function footLayers(surface, take, gait, weight = 1) {
1559
+ const s = SURFACES[surface];
1560
+ const toe = gait.toe * take.t;
1561
+ return [
1562
+ sceneTone({ f: s.heel.f * take.f * weight ** -0.3, f2: s.heel.f * take.f * 0.6, d: s.heel.d * gait.short * take.t * weight ** 0.5, vol: s.heel.vol * gait.vol * take.v * weight ** 0.5 }),
1563
+ sceneNoise({ type: "lowpass", f: 500 * gait.bright, d: 0.02 * take.t, vol: 0.18 * gait.vol * take.v * weight ** 0.5 }),
1564
+ sceneNoise({ type: s.roll.type, f: [s.roll.f * take.f * gait.bright * 0.92, s.roll.f * take.f * gait.bright * 1.08], q: s.roll.q, d: s.roll.d * gait.short * take.t * weight ** 0.3, vol: s.roll.vol * gait.vol * take.v, delay: toe }),
1565
+ ...s.grains ? grainLayers(s.grains, take, toe * 0.5, gait.vol * weight ** 0.5) : [],
1566
+ ...s.ring ? ringLayers(s.ring, take, gait.vol * weight ** 0.5) : [],
1567
+ ...s.splash ? [sceneNoise({ type: "bandpass", f: s.splash.f * take.f, f2: s.splash.f2 * take.f, q: 1.4, d: s.splash.d * take.t * weight ** 0.4, vol: s.splash.vol * gait.vol * take.v * weight ** 0.5 })] : []
1568
+ ];
1569
+ }
1570
+ var quieter = (level, layers) => layers.map((layer) => {
1571
+ const gain = layer.gain ?? 1;
1572
+ if (typeof gain === "number") return { ...layer, gain: gain * level };
1573
+ if (Array.isArray(gain)) return { ...layer, gain: [gain[0] * level, gain[1] * level] };
1574
+ return layer;
1575
+ });
1576
+ var recipe = (id, layers, falloff, bus = "world") => ({ id, bus, pan: true, layers, falloff, sources: ["sdk"] });
1577
+ var takeId = (id, index) => `${id}_${String(index + 1).padStart(2, "0")}`;
1578
+ function takes(id, layersOf, falloff, rate = [0.96, 1.04], bus) {
1579
+ const sounds = TAKES.map((take, index) => recipe(takeId(id, index), layersOf(take, index), falloff, bus));
1580
+ return { sounds, set: { id, variants: sounds.map((sound) => sound.id), rate } };
1581
+ }
1582
+ var footstep = (surface, gait) => takes(footstepSoundId(surface, gait), (take) => footLayers(surface, take, GAITS[gait]), FOOTSTEP_FALLOFF);
1583
+ var LANDINGS = { light: { weight: 1.4, cloth: 0.12 }, heavy: { weight: 2.4, cloth: 0.22 } };
1584
+ var LANDING_LEVEL = 0.65;
1585
+ var landing = (surface, landing2) => takes(
1586
+ `land_${surface}_${landing2}`,
1587
+ (take) => quieter(LANDING_LEVEL, [
1588
+ // both feet, a hair apart, then the knees taking the weight (a low body thump) and the clothes settling
1589
+ ...footLayers(surface, take, GAITS.run, LANDINGS[landing2].weight),
1590
+ ...footLayers(surface, { ...take, v: take.v * 0.6 }, GAITS.run, LANDINGS[landing2].weight * 0.6).map((layer) => ({ ...layer, at: (typeof layer.at === "number" ? layer.at : 0) + 0.018 * take.t })),
1591
+ sceneTone({ f: 60 * take.f, f2: 38, d: 0.14 * LANDINGS[landing2].weight * take.t, vol: 0.22 * LANDINGS[landing2].weight ** 0.7 * take.v, delay: 0.02 }),
1592
+ sceneNoise({ type: "bandpass", f: [1800, 2600], q: 0.8, d: 0.18, vol: LANDINGS[landing2].cloth * take.v, delay: 0.04 })
1593
+ ]),
1594
+ FOOTSTEP_FALLOFF
1595
+ );
1596
+ var whoosh = (blow, from, to, d, vol, q = 1.6) => (take) => [
1597
+ // the air: a band sweeping up as the limb speeds up; it peaks `SWING_LEAD_SECONDS` in, the moment before the contact, then dies away
1598
+ sceneNoise({ type: "bandpass", f: from * take.f, f2: to * take.f, q, a: SWING_LEAD_SECONDS[blow], d: d * take.t, vol: vol * take.v }),
1599
+ sceneNoise({ type: "lowpass", f: 600 * take.f, a: SWING_LEAD_SECONDS[blow], d: d * take.t * 0.8, vol: vol * 0.35 * take.v })
1600
+ ];
1601
+ var fleshHit = (o) => (take) => [
1602
+ sceneNoise({ type: "bandpass", f: o.slapF * take.f, q: 1.2, d: 0.03 * take.t, vol: o.slap * take.v }),
1603
+ sceneNoise({ type: "highpass", f: 3500 * take.f, d: 0.012, vol: o.slap * 0.4 * take.v }),
1604
+ sceneTone({ f: o.thudF * take.f, f2: o.thudF * 0.5, d: o.thudD * take.t, vol: o.thud * take.v }),
1605
+ sceneNoise({ type: "lowpass", f: 600 * take.f, d: o.thudD * 1.2 * take.t, vol: o.thud * 0.5 * take.v }),
1606
+ ...o.crack ? [sceneNoise({ type: "highpass", f: 2500, d: 0.015, vol: o.crack * take.v, delay: 6e-3 }), sceneTone({ wave: "square", f: 900 * take.f, f2: 300, d: 0.02, vol: o.crack * 0.15 * take.v, delay: 6e-3 })] : [],
1607
+ ...o.wet ? [sceneNoise({ type: "bandpass", f: 1400 * take.f, f2: 500, q: 2.5, d: 0.12 * take.t, vol: o.wet * take.v, delay: 0.01 })] : []
1608
+ ];
1609
+ var knock = (o) => (take) => [
1610
+ sceneNoise({ type: "bandpass", f: o.clickF * take.f, q: 1.5, d: 0.018, vol: o.click * take.v }),
1611
+ ...o.tones.map(([f, d, vol]) => sceneTone({ f: f * take.f, d: d * take.t, vol: vol * take.v }))
1612
+ ];
1613
+ var voice = (o) => (take) => [
1614
+ sceneVoice({ f0: o.f0 * take.f, f1: o.f1 * take.f, d: o.d * take.t, fA: o.fA * take.f, fB: o.fB * take.f, noise: o.noise, vol: o.vol * take.v })
1615
+ ];
1616
+ var BODY = {
1617
+ jump: (take) => [
1618
+ sceneNoise({ type: "bandpass", f: 900 * take.f, f2: 1700 * take.f, q: 1, a: 0.03, d: 0.12, vol: 0.18 * take.v }),
1619
+ sceneNoise({ type: "bandpass", f: 2200 * take.f, q: 0.8, d: 0.04, vol: 0.12 * take.v }),
1620
+ sceneTone({ f: 85 * take.f, f2: 60, d: 0.04, vol: 0.2 * take.v })
1621
+ ],
1622
+ cloth_rustle: (take) => [
1623
+ { ...sceneNoise({ type: "bandpass", f: 2400 * take.f, q: 0.8, a: 0.06, d: 0.22 * take.t, vol: 0.12 * take.v }), modulators: [{ target: "gain", wave: "triangle", rate: [9, 14], depth: 0.5 }] }
1624
+ ],
1625
+ body_fall: (take) => [
1626
+ sceneTone({ f: 58 * take.f, f2: 35, d: 0.28 * take.t, vol: 0.9 * take.v }),
1627
+ sceneNoise({ type: "lowpass", f: 480 * take.f, d: 0.3 * take.t, vol: 0.55 * take.v }),
1628
+ sceneNoise({ type: "bandpass", f: 1300 * take.f, q: 1, d: 0.05, vol: 0.3 * take.v }),
1629
+ // the limbs a moment later, and the clothes
1630
+ sceneTone({ f: 75 * take.f, f2: 45, d: 0.12, vol: 0.4 * take.v, delay: 0.13 * take.t }),
1631
+ sceneNoise({ type: "bandpass", f: 2200, q: 0.8, d: 0.2, vol: 0.12 * take.v, delay: 0.05 })
1632
+ ],
1633
+ fall_damage: (take) => [
1634
+ ...BODY.body_fall(take),
1635
+ sceneNoise({ type: "highpass", f: 2800, d: 0.02, vol: 0.35 * take.v, delay: 0.01 }),
1636
+ ...voice({ f0: 170, f1: 110, d: 0.32, fA: 650, fB: 1150, noise: 0.25, vol: 0.32 })(take).map((layer) => ({ ...layer, at: 0.08 }))
1637
+ ],
1638
+ player_hurt: voice({ f0: 150, f1: 105, d: 0.26, fA: 620, fB: 1100, noise: 0.3, vol: 0.35 }),
1639
+ player_breath_run: (take) => [
1640
+ sceneNoise({ type: "bandpass", f: 1200 * take.f, q: 1, a: 0.08, d: 0.22 * take.t, vol: 0.25 * take.v }),
1641
+ sceneNoise({ type: "bandpass", f: 900 * take.f, q: 1, a: 0.06, d: 0.26 * take.t, vol: 0.3 * take.v, delay: 0.3 * take.t })
1642
+ ],
1643
+ player_death: voice({ f0: 135, f1: 68, d: 1, fA: 560, fB: 980, noise: 0.35, vol: 0.4 }),
1644
+ bite: (take) => [
1645
+ sceneNoise({ type: "highpass", f: 2600, d: 0.015, vol: 0.4 * take.v }),
1646
+ sceneNoise({ type: "bandpass", f: 1600 * take.f, f2: 450, q: 2.2, d: 0.16 * take.t, vol: 0.55 * take.v, delay: 0.01 }),
1647
+ sceneNoise({ type: "bandpass", f: 3200 * take.f, f2: 1800, q: 1.2, d: 0.22 * take.t, vol: 0.25 * take.v, delay: 0.09 }),
1648
+ sceneTone({ f: 120 * take.f, f2: 70, d: 0.06, vol: 0.3 * take.v })
1649
+ ],
1650
+ grab: (take) => [
1651
+ sceneNoise({ type: "bandpass", f: 1900 * take.f, q: 0.9, a: 4e-3, d: 0.13 * take.t, vol: 0.32 * take.v }),
1652
+ sceneTone({ f: 95 * take.f, f2: 60, d: 0.07, vol: 0.3 * take.v }),
1653
+ sceneNoise({ type: "lowpass", f: 700, d: 0.08, vol: 0.2 * take.v })
1654
+ ],
1655
+ punch_swing: whoosh("punch", 450, 1500, 0.16, 0.9),
1656
+ punch_hit_body: fleshHit({ slap: 0.55, slapF: 1500, thud: 0.6, thudF: 115, thudD: 0.09 }),
1657
+ punch_hit_face: fleshHit({ slap: 0.75, slapF: 2300, thud: 0.45, thudF: 150, thudD: 0.07, crack: 0.25 }),
1658
+ punch_hit_object: knock({ clickF: 1800, click: 0.3, tones: [[210, 0.04, 0.25]] }),
1659
+ kick_swing: whoosh("kick", 280, 950, 0.22, 1, 1.3),
1660
+ kick_hit: fleshHit({ slap: 0.45, slapF: 1100, thud: 0.85, thudF: 82, thudD: 0.14 }),
1661
+ kick_hit_object: knock({ clickF: 1e3, click: 0.3, tones: [[92, 0.08, 0.5]] }),
1662
+ shove_two_hands: (take) => [
1663
+ sceneNoise({ type: "bandpass", f: 950 * take.f, q: 0.9, a: 0.01, d: 0.13 * take.t, vol: 0.38 * take.v }),
1664
+ sceneTone({ f: 100 * take.f, f2: 60, d: 0.1 * take.t, vol: 0.45 * take.v }),
1665
+ sceneNoise({ type: "bandpass", f: 2300, q: 0.8, d: 0.16, vol: 0.12 * take.v, delay: 0.03 })
1666
+ ],
1667
+ knife_swing: whoosh("blade", 1900, 4600, 0.12, 1.1, 2.2),
1668
+ knife_stab: fleshHit({ slap: 0.2, slapF: 1200, thud: 0.4, thudF: 160, thudD: 0.06, wet: 0.5 }),
1669
+ knife_slash: (take) => [
1670
+ sceneNoise({ type: "highpass", f: 3200 * take.f, f2: 1800, d: 0.13 * take.t, vol: 0.35 * take.v }),
1671
+ sceneNoise({ type: "bandpass", f: 1300 * take.f, f2: 600, q: 2.5, d: 0.12 * take.t, vol: 0.35 * take.v, delay: 0.02 })
1672
+ ],
1673
+ knife_hit_object: knock({ clickF: 3200, click: 0.25, tones: [[2800, 0.08, 0.07], [4150, 0.06, 0.05]] }),
1674
+ blunt_swing: whoosh("blunt", 220, 760, 0.28, 1.1, 1.5),
1675
+ blunt_hit: fleshHit({ slap: 0.35, slapF: 900, thud: 1, thudF: 70, thudD: 0.18, crack: 0.3 }),
1676
+ blunt_hit_object: knock({ clickF: 1400, click: 0.35, tones: [[300, 0.12, 0.25], [760, 0.08, 0.12]] }),
1677
+ axe_swing: whoosh("chop", 190, 620, 0.3, 1.2, 1.4),
1678
+ axe_chop: fleshHit({ slap: 0.3, slapF: 1400, thud: 0.75, thudF: 140, thudD: 0.1, crack: 0.35, wet: 0.45 }),
1679
+ axe_hit_object: knock({ clickF: 2200, click: 0.4, tones: [[1500, 0.15, 0.1], [2300, 0.1, 0.06], [140, 0.1, 0.35]] })
1680
+ };
1681
+ var BODY_BUS = { player_hurt: "voices", player_death: "voices", player_breath_run: "voices", fall_damage: "voices" };
1682
+ var built = [
1683
+ ...SURFACE_IDS.flatMap((surface) => GAIT_IDS.map((gait) => footstep(surface, gait))),
1684
+ ...SURFACE_IDS.flatMap((surface) => LANDING_IDS.map((l) => landing(surface, l))),
1685
+ ...BODY_SOUND_IDS.map((id) => takes(id, BODY[id], BODY_FALLOFF, id.endsWith("_swing") ? [0.94, 1.06] : [0.96, 1.04], BODY_BUS[id]))
1686
+ ];
1687
+ var BODY_FOLEY_BANK = {
1688
+ id: "body_foley",
1689
+ sounds: built.flatMap((entry) => entry.sounds),
1690
+ sets: built.map((entry) => entry.set)
1013
1691
  };
1692
+ var BODY_FOLEY_SET_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
1014
1693
 
1015
1694
  // src/audio/recipes.ts
1016
1695
  var RAIN_LOOP = {