@its-not-rocket-science/ananke 0.1.68 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +274 -0
- package/README.md +150 -431
- package/STABLE_API.md +113 -490
- package/conformance/README.md +46 -44
- package/conformance/lockstep-sequence.json +395 -395
- package/conformance/phase-order.json +21 -0
- package/conformance/replay-parity.json +65 -65
- package/conformance/state-hash-regression.json +39 -0
- package/conformance/state-hash.json +23 -22
- package/dist/src/conformance.d.ts +8 -2
- package/dist/src/content/index.d.ts +3 -0
- package/dist/src/content/index.js +2 -0
- package/dist/src/content/injector.d.ts +19 -0
- package/dist/src/content/injector.js +61 -0
- package/dist/src/content/loader.d.ts +3 -0
- package/dist/src/content/loader.js +170 -0
- package/dist/src/content/types.d.ts +56 -0
- package/dist/src/content/types.js +1 -0
- package/dist/src/content/validator.d.ts +6 -0
- package/dist/src/content/validator.js +14 -0
- package/dist/src/content-pack.d.ts +3 -2
- package/dist/src/content-pack.js +205 -10
- package/dist/src/data-governance.d.ts +73 -0
- package/dist/src/data-governance.js +188 -0
- package/dist/src/debug.d.ts +6 -0
- package/dist/src/debug.js +9 -0
- package/dist/src/determinism.d.ts +12 -0
- package/dist/src/determinism.js +93 -0
- package/dist/src/dialogue.d.ts +41 -0
- package/dist/src/dialogue.js +113 -2
- package/dist/src/economy.d.ts +97 -3
- package/dist/src/economy.js +191 -37
- package/dist/src/history/autosave.d.ts +19 -0
- package/dist/src/history/autosave.js +98 -0
- package/dist/src/history/timetravel.d.ts +28 -0
- package/dist/src/history/timetravel.js +61 -0
- package/dist/src/index.d.ts +19 -31
- package/dist/src/index.js +20 -38
- package/dist/src/model3d.js +63 -2
- package/dist/src/narrative/combat-logger.d.ts +25 -0
- package/dist/src/narrative/combat-logger.js +97 -0
- package/dist/src/narrative/plausibility.d.ts +30 -0
- package/dist/src/narrative/plausibility.js +70 -0
- package/dist/src/narrative-layer.d.ts +2 -0
- package/dist/src/narrative-layer.js +2 -0
- package/dist/src/navigation/causal-chain.d.ts +26 -0
- package/dist/src/navigation/causal-chain.js +74 -0
- package/dist/src/netcode.d.ts +1 -1
- package/dist/src/netcode.js +1 -1
- package/dist/src/performance/adaptive-tick.d.ts +23 -0
- package/dist/src/performance/adaptive-tick.js +50 -0
- package/dist/src/plugins/loader.d.ts +23 -0
- package/dist/src/plugins/loader.js +86 -0
- package/dist/src/plugins/registry.d.ts +11 -0
- package/dist/src/plugins/registry.js +28 -0
- package/dist/src/plugins/types.d.ts +31 -0
- package/dist/src/plugins/types.js +7 -0
- package/dist/src/replay.js +5 -2
- package/dist/src/scenario.js +2 -1
- package/dist/src/serialization/binary.d.ts +5 -0
- package/dist/src/serialization/binary.js +193 -0
- package/dist/src/session.d.ts +115 -0
- package/dist/src/session.js +228 -0
- package/dist/src/sim/ai/decide.js +1 -1
- package/dist/src/sim/ai/personality.js +2 -2
- package/dist/src/sim/bodyplan.d.ts +30 -0
- package/dist/src/sim/context.d.ts +2 -0
- package/dist/src/sim/kernel.js +80 -1294
- package/dist/src/sim/normalization.d.ts +12 -0
- package/dist/src/sim/normalization.js +92 -0
- package/dist/src/sim/resolvers/attack-resolver.d.ts +30 -0
- package/dist/src/sim/resolvers/attack-resolver.js +310 -0
- package/dist/src/sim/resolvers/capability-resolver.d.ts +15 -0
- package/dist/src/sim/resolvers/capability-resolver.js +270 -0
- package/dist/src/sim/resolvers/grapple-resolver.d.ts +28 -0
- package/dist/src/sim/resolvers/grapple-resolver.js +70 -0
- package/dist/src/sim/resolvers/shoot-resolver.d.ts +27 -0
- package/dist/src/sim/resolvers/shoot-resolver.js +212 -0
- package/dist/src/sim/resolvers/treat-resolver.d.ts +16 -0
- package/dist/src/sim/resolvers/treat-resolver.js +77 -0
- package/dist/src/sim/step/apply/intents.d.ts +6 -0
- package/dist/src/sim/step/apply/intents.js +83 -0
- package/dist/src/sim/step/kernel-pipeline.d.ts +9 -0
- package/dist/src/sim/step/kernel-pipeline.js +15 -0
- package/dist/src/sim/step/phases/capability-phase.d.ts +8 -0
- package/dist/src/sim/step/phases/capability-phase.js +65 -0
- package/dist/src/sim/step/phases/cooldowns-phase.d.ts +3 -0
- package/dist/src/sim/step/phases/cooldowns-phase.js +37 -0
- package/dist/src/sim/step/phases/prepare-phase.d.ts +10 -0
- package/dist/src/sim/step/phases/prepare-phase.js +33 -0
- package/dist/src/sim/step/pipeline.d.ts +2 -0
- package/dist/src/sim/step/pipeline.js +15 -0
- package/dist/src/sim/step/resolvers/impact-resolver.d.ts +9 -0
- package/dist/src/sim/step/resolvers/impact-resolver.js +55 -0
- package/dist/src/sim/step/world-phases.d.ts +7 -0
- package/dist/src/sim/step/world-phases.js +15 -0
- package/dist/src/sim/step/world-step-context.d.ts +23 -0
- package/dist/src/sim/step/world-step-context.js +1 -0
- package/dist/src/sim/systemic-toxicology.js +1 -1
- package/dist/src/sim/team.js +2 -2
- package/dist/src/sim/testing.js +4 -3
- package/dist/src/sim/toxicology.d.ts +1 -1
- package/dist/src/sim/toxicology.js +1 -1
- package/dist/src/sim/world.d.ts +17 -24
- package/dist/src/snapshot.js +3 -6
- package/dist/src/tier2.d.ts +19 -0
- package/dist/src/tier2.js +21 -0
- package/dist/src/tier3.d.ts +10 -0
- package/dist/src/tier3.js +12 -0
- package/dist/src/version.d.ts +6 -0
- package/dist/src/version.js +8 -0
- package/dist/src/wasm/bridge.d.ts +14 -0
- package/dist/src/wasm/bridge.js +84 -0
- package/dist/src/wasm-kernel.d.ts +2 -0
- package/dist/src/wasm-kernel.js +1 -0
- package/dist/src/world-evolution-backend/engine.d.ts +4 -0
- package/dist/src/world-evolution-backend/engine.js +347 -0
- package/dist/src/world-evolution-backend/host-schema.d.ts +145 -0
- package/dist/src/world-evolution-backend/host-schema.js +375 -0
- package/dist/src/world-evolution-backend/index.d.ts +1 -0
- package/dist/src/world-evolution-backend/index.js +1 -0
- package/dist/src/world-evolution-backend/open-world-host-adapter.d.ts +96 -0
- package/dist/src/world-evolution-backend/open-world-host-adapter.js +208 -0
- package/dist/src/world-evolution-backend/profiles.d.ts +4 -0
- package/dist/src/world-evolution-backend/profiles.js +136 -0
- package/dist/src/world-evolution-backend/public.d.ts +11 -0
- package/dist/src/world-evolution-backend/public.js +7 -0
- package/dist/src/world-evolution-backend/reproducibility.d.ts +8 -0
- package/dist/src/world-evolution-backend/reproducibility.js +35 -0
- package/dist/src/world-evolution-backend/timeline.d.ts +6 -0
- package/dist/src/world-evolution-backend/timeline.js +337 -0
- package/dist/src/world-evolution-backend/types.d.ts +138 -0
- package/dist/src/world-evolution-backend/types.js +1 -0
- package/dist/src/world-evolution-host-backend.d.ts +51 -0
- package/dist/src/world-evolution-host-backend.js +97 -0
- package/dist/src/world-evolution.d.ts +201 -0
- package/dist/src/world-evolution.js +543 -0
- package/dist/src/world-factory.js +2 -1
- package/dist/tools/pack-cli.js +55 -2
- package/docs/bridge-contract.md +140 -332
- package/docs/completion-evidence-dashboard.md +63 -0
- package/docs/host-contract.md +86 -310
- package/docs/host-world-evolution-schema.md +155 -0
- package/docs/integration-primer.md +29 -22
- package/docs/migration-monolith-to-modular.md +102 -120
- package/docs/package-architecture.md +116 -323
- package/docs/plugins/README.md +42 -0
- package/docs/plugins/hooks.md +22 -0
- package/docs/plugins/publishing.md +29 -0
- package/docs/plugins/security-model.md +273 -0
- package/docs/project-overview.md +30 -30
- package/docs/release-dashboard.md +47 -0
- package/docs/session-api.md +127 -0
- package/docs/stable-api-manifest.json +52 -0
- package/docs/trust-dashboard.md +37 -0
- package/docs/versioning.md +256 -245
- package/docs/wire-protocol.md +140 -209
- package/docs/world-evolution-backend.md +200 -0
- package/docs/world-evolution-engine.md +150 -0
- package/docs/world-evolution-host-backend.md +70 -0
- package/docs/world-evolution-orchestration.md +248 -0
- package/package.json +125 -6
- package/schema/content-pack.schema.json +85 -0
- package/schema/plugin.schema.json +57 -0
- package/schema/world-evolution-input.schema.json +196 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { SCALE } from "../units.js";
|
|
2
|
+
import { toAnankeEvolutionState, } from "./host-schema.js";
|
|
3
|
+
export const OPEN_WORLD_HOST_ADAPTER_SCHEMA_VERSION = "ananke.open-world-host-adapter.v1";
|
|
4
|
+
export function canonicalizeOpenWorldInput(input) {
|
|
5
|
+
const environment = input.environment == null ? undefined : {
|
|
6
|
+
...(input.environment.climateByRegionId != null ? { climateByRegionId: canonicalizeStringRecord(input.environment.climateByRegionId) } : {}),
|
|
7
|
+
...(input.environment.climateByPolity != null ? {
|
|
8
|
+
climateByPolity: [...input.environment.climateByPolity]
|
|
9
|
+
.map((entry) => ({ polityId: entry.polityId, active: [...entry.active] }))
|
|
10
|
+
.sort((a, b) => a.polityId.localeCompare(b.polityId)),
|
|
11
|
+
} : {}),
|
|
12
|
+
...withOptional("metadata", canonicalizeMetadataBuckets(input.environment.metadata)),
|
|
13
|
+
};
|
|
14
|
+
const lore = input.lore == null ? undefined : {
|
|
15
|
+
...withOptional("summary", input.lore.summary),
|
|
16
|
+
...(input.lore.tags != null ? { tags: [...input.lore.tags].sort((a, b) => a.localeCompare(b)) } : {}),
|
|
17
|
+
...withOptional("metadata", canonicalizeMetadataBuckets(input.lore.metadata)),
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
schemaVersion: OPEN_WORLD_HOST_ADAPTER_SCHEMA_VERSION,
|
|
21
|
+
worldSeed: Math.floor(input.worldSeed),
|
|
22
|
+
tick: Math.max(0, Math.floor(input.tick ?? 0)),
|
|
23
|
+
regions: [...input.regions]
|
|
24
|
+
.map((region) => ({ ...region, ...withOptional("metadata", canonicalizeMetadataBuckets(region.metadata)) }))
|
|
25
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
26
|
+
settlements: [...input.settlements]
|
|
27
|
+
.map((settlement) => ({ ...settlement, ...withOptional("metadata", canonicalizeMetadataBuckets(settlement.metadata)) }))
|
|
28
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
29
|
+
factions: [...input.factions]
|
|
30
|
+
.map((faction) => ({ ...faction, ...withOptional("metadata", canonicalizeMetadataBuckets(faction.metadata)) }))
|
|
31
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
32
|
+
...(input.resources != null ? {
|
|
33
|
+
resources: [...input.resources]
|
|
34
|
+
.map((resource) => ({ ...resource, ...withOptional("metadata", canonicalizeMetadataBuckets(resource.metadata)) }))
|
|
35
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
36
|
+
} : {}),
|
|
37
|
+
...(input.tradeLinks != null ? {
|
|
38
|
+
tradeLinks: [...input.tradeLinks]
|
|
39
|
+
.map((tradeLink) => ({ ...tradeLink, ...withOptional("metadata", canonicalizeMetadataBuckets(tradeLink.metadata)) }))
|
|
40
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
41
|
+
} : {}),
|
|
42
|
+
...withOptional("environment", environment),
|
|
43
|
+
...withOptional("lore", lore),
|
|
44
|
+
...withOptional("metadata", canonicalizeMetadataBuckets(input.metadata)),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function mapOpenWorldHostToEvolutionInput(input, options = {}) {
|
|
48
|
+
const canonical = canonicalizeOpenWorldInput(input);
|
|
49
|
+
const mapEntityMetadata = options.entityMetadataTransform ?? metadataToPassthrough;
|
|
50
|
+
const mapRelationshipMetadata = options.relationshipMetadataTransform ?? metadataToPassthrough;
|
|
51
|
+
const factionByPolityId = {};
|
|
52
|
+
const entities = [
|
|
53
|
+
...canonical.factions.map((faction) => {
|
|
54
|
+
const polityId = faction.polityId ?? `p.${faction.id}`;
|
|
55
|
+
factionByPolityId[polityId] = faction.id;
|
|
56
|
+
return {
|
|
57
|
+
kind: "polity",
|
|
58
|
+
id: polityId,
|
|
59
|
+
name: faction.name,
|
|
60
|
+
factionId: faction.id,
|
|
61
|
+
...withOptional("population", faction.population),
|
|
62
|
+
...withOptional("treasury_cu", faction.treasury_cu),
|
|
63
|
+
...withOptional("stabilityQ", faction.stabilityQ),
|
|
64
|
+
...withOptional("moraleQ", faction.moraleQ),
|
|
65
|
+
...withOptional("metadata", mapEntityMetadata(faction.metadata)),
|
|
66
|
+
};
|
|
67
|
+
}),
|
|
68
|
+
...canonical.regions.map((region) => ({
|
|
69
|
+
kind: "region",
|
|
70
|
+
id: region.id,
|
|
71
|
+
name: region.name,
|
|
72
|
+
...withOptional("polityId", region.polityId),
|
|
73
|
+
...withOptional("population", region.population),
|
|
74
|
+
...withOptional("biome", region.climateTag),
|
|
75
|
+
...withOptional("metadata", mapEntityMetadata(region.metadata)),
|
|
76
|
+
})),
|
|
77
|
+
...canonical.settlements.map((settlement) => ({
|
|
78
|
+
kind: "settlement",
|
|
79
|
+
id: settlement.id,
|
|
80
|
+
name: settlement.name,
|
|
81
|
+
...withOptional("polityId", settlement.polityId),
|
|
82
|
+
regionId: settlement.regionId,
|
|
83
|
+
...withOptional("population", settlement.population),
|
|
84
|
+
...withOptional("metadata", mapEntityMetadata(settlement.metadata)),
|
|
85
|
+
})),
|
|
86
|
+
];
|
|
87
|
+
const relationships = [];
|
|
88
|
+
for (const link of canonical.tradeLinks ?? []) {
|
|
89
|
+
const sourceId = resolvePolityId(canonical.factions, link.sourceFactionId);
|
|
90
|
+
const targetId = resolvePolityId(canonical.factions, link.targetFactionId);
|
|
91
|
+
const routeQualityQ = clampQ(link.routeQualityQ ?? SCALE.Q);
|
|
92
|
+
const metadata = mapRelationshipMetadata(link.metadata);
|
|
93
|
+
if (link.sharedBorderCount != null) {
|
|
94
|
+
relationships.push({
|
|
95
|
+
id: `${link.id}:border`, kind: "border", sourceId, targetId,
|
|
96
|
+
sharedBorderCount: Math.max(0, Math.floor(link.sharedBorderCount)),
|
|
97
|
+
routeQualityQ,
|
|
98
|
+
...withOptional("metadata", metadata),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (link.baseVolume_cu != null) {
|
|
102
|
+
relationships.push({
|
|
103
|
+
id: `${link.id}:trade`, kind: "trade_route", sourceId, targetId,
|
|
104
|
+
baseVolume_cu: Math.max(0, Math.floor(link.baseVolume_cu)),
|
|
105
|
+
routeQualityQ,
|
|
106
|
+
...withOptional("metadata", metadata),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (link.treatyType != null) {
|
|
110
|
+
relationships.push({
|
|
111
|
+
id: `${link.id}:treaty`, kind: "treaty", sourceId, targetId,
|
|
112
|
+
treatyType: link.treatyType,
|
|
113
|
+
treatyStrength_Q: clampQ(link.treatyStrength_Q ?? SCALE.Q),
|
|
114
|
+
...withOptional("metadata", metadata),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (link.war === true) {
|
|
118
|
+
relationships.push({ id: `${link.id}:war`, kind: "war", sourceId, targetId, ...withOptional("metadata", metadata) });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const resources = (canonical.resources ?? []).map((resource) => ({
|
|
122
|
+
id: resource.id,
|
|
123
|
+
resourceType: resource.resourceType,
|
|
124
|
+
...withOptional("stock", resource.stock),
|
|
125
|
+
...withOptional("regionId", resource.regionId),
|
|
126
|
+
...withOptional("settlementId", resource.settlementId),
|
|
127
|
+
...withOptional("polityId", resource.factionId == null ? undefined : resolvePolityId(canonical.factions, resource.factionId)),
|
|
128
|
+
...withOptional("metadata", metadataToPassthrough(resource.metadata)),
|
|
129
|
+
}));
|
|
130
|
+
const hostMetadata = canonicalizeRecord({
|
|
131
|
+
openWorld: {
|
|
132
|
+
environment: canonical.environment,
|
|
133
|
+
lore: canonical.lore,
|
|
134
|
+
topLevelMetadata: canonical.metadata,
|
|
135
|
+
...(options.topLevelOpaqueMerge ?? {}),
|
|
136
|
+
},
|
|
137
|
+
}) ?? {};
|
|
138
|
+
return {
|
|
139
|
+
input: {
|
|
140
|
+
schemaVersion: OPEN_WORLD_HOST_ADAPTER_SCHEMA_VERSION,
|
|
141
|
+
worldSeed: canonical.worldSeed,
|
|
142
|
+
tick: canonical.tick ?? 0,
|
|
143
|
+
entities,
|
|
144
|
+
relationships,
|
|
145
|
+
resources,
|
|
146
|
+
hostMetadata,
|
|
147
|
+
...(canonical.environment?.climateByPolity != null ? { simulationState: { climateByPolity: canonical.environment.climateByPolity } } : {}),
|
|
148
|
+
},
|
|
149
|
+
context: {
|
|
150
|
+
schemaVersion: OPEN_WORLD_HOST_ADAPTER_SCHEMA_VERSION,
|
|
151
|
+
metadataPassthrough: hostMetadata,
|
|
152
|
+
factionByPolityId,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export function toAnankeEvolutionStateFromOpenWorld(input, options = {}) {
|
|
157
|
+
return toAnankeEvolutionState(mapOpenWorldHostToEvolutionInput(input, options).input);
|
|
158
|
+
}
|
|
159
|
+
function resolvePolityId(factions, factionId) {
|
|
160
|
+
const faction = factions.find((candidate) => candidate.id === factionId);
|
|
161
|
+
return faction?.polityId ?? `p.${factionId}`;
|
|
162
|
+
}
|
|
163
|
+
function clampQ(value) {
|
|
164
|
+
return Math.max(0, Math.min(SCALE.Q, Math.floor(value)));
|
|
165
|
+
}
|
|
166
|
+
function metadataToPassthrough(metadata) {
|
|
167
|
+
if (metadata == null)
|
|
168
|
+
return undefined;
|
|
169
|
+
return canonicalizeRecord({
|
|
170
|
+
...withOptional("simulation", canonicalizeRecord(metadata.simulation)),
|
|
171
|
+
...withOptional("descriptive", canonicalizeRecord(metadata.descriptive)),
|
|
172
|
+
...withOptional("opaque", canonicalizeRecord(metadata.opaque)),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function canonicalizeMetadataBuckets(metadata) {
|
|
176
|
+
if (metadata == null)
|
|
177
|
+
return undefined;
|
|
178
|
+
return {
|
|
179
|
+
...withOptional("simulation", canonicalizeRecord(metadata.simulation)),
|
|
180
|
+
...withOptional("descriptive", canonicalizeRecord(metadata.descriptive)),
|
|
181
|
+
...withOptional("opaque", canonicalizeRecord(metadata.opaque)),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function canonicalizeStringRecord(record) {
|
|
185
|
+
return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
|
|
186
|
+
}
|
|
187
|
+
function canonicalizeRecord(record) {
|
|
188
|
+
if (record == null)
|
|
189
|
+
return undefined;
|
|
190
|
+
return Object.fromEntries(Object.entries(record)
|
|
191
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
192
|
+
.map(([key, value]) => [key, canonicalizeUnknown(value)]));
|
|
193
|
+
}
|
|
194
|
+
function canonicalizeUnknown(value) {
|
|
195
|
+
if (Array.isArray(value))
|
|
196
|
+
return value.map((entry) => canonicalizeUnknown(entry));
|
|
197
|
+
if (value != null && typeof value === "object") {
|
|
198
|
+
return Object.fromEntries(Object.entries(value)
|
|
199
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
200
|
+
.map(([key, entry]) => [key, canonicalizeUnknown(entry)]));
|
|
201
|
+
}
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
function withOptional(key, value) {
|
|
205
|
+
if (value === undefined)
|
|
206
|
+
return {};
|
|
207
|
+
return { [key]: value };
|
|
208
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorldEvolutionRulesetId, WorldEvolutionRulesetProfile } from "./types.js";
|
|
2
|
+
export declare function listWorldEvolutionProfiles(): WorldEvolutionRulesetProfile[];
|
|
3
|
+
export declare function resolveWorldEvolutionProfile(id?: WorldEvolutionRulesetId): WorldEvolutionRulesetProfile;
|
|
4
|
+
export declare function mergeWorldEvolutionProfileWithOverrides(profileId: WorldEvolutionRulesetId | undefined, overrides: Partial<WorldEvolutionRulesetProfile> | undefined): WorldEvolutionRulesetProfile;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { q } from "../units.js";
|
|
2
|
+
const DEFAULT_PIPELINE_ORDER = [
|
|
3
|
+
"polity",
|
|
4
|
+
"governance",
|
|
5
|
+
"diplomacy",
|
|
6
|
+
"trade",
|
|
7
|
+
"migration",
|
|
8
|
+
"climate",
|
|
9
|
+
"epidemic",
|
|
10
|
+
];
|
|
11
|
+
const PROFILES_BY_CANONICAL_ID = {
|
|
12
|
+
minimal_world_history: {
|
|
13
|
+
id: "minimal_world_history",
|
|
14
|
+
name: "Minimal World History",
|
|
15
|
+
description: "Low-cost long-horizon baseline: polity core only, all other subsystems disabled.",
|
|
16
|
+
pipelineOrder: DEFAULT_PIPELINE_ORDER,
|
|
17
|
+
polityDayEnabled: true,
|
|
18
|
+
governanceEnabled: false,
|
|
19
|
+
diplomacyEnabled: false,
|
|
20
|
+
tradeEnabled: false,
|
|
21
|
+
migrationEnabled: false,
|
|
22
|
+
epidemicEnabled: false,
|
|
23
|
+
climateEnabled: false,
|
|
24
|
+
governanceStabilityDaysPerStep: 0,
|
|
25
|
+
treatyStrengthBoost_Q: 0,
|
|
26
|
+
routeEfficiencyBoost_Q: 0,
|
|
27
|
+
epidemicHealthBuffer_Q: 0,
|
|
28
|
+
},
|
|
29
|
+
polity_dynamics: {
|
|
30
|
+
id: "polity_dynamics",
|
|
31
|
+
name: "Polity Dynamics",
|
|
32
|
+
description: "Political-economy focus: governance, diplomacy, and trade enabled without climate or epidemic load.",
|
|
33
|
+
pipelineOrder: DEFAULT_PIPELINE_ORDER,
|
|
34
|
+
polityDayEnabled: true,
|
|
35
|
+
governanceEnabled: true,
|
|
36
|
+
diplomacyEnabled: true,
|
|
37
|
+
tradeEnabled: true,
|
|
38
|
+
migrationEnabled: false,
|
|
39
|
+
epidemicEnabled: false,
|
|
40
|
+
climateEnabled: false,
|
|
41
|
+
governanceStabilityDaysPerStep: 1,
|
|
42
|
+
treatyStrengthBoost_Q: 0,
|
|
43
|
+
routeEfficiencyBoost_Q: q(0.0005),
|
|
44
|
+
epidemicHealthBuffer_Q: 0,
|
|
45
|
+
},
|
|
46
|
+
conflict_heavy: {
|
|
47
|
+
id: "conflict_heavy",
|
|
48
|
+
name: "Conflict Heavy",
|
|
49
|
+
description: "Conflict-forward settings with weaker diplomatic/trade stabilization and no climate/epidemic overhead.",
|
|
50
|
+
pipelineOrder: DEFAULT_PIPELINE_ORDER,
|
|
51
|
+
polityDayEnabled: true,
|
|
52
|
+
governanceEnabled: true,
|
|
53
|
+
diplomacyEnabled: true,
|
|
54
|
+
tradeEnabled: true,
|
|
55
|
+
migrationEnabled: true,
|
|
56
|
+
epidemicEnabled: false,
|
|
57
|
+
climateEnabled: false,
|
|
58
|
+
governanceStabilityDaysPerStep: 1,
|
|
59
|
+
treatyStrengthBoost_Q: 0,
|
|
60
|
+
routeEfficiencyBoost_Q: 0,
|
|
61
|
+
epidemicHealthBuffer_Q: 0,
|
|
62
|
+
},
|
|
63
|
+
climate_and_migration: {
|
|
64
|
+
id: "climate_and_migration",
|
|
65
|
+
name: "Climate + Migration",
|
|
66
|
+
description: "Environment and movement focus: climate + migration + epidemic pressure with lighter diplomatic/economic mechanics.",
|
|
67
|
+
pipelineOrder: DEFAULT_PIPELINE_ORDER,
|
|
68
|
+
polityDayEnabled: true,
|
|
69
|
+
governanceEnabled: false,
|
|
70
|
+
diplomacyEnabled: false,
|
|
71
|
+
tradeEnabled: false,
|
|
72
|
+
migrationEnabled: true,
|
|
73
|
+
epidemicEnabled: true,
|
|
74
|
+
climateEnabled: true,
|
|
75
|
+
governanceStabilityDaysPerStep: 0,
|
|
76
|
+
treatyStrengthBoost_Q: 0,
|
|
77
|
+
routeEfficiencyBoost_Q: 0,
|
|
78
|
+
epidemicHealthBuffer_Q: q(0.02),
|
|
79
|
+
},
|
|
80
|
+
full_world_evolution: {
|
|
81
|
+
id: "full_world_evolution",
|
|
82
|
+
name: "Full World Evolution",
|
|
83
|
+
description: "Maximal backend composition: all currently integrated world-scale subsystems enabled.",
|
|
84
|
+
pipelineOrder: DEFAULT_PIPELINE_ORDER,
|
|
85
|
+
polityDayEnabled: true,
|
|
86
|
+
governanceEnabled: true,
|
|
87
|
+
diplomacyEnabled: true,
|
|
88
|
+
tradeEnabled: true,
|
|
89
|
+
migrationEnabled: true,
|
|
90
|
+
epidemicEnabled: true,
|
|
91
|
+
climateEnabled: true,
|
|
92
|
+
governanceStabilityDaysPerStep: 1,
|
|
93
|
+
treatyStrengthBoost_Q: 0,
|
|
94
|
+
routeEfficiencyBoost_Q: 0,
|
|
95
|
+
epidemicHealthBuffer_Q: 0,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
const LEGACY_ALIAS_TO_CANONICAL = {
|
|
99
|
+
balanced: "full_world_evolution",
|
|
100
|
+
resilience: "full_world_evolution",
|
|
101
|
+
expansion: "full_world_evolution",
|
|
102
|
+
};
|
|
103
|
+
export function listWorldEvolutionProfiles() {
|
|
104
|
+
return [
|
|
105
|
+
PROFILES_BY_CANONICAL_ID.minimal_world_history,
|
|
106
|
+
PROFILES_BY_CANONICAL_ID.polity_dynamics,
|
|
107
|
+
PROFILES_BY_CANONICAL_ID.conflict_heavy,
|
|
108
|
+
PROFILES_BY_CANONICAL_ID.climate_and_migration,
|
|
109
|
+
PROFILES_BY_CANONICAL_ID.full_world_evolution,
|
|
110
|
+
].map(cloneProfile);
|
|
111
|
+
}
|
|
112
|
+
export function resolveWorldEvolutionProfile(id = "full_world_evolution") {
|
|
113
|
+
const canonicalId = (id in LEGACY_ALIAS_TO_CANONICAL)
|
|
114
|
+
? LEGACY_ALIAS_TO_CANONICAL[id]
|
|
115
|
+
: id;
|
|
116
|
+
return cloneProfile(PROFILES_BY_CANONICAL_ID[canonicalId]);
|
|
117
|
+
}
|
|
118
|
+
export function mergeWorldEvolutionProfileWithOverrides(profileId, overrides) {
|
|
119
|
+
const base = resolveWorldEvolutionProfile(profileId ?? "full_world_evolution");
|
|
120
|
+
if (!overrides)
|
|
121
|
+
return base;
|
|
122
|
+
return cloneProfile({
|
|
123
|
+
...base,
|
|
124
|
+
...overrides,
|
|
125
|
+
id: base.id,
|
|
126
|
+
name: overrides.name ?? `${base.name} (host override)`,
|
|
127
|
+
description: overrides.description ?? `${base.description} Host overrides applied deterministically.`,
|
|
128
|
+
pipelineOrder: DEFAULT_PIPELINE_ORDER,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function cloneProfile(profile) {
|
|
132
|
+
return {
|
|
133
|
+
...profile,
|
|
134
|
+
pipelineOrder: [...profile.pipelineOrder],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { runWorldEvolution, createWorldEvolutionSnapshot, listAvailableWorldEvolutionProfiles, } from "./engine.js";
|
|
2
|
+
export { resolveWorldEvolutionProfile, listWorldEvolutionProfiles, mergeWorldEvolutionProfileWithOverrides, } from "./profiles.js";
|
|
3
|
+
export { WORLD_EVOLUTION_BACKEND_SCHEMA_VERSION, } from "./types.js";
|
|
4
|
+
export type { EvolutionRulesetProfile, WorldEvolutionRulesetId, WorldEvolutionRulesetProfile, WorldEvolutionSnapshot, WorldEvolutionRunRequest, WorldEvolutionRunResult, WorldEvolutionStepEvent, WorldEvolutionDelta, WorldEvolutionCheckpoint, WorldEvolutionMetrics, EvolutionTimelineCategory, EvolutionTimelineFactRef, EvolutionTimelineEvent, } from "./types.js";
|
|
5
|
+
export { buildEvolutionTimeline, sortTimelineEventsBySignificance, } from "./timeline.js";
|
|
6
|
+
export { HOST_WORLD_EVOLUTION_SCHEMA_VERSION, normalizeHostWorldInput, validateWorldEvolutionInput, toAnankeEvolutionState, fromAnankeEvolutionState, toWorldEvolutionRunRequest, fromWorldEvolutionRunResult, } from "./host-schema.js";
|
|
7
|
+
export type { WorldEvolutionInput, NormalizedWorldEvolutionInput, HostWorldEntity, HostPolity, HostSettlement, HostRegion, HostRelationship, HostResourceNode, HostRuleOverrides, HostDiseaseProfile, HostEpidemicState, ValidationError, HostAdapterContext, AnankeEvolutionAdapterState, } from "./host-schema.js";
|
|
8
|
+
export { OPEN_WORLD_HOST_ADAPTER_SCHEMA_VERSION, canonicalizeOpenWorldInput, mapOpenWorldHostToEvolutionInput, toAnankeEvolutionStateFromOpenWorld, } from "./open-world-host-adapter.js";
|
|
9
|
+
export type { MetadataBuckets, OpenWorldHostInput, OpenWorldRegion, OpenWorldSettlement, OpenWorldFaction, OpenWorldResource, OpenWorldTradeLink, OpenWorldEnvironment, OpenWorldLoreMetadata, OpenWorldHostAdapterOptions, OpenWorldAdapterContext, OpenWorldMappedState, } from "./open-world-host-adapter.js";
|
|
10
|
+
export { computeWorldEvolutionRunRequestFingerprint, computeWorldEvolutionRunResultDigest, buildEvolutionRunReproducibilityRecord, } from "./reproducibility.js";
|
|
11
|
+
export type { EvolutionRunReproducibilityRecord, } from "./reproducibility.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { runWorldEvolution, createWorldEvolutionSnapshot, listAvailableWorldEvolutionProfiles, } from "./engine.js";
|
|
2
|
+
export { resolveWorldEvolutionProfile, listWorldEvolutionProfiles, mergeWorldEvolutionProfileWithOverrides, } from "./profiles.js";
|
|
3
|
+
export { WORLD_EVOLUTION_BACKEND_SCHEMA_VERSION, } from "./types.js";
|
|
4
|
+
export { buildEvolutionTimeline, sortTimelineEventsBySignificance, } from "./timeline.js";
|
|
5
|
+
export { HOST_WORLD_EVOLUTION_SCHEMA_VERSION, normalizeHostWorldInput, validateWorldEvolutionInput, toAnankeEvolutionState, fromAnankeEvolutionState, toWorldEvolutionRunRequest, fromWorldEvolutionRunResult, } from "./host-schema.js";
|
|
6
|
+
export { OPEN_WORLD_HOST_ADAPTER_SCHEMA_VERSION, canonicalizeOpenWorldInput, mapOpenWorldHostToEvolutionInput, toAnankeEvolutionStateFromOpenWorld, } from "./open-world-host-adapter.js";
|
|
7
|
+
export { computeWorldEvolutionRunRequestFingerprint, computeWorldEvolutionRunResultDigest, buildEvolutionRunReproducibilityRecord, } from "./reproducibility.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WorldEvolutionRunRequest, WorldEvolutionRunResult } from "./types.js";
|
|
2
|
+
export interface EvolutionRunReproducibilityRecord {
|
|
3
|
+
requestFingerprint: string;
|
|
4
|
+
outputDigest: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function computeWorldEvolutionRunRequestFingerprint(request: WorldEvolutionRunRequest): string;
|
|
7
|
+
export declare function computeWorldEvolutionRunResultDigest(result: WorldEvolutionRunResult): string;
|
|
8
|
+
export declare function buildEvolutionRunReproducibilityRecord(request: WorldEvolutionRunRequest, result: WorldEvolutionRunResult): EvolutionRunReproducibilityRecord;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function computeWorldEvolutionRunRequestFingerprint(request) {
|
|
2
|
+
return stableHashHex(stableJsonStringify(request));
|
|
3
|
+
}
|
|
4
|
+
export function computeWorldEvolutionRunResultDigest(result) {
|
|
5
|
+
return stableHashHex(stableJsonStringify(result));
|
|
6
|
+
}
|
|
7
|
+
export function buildEvolutionRunReproducibilityRecord(request, result) {
|
|
8
|
+
return {
|
|
9
|
+
requestFingerprint: computeWorldEvolutionRunRequestFingerprint(request),
|
|
10
|
+
outputDigest: computeWorldEvolutionRunResultDigest(result),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function stableJsonStringify(value) {
|
|
14
|
+
return JSON.stringify(stableJson(value));
|
|
15
|
+
}
|
|
16
|
+
function stableJson(value) {
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
return value.map((entry) => stableJson(entry));
|
|
19
|
+
}
|
|
20
|
+
if (value != null && typeof value === "object") {
|
|
21
|
+
return Object.fromEntries(Object.entries(value)
|
|
22
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
23
|
+
.map(([key, entry]) => [key, stableJson(entry)]));
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function stableHashHex(input) {
|
|
28
|
+
let hash = 0x811c9dc5;
|
|
29
|
+
for (let i = 0; i < input.length; i++) {
|
|
30
|
+
hash ^= input.charCodeAt(i);
|
|
31
|
+
hash = Math.imul(hash, 0x01000193);
|
|
32
|
+
}
|
|
33
|
+
const normalized = hash >>> 0;
|
|
34
|
+
return normalized.toString(16).padStart(8, "0");
|
|
35
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { EvolutionTimelineEvent, WorldEvolutionRunResult } from "./types.js";
|
|
2
|
+
export interface BuildEvolutionTimelineOptions {
|
|
3
|
+
includeSummaryText?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function buildEvolutionTimeline(result: Pick<WorldEvolutionRunResult, "initialSnapshot" | "timeline">, options?: BuildEvolutionTimelineOptions): EvolutionTimelineEvent[];
|
|
6
|
+
export declare function sortTimelineEventsBySignificance(events: readonly EvolutionTimelineEvent[]): EvolutionTimelineEvent[];
|