refactor(0.1.14-P1): 内核归位——game/ 按引擎架构重排(零行为漂移)

结构(旧 game/core+engine → 新 engine/ 域):
- engine/kernel/  时钟/随机/插件协议/fxqueue/timesense/format/urgency/guide/names(原 core)
- engine/narrative/  legacy/报告/列传/谱系/年轴(原 core 叙事族)
- engine/runtime/   World/creation/pcgen/ApiFacade/capabilities/pluginManager/boot/clocks + Systems/*(12 系统)
- engine/sim/     Market(未来 WorldSim 同行)
- 旧 game/core、engine/systems、engine/world.ts 等路径全部废弃(无 re-export 兼容层)

验证:35 套件/967 测试全绿(金钟罩三档零漂移=纯搬迁无行为变化)
typecheck 0 error
This commit is contained in:
2026-08-23 13:23:25 +08:00
parent 2528226a9f
commit ff6df8054c
89 changed files with 281 additions and 281 deletions
@@ -0,0 +1,102 @@
import { GameState } from '../../types/domain'
import { MAJOR_ORDER } from '../../data/realms'
export interface LegacyDims {
renXing: number
daoXing: number
weiMing: number
xiangHuo: number
total: number
}
export interface LegacyArch {
title: string
poem: string[]
dims: LegacyDims
rank: number
verdict: string
}
export const VERDICTS: Record<string, { title: string; poem: string[] }> = {
feisheng: {
title: '飞升之资',
poem: ['海内升龙真气象,仙班亦录旧香名。', '遥看青山埋骨处,一脉烟霞送飞鸿。']
},
celestial: {
title: '仙朝遗脉',
poem: ['祖庭灯火三千里,曾照中天玉斗垂。', '后世儿孙开卷处,犹闻钟鼎旧清音。']
},
noble: {
title: '中州望族',
poem: ['钟鸣鼎食三百年,莫道朱门无圣贤。', '一炷心香传世绪,青灯犹自照芸编。']
},
warlord: {
title: '一方枭雄',
poem: ['剑气纵横镇八荒,家声不堕尽金汤。', '而今若问兴亡事,半壁江山问晚霜。']
},
recluse: {
title: '隐世大族',
poem: ['不向尘沙争利名,青山深处课桑耕。', '子孙自有莲舟意,一棹烟波到洞庭。']
},
modest: {
title: '积余之家',
poem: ['檐下燕飞春复秋,园蔬新雨补梁楸。', '粗茶淡饭家声在,犹胜浮云逐海流。']
},
dust: {
title: '冢中枯骨',
poem: ['一度花开一度尘,纸灰飞作旧人魂。', '若教重理当年事,且把残篇问故园。']
}
}
const RANK_MAP: [number, string][] = [
[160, 'celestial'],
[120, 'noble'],
[85, 'warlord'],
[55, 'recluse'],
[30, 'modest']
]
export function computeLegacy(s: GameState): LegacyDims {
const st = s.stats
const gens = Math.max(
...Object.values(s.members).map((c) => c.generation).concat(1)
)
const renXing = Math.round(gens * 18 + Math.min(st.popPeak, 40) * 1.6)
const daoXing = Math.round(st.maxRealmIdx * 26 + st.techniqueGrand * 4)
const weiMing = Math.round(st.repPeak * 1.4 + (st.tourneyBest ? (6 - st.tourneyBest) * 12 : 0))
const xiangHuo = Math.round(Math.min(s.year, 300) * 0.9 + st.feishengCount * 60)
return { renXing, daoXing, weiMing, xiangHuo, total: renXing + daoXing + weiMing + xiangHuo }
}
export function resolveLegacy(s: GameState): LegacyArch {
const dims = computeLegacy(s)
let key = 'dust'
if (s.stats.feishengCount > 0) key = 'feisheng'
else {
for (const [need, k] of RANK_MAP) {
if (dims.total >= need) {
key = k
break
}
}
}
const verdict = VERDICTS[key]
return { title: verdict.title, poem: verdict.poem, dims, rank: dims.total, verdict: key }
}
export function peakRealmIndex(members: GameState['members']): number {
let max = -1
for (const c of Object.values(members)) {
const idx = MAJOR_ORDER.indexOf(c.realm.major) * 10 + c.realm.minor
if (idx > max) max = idx
}
return max
}
export function grandTechniqueCount(members: GameState['members']): number {
let n = 0
for (const c of Object.values(members)) {
if ((c.techniqueRank ?? 0) >= 2) n++
}
return n
}