Rework story engine flow and reorganize project docs
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-06 23:19:00 +08:00
parent d678929064
commit ddcb5d5c8c
241 changed files with 19805 additions and 2478 deletions

View File

@@ -0,0 +1,85 @@
import type {
GameState,
PlayerStyleProfile,
StoryOption,
} from '../../types';
function clampWeight(value: number) {
return Math.max(0, Math.min(100, Math.round(value)));
}
function resolveDominantStyle(weights: PlayerStyleProfile['preferenceWeights']) {
const entries = Object.entries(weights) as Array<
[keyof PlayerStyleProfile['preferenceWeights'], number]
>;
entries.sort((a, b) => b[1] - a[1]);
const top = entries[0]?.[0] ?? 'story';
if (top === 'story') return 'story_first';
if (top === 'exploration') return 'explorer';
if (top === 'combat') return 'combat_driver';
if (top === 'companion') return 'companion_bond';
return 'collector';
}
export function buildPlayerStyleProfile(state: GameState) {
const existing = state.storyEngineMemory?.playerStyleProfile;
if (existing) {
return existing;
}
const weights = {
story: 45,
exploration: 40,
combat: 35,
companion: 35,
collection: 30,
};
return {
id: 'player-style:default',
preferenceWeights: weights,
dominantStyle: resolveDominantStyle(weights),
} satisfies PlayerStyleProfile;
}
export function updatePlayerStyleProfileFromAction(params: {
current: PlayerStyleProfile | null | undefined;
actionText: string;
option?: StoryOption | null;
}) {
const current =
params.current ??
({
id: 'player-style:default',
preferenceWeights: {
story: 45,
exploration: 40,
combat: 35,
companion: 35,
collection: 30,
},
dominantStyle: 'story_first',
} satisfies PlayerStyleProfile);
const nextWeights = { ...current.preferenceWeights };
const text = `${params.actionText} ${params.option?.functionId ?? ''}`;
if (/||||/u.test(text)) nextWeights.companion += 4;
if (/|||||线/u.test(text)) nextWeights.exploration += 4;
if (/||||/u.test(text)) nextWeights.combat += 4;
if (/||||/u.test(text)) nextWeights.story += 4;
if (/||||/u.test(text)) nextWeights.collection += 4;
const normalizedWeights = {
story: clampWeight(nextWeights.story),
exploration: clampWeight(nextWeights.exploration),
combat: clampWeight(nextWeights.combat),
companion: clampWeight(nextWeights.companion),
collection: clampWeight(nextWeights.collection),
};
return {
...current,
preferenceWeights: normalizedWeights,
dominantStyle: resolveDominantStyle(normalizedWeights),
} satisfies PlayerStyleProfile;
}