Rework story engine flow and reorganize project docs
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
CI / verify (push) Has been cancelled
This commit is contained in:
@@ -7,6 +7,23 @@ import { mergeCustomWorldPlayableNpcTags } from '../data/customWorldBuildTags';
|
||||
import { normalizeCustomWorldLandmarks } from '../data/customWorldSceneGraph';
|
||||
import { CustomWorldProfile, WorldType } from '../types';
|
||||
import { normalizeCustomWorldProfile } from './customWorld';
|
||||
import {
|
||||
buildFallbackActorNarrativeProfile,
|
||||
normalizeActorNarrativeProfile,
|
||||
} from './storyEngine/actorNarrativeProfile';
|
||||
import { compileCampaignFromWorldProfile } from './storyEngine/campaignPackCompiler';
|
||||
import { buildKnowledgeGraph } from './storyEngine/knowledgeGraph';
|
||||
import { registerScenarioPack } from './storyEngine/scenarioPackRegistry';
|
||||
import { buildSceneNarrativeResidues } from './storyEngine/sceneResidueCompiler';
|
||||
import {
|
||||
buildThemePackFromWorldProfile,
|
||||
normalizeThemePack,
|
||||
} from './storyEngine/themePack';
|
||||
import { buildThreadContractsFromProfile } from './storyEngine/threadContract';
|
||||
import {
|
||||
buildFallbackWorldStoryGraph,
|
||||
normalizeWorldStoryGraph,
|
||||
} from './storyEngine/worldStoryGraph';
|
||||
|
||||
const PLAYABLE_TEMPLATE_CHARACTER_IDS = [
|
||||
'sword-princess',
|
||||
@@ -103,7 +120,7 @@ export function buildExpandedCustomWorldProfile(
|
||||
npc.templateCharacterId ?? getPlayableTemplateCharacterId(index);
|
||||
return {
|
||||
...npc,
|
||||
id: createEntryId('playable-npc', npc.name, index),
|
||||
id: npc.id || createEntryId('playable-npc', npc.name, index),
|
||||
templateCharacterId,
|
||||
tags: mergeCustomWorldPlayableNpcTags(profile, npc, {
|
||||
templateCharacterId,
|
||||
@@ -116,7 +133,7 @@ export function buildExpandedCustomWorldProfile(
|
||||
});
|
||||
const storyNpcs = dedupeByName(profile.storyNpcs).map((npc, index) => ({
|
||||
...npc,
|
||||
id: createEntryId('story-npc', npc.name, index),
|
||||
id: npc.id || createEntryId('story-npc', npc.name, index),
|
||||
description: clampText(npc.description, 72),
|
||||
motivation: clampText(npc.motivation, 72),
|
||||
relationshipHooks: normalizeHooks(npc.relationshipHooks),
|
||||
@@ -139,7 +156,7 @@ export function buildExpandedCustomWorldProfile(
|
||||
});
|
||||
const landmarkDrafts = dedupeByName(profile.landmarks).map((landmark, index) => ({
|
||||
...landmark,
|
||||
id: createEntryId('landmark', landmark.name, index),
|
||||
id: landmark.id || createEntryId('landmark', landmark.name, index),
|
||||
description: clampText(landmark.description, 96),
|
||||
dangerLevel:
|
||||
landmark.dangerLevel ||
|
||||
@@ -176,19 +193,90 @@ export function buildExpandedCustomWorldProfile(
|
||||
})),
|
||||
storyNpcs,
|
||||
});
|
||||
|
||||
return {
|
||||
const items = dedupeByName(profile.items).map((item, index) => ({
|
||||
...item,
|
||||
id: item.id || createEntryId('item', item.name, index),
|
||||
description: clampText(item.description, 72),
|
||||
tags: normalizeTags(item.tags),
|
||||
attributeResonance:
|
||||
item.attributeResonance ?? buildItemAttributeResonance(item),
|
||||
}));
|
||||
const baseExpandedProfile = {
|
||||
...profile,
|
||||
playableNpcs,
|
||||
storyNpcs,
|
||||
items: dedupeByName(profile.items).map((item, index) => ({
|
||||
...item,
|
||||
id: createEntryId('item', item.name, index),
|
||||
description: clampText(item.description, 72),
|
||||
tags: normalizeTags(item.tags),
|
||||
attributeResonance:
|
||||
item.attributeResonance ?? buildItemAttributeResonance(item),
|
||||
})),
|
||||
items,
|
||||
landmarks,
|
||||
} satisfies CustomWorldProfile;
|
||||
const themePack = normalizeThemePack(
|
||||
profile.themePack,
|
||||
buildThemePackFromWorldProfile(baseExpandedProfile),
|
||||
);
|
||||
const storyGraph = normalizeWorldStoryGraph(
|
||||
profile.storyGraph,
|
||||
buildFallbackWorldStoryGraph(baseExpandedProfile, themePack),
|
||||
);
|
||||
const enrichedPlayableNpcs = playableNpcs.map((npc) => ({
|
||||
...npc,
|
||||
narrativeProfile: normalizeActorNarrativeProfile(
|
||||
npc.narrativeProfile,
|
||||
buildFallbackActorNarrativeProfile(npc, storyGraph, themePack),
|
||||
),
|
||||
}));
|
||||
const enrichedStoryNpcs = storyNpcs.map((npc) => ({
|
||||
...npc,
|
||||
narrativeProfile: normalizeActorNarrativeProfile(
|
||||
npc.narrativeProfile,
|
||||
buildFallbackActorNarrativeProfile(npc, storyGraph, themePack),
|
||||
),
|
||||
}));
|
||||
const landmarksWithResidues = landmarks.map((landmark) => ({
|
||||
...landmark,
|
||||
narrativeResidues:
|
||||
landmark.narrativeResidues && landmark.narrativeResidues.length > 0
|
||||
? landmark.narrativeResidues
|
||||
: buildSceneNarrativeResidues({
|
||||
sceneId: landmark.id,
|
||||
sceneName: landmark.name,
|
||||
profile: {
|
||||
...baseExpandedProfile,
|
||||
playableNpcs: enrichedPlayableNpcs,
|
||||
storyNpcs: enrichedStoryNpcs,
|
||||
storyGraph,
|
||||
themePack,
|
||||
},
|
||||
}),
|
||||
}));
|
||||
const profileWithNarrative = {
|
||||
...baseExpandedProfile,
|
||||
playableNpcs: enrichedPlayableNpcs,
|
||||
storyNpcs: enrichedStoryNpcs,
|
||||
themePack,
|
||||
storyGraph,
|
||||
landmarks: landmarksWithResidues,
|
||||
} satisfies CustomWorldProfile;
|
||||
const knowledgeFacts =
|
||||
profile.knowledgeFacts && profile.knowledgeFacts.length > 0
|
||||
? profile.knowledgeFacts
|
||||
: buildKnowledgeGraph(profileWithNarrative);
|
||||
const threadContracts =
|
||||
profile.threadContracts && profile.threadContracts.length > 0
|
||||
? profile.threadContracts
|
||||
: buildThreadContractsFromProfile(profileWithNarrative);
|
||||
const compiledPacks = compileCampaignFromWorldProfile({
|
||||
profile: {
|
||||
...profileWithNarrative,
|
||||
knowledgeFacts,
|
||||
threadContracts,
|
||||
},
|
||||
});
|
||||
registerScenarioPack(compiledPacks.scenarioPack);
|
||||
|
||||
return {
|
||||
...profileWithNarrative,
|
||||
knowledgeFacts,
|
||||
threadContracts,
|
||||
scenarioPackId: profile.scenarioPackId ?? compiledPacks.scenarioPack.id,
|
||||
campaignPackId: profile.campaignPackId ?? compiledPacks.campaignPack.id,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user