@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,677 @@
1
+ // src/sim/bodyplan.ts — Phase 8: Universal Body and Species System
2
+ //
3
+ // Body plans are data files. Adding a new species requires authoring a BodyPlan
4
+ // and an Archetype baseline; the simulation kernel does not need modification.
5
+ //
6
+ // The `id` of each BodySegment becomes the key in InjuryState.byRegion.
7
+ import { q } from "../units.js";
8
+ import { DamageChannel } from "../channels.js";
9
+ // ─── helpers ─────────────────────────────────────────────────────────────────
10
+ /**
11
+ * Get the exposure weight for a segment on a given damage channel.
12
+ * Falls back to the kinetic weight when the channel is not explicitly specified.
13
+ */
14
+ export function getExposureWeight(seg, channel) {
15
+ return seg.exposureWeight[channel] ?? seg.exposureWeight[DamageChannel.Kinetic] ?? q(0);
16
+ }
17
+ /**
18
+ * Resolve which segment is struck, given a uniform [0, SCALE.Q) random value.
19
+ * Uses kinetic exposure weights for physical-impact hits.
20
+ */
21
+ export function resolveHitSegment(plan, r01) {
22
+ let cum = 0;
23
+ for (const seg of plan.segments) {
24
+ cum += seg.exposureWeight[DamageChannel.Kinetic] ?? 0;
25
+ if (r01 < cum)
26
+ return seg.id;
27
+ }
28
+ // Fallback: last segment (handles rounding)
29
+ return plan.segments[plan.segments.length - 1].id;
30
+ }
31
+ /** Return all segment ids from a body plan. */
32
+ export function segmentIds(plan) {
33
+ return plan.segments.map(s => s.id);
34
+ }
35
+ // ─── body plan data ───────────────────────────────────────────────────────────
36
+ //
37
+ // Kinetic exposure weights sum to exactly 10000 (SCALE.Q) per plan.
38
+ // Other channels are specified where they differ meaningfully; otherwise
39
+ // they fall back to the kinetic weight via getExposureWeight().
40
+ /**
41
+ * Standard humanoid (human, elf, robot):
42
+ * bilateral upright, 4 limbs, centralized CNS.
43
+ */
44
+ export const HUMANOID_PLAN = {
45
+ id: "humanoid",
46
+ locomotion: { type: "biped" },
47
+ cnsLayout: { type: "centralized" },
48
+ segments: [
49
+ {
50
+ id: "head",
51
+ parent: null,
52
+ mass_kg: 5000,
53
+ exposureWeight: {
54
+ [DamageChannel.Kinetic]: q(0.12),
55
+ [DamageChannel.Thermal]: q(0.18),
56
+ [DamageChannel.Electrical]: q(0.10),
57
+ [DamageChannel.Radiation]: q(0.12),
58
+ [DamageChannel.Chemical]: q(0.16),
59
+ },
60
+ cnsRole: "central",
61
+ tags: ["head", "shield-small-cover"],
62
+ },
63
+ {
64
+ id: "torso",
65
+ parent: null,
66
+ mass_kg: 35000,
67
+ exposureWeight: {
68
+ [DamageChannel.Kinetic]: q(0.50),
69
+ [DamageChannel.Thermal]: q(0.28),
70
+ [DamageChannel.Electrical]: q(0.22),
71
+ [DamageChannel.Radiation]: q(0.52),
72
+ [DamageChannel.Chemical]: q(0.36),
73
+ },
74
+ cnsRole: "ganglionic",
75
+ tags: ["torso", "shield-small-cover"],
76
+ },
77
+ {
78
+ id: "leftArm",
79
+ parent: "torso",
80
+ mass_kg: 4000,
81
+ exposureWeight: {
82
+ [DamageChannel.Kinetic]: q(0.095),
83
+ [DamageChannel.Thermal]: q(0.14),
84
+ [DamageChannel.Electrical]: q(0.22),
85
+ [DamageChannel.Radiation]: q(0.09),
86
+ [DamageChannel.Chemical]: q(0.12),
87
+ },
88
+ manipulationRole: "primary",
89
+ tags: ["arm", "shield-small-cover"],
90
+ },
91
+ {
92
+ id: "rightArm",
93
+ parent: "torso",
94
+ mass_kg: 4000,
95
+ exposureWeight: {
96
+ [DamageChannel.Kinetic]: q(0.095),
97
+ [DamageChannel.Thermal]: q(0.14),
98
+ [DamageChannel.Electrical]: q(0.22),
99
+ [DamageChannel.Radiation]: q(0.09),
100
+ [DamageChannel.Chemical]: q(0.12),
101
+ },
102
+ manipulationRole: "primary",
103
+ tags: ["arm", "shield-small-cover"],
104
+ },
105
+ {
106
+ id: "leftLeg",
107
+ parent: "torso",
108
+ mass_kg: 10000,
109
+ exposureWeight: {
110
+ [DamageChannel.Kinetic]: q(0.095),
111
+ [DamageChannel.Thermal]: q(0.13),
112
+ [DamageChannel.Electrical]: q(0.12),
113
+ [DamageChannel.Radiation]: q(0.09),
114
+ [DamageChannel.Chemical]: q(0.12),
115
+ },
116
+ locomotionRole: "primary",
117
+ tags: ["leg"],
118
+ },
119
+ {
120
+ id: "rightLeg",
121
+ parent: "torso",
122
+ mass_kg: 10000,
123
+ exposureWeight: {
124
+ [DamageChannel.Kinetic]: q(0.095),
125
+ [DamageChannel.Thermal]: q(0.13),
126
+ [DamageChannel.Electrical]: q(0.12),
127
+ [DamageChannel.Radiation]: q(0.09),
128
+ [DamageChannel.Chemical]: q(0.12),
129
+ },
130
+ locomotionRole: "primary",
131
+ tags: ["leg"],
132
+ },
133
+ ],
134
+ };
135
+ /**
136
+ * Quadruped (dog, horse, bear):
137
+ * 4 locomotion limbs, lower centre of gravity, no dedicated manipulation.
138
+ */
139
+ export const QUADRUPED_PLAN = {
140
+ id: "quadruped",
141
+ locomotion: { type: "quadruped" },
142
+ cnsLayout: { type: "centralized" },
143
+ segments: [
144
+ {
145
+ id: "head",
146
+ parent: null,
147
+ mass_kg: 4000,
148
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
149
+ cnsRole: "central",
150
+ },
151
+ {
152
+ id: "neck",
153
+ parent: "head",
154
+ mass_kg: 6000,
155
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
156
+ },
157
+ {
158
+ id: "torso",
159
+ parent: null,
160
+ mass_kg: 40000,
161
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.43) },
162
+ cnsRole: "ganglionic",
163
+ },
164
+ {
165
+ id: "tail",
166
+ parent: "torso",
167
+ mass_kg: 3000,
168
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.03) },
169
+ },
170
+ {
171
+ id: "frontLeftLeg",
172
+ parent: "torso",
173
+ mass_kg: 5000,
174
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
175
+ locomotionRole: "primary",
176
+ },
177
+ {
178
+ id: "frontRightLeg",
179
+ parent: "torso",
180
+ mass_kg: 5000,
181
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
182
+ locomotionRole: "primary",
183
+ },
184
+ {
185
+ id: "rearLeftLeg",
186
+ parent: "torso",
187
+ mass_kg: 7000,
188
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
189
+ locomotionRole: "primary",
190
+ },
191
+ {
192
+ id: "rearRightLeg",
193
+ parent: "torso",
194
+ mass_kg: 7000,
195
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
196
+ locomotionRole: "primary",
197
+ },
198
+ ],
199
+ };
200
+ // QUADRUPED kinetic sum: 1000+800+4300+300+1000+1000+800+800 = 10000 ✓
201
+ /**
202
+ * Theropod (large bipedal predator, fantasy drake):
203
+ * bipedal, heavy tail counterbalance, vestigial forelimbs.
204
+ */
205
+ export const THEROPOD_PLAN = {
206
+ id: "theropod",
207
+ locomotion: { type: "biped" },
208
+ cnsLayout: { type: "centralized" },
209
+ segments: [
210
+ {
211
+ id: "head",
212
+ parent: null,
213
+ mass_kg: 15000,
214
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
215
+ cnsRole: "central",
216
+ },
217
+ {
218
+ id: "neck",
219
+ parent: "head",
220
+ mass_kg: 12000,
221
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
222
+ },
223
+ {
224
+ id: "torso",
225
+ parent: null,
226
+ mass_kg: 80000,
227
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.38) },
228
+ cnsRole: "ganglionic",
229
+ },
230
+ {
231
+ id: "tail",
232
+ parent: "torso",
233
+ mass_kg: 30000,
234
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.15) },
235
+ },
236
+ {
237
+ id: "leftArm",
238
+ parent: "torso",
239
+ mass_kg: 6000,
240
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.03) },
241
+ manipulationRole: "secondary",
242
+ },
243
+ {
244
+ id: "rightArm",
245
+ parent: "torso",
246
+ mass_kg: 6000,
247
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.03) },
248
+ manipulationRole: "secondary",
249
+ },
250
+ {
251
+ id: "leftLeg",
252
+ parent: "torso",
253
+ mass_kg: 25000,
254
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.12) },
255
+ locomotionRole: "primary",
256
+ },
257
+ {
258
+ id: "rightLeg",
259
+ parent: "torso",
260
+ mass_kg: 25000,
261
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.11) },
262
+ locomotionRole: "primary",
263
+ },
264
+ ],
265
+ };
266
+ /**
267
+ * Sauropod (long neck and tail, 4 locomotion limbs):
268
+ * brachiosaurus-type, massive torso, slow-moving.
269
+ */
270
+ export const SAUROPOD_PLAN = {
271
+ id: "sauropod",
272
+ locomotion: { type: "quadruped" },
273
+ cnsLayout: { type: "distributed" },
274
+ segments: [
275
+ {
276
+ id: "head",
277
+ parent: null,
278
+ mass_kg: 10000,
279
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.03) },
280
+ cnsRole: "central",
281
+ },
282
+ {
283
+ id: "neck",
284
+ parent: "head",
285
+ mass_kg: 50000,
286
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.12) },
287
+ },
288
+ {
289
+ id: "torso",
290
+ parent: null,
291
+ mass_kg: 200000,
292
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.35) },
293
+ cnsRole: "ganglionic",
294
+ },
295
+ {
296
+ id: "tail",
297
+ parent: "torso",
298
+ mass_kg: 60000,
299
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.15) },
300
+ },
301
+ {
302
+ id: "frontLeftLeg",
303
+ parent: "torso",
304
+ mass_kg: 30000,
305
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
306
+ locomotionRole: "primary",
307
+ },
308
+ {
309
+ id: "frontRightLeg",
310
+ parent: "torso",
311
+ mass_kg: 30000,
312
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
313
+ locomotionRole: "primary",
314
+ },
315
+ {
316
+ id: "rearLeftLeg",
317
+ parent: "torso",
318
+ mass_kg: 35000,
319
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
320
+ locomotionRole: "primary",
321
+ },
322
+ {
323
+ id: "rearRightLeg",
324
+ parent: "torso",
325
+ mass_kg: 35000,
326
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.07) },
327
+ locomotionRole: "primary",
328
+ },
329
+ ],
330
+ };
331
+ /**
332
+ * Avian (bird, winged creature):
333
+ * hollow bones, wings as forelimbs, legs for perching/walking.
334
+ */
335
+ export const AVIAN_PLAN = {
336
+ id: "avian",
337
+ locomotion: { type: "flight" },
338
+ cnsLayout: { type: "centralized" },
339
+ segments: [
340
+ {
341
+ id: "head",
342
+ parent: null,
343
+ mass_kg: 1000,
344
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
345
+ cnsRole: "central",
346
+ },
347
+ {
348
+ id: "torso",
349
+ parent: null,
350
+ mass_kg: 5000,
351
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.42) },
352
+ cnsRole: "ganglionic",
353
+ },
354
+ {
355
+ id: "leftWing",
356
+ parent: "torso",
357
+ mass_kg: 2000,
358
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.20) },
359
+ locomotionRole: "primary",
360
+ manipulationRole: "secondary",
361
+ },
362
+ {
363
+ id: "rightWing",
364
+ parent: "torso",
365
+ mass_kg: 2000,
366
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.20) },
367
+ locomotionRole: "primary",
368
+ manipulationRole: "secondary",
369
+ },
370
+ {
371
+ id: "leftLeg",
372
+ parent: "torso",
373
+ mass_kg: 1000,
374
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.05) },
375
+ locomotionRole: "secondary",
376
+ },
377
+ {
378
+ id: "rightLeg",
379
+ parent: "torso",
380
+ mass_kg: 1000,
381
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.05) },
382
+ locomotionRole: "secondary",
383
+ },
384
+ ],
385
+ };
386
+ /**
387
+ * Vermiform (snake, worm):
388
+ * no discrete limbs, lateral undulation locomotion.
389
+ */
390
+ export const VERMIFORM_PLAN = {
391
+ id: "vermiform",
392
+ locomotion: { type: "undulation" },
393
+ cnsLayout: { type: "distributed" },
394
+ segments: [
395
+ {
396
+ id: "head",
397
+ parent: null,
398
+ mass_kg: 2000,
399
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
400
+ cnsRole: "central",
401
+ },
402
+ {
403
+ id: "neckSeg",
404
+ parent: "head",
405
+ mass_kg: 5000,
406
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.20) },
407
+ cnsRole: "ganglionic",
408
+ locomotionRole: "secondary",
409
+ },
410
+ {
411
+ id: "midBody",
412
+ parent: "neckSeg",
413
+ mass_kg: 10000,
414
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.48) },
415
+ locomotionRole: "primary",
416
+ },
417
+ {
418
+ id: "tailSeg",
419
+ parent: "midBody",
420
+ mass_kg: 5000,
421
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.24) },
422
+ locomotionRole: "secondary",
423
+ },
424
+ ],
425
+ };
426
+ /**
427
+ * Centaur (combined horse and humanoid upper body):
428
+ * 4 locomotion limbs + 2 manipulation limbs.
429
+ */
430
+ export const CENTAUR_PLAN = {
431
+ id: "centaur",
432
+ locomotion: { type: "quadruped" },
433
+ cnsLayout: { type: "centralized" },
434
+ segments: [
435
+ {
436
+ id: "head",
437
+ parent: null,
438
+ mass_kg: 5000,
439
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.06) },
440
+ cnsRole: "central",
441
+ },
442
+ {
443
+ id: "upperTorso",
444
+ parent: null,
445
+ mass_kg: 25000,
446
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.18) },
447
+ cnsRole: "ganglionic",
448
+ },
449
+ {
450
+ id: "lowerTorso",
451
+ parent: "upperTorso",
452
+ mass_kg: 40000,
453
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.22) },
454
+ },
455
+ {
456
+ id: "leftArm",
457
+ parent: "upperTorso",
458
+ mass_kg: 4000,
459
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
460
+ manipulationRole: "primary",
461
+ },
462
+ {
463
+ id: "rightArm",
464
+ parent: "upperTorso",
465
+ mass_kg: 4000,
466
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
467
+ manipulationRole: "primary",
468
+ },
469
+ {
470
+ id: "frontLeftLeg",
471
+ parent: "lowerTorso",
472
+ mass_kg: 10000,
473
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.09) },
474
+ locomotionRole: "primary",
475
+ },
476
+ {
477
+ id: "frontRightLeg",
478
+ parent: "lowerTorso",
479
+ mass_kg: 10000,
480
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.09) },
481
+ locomotionRole: "primary",
482
+ },
483
+ {
484
+ id: "rearLeftLeg",
485
+ parent: "lowerTorso",
486
+ mass_kg: 12000,
487
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
488
+ locomotionRole: "primary",
489
+ },
490
+ {
491
+ id: "rearRightLeg",
492
+ parent: "lowerTorso",
493
+ mass_kg: 12000,
494
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
495
+ locomotionRole: "primary",
496
+ },
497
+ ],
498
+ };
499
+ /**
500
+ * Octopoid (octopus-type):
501
+ * distributed manipulation, all arms contribute to locomotion.
502
+ */
503
+ export const OCTOPOID_PLAN = {
504
+ id: "octopoid",
505
+ locomotion: { type: "distributed" },
506
+ cnsLayout: { type: "distributed" },
507
+ segments: [
508
+ {
509
+ id: "mantle",
510
+ parent: null,
511
+ mass_kg: 5000,
512
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.28) },
513
+ cnsRole: "central",
514
+ },
515
+ { id: "arm1", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
516
+ { id: "arm2", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
517
+ { id: "arm3", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
518
+ { id: "arm4", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
519
+ { id: "arm5", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
520
+ { id: "arm6", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
521
+ { id: "arm7", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
522
+ { id: "arm8", parent: "mantle", mass_kg: 1500, exposureWeight: { [DamageChannel.Kinetic]: q(0.09) }, manipulationRole: "primary", locomotionRole: "secondary" },
523
+ ],
524
+ };
525
+ /**
526
+ * Phase 8B reference plan: giant grasshopper (arthropod exoskeleton).
527
+ * Demonstrates all Phase 8B fields:
528
+ * - All segments have structureType: "exoskeleton"
529
+ * - Thorax has fluidSystem: "open" + hemolymphLossRate
530
+ * - Wings have breachThreshold, isJoint, jointDamageMultiplier
531
+ * - Legs have regeneratesViaMolting: true
532
+ * - locomotion.flight wired to wing segment IDs
533
+ *
534
+ * Kinetic exposure weights sum to exactly 10000 (SCALE.Q).
535
+ */
536
+ export const GRASSHOPPER_PLAN = {
537
+ id: "grasshopper",
538
+ locomotion: {
539
+ type: "hexapod",
540
+ flight: {
541
+ wingSegments: ["forewing_l", "forewing_r", "hindwing_l", "hindwing_r"],
542
+ liftCapacity_kg: 10000, // 10 kg — just enough to carry itself
543
+ flightStaminaCost: q(2.0), // flight costs 2× ground stamina
544
+ wingDamagePenalty: q(0.8), // 80% speed loss per unit of wing damage
545
+ },
546
+ },
547
+ cnsLayout: { type: "distributed" },
548
+ segments: [
549
+ {
550
+ id: "head",
551
+ parent: null,
552
+ mass_kg: 1000,
553
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.05) },
554
+ cnsRole: "central",
555
+ structureType: "exoskeleton",
556
+ breachThreshold: q(0.5),
557
+ fluidSystem: "none",
558
+ },
559
+ {
560
+ id: "thorax",
561
+ parent: null,
562
+ mass_kg: 3000,
563
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.35) },
564
+ cnsRole: "ganglionic",
565
+ structureType: "exoskeleton",
566
+ breachThreshold: q(0.4),
567
+ fluidSystem: "open",
568
+ hemolymphLossRate: q(0.002),
569
+ intrinsicArmor_J: 40, // Phase 8C: chitinous shell absorbs 40 J before channel split
570
+ },
571
+ {
572
+ id: "forewing_l",
573
+ parent: "thorax",
574
+ mass_kg: 500,
575
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
576
+ locomotionRole: "primary",
577
+ structureType: "exoskeleton",
578
+ breachThreshold: q(0.3),
579
+ isJoint: true,
580
+ jointDamageMultiplier: q(1.5),
581
+ },
582
+ {
583
+ id: "forewing_r",
584
+ parent: "thorax",
585
+ mass_kg: 500,
586
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.08) },
587
+ locomotionRole: "primary",
588
+ structureType: "exoskeleton",
589
+ breachThreshold: q(0.3),
590
+ isJoint: true,
591
+ jointDamageMultiplier: q(1.5),
592
+ },
593
+ {
594
+ id: "hindwing_l",
595
+ parent: "thorax",
596
+ mass_kg: 700,
597
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
598
+ locomotionRole: "primary",
599
+ structureType: "exoskeleton",
600
+ breachThreshold: q(0.3),
601
+ isJoint: true,
602
+ jointDamageMultiplier: q(1.5),
603
+ },
604
+ {
605
+ id: "hindwing_r",
606
+ parent: "thorax",
607
+ mass_kg: 700,
608
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.10) },
609
+ locomotionRole: "primary",
610
+ structureType: "exoskeleton",
611
+ breachThreshold: q(0.3),
612
+ isJoint: true,
613
+ jointDamageMultiplier: q(1.5),
614
+ },
615
+ {
616
+ id: "foreleg_l",
617
+ parent: "thorax",
618
+ mass_kg: 500,
619
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.035) },
620
+ locomotionRole: "secondary",
621
+ structureType: "exoskeleton",
622
+ breachThreshold: q(0.5),
623
+ regeneratesViaMolting: true,
624
+ },
625
+ {
626
+ id: "foreleg_r",
627
+ parent: "thorax",
628
+ mass_kg: 500,
629
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.035) },
630
+ locomotionRole: "secondary",
631
+ structureType: "exoskeleton",
632
+ breachThreshold: q(0.5),
633
+ regeneratesViaMolting: true,
634
+ },
635
+ {
636
+ id: "midleg_l",
637
+ parent: "thorax",
638
+ mass_kg: 500,
639
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.035) },
640
+ locomotionRole: "secondary",
641
+ structureType: "exoskeleton",
642
+ breachThreshold: q(0.5),
643
+ regeneratesViaMolting: true,
644
+ },
645
+ {
646
+ id: "midleg_r",
647
+ parent: "thorax",
648
+ mass_kg: 500,
649
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.035) },
650
+ locomotionRole: "secondary",
651
+ structureType: "exoskeleton",
652
+ breachThreshold: q(0.5),
653
+ regeneratesViaMolting: true,
654
+ },
655
+ {
656
+ id: "hindleg_l",
657
+ parent: "thorax",
658
+ mass_kg: 800,
659
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.05) },
660
+ locomotionRole: "primary",
661
+ structureType: "exoskeleton",
662
+ breachThreshold: q(0.5),
663
+ regeneratesViaMolting: true,
664
+ },
665
+ {
666
+ id: "hindleg_r",
667
+ parent: "thorax",
668
+ mass_kg: 800,
669
+ exposureWeight: { [DamageChannel.Kinetic]: q(0.05) },
670
+ locomotionRole: "primary",
671
+ structureType: "exoskeleton",
672
+ breachThreshold: q(0.5),
673
+ regeneratesViaMolting: true,
674
+ },
675
+ ],
676
+ };
677
+ // GRASSHOPPER_PLAN kinetic sum: 500+3500+800+800+1000+1000+350+350+350+350+500+500 = 10000 ✓