Files
ChronicleOfTheImmortalClan/src/renderer/game/engine/runtime/creation.ts
T
thzxx ff6df8054c 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
2026-08-23 13:23:25 +08:00

204 lines
5.5 KiB
TypeScript

import { Character, GameState, NpcFamilyState, RealmMajor } from '../../types/domain'
import { Rng, seedToRng } from '../kernel/rng'
import { randomSurname, MALE_GIVEN, FEMALE_GIVEN } from '../kernel/names'
import { newCharacter } from './pcgen'
import { NPCS } from '../../data/npcs'
import { World } from './World'
export interface NewGameOptions {
seed: string
surname: string
familyName: string
motto: string
difficulty: 'easy' | 'normal' | 'hard'
}
export function createWorldState(opts: NewGameOptions): GameState {
const rng = new Rng(seedToRng(opts.seed))
const surname = opts.surname.trim() || randomSurname(rng)
const familyName = opts.familyName.trim() || `${surname}家`
const diff = opts.difficulty
const stones = diff === 'easy' ? 1200 : diff === 'normal' ? 800 : 550
const npcStrength = diff === 'easy' ? 0.9 : diff === 'normal' ? 1 : 1.15
const state: GameState = {
schemaVersion: 1,
seed: opts.seed,
rng: rng.getState(),
year: 1,
month: 1,
seq: 0,
family: {
surname,
name: familyName,
motto: opts.motto.trim() || '耕读传家,术法继世',
crest: '#c9a227',
estate: '青云庄',
yearFounded: 1,
generation: 1,
reputation: 5,
stones,
inventory: {
lingcao: 60,
lingkuang: 30,
beastcore: 0,
'pill-qiyuan': 2,
'pill-ningyuan': 1
},
buildings: { lingtian: 1, zongci: 1 },
techniques: ['t-qinglian', 't-houtu'],
missionIds: [],
headId: '',
difficulty: diff,
flag: { priceMult: 1, tenants: 0, headBless: 0 }
},
members: {},
npcFamilies: Object.fromEntries(
NPCS.map((n) => [
n.id,
{
id: n.id,
name: n.name,
region: n.region,
power: Math.round(n.initialPower * npcStrength),
relation: 0,
allied: false,
raidCount: 0
} as NpcFamilyState
])
),
missions: [],
chronicle: [],
battles: [],
eventQueue: [],
completedEvents: [],
flags: {},
totalTicks: 0,
finance: { accum: 0 },
yearStats: { births: 0, deaths: 0 },
yearlyReports: [],
stats: {
repPeak: 5,
popPeak: 5,
maxRealmIdx: 25,
techniqueGrand: 0,
tourneyHistory: [],
feishengCount: 0
}
}
const w = new World(state, [])
const male1: string = rng.pick(MALE_GIVEN)
const female1: string = rng.pick(FEMALE_GIVEN)
const head: Character = newCharacter(rng, {
name: `${surname}${male1}`,
gender: 'male',
generation: 1,
bornYear: 1 - 35,
age: 35,
realm: { major: 'qi', minor: 4 },
isHead: true,
isFounder: true,
fortuneBase: 7
})
head.realmProgress = 40
head.techniqueId = 't-qinglian'
head.traits = ['tiangan', 'shensui']
const wife: Character = newCharacter(rng, {
name: `${surname}${female1}`,
gender: 'female',
generation: 1,
bornYear: 1 - 33,
age: 33,
realm: { major: 'qi', minor: 2 },
fortuneBase: 6
})
wife.realmProgress = 55
head.spouseId = 'x2'
wife.spouseId = 'x1'
head.children = ['x3', 'x5']
const elderBrother: Character = newCharacter(rng, {
name: `${surname}${rng.pick(MALE_GIVEN)}`,
gender: 'male',
generation: 2,
bornYear: 1 - 16,
age: 16,
realm: { major: 'qi', minor: 1 },
father: head,
mother: wife
})
elderBrother.realmProgress = 20
elderBrother.techniqueId = 't-houtu'
elderBrother.fatherId = 'x1'
elderBrother.motherId = 'x2'
const sister: Character = newCharacter(rng, {
name: `${surname}${rng.pick(FEMALE_GIVEN)}`,
gender: 'female',
generation: 2,
bornYear: 1 - 12,
age: 12,
realm: { major: 'mortal', minor: 0 },
father: head,
mother: wife
})
sister.fatherId = 'x1'
sister.motherId = 'x2'
const uncle: Character = newCharacter(rng, {
name: `${surname}${rng.pick(MALE_GIVEN)}`,
gender: 'male',
generation: 1,
bornYear: 1 - 45,
age: 45,
realm: { major: 'qi', minor: 6 },
fortuneBase: 6
})
uncle.realmProgress = 30
uncle.techniqueId = 't-houtu'
uncle.traits = ['xinheng', 'shensui']
uncle.id = 'x4'
uncle.spouseHouse = '四海王氏'
uncle.children = []
head.id = 'x1'
wife.id = 'x2'
elderBrother.id = 'x3'
sister.id = 'x5'
wife.children = ['x3', 'x5']
state.members = { x1: head, x2: wife, x3: elderBrother, x4: uncle, x5: sister }
state.family.headId = 'x1'
state.seq = 10
w.chronicle('misc', `${surname}氏一族定居山阴,立${familyName}。庄主${head.name},年方三十五。`, head.id, true)
w.log('info', `青云庄立,${familyName}始兴。`)
return state
}
export function findInheritor(world: World): Character | undefined {
const alive = world.aliveMembers()
if (alive.length === 0) return undefined
const head = world.state.members[world.state.family.headId]
const candidates = alive.filter((c) => c.id !== head?.id)
if (candidates.length === 0) return undefined
const byBlood = candidates
.filter((c) => (head && head.children.includes(c.id)) || (c.fatherId === head?.id))
.sort((a, b) => world.ageOf(b) - world.ageOf(a))
if (byBlood.length > 0) return byBlood[0]
const byRealm = [...candidates].sort((a, b) => {
const ra = realmRank(a.realm)
const rb = realmRank(b.realm)
return rb - ra || b.charm - a.charm || world.ageOf(b) - world.ageOf(a)
})
return byRealm[0]
}
function realmRank(realm: { major: RealmMajor; minor: number }): number {
const order: RealmMajor[] = ['mortal', 'qi', 'foundation', 'core', 'nascent', 'spirit']
return order.indexOf(realm.major) * 10 + realm.minor
}