@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.
- package/CHANGELOG.md +135 -0
- package/LICENSE +21 -0
- package/README.md +2199 -0
- package/STABLE_API.md +266 -0
- package/dist/src/anatomy/anatomy-compiler.d.ts +14 -0
- package/dist/src/anatomy/anatomy-compiler.js +277 -0
- package/dist/src/anatomy/anatomy-contracts.d.ts +94 -0
- package/dist/src/anatomy/anatomy-contracts.js +1 -0
- package/dist/src/anatomy/anatomy-helpers.d.ts +82 -0
- package/dist/src/anatomy/anatomy-helpers.js +233 -0
- package/dist/src/anatomy/anatomy-schema.d.ts +28 -0
- package/dist/src/anatomy/anatomy-schema.js +388 -0
- package/dist/src/anatomy/index.d.ts +4 -0
- package/dist/src/anatomy/index.js +4 -0
- package/dist/src/archetypes.d.ts +87 -0
- package/dist/src/archetypes.js +285 -0
- package/dist/src/arena.d.ts +173 -0
- package/dist/src/arena.js +695 -0
- package/dist/src/bridge/bridge-engine.d.ts +46 -0
- package/dist/src/bridge/bridge-engine.js +252 -0
- package/dist/src/bridge/index.d.ts +4 -0
- package/dist/src/bridge/index.js +5 -0
- package/dist/src/bridge/interpolation.d.ts +64 -0
- package/dist/src/bridge/interpolation.js +130 -0
- package/dist/src/bridge/mapping.d.ts +33 -0
- package/dist/src/bridge/mapping.js +54 -0
- package/dist/src/bridge/types.d.ts +94 -0
- package/dist/src/bridge/types.js +2 -0
- package/dist/src/campaign.d.ts +141 -0
- package/dist/src/campaign.js +235 -0
- package/dist/src/channels.d.ts +15 -0
- package/dist/src/channels.js +20 -0
- package/dist/src/chronicle.d.ts +124 -0
- package/dist/src/chronicle.js +232 -0
- package/dist/src/collective-activities.d.ts +154 -0
- package/dist/src/collective-activities.js +247 -0
- package/dist/src/competence/acoustic.d.ts +101 -0
- package/dist/src/competence/acoustic.js +242 -0
- package/dist/src/competence/catalogue.d.ts +30 -0
- package/dist/src/competence/catalogue.js +241 -0
- package/dist/src/competence/crafting.d.ts +35 -0
- package/dist/src/competence/crafting.js +88 -0
- package/dist/src/competence/engineering.d.ts +53 -0
- package/dist/src/competence/engineering.js +108 -0
- package/dist/src/competence/framework.d.ts +68 -0
- package/dist/src/competence/framework.js +694 -0
- package/dist/src/competence/index.d.ts +12 -0
- package/dist/src/competence/index.js +13 -0
- package/dist/src/competence/interspecies.d.ts +81 -0
- package/dist/src/competence/interspecies.js +108 -0
- package/dist/src/competence/language.d.ts +79 -0
- package/dist/src/competence/language.js +115 -0
- package/dist/src/competence/naturalist.d.ts +97 -0
- package/dist/src/competence/naturalist.js +187 -0
- package/dist/src/competence/navigation.d.ts +24 -0
- package/dist/src/competence/navigation.js +48 -0
- package/dist/src/competence/performance.d.ts +125 -0
- package/dist/src/competence/performance.js +210 -0
- package/dist/src/competence/teaching.d.ts +64 -0
- package/dist/src/competence/teaching.js +121 -0
- package/dist/src/competence/willpower.d.ts +74 -0
- package/dist/src/competence/willpower.js +114 -0
- package/dist/src/crafting/index.d.ts +55 -0
- package/dist/src/crafting/index.js +229 -0
- package/dist/src/crafting/manufacturing.d.ts +83 -0
- package/dist/src/crafting/manufacturing.js +165 -0
- package/dist/src/crafting/materials.d.ts +53 -0
- package/dist/src/crafting/materials.js +120 -0
- package/dist/src/crafting/recipes.d.ts +75 -0
- package/dist/src/crafting/recipes.js +233 -0
- package/dist/src/crafting/workshops.d.ts +61 -0
- package/dist/src/crafting/workshops.js +170 -0
- package/dist/src/debug.d.ts +86 -0
- package/dist/src/debug.js +76 -0
- package/dist/src/derive.d.ts +21 -0
- package/dist/src/derive.js +88 -0
- package/dist/src/describe.d.ts +29 -0
- package/dist/src/describe.js +276 -0
- package/dist/src/dialogue.d.ts +122 -0
- package/dist/src/dialogue.js +266 -0
- package/dist/src/dist.d.ts +20 -0
- package/dist/src/dist.js +39 -0
- package/dist/src/downtime.d.ts +89 -0
- package/dist/src/downtime.js +391 -0
- package/dist/src/economy.d.ts +116 -0
- package/dist/src/economy.js +182 -0
- package/dist/src/emotional-contagion.d.ts +142 -0
- package/dist/src/emotional-contagion.js +274 -0
- package/dist/src/equipment.d.ts +206 -0
- package/dist/src/equipment.js +598 -0
- package/dist/src/faction.d.ts +102 -0
- package/dist/src/faction.js +237 -0
- package/dist/src/generate.d.ts +35 -0
- package/dist/src/generate.js +166 -0
- package/dist/src/index.d.ts +42 -0
- package/dist/src/index.js +54 -0
- package/dist/src/inheritance.d.ts +69 -0
- package/dist/src/inheritance.js +136 -0
- package/dist/src/inventory.d.ts +194 -0
- package/dist/src/inventory.js +637 -0
- package/dist/src/item-durability.d.ts +69 -0
- package/dist/src/item-durability.js +308 -0
- package/dist/src/legend.d.ts +97 -0
- package/dist/src/legend.js +269 -0
- package/dist/src/lod.d.ts +9 -0
- package/dist/src/lod.js +84 -0
- package/dist/src/metrics.d.ts +51 -0
- package/dist/src/metrics.js +91 -0
- package/dist/src/model3d.d.ts +138 -0
- package/dist/src/model3d.js +214 -0
- package/dist/src/mythology.d.ts +101 -0
- package/dist/src/mythology.js +308 -0
- package/dist/src/narrative-render.d.ts +42 -0
- package/dist/src/narrative-render.js +194 -0
- package/dist/src/narrative-stress.d.ts +123 -0
- package/dist/src/narrative-stress.js +183 -0
- package/dist/src/narrative.d.ts +44 -0
- package/dist/src/narrative.js +257 -0
- package/dist/src/party.d.ts +70 -0
- package/dist/src/party.js +226 -0
- package/dist/src/polity.d.ts +262 -0
- package/dist/src/polity.js +398 -0
- package/dist/src/presets.d.ts +42 -0
- package/dist/src/presets.js +170 -0
- package/dist/src/progression.d.ts +170 -0
- package/dist/src/progression.js +256 -0
- package/dist/src/quest-generators.d.ts +76 -0
- package/dist/src/quest-generators.js +534 -0
- package/dist/src/quest.d.ts +239 -0
- package/dist/src/quest.js +520 -0
- package/dist/src/relationships-effects.d.ts +75 -0
- package/dist/src/relationships-effects.js +219 -0
- package/dist/src/relationships.d.ts +104 -0
- package/dist/src/relationships.js +347 -0
- package/dist/src/replay.d.ts +47 -0
- package/dist/src/replay.js +82 -0
- package/dist/src/rng.d.ts +9 -0
- package/dist/src/rng.js +37 -0
- package/dist/src/settlement-services.d.ts +67 -0
- package/dist/src/settlement-services.js +267 -0
- package/dist/src/settlement.d.ts +143 -0
- package/dist/src/settlement.js +419 -0
- package/dist/src/sim/action.d.ts +28 -0
- package/dist/src/sim/action.js +12 -0
- package/dist/src/sim/aging.d.ts +95 -0
- package/dist/src/sim/aging.js +243 -0
- package/dist/src/sim/ai/decide.d.ts +10 -0
- package/dist/src/sim/ai/decide.js +267 -0
- package/dist/src/sim/ai/perception.d.ts +12 -0
- package/dist/src/sim/ai/perception.js +54 -0
- package/dist/src/sim/ai/personality.d.ts +54 -0
- package/dist/src/sim/ai/personality.js +202 -0
- package/dist/src/sim/ai/presets.d.ts +2 -0
- package/dist/src/sim/ai/presets.js +28 -0
- package/dist/src/sim/ai/system.d.ts +6 -0
- package/dist/src/sim/ai/system.js +13 -0
- package/dist/src/sim/ai/targeting.d.ts +8 -0
- package/dist/src/sim/ai/targeting.js +42 -0
- package/dist/src/sim/ai/types.d.ts +14 -0
- package/dist/src/sim/ai/types.js +1 -0
- package/dist/src/sim/body.d.ts +9 -0
- package/dist/src/sim/body.js +32 -0
- package/dist/src/sim/bodyplan.d.ts +161 -0
- package/dist/src/sim/bodyplan.js +677 -0
- package/dist/src/sim/capability.d.ts +135 -0
- package/dist/src/sim/capability.js +8 -0
- package/dist/src/sim/combat.d.ts +21 -0
- package/dist/src/sim/combat.js +77 -0
- package/dist/src/sim/commandBuilders.d.ts +11 -0
- package/dist/src/sim/commandBuilders.js +39 -0
- package/dist/src/sim/commands.d.ts +71 -0
- package/dist/src/sim/commands.js +8 -0
- package/dist/src/sim/condition.d.ts +35 -0
- package/dist/src/sim/condition.js +21 -0
- package/dist/src/sim/cone.d.ts +40 -0
- package/dist/src/sim/cone.js +44 -0
- package/dist/src/sim/context.d.ts +68 -0
- package/dist/src/sim/context.js +1 -0
- package/dist/src/sim/density.d.ts +14 -0
- package/dist/src/sim/density.js +33 -0
- package/dist/src/sim/disease.d.ts +141 -0
- package/dist/src/sim/disease.js +353 -0
- package/dist/src/sim/entity.d.ts +251 -0
- package/dist/src/sim/entity.js +19 -0
- package/dist/src/sim/events.d.ts +25 -0
- package/dist/src/sim/events.js +5 -0
- package/dist/src/sim/explosion.d.ts +40 -0
- package/dist/src/sim/explosion.js +40 -0
- package/dist/src/sim/formation-unit.d.ts +138 -0
- package/dist/src/sim/formation-unit.js +197 -0
- package/dist/src/sim/formation.d.ts +12 -0
- package/dist/src/sim/formation.js +54 -0
- package/dist/src/sim/frontage.d.ts +30 -0
- package/dist/src/sim/frontage.js +84 -0
- package/dist/src/sim/grapple.d.ts +100 -0
- package/dist/src/sim/grapple.js +480 -0
- package/dist/src/sim/hazard.d.ts +104 -0
- package/dist/src/sim/hazard.js +201 -0
- package/dist/src/sim/hydrostatic.d.ts +58 -0
- package/dist/src/sim/hydrostatic.js +117 -0
- package/dist/src/sim/impairment.d.ts +20 -0
- package/dist/src/sim/impairment.js +162 -0
- package/dist/src/sim/indexing.d.ts +7 -0
- package/dist/src/sim/indexing.js +7 -0
- package/dist/src/sim/injury.d.ts +54 -0
- package/dist/src/sim/injury.js +66 -0
- package/dist/src/sim/intent.d.ts +26 -0
- package/dist/src/sim/intent.js +7 -0
- package/dist/src/sim/kernel.d.ts +45 -0
- package/dist/src/sim/kernel.js +1992 -0
- package/dist/src/sim/kinds.d.ts +64 -0
- package/dist/src/sim/kinds.js +56 -0
- package/dist/src/sim/knockback.d.ts +50 -0
- package/dist/src/sim/knockback.js +82 -0
- package/dist/src/sim/limb.d.ts +48 -0
- package/dist/src/sim/limb.js +78 -0
- package/dist/src/sim/medical.d.ts +32 -0
- package/dist/src/sim/medical.js +33 -0
- package/dist/src/sim/morale.d.ts +69 -0
- package/dist/src/sim/morale.js +92 -0
- package/dist/src/sim/mount.d.ts +150 -0
- package/dist/src/sim/mount.js +225 -0
- package/dist/src/sim/nutrition.d.ts +74 -0
- package/dist/src/sim/nutrition.js +168 -0
- package/dist/src/sim/occlusion.d.ts +8 -0
- package/dist/src/sim/occlusion.js +71 -0
- package/dist/src/sim/push.d.ts +11 -0
- package/dist/src/sim/push.js +79 -0
- package/dist/src/sim/ranged.d.ts +44 -0
- package/dist/src/sim/ranged.js +69 -0
- package/dist/src/sim/seeds.d.ts +3 -0
- package/dist/src/sim/seeds.js +16 -0
- package/dist/src/sim/sensory-extended.d.ts +103 -0
- package/dist/src/sim/sensory-extended.js +181 -0
- package/dist/src/sim/sensory.d.ts +38 -0
- package/dist/src/sim/sensory.js +109 -0
- package/dist/src/sim/skills.d.ts +70 -0
- package/dist/src/sim/skills.js +69 -0
- package/dist/src/sim/sleep.d.ts +107 -0
- package/dist/src/sim/sleep.js +215 -0
- package/dist/src/sim/spatial.d.ts +8 -0
- package/dist/src/sim/spatial.js +59 -0
- package/dist/src/sim/step/capability.d.ts +8 -0
- package/dist/src/sim/step/capability.js +77 -0
- package/dist/src/sim/step/concentration.d.ts +9 -0
- package/dist/src/sim/step/concentration.js +25 -0
- package/dist/src/sim/step/effects.d.ts +17 -0
- package/dist/src/sim/step/effects.js +96 -0
- package/dist/src/sim/step/energy.d.ts +3 -0
- package/dist/src/sim/step/energy.js +31 -0
- package/dist/src/sim/step/hazards.d.ts +4 -0
- package/dist/src/sim/step/hazards.js +19 -0
- package/dist/src/sim/step/injury.d.ts +10 -0
- package/dist/src/sim/step/injury.js +353 -0
- package/dist/src/sim/step/morale.d.ts +11 -0
- package/dist/src/sim/step/morale.js +130 -0
- package/dist/src/sim/step/movement.d.ts +5 -0
- package/dist/src/sim/step/movement.js +172 -0
- package/dist/src/sim/step/push.d.ts +11 -0
- package/dist/src/sim/step/push.js +79 -0
- package/dist/src/sim/step/substances.d.ts +3 -0
- package/dist/src/sim/step/substances.js +75 -0
- package/dist/src/sim/substance.d.ts +38 -0
- package/dist/src/sim/substance.js +57 -0
- package/dist/src/sim/systemic-toxicology.d.ts +109 -0
- package/dist/src/sim/systemic-toxicology.js +263 -0
- package/dist/src/sim/team.d.ts +9 -0
- package/dist/src/sim/team.js +37 -0
- package/dist/src/sim/tech.d.ts +36 -0
- package/dist/src/sim/tech.js +46 -0
- package/dist/src/sim/terrain.d.ts +121 -0
- package/dist/src/sim/terrain.js +141 -0
- package/dist/src/sim/testing.d.ts +13 -0
- package/dist/src/sim/testing.js +100 -0
- package/dist/src/sim/thermoregulation.d.ts +77 -0
- package/dist/src/sim/thermoregulation.js +161 -0
- package/dist/src/sim/tick.d.ts +3 -0
- package/dist/src/sim/tick.js +3 -0
- package/dist/src/sim/toxicology.d.ts +52 -0
- package/dist/src/sim/toxicology.js +104 -0
- package/dist/src/sim/trace.d.ts +141 -0
- package/dist/src/sim/trace.js +1 -0
- package/dist/src/sim/tuning.d.ts +16 -0
- package/dist/src/sim/tuning.js +42 -0
- package/dist/src/sim/vec3.d.ts +14 -0
- package/dist/src/sim/vec3.js +31 -0
- package/dist/src/sim/weapon_dynamics.d.ts +102 -0
- package/dist/src/sim/weapon_dynamics.js +142 -0
- package/dist/src/sim/weather.d.ts +95 -0
- package/dist/src/sim/weather.js +105 -0
- package/dist/src/sim/world.d.ts +52 -0
- package/dist/src/sim/world.js +1 -0
- package/dist/src/sim/wound-aging.d.ts +120 -0
- package/dist/src/sim/wound-aging.js +223 -0
- package/dist/src/species.d.ts +106 -0
- package/dist/src/species.js +664 -0
- package/dist/src/story-arcs.d.ts +17 -0
- package/dist/src/story-arcs.js +276 -0
- package/dist/src/tech-diffusion.d.ts +80 -0
- package/dist/src/tech-diffusion.js +185 -0
- package/dist/src/traits.d.ts +25 -0
- package/dist/src/traits.js +178 -0
- package/dist/src/types.d.ts +117 -0
- package/dist/src/types.js +1 -0
- package/dist/src/units.d.ts +41 -0
- package/dist/src/units.js +64 -0
- package/dist/src/weapons.d.ts +20 -0
- package/dist/src/weapons.js +824 -0
- package/dist/src/world-generation.d.ts +52 -0
- package/dist/src/world-generation.js +301 -0
- package/package.json +74 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/competence/crafting.ts — Phase 34: Bodily-Kinesthetic Non-Combat Applications
|
|
2
|
+
//
|
|
3
|
+
// Crafting quality model:
|
|
4
|
+
// quality_Q = materialQ × bodilyKinesthetic × skillBonus × toolBonus (± RNG variance)
|
|
5
|
+
// timeTaken_s = baseTime_s × q(0.50) / bodilyKinesthetic
|
|
6
|
+
// (baseTime_s is defined for a BK q(0.50) entity as the reference)
|
|
7
|
+
//
|
|
8
|
+
// No kernel import — pure resolution module.
|
|
9
|
+
import { SCALE, q, clampQ, qMul, mulDiv } from "../units.js";
|
|
10
|
+
import { makeRng } from "../rng.js";
|
|
11
|
+
// ── Constants ─────────────────────────────────────────────────────────────────
|
|
12
|
+
const TOOL_BONUS = {
|
|
13
|
+
precision: q(1.20),
|
|
14
|
+
bladed: q(1.10),
|
|
15
|
+
forge: q(1.10),
|
|
16
|
+
needlework: q(1.05),
|
|
17
|
+
blunt: q(1.05),
|
|
18
|
+
};
|
|
19
|
+
/** Half-width of RNG quality variance band. */
|
|
20
|
+
const VARIANCE_HALF = q(0.10);
|
|
21
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
22
|
+
function toDescriptor(quality_Q) {
|
|
23
|
+
if (quality_Q >= q(0.85))
|
|
24
|
+
return "masterwork";
|
|
25
|
+
if (quality_Q >= q(0.65))
|
|
26
|
+
return "fine";
|
|
27
|
+
if (quality_Q >= q(0.40))
|
|
28
|
+
return "adequate";
|
|
29
|
+
if (quality_Q >= q(0.20))
|
|
30
|
+
return "poor";
|
|
31
|
+
return "ruined";
|
|
32
|
+
}
|
|
33
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a crafting attempt.
|
|
36
|
+
*
|
|
37
|
+
* @param entity - The crafter; uses `cognition.bodilyKinesthetic` and `control.fineControl`.
|
|
38
|
+
* @param spec - Crafting specification.
|
|
39
|
+
* @param seed - Deterministic seed (e.g. from eventSeed()).
|
|
40
|
+
*/
|
|
41
|
+
export function resolveCrafting(entity, spec, seed) {
|
|
42
|
+
const bkQ = (entity.attributes.cognition?.bodilyKinesthetic ?? q(0.50));
|
|
43
|
+
// Minimum BK gate: not skilled enough to attempt this work
|
|
44
|
+
if (bkQ < spec.minBKQ) {
|
|
45
|
+
return {
|
|
46
|
+
quality_Q: q(0),
|
|
47
|
+
timeTaken_s: spec.baseTime_s,
|
|
48
|
+
success: false,
|
|
49
|
+
descriptor: "ruined",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Tool bonus
|
|
53
|
+
const toolBonus = spec.toolCategory ? TOOL_BONUS[spec.toolCategory] : q(1.0);
|
|
54
|
+
// Skill bonus from fineControl: lerp(q(0.80), q(1.20), fineControl)
|
|
55
|
+
// fineControl q(0.0) → skillBonus q(0.80) (no precision in hands)
|
|
56
|
+
// fineControl q(0.50) → skillBonus q(1.00) (neutral)
|
|
57
|
+
// fineControl q(1.0) → skillBonus q(1.20) (exceptional fine motor control)
|
|
58
|
+
const fc = entity.attributes.control.fineControl;
|
|
59
|
+
const skillBonus = clampQ((q(0.80) + mulDiv(q(0.40), fc, SCALE.Q)), q(0.80), q(1.20));
|
|
60
|
+
// Expected quality = materialQ × bkQ × skillBonus × toolBonus (all Q-scaled)
|
|
61
|
+
const expected = qMul(qMul(spec.materialQ, bkQ), qMul(skillBonus, toolBonus));
|
|
62
|
+
// RNG variance ±VARIANCE_HALF (roll in [0, SCALE.Q-1], centered at SCALE.Q/2)
|
|
63
|
+
const rng = makeRng(seed, SCALE.Q);
|
|
64
|
+
const roll = rng.q01();
|
|
65
|
+
const variance = mulDiv(roll - SCALE.Q / 2, 2 * VARIANCE_HALF, SCALE.Q);
|
|
66
|
+
const quality_Q = clampQ((expected + variance), q(0), q(1.0));
|
|
67
|
+
// Time: baseTime_s is the reference at BK q(0.50); scales inversely with BK
|
|
68
|
+
const timeTaken_s = Math.round(spec.baseTime_s * q(0.50) / bkQ);
|
|
69
|
+
const success = quality_Q >= q(0.20);
|
|
70
|
+
return {
|
|
71
|
+
quality_Q,
|
|
72
|
+
timeTaken_s,
|
|
73
|
+
success,
|
|
74
|
+
descriptor: success ? toDescriptor(quality_Q) : "ruined",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Phase 34: compute surgical precision multiplier from surgeon's bodilyKinesthetic.
|
|
79
|
+
* Result: lerp(q(0.70), q(1.30), bk)
|
|
80
|
+
* - Assign to `TreatmentSchedule.surgicalPrecisionMul` in downtime config.
|
|
81
|
+
* - BK q(0.00) → q(0.70) (clumsy; slower/worse surgery)
|
|
82
|
+
* - BK q(0.50) → q(1.00) (normal)
|
|
83
|
+
* - BK q(1.00) → q(1.30) (expert; faster/better surgery)
|
|
84
|
+
*/
|
|
85
|
+
export function computeSurgicalPrecision(entity) {
|
|
86
|
+
const bkQ = (entity.attributes.cognition?.bodilyKinesthetic ?? q(0.50));
|
|
87
|
+
return clampQ((q(0.70) + mulDiv(q(0.60), bkQ, SCALE.Q)), q(0.70), q(1.30));
|
|
88
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Q } from "../units.js";
|
|
2
|
+
import type { Entity } from "../sim/entity.js";
|
|
3
|
+
export interface EngineeringSpec {
|
|
4
|
+
/** Engineering category. */
|
|
5
|
+
category: "fortification" | "mechanism" | "weapon" | "vessel";
|
|
6
|
+
/** Complexity of the project (0–1). */
|
|
7
|
+
complexity_Q: Q;
|
|
8
|
+
/** Time budget in hours. */
|
|
9
|
+
timeBudget_h: number;
|
|
10
|
+
}
|
|
11
|
+
export interface EngineeringOutcome {
|
|
12
|
+
/** Quality multiplier on structural integrity / resist_J. */
|
|
13
|
+
qualityMul: Q;
|
|
14
|
+
/** True if project has a latent flaw. */
|
|
15
|
+
latentFlaw: boolean;
|
|
16
|
+
/** Time actually taken (may exceed budget if quality suffers). */
|
|
17
|
+
timeTaken_h: number;
|
|
18
|
+
/** Success descriptor. */
|
|
19
|
+
descriptor: "exceptional" | "good" | "adequate" | "poor" | "failure";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve an engineering project.
|
|
23
|
+
*
|
|
24
|
+
* Formulas:
|
|
25
|
+
* qualityMul = logicalMath × (1 − complexity_Q × 0.30) × timeFactor
|
|
26
|
+
* P_latentFlaw = max(0, complexity_Q − logicalMath) × 0.40
|
|
27
|
+
*
|
|
28
|
+
* Troll (0.25) building complex siege engine → ~48% flaw chance. Heechee (0.95) → 0%.
|
|
29
|
+
*
|
|
30
|
+
* @param entity - The engineer; uses `cognition.logicalMathematical`.
|
|
31
|
+
* @param spec - Engineering specification.
|
|
32
|
+
* @param seed - Deterministic seed for RNG.
|
|
33
|
+
* @returns Engineering outcome.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveEngineering(entity: Entity, spec: EngineeringSpec, seed: number): EngineeringOutcome;
|
|
36
|
+
/**
|
|
37
|
+
* Compute structural integrity multiplier from engineering quality.
|
|
38
|
+
*/
|
|
39
|
+
export declare function applyEngineeringQuality(baseIntegrity: Q, qualityMul: Q): Q;
|
|
40
|
+
/**
|
|
41
|
+
* Check if entity is qualified for an engineering project.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isQualifiedEngineer(entity: Entity, minLogicalMath?: Q): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Estimate project difficulty for an engineer.
|
|
46
|
+
* Returns estimated quality multiplier without consuming resources.
|
|
47
|
+
*/
|
|
48
|
+
export declare function estimateProjectQuality(entity: Entity, spec: Omit<EngineeringSpec, "timeBudget_h"> & {
|
|
49
|
+
timeBudget_h?: number;
|
|
50
|
+
}): {
|
|
51
|
+
estimatedQuality_Q: Q;
|
|
52
|
+
flawRiskPercent: number;
|
|
53
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// src/competence/engineering.ts — Phase 38: Engineering Quality (Logical-Mathematical Intelligence)
|
|
2
|
+
//
|
|
3
|
+
// Logical-mathematical intelligence governs systematic reasoning applied to complex
|
|
4
|
+
// external problems: tactical analysis, engineering, research, resource planning.
|
|
5
|
+
//
|
|
6
|
+
// No kernel import — pure resolution module.
|
|
7
|
+
import { SCALE, q, clampQ, mulDiv } from "../units.js";
|
|
8
|
+
import { makeRng } from "../rng.js";
|
|
9
|
+
// ── Constants ─────────────────────────────────────────────────────────────────
|
|
10
|
+
/** Base quality multiplier at logicalMath q(0.50). */
|
|
11
|
+
const BASE_QUALITY_MUL = q(0.70);
|
|
12
|
+
/** Maximum quality multiplier. */
|
|
13
|
+
const MAX_QUALITY_MUL = q(1.20);
|
|
14
|
+
/** Minimum quality multiplier for success. */
|
|
15
|
+
const MIN_SUCCESS_QUALITY = q(0.30);
|
|
16
|
+
/** Time factor: rushed work reduces quality. */
|
|
17
|
+
const TIME_FACTOR_BASE = 1.0;
|
|
18
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Resolve an engineering project.
|
|
21
|
+
*
|
|
22
|
+
* Formulas:
|
|
23
|
+
* qualityMul = logicalMath × (1 − complexity_Q × 0.30) × timeFactor
|
|
24
|
+
* P_latentFlaw = max(0, complexity_Q − logicalMath) × 0.40
|
|
25
|
+
*
|
|
26
|
+
* Troll (0.25) building complex siege engine → ~48% flaw chance. Heechee (0.95) → 0%.
|
|
27
|
+
*
|
|
28
|
+
* @param entity - The engineer; uses `cognition.logicalMathematical`.
|
|
29
|
+
* @param spec - Engineering specification.
|
|
30
|
+
* @param seed - Deterministic seed for RNG.
|
|
31
|
+
* @returns Engineering outcome.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveEngineering(entity, spec, seed) {
|
|
34
|
+
const logicalMath = (entity.attributes.cognition?.logicalMathematical ?? q(0.50));
|
|
35
|
+
// Complexity penalty: higher complexity reduces base quality
|
|
36
|
+
const complexityPenalty = mulDiv(spec.complexity_Q, q(0.30), SCALE.Q);
|
|
37
|
+
const complexityMul = clampQ((SCALE.Q - complexityPenalty), q(0.40), SCALE.Q);
|
|
38
|
+
// Time factor: adequate time budget improves quality
|
|
39
|
+
// Optimal time = complexity × 10 hours baseline
|
|
40
|
+
const optimalTime_h = 5 + (spec.complexity_Q / SCALE.Q) * 15; // 5-20 hours based on complexity
|
|
41
|
+
const timeFactor = Math.min(1.2, spec.timeBudget_h / optimalTime_h);
|
|
42
|
+
// Calculate quality multiplier
|
|
43
|
+
const rawQuality = mulDiv(mulDiv(logicalMath, complexityMul, SCALE.Q), Math.round(timeFactor * SCALE.Q), SCALE.Q);
|
|
44
|
+
const qualityMul = clampQ((BASE_QUALITY_MUL + mulDiv(rawQuality, q(0.50), SCALE.Q)), q(0.20), MAX_QUALITY_MUL);
|
|
45
|
+
// Latent flaw probability
|
|
46
|
+
// P_flaw = max(0, complexity_Q − logicalMath) × 0.40
|
|
47
|
+
const skillDeficit = Math.max(0, spec.complexity_Q - logicalMath);
|
|
48
|
+
const pFlaw = mulDiv(skillDeficit, q(0.40), SCALE.Q);
|
|
49
|
+
// RNG for flaw check
|
|
50
|
+
const rng = makeRng(seed, SCALE.Q);
|
|
51
|
+
const flawRoll = rng.q01();
|
|
52
|
+
const latentFlaw = flawRoll < pFlaw;
|
|
53
|
+
// Determine descriptor
|
|
54
|
+
let descriptor;
|
|
55
|
+
if (qualityMul >= q(1.0)) {
|
|
56
|
+
descriptor = latentFlaw ? "good" : "exceptional";
|
|
57
|
+
}
|
|
58
|
+
else if (qualityMul >= q(0.70)) {
|
|
59
|
+
descriptor = "good";
|
|
60
|
+
}
|
|
61
|
+
else if (qualityMul >= MIN_SUCCESS_QUALITY) {
|
|
62
|
+
descriptor = "adequate";
|
|
63
|
+
}
|
|
64
|
+
else if (qualityMul >= q(0.15)) {
|
|
65
|
+
descriptor = "poor";
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
descriptor = "failure";
|
|
69
|
+
}
|
|
70
|
+
// Time taken: may overrun if quality is poor
|
|
71
|
+
const timeTaken_h = descriptor === "poor"
|
|
72
|
+
? Math.round(spec.timeBudget_h * 1.5)
|
|
73
|
+
: spec.timeBudget_h;
|
|
74
|
+
return { qualityMul, latentFlaw, timeTaken_h, descriptor };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compute structural integrity multiplier from engineering quality.
|
|
78
|
+
*/
|
|
79
|
+
export function applyEngineeringQuality(baseIntegrity, qualityMul) {
|
|
80
|
+
return clampQ(mulDiv(baseIntegrity, qualityMul, SCALE.Q), q(0.30), SCALE.Q);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if entity is qualified for an engineering project.
|
|
84
|
+
*/
|
|
85
|
+
export function isQualifiedEngineer(entity, minLogicalMath = q(0.40)) {
|
|
86
|
+
const logicalMath = (entity.attributes.cognition?.logicalMathematical ?? q(0.50));
|
|
87
|
+
return logicalMath >= minLogicalMath;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Estimate project difficulty for an engineer.
|
|
91
|
+
* Returns estimated quality multiplier without consuming resources.
|
|
92
|
+
*/
|
|
93
|
+
export function estimateProjectQuality(entity, spec) {
|
|
94
|
+
const logicalMath = (entity.attributes.cognition?.logicalMathematical ?? q(0.50));
|
|
95
|
+
// Simplified quality estimate
|
|
96
|
+
const complexityPenalty = mulDiv(spec.complexity_Q, q(0.30), SCALE.Q);
|
|
97
|
+
const complexityMul = clampQ((SCALE.Q - complexityPenalty), q(0.40), SCALE.Q);
|
|
98
|
+
const timeBudget = spec.timeBudget_h ?? 10;
|
|
99
|
+
const optimalTime_h = 5 + (spec.complexity_Q / SCALE.Q) * 15;
|
|
100
|
+
const timeFactor = Math.min(1.2, timeBudget / optimalTime_h);
|
|
101
|
+
const rawQuality = mulDiv(mulDiv(logicalMath, complexityMul, SCALE.Q), Math.round(timeFactor * SCALE.Q), SCALE.Q);
|
|
102
|
+
const estimatedQuality_Q = clampQ((BASE_QUALITY_MUL + mulDiv(rawQuality, q(0.50), SCALE.Q)), q(0.20), MAX_QUALITY_MUL);
|
|
103
|
+
// Flaw risk
|
|
104
|
+
const skillDeficit = Math.max(0, spec.complexity_Q - logicalMath);
|
|
105
|
+
const pFlaw = mulDiv(skillDeficit, q(0.40), SCALE.Q);
|
|
106
|
+
const flawRiskPercent = Math.round((pFlaw / SCALE.Q) * 100);
|
|
107
|
+
return { estimatedQuality_Q, flawRiskPercent };
|
|
108
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Q } from "../units.js";
|
|
2
|
+
import type { Entity } from "../sim/entity.js";
|
|
3
|
+
import type { WorldState } from "../sim/world.js";
|
|
4
|
+
import type { CompetenceDomain } from "./catalogue.js";
|
|
5
|
+
/** A competence action to be resolved. */
|
|
6
|
+
export interface CompetenceAction {
|
|
7
|
+
/** Primary competence domain. */
|
|
8
|
+
domain: CompetenceDomain;
|
|
9
|
+
/** Task identifier (references CompetenceCatalogue). */
|
|
10
|
+
taskId: string;
|
|
11
|
+
/** Target entity ID (for interpersonal / inter-species tasks). */
|
|
12
|
+
targetEntityId?: number;
|
|
13
|
+
/** Tool/equipment item used. */
|
|
14
|
+
toolId?: string;
|
|
15
|
+
/** Time available for the task in seconds. */
|
|
16
|
+
timeAvailable_s: number;
|
|
17
|
+
/** Deterministic seed for RNG. */
|
|
18
|
+
seed: number;
|
|
19
|
+
/** Terrain/biome context for environmental tasks. */
|
|
20
|
+
terrain?: string;
|
|
21
|
+
/** Whether to include narrative description in outcome. */
|
|
22
|
+
narrative?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Outcome of a competence action resolution. */
|
|
25
|
+
export interface CompetenceOutcome {
|
|
26
|
+
/** Domain that was resolved. */
|
|
27
|
+
domain: CompetenceDomain;
|
|
28
|
+
/** Quality of the outcome (0–1). */
|
|
29
|
+
quality_Q: Q;
|
|
30
|
+
/** Time actually taken in seconds. */
|
|
31
|
+
timeTaken_s: number;
|
|
32
|
+
/** Whether the task succeeded. */
|
|
33
|
+
success: boolean;
|
|
34
|
+
/** Outcome descriptor. */
|
|
35
|
+
descriptor: "exceptional" | "good" | "adequate" | "poor" | "failure";
|
|
36
|
+
/** XP gained from this attempt (fed into Phase 21). */
|
|
37
|
+
xpGained: number;
|
|
38
|
+
/** Optional narrative description of outcome. */
|
|
39
|
+
narrativeLine?: string | undefined;
|
|
40
|
+
/** Domain-specific result data. */
|
|
41
|
+
details?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Map domain-specific descriptors to canonical descriptors.
|
|
45
|
+
*/
|
|
46
|
+
declare function canonicalizeDescriptor(descriptor: string): CompetenceOutcome["descriptor"];
|
|
47
|
+
/**
|
|
48
|
+
* Calculate XP gain based on outcome.
|
|
49
|
+
*/
|
|
50
|
+
declare function calculateXP(descriptor: CompetenceOutcome["descriptor"], difficulty_Q: Q): number;
|
|
51
|
+
/**
|
|
52
|
+
* Get the relevant cognitive attribute for a domain.
|
|
53
|
+
*/
|
|
54
|
+
declare function getDomainIntelligence(entity: Entity, domain: CompetenceDomain): Q;
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a competence action.
|
|
57
|
+
*
|
|
58
|
+
* This is the main entry point for the Phase 40 competence framework.
|
|
59
|
+
* It routes to the appropriate domain-specific resolver and computes
|
|
60
|
+
* XP gain for Phase 21 integration.
|
|
61
|
+
*
|
|
62
|
+
* @param actor - The entity performing the action.
|
|
63
|
+
* @param action - The competence action specification.
|
|
64
|
+
* @param world - The world state (for finding targets, etc.).
|
|
65
|
+
* @returns Competence outcome with quality, XP, and narrative.
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveCompetence(actor: Entity, action: CompetenceAction, world: WorldState): CompetenceOutcome;
|
|
68
|
+
export { getDomainIntelligence, canonicalizeDescriptor, calculateXP };
|