@its-not-rocket-science/ananke 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/LICENSE +21 -0
  3. package/README.md +2199 -0
  4. package/STABLE_API.md +266 -0
  5. package/dist/src/anatomy/anatomy-compiler.d.ts +14 -0
  6. package/dist/src/anatomy/anatomy-compiler.js +277 -0
  7. package/dist/src/anatomy/anatomy-contracts.d.ts +94 -0
  8. package/dist/src/anatomy/anatomy-contracts.js +1 -0
  9. package/dist/src/anatomy/anatomy-helpers.d.ts +82 -0
  10. package/dist/src/anatomy/anatomy-helpers.js +233 -0
  11. package/dist/src/anatomy/anatomy-schema.d.ts +28 -0
  12. package/dist/src/anatomy/anatomy-schema.js +388 -0
  13. package/dist/src/anatomy/index.d.ts +4 -0
  14. package/dist/src/anatomy/index.js +4 -0
  15. package/dist/src/archetypes.d.ts +87 -0
  16. package/dist/src/archetypes.js +285 -0
  17. package/dist/src/arena.d.ts +173 -0
  18. package/dist/src/arena.js +695 -0
  19. package/dist/src/bridge/bridge-engine.d.ts +46 -0
  20. package/dist/src/bridge/bridge-engine.js +252 -0
  21. package/dist/src/bridge/index.d.ts +4 -0
  22. package/dist/src/bridge/index.js +5 -0
  23. package/dist/src/bridge/interpolation.d.ts +64 -0
  24. package/dist/src/bridge/interpolation.js +130 -0
  25. package/dist/src/bridge/mapping.d.ts +33 -0
  26. package/dist/src/bridge/mapping.js +54 -0
  27. package/dist/src/bridge/types.d.ts +94 -0
  28. package/dist/src/bridge/types.js +2 -0
  29. package/dist/src/campaign.d.ts +141 -0
  30. package/dist/src/campaign.js +235 -0
  31. package/dist/src/channels.d.ts +15 -0
  32. package/dist/src/channels.js +20 -0
  33. package/dist/src/chronicle.d.ts +124 -0
  34. package/dist/src/chronicle.js +232 -0
  35. package/dist/src/collective-activities.d.ts +154 -0
  36. package/dist/src/collective-activities.js +247 -0
  37. package/dist/src/competence/acoustic.d.ts +101 -0
  38. package/dist/src/competence/acoustic.js +242 -0
  39. package/dist/src/competence/catalogue.d.ts +30 -0
  40. package/dist/src/competence/catalogue.js +241 -0
  41. package/dist/src/competence/crafting.d.ts +35 -0
  42. package/dist/src/competence/crafting.js +88 -0
  43. package/dist/src/competence/engineering.d.ts +53 -0
  44. package/dist/src/competence/engineering.js +108 -0
  45. package/dist/src/competence/framework.d.ts +68 -0
  46. package/dist/src/competence/framework.js +694 -0
  47. package/dist/src/competence/index.d.ts +12 -0
  48. package/dist/src/competence/index.js +13 -0
  49. package/dist/src/competence/interspecies.d.ts +81 -0
  50. package/dist/src/competence/interspecies.js +108 -0
  51. package/dist/src/competence/language.d.ts +79 -0
  52. package/dist/src/competence/language.js +115 -0
  53. package/dist/src/competence/naturalist.d.ts +97 -0
  54. package/dist/src/competence/naturalist.js +187 -0
  55. package/dist/src/competence/navigation.d.ts +24 -0
  56. package/dist/src/competence/navigation.js +48 -0
  57. package/dist/src/competence/performance.d.ts +125 -0
  58. package/dist/src/competence/performance.js +210 -0
  59. package/dist/src/competence/teaching.d.ts +64 -0
  60. package/dist/src/competence/teaching.js +121 -0
  61. package/dist/src/competence/willpower.d.ts +74 -0
  62. package/dist/src/competence/willpower.js +114 -0
  63. package/dist/src/crafting/index.d.ts +55 -0
  64. package/dist/src/crafting/index.js +229 -0
  65. package/dist/src/crafting/manufacturing.d.ts +83 -0
  66. package/dist/src/crafting/manufacturing.js +165 -0
  67. package/dist/src/crafting/materials.d.ts +53 -0
  68. package/dist/src/crafting/materials.js +120 -0
  69. package/dist/src/crafting/recipes.d.ts +75 -0
  70. package/dist/src/crafting/recipes.js +233 -0
  71. package/dist/src/crafting/workshops.d.ts +61 -0
  72. package/dist/src/crafting/workshops.js +170 -0
  73. package/dist/src/debug.d.ts +86 -0
  74. package/dist/src/debug.js +76 -0
  75. package/dist/src/derive.d.ts +21 -0
  76. package/dist/src/derive.js +88 -0
  77. package/dist/src/describe.d.ts +29 -0
  78. package/dist/src/describe.js +276 -0
  79. package/dist/src/dialogue.d.ts +122 -0
  80. package/dist/src/dialogue.js +266 -0
  81. package/dist/src/dist.d.ts +20 -0
  82. package/dist/src/dist.js +39 -0
  83. package/dist/src/downtime.d.ts +89 -0
  84. package/dist/src/downtime.js +391 -0
  85. package/dist/src/economy.d.ts +116 -0
  86. package/dist/src/economy.js +182 -0
  87. package/dist/src/emotional-contagion.d.ts +142 -0
  88. package/dist/src/emotional-contagion.js +274 -0
  89. package/dist/src/equipment.d.ts +206 -0
  90. package/dist/src/equipment.js +598 -0
  91. package/dist/src/faction.d.ts +102 -0
  92. package/dist/src/faction.js +237 -0
  93. package/dist/src/generate.d.ts +35 -0
  94. package/dist/src/generate.js +166 -0
  95. package/dist/src/index.d.ts +42 -0
  96. package/dist/src/index.js +54 -0
  97. package/dist/src/inheritance.d.ts +69 -0
  98. package/dist/src/inheritance.js +136 -0
  99. package/dist/src/inventory.d.ts +194 -0
  100. package/dist/src/inventory.js +637 -0
  101. package/dist/src/item-durability.d.ts +69 -0
  102. package/dist/src/item-durability.js +308 -0
  103. package/dist/src/legend.d.ts +97 -0
  104. package/dist/src/legend.js +269 -0
  105. package/dist/src/lod.d.ts +9 -0
  106. package/dist/src/lod.js +84 -0
  107. package/dist/src/metrics.d.ts +51 -0
  108. package/dist/src/metrics.js +91 -0
  109. package/dist/src/model3d.d.ts +138 -0
  110. package/dist/src/model3d.js +214 -0
  111. package/dist/src/mythology.d.ts +101 -0
  112. package/dist/src/mythology.js +308 -0
  113. package/dist/src/narrative-render.d.ts +42 -0
  114. package/dist/src/narrative-render.js +194 -0
  115. package/dist/src/narrative-stress.d.ts +123 -0
  116. package/dist/src/narrative-stress.js +183 -0
  117. package/dist/src/narrative.d.ts +44 -0
  118. package/dist/src/narrative.js +257 -0
  119. package/dist/src/party.d.ts +70 -0
  120. package/dist/src/party.js +226 -0
  121. package/dist/src/polity.d.ts +262 -0
  122. package/dist/src/polity.js +398 -0
  123. package/dist/src/presets.d.ts +42 -0
  124. package/dist/src/presets.js +170 -0
  125. package/dist/src/progression.d.ts +170 -0
  126. package/dist/src/progression.js +256 -0
  127. package/dist/src/quest-generators.d.ts +76 -0
  128. package/dist/src/quest-generators.js +534 -0
  129. package/dist/src/quest.d.ts +239 -0
  130. package/dist/src/quest.js +520 -0
  131. package/dist/src/relationships-effects.d.ts +75 -0
  132. package/dist/src/relationships-effects.js +219 -0
  133. package/dist/src/relationships.d.ts +104 -0
  134. package/dist/src/relationships.js +347 -0
  135. package/dist/src/replay.d.ts +47 -0
  136. package/dist/src/replay.js +82 -0
  137. package/dist/src/rng.d.ts +9 -0
  138. package/dist/src/rng.js +37 -0
  139. package/dist/src/settlement-services.d.ts +67 -0
  140. package/dist/src/settlement-services.js +267 -0
  141. package/dist/src/settlement.d.ts +143 -0
  142. package/dist/src/settlement.js +419 -0
  143. package/dist/src/sim/action.d.ts +28 -0
  144. package/dist/src/sim/action.js +12 -0
  145. package/dist/src/sim/aging.d.ts +95 -0
  146. package/dist/src/sim/aging.js +243 -0
  147. package/dist/src/sim/ai/decide.d.ts +10 -0
  148. package/dist/src/sim/ai/decide.js +267 -0
  149. package/dist/src/sim/ai/perception.d.ts +12 -0
  150. package/dist/src/sim/ai/perception.js +54 -0
  151. package/dist/src/sim/ai/personality.d.ts +54 -0
  152. package/dist/src/sim/ai/personality.js +202 -0
  153. package/dist/src/sim/ai/presets.d.ts +2 -0
  154. package/dist/src/sim/ai/presets.js +28 -0
  155. package/dist/src/sim/ai/system.d.ts +6 -0
  156. package/dist/src/sim/ai/system.js +13 -0
  157. package/dist/src/sim/ai/targeting.d.ts +8 -0
  158. package/dist/src/sim/ai/targeting.js +42 -0
  159. package/dist/src/sim/ai/types.d.ts +14 -0
  160. package/dist/src/sim/ai/types.js +1 -0
  161. package/dist/src/sim/body.d.ts +9 -0
  162. package/dist/src/sim/body.js +32 -0
  163. package/dist/src/sim/bodyplan.d.ts +161 -0
  164. package/dist/src/sim/bodyplan.js +677 -0
  165. package/dist/src/sim/capability.d.ts +135 -0
  166. package/dist/src/sim/capability.js +8 -0
  167. package/dist/src/sim/combat.d.ts +21 -0
  168. package/dist/src/sim/combat.js +77 -0
  169. package/dist/src/sim/commandBuilders.d.ts +11 -0
  170. package/dist/src/sim/commandBuilders.js +39 -0
  171. package/dist/src/sim/commands.d.ts +71 -0
  172. package/dist/src/sim/commands.js +8 -0
  173. package/dist/src/sim/condition.d.ts +35 -0
  174. package/dist/src/sim/condition.js +21 -0
  175. package/dist/src/sim/cone.d.ts +40 -0
  176. package/dist/src/sim/cone.js +44 -0
  177. package/dist/src/sim/context.d.ts +68 -0
  178. package/dist/src/sim/context.js +1 -0
  179. package/dist/src/sim/density.d.ts +14 -0
  180. package/dist/src/sim/density.js +33 -0
  181. package/dist/src/sim/disease.d.ts +141 -0
  182. package/dist/src/sim/disease.js +353 -0
  183. package/dist/src/sim/entity.d.ts +251 -0
  184. package/dist/src/sim/entity.js +19 -0
  185. package/dist/src/sim/events.d.ts +25 -0
  186. package/dist/src/sim/events.js +5 -0
  187. package/dist/src/sim/explosion.d.ts +40 -0
  188. package/dist/src/sim/explosion.js +40 -0
  189. package/dist/src/sim/formation-unit.d.ts +138 -0
  190. package/dist/src/sim/formation-unit.js +197 -0
  191. package/dist/src/sim/formation.d.ts +12 -0
  192. package/dist/src/sim/formation.js +54 -0
  193. package/dist/src/sim/frontage.d.ts +30 -0
  194. package/dist/src/sim/frontage.js +84 -0
  195. package/dist/src/sim/grapple.d.ts +100 -0
  196. package/dist/src/sim/grapple.js +480 -0
  197. package/dist/src/sim/hazard.d.ts +104 -0
  198. package/dist/src/sim/hazard.js +201 -0
  199. package/dist/src/sim/hydrostatic.d.ts +58 -0
  200. package/dist/src/sim/hydrostatic.js +117 -0
  201. package/dist/src/sim/impairment.d.ts +20 -0
  202. package/dist/src/sim/impairment.js +162 -0
  203. package/dist/src/sim/indexing.d.ts +7 -0
  204. package/dist/src/sim/indexing.js +7 -0
  205. package/dist/src/sim/injury.d.ts +54 -0
  206. package/dist/src/sim/injury.js +66 -0
  207. package/dist/src/sim/intent.d.ts +26 -0
  208. package/dist/src/sim/intent.js +7 -0
  209. package/dist/src/sim/kernel.d.ts +45 -0
  210. package/dist/src/sim/kernel.js +1992 -0
  211. package/dist/src/sim/kinds.d.ts +64 -0
  212. package/dist/src/sim/kinds.js +56 -0
  213. package/dist/src/sim/knockback.d.ts +50 -0
  214. package/dist/src/sim/knockback.js +82 -0
  215. package/dist/src/sim/limb.d.ts +48 -0
  216. package/dist/src/sim/limb.js +78 -0
  217. package/dist/src/sim/medical.d.ts +32 -0
  218. package/dist/src/sim/medical.js +33 -0
  219. package/dist/src/sim/morale.d.ts +69 -0
  220. package/dist/src/sim/morale.js +92 -0
  221. package/dist/src/sim/mount.d.ts +150 -0
  222. package/dist/src/sim/mount.js +225 -0
  223. package/dist/src/sim/nutrition.d.ts +74 -0
  224. package/dist/src/sim/nutrition.js +168 -0
  225. package/dist/src/sim/occlusion.d.ts +8 -0
  226. package/dist/src/sim/occlusion.js +71 -0
  227. package/dist/src/sim/push.d.ts +11 -0
  228. package/dist/src/sim/push.js +79 -0
  229. package/dist/src/sim/ranged.d.ts +44 -0
  230. package/dist/src/sim/ranged.js +69 -0
  231. package/dist/src/sim/seeds.d.ts +3 -0
  232. package/dist/src/sim/seeds.js +16 -0
  233. package/dist/src/sim/sensory-extended.d.ts +103 -0
  234. package/dist/src/sim/sensory-extended.js +181 -0
  235. package/dist/src/sim/sensory.d.ts +38 -0
  236. package/dist/src/sim/sensory.js +109 -0
  237. package/dist/src/sim/skills.d.ts +70 -0
  238. package/dist/src/sim/skills.js +69 -0
  239. package/dist/src/sim/sleep.d.ts +107 -0
  240. package/dist/src/sim/sleep.js +215 -0
  241. package/dist/src/sim/spatial.d.ts +8 -0
  242. package/dist/src/sim/spatial.js +59 -0
  243. package/dist/src/sim/step/capability.d.ts +8 -0
  244. package/dist/src/sim/step/capability.js +77 -0
  245. package/dist/src/sim/step/concentration.d.ts +9 -0
  246. package/dist/src/sim/step/concentration.js +25 -0
  247. package/dist/src/sim/step/effects.d.ts +17 -0
  248. package/dist/src/sim/step/effects.js +96 -0
  249. package/dist/src/sim/step/energy.d.ts +3 -0
  250. package/dist/src/sim/step/energy.js +31 -0
  251. package/dist/src/sim/step/hazards.d.ts +4 -0
  252. package/dist/src/sim/step/hazards.js +19 -0
  253. package/dist/src/sim/step/injury.d.ts +10 -0
  254. package/dist/src/sim/step/injury.js +353 -0
  255. package/dist/src/sim/step/morale.d.ts +11 -0
  256. package/dist/src/sim/step/morale.js +130 -0
  257. package/dist/src/sim/step/movement.d.ts +5 -0
  258. package/dist/src/sim/step/movement.js +172 -0
  259. package/dist/src/sim/step/push.d.ts +11 -0
  260. package/dist/src/sim/step/push.js +79 -0
  261. package/dist/src/sim/step/substances.d.ts +3 -0
  262. package/dist/src/sim/step/substances.js +75 -0
  263. package/dist/src/sim/substance.d.ts +38 -0
  264. package/dist/src/sim/substance.js +57 -0
  265. package/dist/src/sim/systemic-toxicology.d.ts +109 -0
  266. package/dist/src/sim/systemic-toxicology.js +263 -0
  267. package/dist/src/sim/team.d.ts +9 -0
  268. package/dist/src/sim/team.js +37 -0
  269. package/dist/src/sim/tech.d.ts +36 -0
  270. package/dist/src/sim/tech.js +46 -0
  271. package/dist/src/sim/terrain.d.ts +121 -0
  272. package/dist/src/sim/terrain.js +141 -0
  273. package/dist/src/sim/testing.d.ts +13 -0
  274. package/dist/src/sim/testing.js +100 -0
  275. package/dist/src/sim/thermoregulation.d.ts +77 -0
  276. package/dist/src/sim/thermoregulation.js +161 -0
  277. package/dist/src/sim/tick.d.ts +3 -0
  278. package/dist/src/sim/tick.js +3 -0
  279. package/dist/src/sim/toxicology.d.ts +52 -0
  280. package/dist/src/sim/toxicology.js +104 -0
  281. package/dist/src/sim/trace.d.ts +141 -0
  282. package/dist/src/sim/trace.js +1 -0
  283. package/dist/src/sim/tuning.d.ts +16 -0
  284. package/dist/src/sim/tuning.js +42 -0
  285. package/dist/src/sim/vec3.d.ts +14 -0
  286. package/dist/src/sim/vec3.js +31 -0
  287. package/dist/src/sim/weapon_dynamics.d.ts +102 -0
  288. package/dist/src/sim/weapon_dynamics.js +142 -0
  289. package/dist/src/sim/weather.d.ts +95 -0
  290. package/dist/src/sim/weather.js +105 -0
  291. package/dist/src/sim/world.d.ts +52 -0
  292. package/dist/src/sim/world.js +1 -0
  293. package/dist/src/sim/wound-aging.d.ts +120 -0
  294. package/dist/src/sim/wound-aging.js +223 -0
  295. package/dist/src/species.d.ts +106 -0
  296. package/dist/src/species.js +664 -0
  297. package/dist/src/story-arcs.d.ts +17 -0
  298. package/dist/src/story-arcs.js +276 -0
  299. package/dist/src/tech-diffusion.d.ts +80 -0
  300. package/dist/src/tech-diffusion.js +185 -0
  301. package/dist/src/traits.d.ts +25 -0
  302. package/dist/src/traits.js +178 -0
  303. package/dist/src/types.d.ts +117 -0
  304. package/dist/src/types.js +1 -0
  305. package/dist/src/units.d.ts +41 -0
  306. package/dist/src/units.js +64 -0
  307. package/dist/src/weapons.d.ts +20 -0
  308. package/dist/src/weapons.js +824 -0
  309. package/dist/src/world-generation.d.ts +52 -0
  310. package/dist/src/world-generation.js +301 -0
  311. package/package.json +74 -0
@@ -0,0 +1,101 @@
1
+ import type { Q } from "../units.js";
2
+ import type { Entity } from "../sim/entity.js";
3
+ /** Acoustic signature of an entity — how much noise it produces. */
4
+ export interface AcousticSignature {
5
+ /** Base noise level in arbitrary units (0 = silent, 100 = very loud). */
6
+ baseNoise: number;
7
+ /** Noise from movement (scales with velocity). */
8
+ movementNoise: number;
9
+ /** Noise from equipment (armour clanking, weapon swinging). */
10
+ equipmentNoise: number;
11
+ /** Total noise level (computed). */
12
+ totalNoise: number;
13
+ }
14
+ /** Formation signal types for military/organized coordination. */
15
+ export type FormationSignal = "advance" | "retreat" | "hold" | "flank_left" | "flank_right" | "rally";
16
+ /** Outcome of a formation signal transmission attempt. */
17
+ export interface FormationSignalOutcome {
18
+ /** Clarity of the signal (0–1). */
19
+ clarity_Q: Q;
20
+ /** Whether the signal was successfully received. */
21
+ received: boolean;
22
+ /** Latency in milliseconds before signal is understood. */
23
+ latency_ms: number;
24
+ }
25
+ /** Detection outcome for acoustic sensing. */
26
+ export interface AcousticDetectionOutcome {
27
+ /** Detection confidence (0–1). */
28
+ confidence_Q: Q;
29
+ /** Estimated direction in degrees (0–360, -1 if unknown). */
30
+ estimatedDirection_deg: number;
31
+ /** Estimated distance in metres (-1 if unknown). */
32
+ estimatedDistance_m: number;
33
+ /** Whether detection is certain enough to act on. */
34
+ detected: boolean;
35
+ }
36
+ /**
37
+ * Derive the acoustic signature of an entity.
38
+ *
39
+ * Formula:
40
+ * baseNoise = 50 (normal human movement)
41
+ * stealth reduces baseNoise: base × (1 − stealth × 0.60)
42
+ * movementNoise = velocity_mps × 10
43
+ * equipmentNoise = based on armour material and weapon mass
44
+ *
45
+ * @param entity - The entity to analyze.
46
+ * @returns Acoustic signature with all noise components.
47
+ */
48
+ export declare function deriveAcousticSignature(entity: Entity): AcousticSignature;
49
+ /**
50
+ * Detect an acoustic signature.
51
+ *
52
+ * Formula:
53
+ * detection_Q = clamp(sourceNoise / dist_m × listener.musical × SCALE_ACOUSTIC, 0, 1)
54
+ *
55
+ * Higher sourceNoise = easier to detect.
56
+ * Higher listener musical intelligence = better detection.
57
+ * Distance degrades detection linearly.
58
+ *
59
+ * @param listener - The entity attempting to detect.
60
+ * @param source - The entity producing sound.
61
+ * @param dist_m - Distance between entities in metres.
62
+ * @returns Detection confidence and metadata.
63
+ */
64
+ export declare function detectAcousticSignature(listener: Entity, source: Entity, dist_m: number): AcousticDetectionOutcome;
65
+ /**
66
+ * Resolve a formation signal transmission.
67
+ *
68
+ * Used for military coordination: drums, horns, whistles, shouted commands.
69
+ *
70
+ * Formula:
71
+ * clarity_Q = musical(signaller) × musical(listener) × rangeFactor(dist_m)
72
+ * received = clarity_Q >= SIGNAL_RECEPTION_THRESHOLD
73
+ * latency_ms = BASE_LATENCY_MS × (1 − avgMusical × 0.50)
74
+ *
75
+ * Satyr signaller (0.95) → Elf listeners (0.85) → near-perfect reception at long range.
76
+ * Troll → Troll → commands degrade rapidly beyond a few metres.
77
+ *
78
+ * @param signaller - The entity sending the signal.
79
+ * @param signal - The formation signal type.
80
+ * @param listener - The entity receiving the signal.
81
+ * @param dist_m - Distance between entities in metres.
82
+ * @returns Signal outcome with clarity and reception status.
83
+ */
84
+ export declare function resolveFormationSignal(signaller: Entity, signal: FormationSignal, listener: Entity, dist_m: number): FormationSignalOutcome;
85
+ /**
86
+ * Check if an entity can effectively use formation signals.
87
+ * Requires minimum musical intelligence to produce clear signals.
88
+ *
89
+ * @param entity - The potential signaller.
90
+ * @param minMusical - Minimum musical intelligence required (default q(0.40)).
91
+ * @returns True if entity can serve as a signaller.
92
+ */
93
+ export declare function canUseFormationSignals(entity: Entity, minMusical?: Q): boolean;
94
+ /**
95
+ * Calculate maximum effective signal range for a signaller.
96
+ *
97
+ * @param signaller - The entity sending signals.
98
+ * @param minClarity - Minimum clarity required for reception (default q(0.40)).
99
+ * @returns Maximum range in metres.
100
+ */
101
+ export declare function calculateSignalRange(signaller: Entity, minClarity?: Q): number;
@@ -0,0 +1,242 @@
1
+ // src/competence/acoustic.ts — Phase 39: Musical Intelligence & Acoustic Systems
2
+ //
3
+ // Musical intelligence governs cognition in the time-acoustic domain:
4
+ // - Recognition of rhythmic patterns and sound cues
5
+ // - Formation signal interpretation (drums, horns)
6
+ // - Acoustic detection and stealth counter-detection
7
+ //
8
+ // No kernel import — pure resolution module.
9
+ import { SCALE, q, clampQ, mulDiv } from "../units.js";
10
+ // ── Constants ─────────────────────────────────────────────────────────────────
11
+ /** Scale factor for acoustic detection formula. */
12
+ const SCALE_ACOUSTIC = 100; // multiplier to get useful detection ranges
13
+ /** Base detection range in metres at average musical intelligence. */
14
+ const BASE_DETECTION_RANGE_m = 50;
15
+ /** Maximum effective detection range. */
16
+ const MAX_DETECTION_RANGE_m = 500;
17
+ /** Range factor: clarity degrades with distance. */
18
+ const RANGE_DEGRADATION_PER_METER = 0.002; // 0.2% per metre
19
+ /** Threshold for successful signal reception. */
20
+ const SIGNAL_RECEPTION_THRESHOLD = q(0.40);
21
+ /** Base latency for signal interpretation in milliseconds. */
22
+ const BASE_SIGNAL_LATENCY_MS = 200;
23
+ /** Latency reduction from high musical intelligence. */
24
+ const MUSICAL_LATENCY_REDUCTION_FACTOR = 0.5; // up to 50% faster
25
+ // Noise level constants
26
+ const NOISE_SILENT = 0;
27
+ const NOISE_VERY_QUIET = 10;
28
+ const NOISE_QUIET = 25;
29
+ const NOISE_NORMAL = 50;
30
+ const NOISE_LOUD = 75;
31
+ const NOISE_VERY_LOUD = 100;
32
+ // ── Helpers ───────────────────────────────────────────────────────────────────
33
+ /**
34
+ * Get stealth skill value from entity (0 if not present).
35
+ * Higher stealth = lower noise.
36
+ */
37
+ function getStealthValue(entity) {
38
+ // Check for stealth in skills map
39
+ const stealthSkill = entity.skills?.get("stealth");
40
+ if (stealthSkill !== undefined) {
41
+ // Convert SkillLevel to Q (SkillLevel is already a Q-encoded value)
42
+ return stealthSkill;
43
+ }
44
+ // Default: average stealth
45
+ return q(0.50);
46
+ }
47
+ /**
48
+ * Calculate equipment noise based on armour type.
49
+ */
50
+ function calculateEquipmentNoise(entity) {
51
+ let noise = NOISE_NORMAL; // base walking noise
52
+ // Process all items in loadout
53
+ for (const item of entity.loadout.items) {
54
+ // Armour adds noise based on material
55
+ if (item.kind === "armour") {
56
+ const armour = item;
57
+ if (armour.material === "metal") {
58
+ noise += 15; // clanking
59
+ }
60
+ else if (armour.material === "leather") {
61
+ noise += 5; // creaking
62
+ }
63
+ // fabric/cloth is silent
64
+ }
65
+ // Weapons add noise when moved
66
+ if (item.kind === "weapon") {
67
+ const weapon = item;
68
+ if (weapon.mass_kg > 2000) { // heavy weapons
69
+ noise += 10;
70
+ }
71
+ else if (weapon.mass_kg > 1000) {
72
+ noise += 5;
73
+ }
74
+ }
75
+ }
76
+ return Math.min(NOISE_VERY_LOUD, noise);
77
+ }
78
+ // ── Public API ────────────────────────────────────────────────────────────────
79
+ /**
80
+ * Derive the acoustic signature of an entity.
81
+ *
82
+ * Formula:
83
+ * baseNoise = 50 (normal human movement)
84
+ * stealth reduces baseNoise: base × (1 − stealth × 0.60)
85
+ * movementNoise = velocity_mps × 10
86
+ * equipmentNoise = based on armour material and weapon mass
87
+ *
88
+ * @param entity - The entity to analyze.
89
+ * @returns Acoustic signature with all noise components.
90
+ */
91
+ export function deriveAcousticSignature(entity) {
92
+ // Base noise level
93
+ let baseNoise = NOISE_NORMAL;
94
+ // Stealth reduces base noise
95
+ const stealth = getStealthValue(entity);
96
+ const stealthReduction = mulDiv(stealth, q(0.60), SCALE.Q) / SCALE.Q;
97
+ baseNoise = Math.round(baseNoise * (1 - stealthReduction));
98
+ // Movement noise from velocity
99
+ const velocity = Math.sqrt(entity.velocity_mps.x ** 2 +
100
+ entity.velocity_mps.y ** 2 +
101
+ entity.velocity_mps.z ** 2) / SCALE.mps; // convert to m/s
102
+ const movementNoise = Math.round(velocity * 10);
103
+ // Equipment noise
104
+ const equipmentNoise = calculateEquipmentNoise(entity);
105
+ // Total noise
106
+ const totalNoise = Math.min(NOISE_VERY_LOUD, baseNoise + movementNoise + equipmentNoise);
107
+ return {
108
+ baseNoise,
109
+ movementNoise,
110
+ equipmentNoise,
111
+ totalNoise,
112
+ };
113
+ }
114
+ /**
115
+ * Detect an acoustic signature.
116
+ *
117
+ * Formula:
118
+ * detection_Q = clamp(sourceNoise / dist_m × listener.musical × SCALE_ACOUSTIC, 0, 1)
119
+ *
120
+ * Higher sourceNoise = easier to detect.
121
+ * Higher listener musical intelligence = better detection.
122
+ * Distance degrades detection linearly.
123
+ *
124
+ * @param listener - The entity attempting to detect.
125
+ * @param source - The entity producing sound.
126
+ * @param dist_m - Distance between entities in metres.
127
+ * @returns Detection confidence and metadata.
128
+ */
129
+ export function detectAcousticSignature(listener, source, dist_m) {
130
+ const musical = (listener.attributes.cognition?.musical ?? q(0.50));
131
+ // Get source noise
132
+ const signature = deriveAcousticSignature(source);
133
+ const sourceNoise = signature.totalNoise;
134
+ // Distance factor: detection degrades with distance
135
+ const distanceFactor = Math.max(0, 1 - dist_m * RANGE_DEGRADATION_PER_METER);
136
+ // Detection formula
137
+ const musicalNorm = musical / SCALE.Q; // 0-1
138
+ const rawDetection = (sourceNoise / 100) * distanceFactor * musicalNorm * SCALE_ACOUSTIC;
139
+ // Clamp to valid Q range
140
+ const confidence_Q = clampQ(Math.round(rawDetection * SCALE.Q), q(0), SCALE.Q);
141
+ // Detection threshold
142
+ const detected = confidence_Q >= q(0.30);
143
+ // Estimate direction (simplified: assume we can determine direction if confidence is high)
144
+ let estimatedDirection_deg = -1;
145
+ let estimatedDistance_m = -1;
146
+ if (confidence_Q >= q(0.50)) {
147
+ // Can estimate distance with moderate accuracy
148
+ estimatedDistance_m = Math.round(dist_m * (0.8 + Math.random() * 0.4));
149
+ }
150
+ if (confidence_Q >= q(0.70)) {
151
+ // Can determine direction (in a real implementation, would compute from positions)
152
+ estimatedDirection_deg = Math.floor(Math.random() * 360);
153
+ }
154
+ return {
155
+ confidence_Q,
156
+ estimatedDirection_deg,
157
+ estimatedDistance_m,
158
+ detected,
159
+ };
160
+ }
161
+ /**
162
+ * Resolve a formation signal transmission.
163
+ *
164
+ * Used for military coordination: drums, horns, whistles, shouted commands.
165
+ *
166
+ * Formula:
167
+ * clarity_Q = musical(signaller) × musical(listener) × rangeFactor(dist_m)
168
+ * received = clarity_Q >= SIGNAL_RECEPTION_THRESHOLD
169
+ * latency_ms = BASE_LATENCY_MS × (1 − avgMusical × 0.50)
170
+ *
171
+ * Satyr signaller (0.95) → Elf listeners (0.85) → near-perfect reception at long range.
172
+ * Troll → Troll → commands degrade rapidly beyond a few metres.
173
+ *
174
+ * @param signaller - The entity sending the signal.
175
+ * @param signal - The formation signal type.
176
+ * @param listener - The entity receiving the signal.
177
+ * @param dist_m - Distance between entities in metres.
178
+ * @returns Signal outcome with clarity and reception status.
179
+ */
180
+ export function resolveFormationSignal(signaller, signal, listener, dist_m) {
181
+ const signallerMusical = (signaller.attributes.cognition?.musical ?? q(0.50));
182
+ const listenerMusical = (listener.attributes.cognition?.musical ?? q(0.50));
183
+ // Range factor degrades with distance
184
+ const rangeFactor = Math.max(0, 1 - dist_m * RANGE_DEGRADATION_PER_METER * 0.5); // slower degradation for intentional signals
185
+ // Musical product (both need musical intelligence for clear transmission)
186
+ const signallerNorm = signallerMusical / SCALE.Q;
187
+ const listenerNorm = listenerMusical / SCALE.Q;
188
+ const musicalProduct = signallerNorm * listenerNorm;
189
+ // Clarity calculation
190
+ const rawClarity = musicalProduct * rangeFactor * SCALE_ACOUSTIC / 100;
191
+ const clarity_Q = clampQ(Math.round(rawClarity * SCALE.Q), q(0), SCALE.Q);
192
+ // Reception check
193
+ const received = clarity_Q >= SIGNAL_RECEPTION_THRESHOLD;
194
+ // Latency: better musical intelligence = faster interpretation
195
+ const avgMusical = (signallerNorm + listenerNorm) / 2;
196
+ const latencyReduction = avgMusical * MUSICAL_LATENCY_REDUCTION_FACTOR;
197
+ const latency_ms = Math.round(BASE_SIGNAL_LATENCY_MS * (1 - latencyReduction));
198
+ return {
199
+ clarity_Q,
200
+ received,
201
+ latency_ms,
202
+ };
203
+ }
204
+ /**
205
+ * Check if an entity can effectively use formation signals.
206
+ * Requires minimum musical intelligence to produce clear signals.
207
+ *
208
+ * @param entity - The potential signaller.
209
+ * @param minMusical - Minimum musical intelligence required (default q(0.40)).
210
+ * @returns True if entity can serve as a signaller.
211
+ */
212
+ export function canUseFormationSignals(entity, minMusical = q(0.40)) {
213
+ const musical = (entity.attributes.cognition?.musical ?? q(0.50));
214
+ return musical >= minMusical;
215
+ }
216
+ /**
217
+ * Calculate maximum effective signal range for a signaller.
218
+ *
219
+ * @param signaller - The entity sending signals.
220
+ * @param minClarity - Minimum clarity required for reception (default q(0.40)).
221
+ * @returns Maximum range in metres.
222
+ */
223
+ export function calculateSignalRange(signaller, minClarity = q(0.40)) {
224
+ const signallerMusical = (signaller.attributes.cognition?.musical ?? q(0.50));
225
+ const musicalNorm = signallerMusical / SCALE.Q;
226
+ // clarity = musicalProduct * rangeFactor * SCALE_ACOUSTIC / SCALE.Q
227
+ // At distance 0, rangeFactor = 1, so maxClarity = musicalProduct * SCALE_ACOUSTIC / SCALE.Q
228
+ // Assuming average listener (musical = 0.50)
229
+ const listenerNorm = 0.50;
230
+ const musicalProduct = musicalNorm * listenerNorm;
231
+ // Max possible clarity at point-blank
232
+ const maxClarity = musicalProduct * SCALE_ACOUSTIC; // This gives 0-100 range
233
+ const minClarityNorm = minClarity / SCALE.Q; // Convert Q to 0-1
234
+ if (maxClarity < minClarityNorm * 100) {
235
+ return 0; // Cannot reach minimum clarity even at point-blank
236
+ }
237
+ // minClarityNorm = musicalProduct * (1 - dist * degradation * 0.5) * SCALE_ACOUSTIC / SCALE.Q
238
+ // Solve for dist where clarity = minClarity
239
+ const requiredRatio = (minClarityNorm * 100) / (musicalProduct * SCALE_ACOUSTIC);
240
+ const maxDist = (1 - requiredRatio) / (RANGE_DEGRADATION_PER_METER * 0.5);
241
+ return Math.min(MAX_DETECTION_RANGE_m, Math.round(maxDist));
242
+ }
@@ -0,0 +1,30 @@
1
+ import type { Q } from "../units.js";
2
+ /** Domain of competence — maps to cognitive intelligence types. */
3
+ export type CompetenceDomain = "linguistic" | "logicalMathematical" | "spatial" | "bodilyKinesthetic" | "musical" | "interpersonal" | "intrapersonal" | "naturalist" | "interSpecies";
4
+ /** A single competence task definition. */
5
+ export interface CompetenceTask {
6
+ /** Unique task identifier. */
7
+ taskId: string;
8
+ /** Primary competence domain. */
9
+ domain: CompetenceDomain;
10
+ /** Secondary domain (optional, for compound tasks). */
11
+ secondaryDomain?: CompetenceDomain;
12
+ /** Difficulty rating (0–1). */
13
+ difficulty_Q: Q;
14
+ /** Base time required in seconds. */
15
+ timeBase_s: number;
16
+ /** Required tool/equipment (optional). */
17
+ requiredTool?: string;
18
+ /** Human-readable description. */
19
+ description: string;
20
+ }
21
+ /** Read-only catalogue of all competence tasks. */
22
+ export declare const COMPETENCE_CATALOGUE: readonly CompetenceTask[];
23
+ /** Lookup map for taskId → task. */
24
+ export declare const COMPETENCE_TASK_BY_ID: ReadonlyMap<string, CompetenceTask>;
25
+ /** Get a task by ID. Returns undefined if not found. */
26
+ export declare function getTaskById(taskId: string): CompetenceTask | undefined;
27
+ /** Check if a task exists in the catalogue. */
28
+ export declare function hasTask(taskId: string): boolean;
29
+ /** Get all tasks for a specific domain. */
30
+ export declare function getTasksByDomain(domain: CompetenceDomain): CompetenceTask[];
@@ -0,0 +1,241 @@
1
+ // src/competence/catalogue.ts — Phase 40: Competence Catalogue
2
+ //
3
+ // Predefined competence tasks with difficulty, time requirements, and domain.
4
+ // Parallel to weapons and food catalogues.
5
+ import { q } from "../units.js";
6
+ // ── Catalogue Entries ─────────────────────────────────────────────────────────
7
+ const entries = [
8
+ // ── Bodily-Kinesthetic (crafting, physical skill) ────────────────────────────
9
+ {
10
+ taskId: "craft_sword_basic",
11
+ domain: "bodilyKinesthetic",
12
+ difficulty_Q: q(0.40),
13
+ timeBase_s: 14400, // 4 hours
14
+ requiredTool: "forge",
15
+ description: "Forge a basic serviceable sword",
16
+ },
17
+ {
18
+ taskId: "craft_sword_master",
19
+ domain: "bodilyKinesthetic",
20
+ difficulty_Q: q(0.85),
21
+ timeBase_s: 28800, // 8 hours
22
+ requiredTool: "forge",
23
+ description: "Forge a masterwork sword",
24
+ },
25
+ {
26
+ taskId: "treat_wound_field",
27
+ domain: "bodilyKinesthetic",
28
+ difficulty_Q: q(0.50),
29
+ timeBase_s: 300, // 5 minutes
30
+ requiredTool: "medical_kit",
31
+ description: "Field treatment of bleeding wound",
32
+ },
33
+ {
34
+ taskId: "perform_surgery",
35
+ domain: "bodilyKinesthetic",
36
+ difficulty_Q: q(0.75),
37
+ timeBase_s: 3600, // 1 hour
38
+ requiredTool: "surgical_kit",
39
+ description: "Surgical repair of internal injuries",
40
+ },
41
+ // ── Spatial (navigation, wayfinding) ────────────────────────────────────────
42
+ {
43
+ taskId: "navigate_wilderness",
44
+ domain: "spatial",
45
+ difficulty_Q: q(0.50),
46
+ timeBase_s: 3600, // per hour of travel
47
+ description: "Navigate through untracked wilderness",
48
+ },
49
+ {
50
+ taskId: "navigate_urban",
51
+ domain: "spatial",
52
+ difficulty_Q: q(0.30),
53
+ timeBase_s: 600, // 10 minutes
54
+ description: "Find route through complex urban environment",
55
+ },
56
+ {
57
+ taskId: "read_map",
58
+ domain: "spatial",
59
+ difficulty_Q: q(0.25),
60
+ timeBase_s: 60, // 1 minute
61
+ requiredTool: "map",
62
+ description: "Interpret map and locate position",
63
+ },
64
+ // ── Naturalist (tracking, foraging, animal handling) ─────────────────────────
65
+ {
66
+ taskId: "track_quarry_fresh",
67
+ domain: "naturalist",
68
+ difficulty_Q: q(0.30),
69
+ timeBase_s: 1800, // 30 minutes
70
+ description: "Track quarry with fresh trail (< 1 hour)",
71
+ },
72
+ {
73
+ taskId: "track_quarry_aged",
74
+ domain: "naturalist",
75
+ difficulty_Q: q(0.60),
76
+ timeBase_s: 3600, // 1 hour
77
+ description: "Track quarry with aged trail (> 1 day)",
78
+ },
79
+ {
80
+ taskId: "forage_herbs",
81
+ domain: "naturalist",
82
+ difficulty_Q: q(0.35),
83
+ timeBase_s: 3600, // 1 hour
84
+ description: "Search for medicinal herbs",
85
+ },
86
+ {
87
+ taskId: "identify_herb",
88
+ domain: "naturalist",
89
+ difficulty_Q: q(0.25),
90
+ timeBase_s: 60, // 1 minute
91
+ description: "Identify unknown plant and properties",
92
+ },
93
+ {
94
+ taskId: "tame_horse",
95
+ domain: "naturalist",
96
+ secondaryDomain: "interSpecies",
97
+ difficulty_Q: q(0.40),
98
+ timeBase_s: 7200, // 2 hours per session
99
+ description: "Build trust with untrained horse",
100
+ },
101
+ // ── Inter-Species (communication across species boundaries) ───────────────────
102
+ {
103
+ taskId: "signal_alien_species",
104
+ domain: "interSpecies",
105
+ difficulty_Q: q(0.60),
106
+ timeBase_s: 300, // 5 minutes
107
+ description: "Attempt first-contact communication with unknown species",
108
+ },
109
+ {
110
+ taskId: "calm_agitated_beast",
111
+ domain: "interSpecies",
112
+ difficulty_Q: q(0.55),
113
+ timeBase_s: 600, // 10 minutes
114
+ description: "Calm frightened or aggressive animal",
115
+ },
116
+ // ── Linguistic (language, communication) ─────────────────────────────────────
117
+ {
118
+ taskId: "negotiate_treaty",
119
+ domain: "linguistic",
120
+ secondaryDomain: "interpersonal",
121
+ difficulty_Q: q(0.70),
122
+ timeBase_s: 1800, // 30 minutes
123
+ description: "Negotiate terms between conflicting parties",
124
+ },
125
+ {
126
+ taskId: "translate_foreign",
127
+ domain: "linguistic",
128
+ difficulty_Q: q(0.50),
129
+ timeBase_s: 3600, // 1 hour per page
130
+ requiredTool: "reference_texts",
131
+ description: "Translate unfamiliar language",
132
+ },
133
+ {
134
+ taskId: "command_formation",
135
+ domain: "linguistic",
136
+ difficulty_Q: q(0.40),
137
+ timeBase_s: 60, // 1 minute
138
+ description: "Issue clear commands to military formation",
139
+ },
140
+ // ── Interpersonal (teaching, leadership, empathy) ────────────────────────────
141
+ {
142
+ taskId: "teach_skill",
143
+ domain: "interpersonal",
144
+ difficulty_Q: q(0.45),
145
+ timeBase_s: 3600, // 1 hour lesson
146
+ description: "Teach specific skill to student",
147
+ },
148
+ {
149
+ taskId: "rally_troops",
150
+ domain: "interpersonal",
151
+ difficulty_Q: q(0.55),
152
+ timeBase_s: 300, // 5 minutes
153
+ description: "Rally frightened troops back to combat readiness",
154
+ },
155
+ {
156
+ taskId: "detect_deception",
157
+ domain: "interpersonal",
158
+ difficulty_Q: q(0.50),
159
+ timeBase_s: 60, // 1 minute during conversation
160
+ description: "Detect lies and falsehoods in conversation",
161
+ },
162
+ // ── Logical-Mathematical (engineering, planning, analysis) ────────────────────
163
+ {
164
+ taskId: "design_fortification",
165
+ domain: "logicalMathematical",
166
+ difficulty_Q: q(0.60),
167
+ timeBase_s: 86400, // 1 day
168
+ requiredTool: "drafting_tools",
169
+ description: "Engineer defensive fortification plans",
170
+ },
171
+ {
172
+ taskId: "design_siege_engine",
173
+ domain: "logicalMathematical",
174
+ difficulty_Q: q(0.75),
175
+ timeBase_s: 172800, // 2 days
176
+ requiredTool: "drafting_tools",
177
+ description: "Design complex siege machinery",
178
+ },
179
+ {
180
+ taskId: "solve_tactical_puzzle",
181
+ domain: "logicalMathematical",
182
+ difficulty_Q: q(0.55),
183
+ timeBase_s: 1800, // 30 minutes
184
+ description: "Analyze tactical situation and propose solution",
185
+ },
186
+ // ── Musical (performance, signaling) ─────────────────────────────────────────
187
+ {
188
+ taskId: "compose_march",
189
+ domain: "musical",
190
+ difficulty_Q: q(0.35),
191
+ timeBase_s: 1800, // 30 minutes
192
+ description: "Compose military marching cadence",
193
+ },
194
+ {
195
+ taskId: "perform_morale",
196
+ domain: "musical",
197
+ difficulty_Q: q(0.45),
198
+ timeBase_s: 1800, // 30 minutes performance
199
+ description: "Musical performance to boost morale",
200
+ },
201
+ {
202
+ taskId: "signal_formation",
203
+ domain: "musical",
204
+ difficulty_Q: q(0.30),
205
+ timeBase_s: 10, // 10 seconds
206
+ requiredTool: "signal_horn_or_drum",
207
+ description: "Signal formation maneuver via horn/drum",
208
+ },
209
+ // ── Intrapersonal (meditation, willpower) ────────────────────────────────────
210
+ {
211
+ taskId: "meditate_focus",
212
+ domain: "intrapersonal",
213
+ difficulty_Q: q(0.25),
214
+ timeBase_s: 1800, // 30 minutes
215
+ description: "Meditation to restore willpower",
216
+ },
217
+ {
218
+ taskId: "resist_temptation",
219
+ domain: "intrapersonal",
220
+ difficulty_Q: q(0.50),
221
+ timeBase_s: 60, // 1 minute decision point
222
+ description: "Resist immediate temptation for long-term gain",
223
+ },
224
+ ];
225
+ // ── Exported Catalogue ───────────────────────────────────────────────────────
226
+ /** Read-only catalogue of all competence tasks. */
227
+ export const COMPETENCE_CATALOGUE = Object.freeze(entries);
228
+ /** Lookup map for taskId → task. */
229
+ export const COMPETENCE_TASK_BY_ID = new Map(entries.map((e) => [e.taskId, e]));
230
+ /** Get a task by ID. Returns undefined if not found. */
231
+ export function getTaskById(taskId) {
232
+ return COMPETENCE_TASK_BY_ID.get(taskId);
233
+ }
234
+ /** Check if a task exists in the catalogue. */
235
+ export function hasTask(taskId) {
236
+ return COMPETENCE_TASK_BY_ID.has(taskId);
237
+ }
238
+ /** Get all tasks for a specific domain. */
239
+ export function getTasksByDomain(domain) {
240
+ return entries.filter((t) => t.domain === domain || t.secondaryDomain === domain);
241
+ }
@@ -0,0 +1,35 @@
1
+ import type { Q } from "../units.js";
2
+ import type { Entity } from "../sim/entity.js";
3
+ export interface CraftingSpec {
4
+ outputId: string;
5
+ toolCategory?: "bladed" | "blunt" | "needlework" | "forge" | "precision";
6
+ /** Base seconds for a bodilyKinesthetic q(0.50) entity. */
7
+ baseTime_s: number;
8
+ /** Raw material quality 0–1 (Q-encoded). */
9
+ materialQ: Q;
10
+ /** Minimum bodilyKinesthetic required to attempt; below → success=false. */
11
+ minBKQ: Q;
12
+ }
13
+ export interface CraftingOutcome {
14
+ quality_Q: Q;
15
+ timeTaken_s: number;
16
+ success: boolean;
17
+ descriptor: "masterwork" | "fine" | "adequate" | "poor" | "ruined";
18
+ }
19
+ /**
20
+ * Resolve a crafting attempt.
21
+ *
22
+ * @param entity - The crafter; uses `cognition.bodilyKinesthetic` and `control.fineControl`.
23
+ * @param spec - Crafting specification.
24
+ * @param seed - Deterministic seed (e.g. from eventSeed()).
25
+ */
26
+ export declare function resolveCrafting(entity: Entity, spec: CraftingSpec, seed: number): CraftingOutcome;
27
+ /**
28
+ * Phase 34: compute surgical precision multiplier from surgeon's bodilyKinesthetic.
29
+ * Result: lerp(q(0.70), q(1.30), bk)
30
+ * - Assign to `TreatmentSchedule.surgicalPrecisionMul` in downtime config.
31
+ * - BK q(0.00) → q(0.70) (clumsy; slower/worse surgery)
32
+ * - BK q(0.50) → q(1.00) (normal)
33
+ * - BK q(1.00) → q(1.30) (expert; faster/better surgery)
34
+ */
35
+ export declare function computeSurgicalPrecision(entity: Entity): Q;