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
@@ -1,4 +1,4 @@
import type { World } from '../engine/world' import type { World } from '../runtime/World'
/** /**
* phase * phase
@@ -1,4 +1,4 @@
import type { World } from '../engine/world' import type { World } from '../runtime/World'
export interface GuideStep { export interface GuideStep {
id: string id: string
@@ -1,7 +1,7 @@
import { GameClock, SystemHook } from './clock' import { GameClock, SystemHook } from './clock'
import { DataPack } from '../data/registry' import { DataPack } from '../../data/registry'
import { EventDef } from '../data/events' import { EventDef } from '../../data/events'
import type { World } from '../engine/world' import type { World } from '../runtime/World'
export type PluginKind = 'system' | 'data' | 'events' | 'content' export type PluginKind = 'system' | 'data' | 'events' | 'content'
@@ -1,4 +1,4 @@
import type { RngState } from '../types/domain' import type { RngState } from '../../types/domain'
function xmur3(str: string): () => number { function xmur3(str: string): () => number {
let h = 1779033703 ^ str.length let h = 1779033703 ^ str.length
@@ -1,4 +1,4 @@
import { Season } from '../data/season' import { Season } from '../../data/season'
export const TIDES: string[] = [ export const TIDES: string[] = [
'立春', '雨水', '惊蛰', '春分', '清明', '谷雨', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨',
@@ -1,4 +1,4 @@
import type { World } from '../engine/world' import type { World } from '../runtime/World'
export interface Urgency { export interface Urgency {
blockedCount: number blockedCount: number
@@ -1,8 +1,8 @@
import { GameState } from '../types/domain' import { GameState } from '../../types/domain'
import { TECHNIQUES } from '../data/techniques' import { TECHNIQUES } from '../../data/techniques'
import { describeRealm } from '../data/realms' import { describeRealm } from '../../data/realms'
import { aspirationById } from '../data/aspirations' import { aspirationById } from '../../data/aspirations'
import { postById } from '../data/posts' import { postById } from '../../data/posts'
export interface BioLine { export interface BioLine {
at?: number at?: number
@@ -1,5 +1,5 @@
import { Character } from '../types/domain' import { Character } from '../../types/domain'
import type { World } from '../engine/world' import type { World } from '../runtime/World'
export interface FamilyUnit { export interface FamilyUnit {
parents: [Character | undefined, Character | undefined] parents: [Character | undefined, Character | undefined]
@@ -1,5 +1,5 @@
import { GameState } from '../types/domain' import { GameState } from '../../types/domain'
import { MAJOR_ORDER } from '../data/realms' import { MAJOR_ORDER } from '../../data/realms'
export interface LegacyDims { export interface LegacyDims {
renXing: number renXing: number
@@ -1,4 +1,4 @@
import { GameState } from '../types/domain' import { GameState } from '../../types/domain'
export interface LegacyReport { export interface LegacyReport {
years: number[] years: number[]
@@ -1,4 +1,4 @@
import { GameState } from '../types/domain' import { GameState } from '../../types/domain'
export interface AxisEvent { export interface AxisEvent {
year: number year: number
@@ -1,14 +1,14 @@
import type { World } from './world' import type { World } from './World'
import { WorldEventBus } from './world' import { WorldEventBus } from './World'
import { YearlyReport, BattleLog, ChronicleEntry, SaveMeta } from '../types/domain' import { YearlyReport, BattleLog, ChronicleEntry, SaveMeta } from '../../types/domain'
import { marketPrice, buyItem, sellItem, buyTechnique } from './market' import { marketPrice, buyItem, sellItem, buyTechnique } from '../sim/Market'
import { sendMission, recallAll } from './systems/missions' import { sendMission, recallAll } from './Systems/missions'
import { giftNpc, makePeace, marryNpcFamily } from './systems/diplomacy' import { giftNpc, makePeace, marryNpcFamily } from './Systems/diplomacy'
import { combatPowerOf } from './systems/combat' import { combatPowerOf } from './Systems/combat'
import type { LogKind } from './world' import type { LogKind } from './World'
import { computeLegacy, resolveLegacy, LegacyArch } from '../core/legacy' import { computeLegacy, resolveLegacy, LegacyArch } from '../narrative/legacy'
import { yearAxis, AxisCell } from '../core/yearaxis' import { yearAxis, AxisCell } from '../narrative/yearaxis'
import { PACK } from '../data/registry' import { PACK } from '../../data/registry'
export type ActName = export type ActName =
| 'head.set' | 'head.set'
@@ -1,14 +1,14 @@
import type { World } from '../world' import type { World } from '../World'
import { Character, BattleLog } from '../../types/domain' import { Character, BattleLog } from '../../../types/domain'
import { basePower, describeRealm } from '../../data/realms' import { basePower, describeRealm } from '../../../data/realms'
import { pack } from '../../data/registry' import { pack } from '../../../data/registry'
import { techniqueById } from '../../data/techniques' import { techniqueById } from '../../../data/techniques'
import { EnemyDef, LootDef } from '../../data/secrets' import { EnemyDef, LootDef } from '../../../data/secrets'
import { traitBonuses } from '../pcgen' import { traitBonuses } from '../pcgen'
import { npcById } from '../../data/npcs' import { npcById } from '../../../data/npcs'
import { aspirationById, fitBonusOf } from '../../data/aspirations' import { aspirationById, fitBonusOf } from '../../../data/aspirations'
import { formationById, FormationId } from '../../data/formations' import { formationById, FormationId } from '../../../data/formations'
export function combatPowerOf(w: World, c: Character): number { export function combatPowerOf(w: World, c: Character): number {
if (!c.alive) return 0 if (!c.alive) return 0
@@ -1,16 +1,16 @@
import type { World } from '../world' import type { World } from '../World'
import { Character } from '../../types/domain' import { Character } from '../../../types/domain'
import { ROOT_GRADES } from '../../data/elements' import { ROOT_GRADES } from '../../../data/elements'
import { masteryRateOfMajor } from '../../data/pacing' import { masteryRateOfMajor } from '../../../data/pacing'
import { aspirationById, fitBonusOf } from '../../data/aspirations' import { aspirationById, fitBonusOf } from '../../../data/aspirations'
import { techniqueById } from '../../data/techniques' import { techniqueById } from '../../../data/techniques'
import { nextRealm, breakthroughBaseChance, realmDeathChance, describeRealm, MAJOR_ORDER } from '../../data/realms' import { nextRealm, breakthroughBaseChance, realmDeathChance, describeRealm, MAJOR_ORDER } from '../../../data/realms'
import { lifespanOf } from './lifecycle' import { lifespanOf } from './lifecycle'
import { traitBonuses } from '../pcgen' import { traitBonuses } from '../pcgen'
import { newCharacter } from '../pcgen' import { newCharacter } from '../pcgen'
import { MALE_GIVEN, FEMALE_GIVEN } from '../../core/names' import { MALE_GIVEN, FEMALE_GIVEN } from '../../kernel/names'
import { ASPIRATION_IDS } from '../../data/aspirations' import { ASPIRATION_IDS } from '../../../data/aspirations'
import { seasonMod } from '../../data/season' import { seasonMod } from '../../../data/season'
import { needsTribulation, tribulationEventId } from './tribulation' import { needsTribulation, tribulationEventId } from './tribulation'
export function monthlyRate(w: World, c: Character): number { export function monthlyRate(w: World, c: Character): number {
@@ -1,5 +1,5 @@
import type { World } from '../world' import type { World } from '../World'
import { npcById } from '../../data/npcs' import { npcById } from '../../../data/npcs'
import { findEvent, fire } from './events' import { findEvent, fire } from './events'
export function diplomacyTick(w: World): void { export function diplomacyTick(w: World): void {
@@ -1,16 +1,16 @@
import type { World } from '../world' import type { World } from '../World'
import { Character } from '../../types/domain' import { Character } from '../../../types/domain'
import { Cond, EffectDef, EventDef, EVENTS, MemberEffect } from '../../data/events' import { Cond, EffectDef, EventDef, EVENTS, MemberEffect } from '../../../data/events'
import { MAJOR_ORDER } from '../../data/realms' import { MAJOR_ORDER } from '../../../data/realms'
import { npcById } from '../../data/npcs' import { npcById } from '../../../data/npcs'
import { resolveRaid } from './combat' import { resolveRaid } from './combat'
import { sendMission } from './missions' import { sendMission } from './missions'
import { pack } from '../../data/registry' import { pack } from '../../../data/registry'
import { findInheritor } from '../creation' import { findInheritor } from '../creation'
import { resolveTribulation } from './tribulation' import { resolveTribulation } from './tribulation'
import { nextRealm, describeRealm } from '../../data/realms' import { nextRealm, describeRealm } from '../../../data/realms'
const ALL_EVENTS: EventDef[] = [...EVENTS] const ALL_EVENTS: EventDef[] = [...EVENTS]
@@ -1,5 +1,5 @@
import type { World } from '../world' import type { World } from '../World'
import { MAJORS } from '../../data/realms' import { MAJORS } from '../../../data/realms'
import { calcLifespan } from '../pcgen' import { calcLifespan } from '../pcgen'
export function lifespanOf(w: World, c: { realm: { major: keyof typeof MAJORS }; physique: number }): number { export function lifespanOf(w: World, c: { realm: { major: keyof typeof MAJORS }; physique: number }): number {
@@ -1,9 +1,9 @@
import type { World } from '../world' import type { World } from '../World'
import { Character } from '../../types/domain' import { Character } from '../../../types/domain'
import { produceOffspring } from './cultivation' import { produceOffspring } from './cultivation'
import { yearGrowth } from './diplomacy' import { yearGrowth } from './diplomacy'
import { MALE_GIVEN, FEMALE_GIVEN } from '../../core/names' import { MALE_GIVEN, FEMALE_GIVEN } from '../../kernel/names'
import { aspirationById } from '../../data/aspirations' import { aspirationById } from '../../../data/aspirations'
export function yearStartMarriage(w: World): void { export function yearStartMarriage(w: World): void {
yearGrowth(w) yearGrowth(w)
@@ -1,10 +1,10 @@
import type { World } from '../world' import type { World } from '../World'
import { MissionState } from '../../types/domain' import { MissionState } from '../../../types/domain'
import { FormationId } from '../../data/formations' import { FormationId } from '../../../data/formations'
import { missionById, MissionDef, ENEMIES } from '../../data/secrets' import { missionById, MissionDef, ENEMIES } from '../../../data/secrets'
import { resolveEncounter, rollWarbooty } from './combat' import { resolveEncounter, rollWarbooty } from './combat'
import { techniqueById } from '../../data/techniques' import { techniqueById } from '../../../data/techniques'
import { describeRealm } from '../../data/realms' import { describeRealm } from '../../../data/realms'
export function missionTick(w: World): void { export function missionTick(w: World): void {
const active = w.state.missions.filter((m) => !m.done) const active = w.state.missions.filter((m) => !m.done)
@@ -1,6 +1,6 @@
import type { World } from '../world' import type { World } from '../World'
import { aspirationById } from '../../data/aspirations' import { aspirationById } from '../../../data/aspirations'
import { seasonMod } from '../../data/season' import { seasonMod } from '../../../data/season'
export function productionTick(w: World): void { export function productionTick(w: World): void {
const fam = w.state.family const fam = w.state.family
@@ -1,10 +1,10 @@
import type { World } from '../world' import type { World } from '../World'
import { Character } from '../../types/domain' import { Character } from '../../../types/domain'
import { ENEMIES, EnemyDef } from '../../data/secrets' import { ENEMIES, EnemyDef } from '../../../data/secrets'
import { resolveEncounter } from './combat' import { resolveEncounter } from './combat'
import { rankPower } from './events' import { rankPower } from './events'
import { resolveBreakthrough } from './cultivation' import { resolveBreakthrough } from './cultivation'
import { FormationId } from '../../data/formations' import { FormationId } from '../../../data/formations'
export const SECTS = ['云栖宗', '太谷书院', '玄微剑阁', '丹霞洞天'] export const SECTS = ['云栖宗', '太谷书院', '玄微剑阁', '丹霞洞天']
@@ -1,6 +1,6 @@
import type { World } from '../world' import type { World } from '../World'
import { Character } from '../../types/domain' import { Character } from '../../../types/domain'
import { nextRealm, MAJOR_ORDER, realmDeathChance, describeRealm } from '../../data/realms' import { nextRealm, MAJOR_ORDER, realmDeathChance, describeRealm } from '../../../data/realms'
export const TRIB_MAJORS: string[] = ['foundation', 'core', 'nascent', 'spirit'] export const TRIB_MAJORS: string[] = ['foundation', 'core', 'nascent', 'spirit']
@@ -7,25 +7,25 @@ import {
LogItem, LogItem,
Realm, Realm,
YearlyReport YearlyReport
} from '../types/domain' } from '../../types/domain'
import { Rng } from '../core/rng' import { Rng } from '../kernel/rng'
import { BUILDINGS } from '../data/buildings' import { BUILDINGS } from '../../data/buildings'
import { POSTS } from '../data/posts' import { POSTS } from '../../data/posts'
import { aspirationById as aspirationOf } from '../data/aspirations' import { aspirationById as aspirationOf } from '../../data/aspirations'
import { computeLegacy, resolveLegacy, peakRealmIndex, grandTechniqueCount, LegacyArch } from '../core/legacy' import { computeLegacy, resolveLegacy, peakRealmIndex, grandTechniqueCount, LegacyArch } from '../narrative/legacy'
import { createWorldState, findInheritor } from './creation' import { createWorldState, findInheritor } from './creation'
import { SYSTEM_DEFS, SystemDef } from './capabilities' import { SYSTEM_DEFS, SystemDef } from './capabilities'
import { emptyClock } from './clocks' import { emptyClock } from './clocks'
import { CotycPlugin, PluginContext, PluginStatus } from '../core/plugin' import { CotycPlugin, PluginContext, PluginStatus } from '../kernel/plugin'
import { PluginManager } from './pluginManager' import { PluginManager } from './pluginManager'
import { EventDef } from '../data/events' import { EventDef } from '../../data/events'
import { pack, DEFAULT_PACK, PACK } from '../data/registry' import { pack, DEFAULT_PACK, PACK } from '../../data/registry'
import { CORE_PLUGINS } from './plugin-bootstrap' import { CORE_PLUGINS } from './plugin-bootstrap'
import { GameClock } from '../core/clock' import { GameClock } from '../kernel/clock'
import { SystemHook } from '../core/clock' import { SystemHook } from '../kernel/clock'
import { resolveBreakthrough } from './systems/cultivation' import { resolveBreakthrough } from './Systems/cultivation'
import { applyEventChoice } from './systems/events' import { applyEventChoice } from './Systems/events'
import { combatPowerOf } from './systems/combat' import { combatPowerOf } from './Systems/combat'
export type LogKind = LogItem['kind'] export type LogKind = LogItem['kind']
@@ -138,7 +138,7 @@ export class World {
} }
} }
private packOverride(partial: Partial<import('../data/registry').DataPack>): void { private packOverride(partial: Partial<import('../../data/registry').DataPack>): void {
PACK.override(partial) PACK.override(partial)
} }
@@ -1,4 +1,4 @@
import type { PhaseId } from '../core/clock' import type { PhaseId } from '../kernel/clock'
export interface SystemDef { export interface SystemDef {
id: string id: string
@@ -1,13 +1,13 @@
import { GameClock } from '../core/clock' import { GameClock } from '../kernel/clock'
import { PluginContext } from '../core/plugin' import { PluginContext } from '../kernel/plugin'
import type { World } from './world' import type { World } from './World'
import { productionTick } from './systems/production' import { productionTick } from './Systems/production'
import { deathTick, woundHealTick } from './systems/lifecycle' import { deathTick, woundHealTick } from './Systems/lifecycle'
import { cultivationTick } from './systems/cultivation' import { cultivationTick } from './Systems/cultivation'
import { missionTick } from './systems/missions' import { missionTick } from './Systems/missions'
import { eventRoll } from './systems/events' import { eventRoll } from './Systems/events'
import { diplomacyTick } from './systems/diplomacy' import { diplomacyTick } from './Systems/diplomacy'
import { yearStartMarriage } from './systems/marriage' import { yearStartMarriage } from './Systems/marriage'
/** 原语义保留:满门凋零后仅存生产/寿元与收尾 */ /** 原语义保留:满门凋零后仅存生产/寿元与收尾 */
function ifAlive(fn: (w: World) => void): (w: World) => void { function ifAlive(fn: (w: World) => void): (w: World) => void {
@@ -1,9 +1,9 @@
import { Character, GameState, NpcFamilyState, RealmMajor } from '../types/domain' import { Character, GameState, NpcFamilyState, RealmMajor } from '../../types/domain'
import { Rng, seedToRng } from '../core/rng' import { Rng, seedToRng } from '../kernel/rng'
import { randomSurname, MALE_GIVEN, FEMALE_GIVEN } from '../core/names' import { randomSurname, MALE_GIVEN, FEMALE_GIVEN } from '../kernel/names'
import { newCharacter } from './pcgen' import { newCharacter } from './pcgen'
import { NPCS } from '../data/npcs' import { NPCS } from '../../data/npcs'
import { World } from './world' import { World } from './World'
export interface NewGameOptions { export interface NewGameOptions {
seed: string seed: string
@@ -1,4 +1,4 @@
import { CotycPlugin } from '../core/plugin' import { CotycPlugin } from '../kernel/plugin'
/** 示例内容插件:注入事件池 + 一个护山能力(开发范本) */ /** 示例内容插件:注入事件池 + 一个护山能力(开发范本) */
export const examplePlugin: CotycPlugin = { export const examplePlugin: CotycPlugin = {
@@ -1,8 +1,8 @@
import { Character, Element, Gender, Realm, RealmMajor } from '../types/domain' import { Character, Element, Gender, Realm, RealmMajor } from '../../types/domain'
import { Rng } from '../core/rng' import { Rng } from '../kernel/rng'
import { ELEMENT_LIST, ROOT_GRADES } from '../data/elements' import { ELEMENT_LIST, ROOT_GRADES } from '../../data/elements'
import { MAJORS } from '../data/realms' import { MAJORS } from '../../data/realms'
import { TRAIT_POOL, TRAITS } from '../data/traits' import { TRAIT_POOL, TRAITS } from '../../data/traits'
export function rollRoots(rng: Rng, parents?: { m?: Character; f?: Character }): { grade: number; primary: Element; secondary: Element[] } { export function rollRoots(rng: Rng, parents?: { m?: Character; f?: Character }): { grade: number; primary: Element; secondary: Element[] } {
let grade: number let grade: number
@@ -1,7 +1,7 @@
import { CotycPlugin } from '../core/plugin' import { CotycPlugin } from '../kernel/plugin'
import { installCoreSystems } from './clocks' import { installCoreSystems } from './clocks'
import { EVENTS } from '../data/events' import { EVENTS } from '../../data/events'
import { DEFAULT_PACK } from '../data/registry' import { DEFAULT_PACK } from '../../data/registry'
/** 内置插件一:镇族基石(12 能力卡与时轮钩子) */ /** 内置插件一:镇族基石(12 能力卡与时轮钩子) */
export function makeCoreSystemsPlugin(): CotycPlugin { export function makeCoreSystemsPlugin(): CotycPlugin {
@@ -1,8 +1,8 @@
import { CotycPlugin, PluginContext, PluginStatus, PluginChange } from '../core/plugin' import { CotycPlugin, PluginContext, PluginStatus, PluginChange } from '../kernel/plugin'
import { SystemDef, SYSTEM_DEFS } from '../engine/capabilities' import { SystemDef, SYSTEM_DEFS } from './capabilities'
import type { World } from '../engine/world' import type { World } from './World'
import { SystemHook } from '../core/clock' import { SystemHook } from '../kernel/clock'
import { GameClock } from '../core/clock' import { GameClock } from '../kernel/clock'
interface RuntimePlugin { interface RuntimePlugin {
plugin: CotycPlugin plugin: CotycPlugin
@@ -1,6 +1,6 @@
import type { World } from './world' import type { World } from '../runtime/World'
import { pack } from '../data/registry' import { pack } from '../../data/registry'
import { traitBonuses } from './pcgen' import { traitBonuses } from '../runtime/pcgen'
export function marketPrice(w: World, itemId: string): number { export function marketPrice(w: World, itemId: string): number {
const item = pack().items[itemId] const item = pack().items[itemId]
@@ -48,7 +48,7 @@ export function techniquePrice(techId: string): number {
return TECH_GRADE_BASE[techId] ?? 200 return TECH_GRADE_BASE[techId] ?? 200
} }
import { TECHNIQUES } from '../data/techniques' import { TECHNIQUES } from '../../data/techniques'
const TECHNIQUE_GRADE_PRICE: Record<number, number> = { 1: 120, 2: 300, 3: 700, 4: 1600 } const TECHNIQUE_GRADE_PRICE: Record<number, number> = { 1: 120, 2: 300, 3: 700, 4: 1600 }
const TECH_GRADE_BASE: Record<string, number> = Object.fromEntries( const TECH_GRADE_BASE: Record<string, number> = Object.fromEntries(
+1 -1
View File
@@ -1,5 +1,5 @@
import { GameState } from '../types/domain' import { GameState } from '../types/domain'
import { normalizeGameState } from '../engine/world' import { normalizeGameState } from '../engine/runtime/World'
export const CURRENT_SCHEMA = 2 export const CURRENT_SCHEMA = 2
export const APP_ID = 'cotyc' export const APP_ID = 'cotyc'
+2 -2
View File
@@ -1,10 +1,10 @@
import { useState } from 'react' import { useState } from 'react'
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { applyEventChoice, rankPower } from '../../game/engine/systems/events' import { applyEventChoice, rankPower } from '../../game/engine/runtime/Systems/events'
import { eventCategoryName } from '../../game/data/events' import { eventCategoryName } from '../../game/data/events'
import { describeRealm } from '../../game/data/realms' import { describeRealm } from '../../game/data/realms'
import { Character } from '../../game/types/domain' import { Character } from '../../game/types/domain'
import { combatPowerOf } from '../../game/engine/systems/combat' import { combatPowerOf } from '../../game/engine/runtime/Systems/combat'
import { FORMATIONS, FormationId } from '../../game/data/formations' import { FORMATIONS, FormationId } from '../../game/data/formations'
import { ModalShell } from './ModalShell' import { ModalShell } from './ModalShell'
+1 -1
View File
@@ -1,5 +1,5 @@
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { GUIDE_STEPS, computeGuide, guideAdvance } from '../../game/core/guide' import { GUIDE_STEPS, computeGuide, guideAdvance } from '../../game/engine/kernel/guide'
export function GuideStrip() { export function GuideStrip() {
const world = useGameStore((s) => s.world) const world = useGameStore((s) => s.world)
+4 -4
View File
@@ -5,12 +5,12 @@ import { describeRoots, ROOT_GRADE_NAMES } from '../../game/data/elements'
import { TRAITS } from '../../game/data/traits' import { TRAITS } from '../../game/data/traits'
import { TECHNIQUES } from '../../game/data/techniques' import { TECHNIQUES } from '../../game/data/techniques'
import { ITEMS, ARTIFACT_POWER } from '../../game/data/items' import { ITEMS, ARTIFACT_POWER } from '../../game/data/items'
import { combatPowerOf } from '../../game/engine/systems/combat' import { combatPowerOf } from '../../game/engine/runtime/Systems/combat'
import { lifespanOf } from '../../game/engine/systems/lifecycle' import { lifespanOf } from '../../game/engine/runtime/Systems/lifecycle'
import { perAttemptChance } from '../../game/engine/systems/cultivation' import { perAttemptChance } from '../../game/engine/runtime/Systems/cultivation'
import { POSTS, POST_ORDER } from '../../game/data/posts' import { POSTS, POST_ORDER } from '../../game/data/posts'
import { ModalShell } from './ModalShell' import { ModalShell } from './ModalShell'
import { buildBiography } from '../../game/core/biography' import { buildBiography } from '../../game/engine/narrative/biography'
function aspName(c: Character): string { function aspName(c: Character): string {
const map: Record<string, string> = { const map: Record<string, string> = {
+1 -1
View File
@@ -1,5 +1,5 @@
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { LegacyArch } from '../../game/core/legacy' import { LegacyArch } from '../../game/engine/narrative/legacy'
import { sBell } from '../sound' import { sBell } from '../sound'
import { ModalShell } from './ModalShell' import { ModalShell } from './ModalShell'
+1 -1
View File
@@ -1,5 +1,5 @@
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { computeUrgency } from '../../game/core/urgency' import { computeUrgency } from '../../game/engine/kernel/urgency'
export function UrgentBadges() { export function UrgentBadges() {
const world = useGameStore((s) => s.world) const world = useGameStore((s) => s.world)
+1 -1
View File
@@ -1,4 +1,4 @@
import { FxGate, FxKind } from '../game/core/fxqueue' import { FxGate, FxKind } from '../game/engine/kernel/fxqueue'
import { seasonOf } from '../game/data/season' import { seasonOf } from '../game/data/season'
let gate: FxGate | null = null let gate: FxGate | null = null
+1 -1
View File
@@ -1,6 +1,6 @@
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { npcById } from '../../game/data/npcs' import { npcById } from '../../game/data/npcs'
import { giftNpc, makePeace, marryNpcFamily, calcGiftGain, GIFT_TIERS } from '../../game/engine/systems/diplomacy' import { giftNpc, makePeace, marryNpcFamily, calcGiftGain, GIFT_TIERS } from '../../game/engine/runtime/Systems/diplomacy'
import { useMemo } from 'react' import { useMemo } from 'react'
import { MAJOR_NAMES } from '../../game/data/realms' import { MAJOR_NAMES } from '../../game/data/realms'
+2 -2
View File
@@ -1,7 +1,7 @@
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { MISSIONS, missionById } from '../../game/data/secrets' import { MISSIONS, missionById } from '../../game/data/secrets'
import { sendMission, recallAll } from '../../game/engine/systems/missions' import { sendMission, recallAll } from '../../game/engine/runtime/Systems/missions'
import { combatPowerOf } from '../../game/engine/systems/combat' import { combatPowerOf } from '../../game/engine/runtime/Systems/combat'
import { useState } from 'react' import { useState } from 'react'
import { describeRealm, MAJOR_ORDER } from '../../game/data/realms' import { describeRealm, MAJOR_ORDER } from '../../game/data/realms'
import { FORMATIONS, FormationId } from '../../game/data/formations' import { FORMATIONS, FormationId } from '../../game/data/formations'
+1 -1
View File
@@ -1,5 +1,5 @@
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { computeGenealogy } from '../../game/core/genealogy' import { computeGenealogy } from '../../game/engine/narrative/genealogy'
import { describeRealm } from '../../game/data/realms' import { describeRealm } from '../../game/data/realms'
import { Character, FamilyState } from '../../game/types/domain' import { Character, FamilyState } from '../../game/types/domain'
import { useState } from 'react' import { useState } from 'react'
+5 -5
View File
@@ -1,11 +1,11 @@
import { useState } from 'react' import { useState } from 'react'
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { computeLegacy, resolveLegacy } from '../../game/core/legacy' import { computeLegacy, resolveLegacy } from '../../game/engine/narrative/legacy'
import { resolveLegacy as doesIt } from '../../game/core/legacy' import { resolveLegacy as doesIt } from '../../game/engine/narrative/legacy'
import { ResolveModal } from '../components/ResolveModal' import { ResolveModal } from '../components/ResolveModal'
import { buildBiography } from '../../game/core/biography' import { buildBiography } from '../../game/engine/narrative/biography'
import { yearAxis, decadeLabel } from '../../game/core/yearaxis' import { yearAxis, decadeLabel } from '../../game/engine/narrative/yearaxis'
import { buildReport, verdictLine } from '../../game/core/legacyreport' import { buildReport, verdictLine } from '../../game/engine/narrative/legacyreport'
void doesIt void doesIt
+1 -1
View File
@@ -2,7 +2,7 @@ import { useGameStore } from '../store'
import { ITEMS } from '../../game/data/items' import { ITEMS } from '../../game/data/items'
import { TECHNIQUES } from '../../game/data/techniques' import { TECHNIQUES } from '../../game/data/techniques'
import { techniqueGradeName } from '../../game/data/realms' import { techniqueGradeName } from '../../game/data/realms'
import { marketPrice, buyItem, sellItem, buyTechnique } from '../../game/engine/market' import { marketPrice, buyItem, sellItem, buyTechnique } from '../../game/engine/sim/Market'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
export default function MarketPanel() { export default function MarketPanel() {
+3 -3
View File
@@ -1,9 +1,9 @@
import { useState } from 'react' import { useState } from 'react'
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { examplePlugin } from '../../game/engine/demo-plugins' import { examplePlugin } from '../../game/engine/runtime/demo-plugins'
import { ensureFx } from '../fx' import { ensureFx } from '../fx'
import { SYSTEM_DEFS } from '../../game/engine/capabilities' import { SYSTEM_DEFS } from '../../game/engine/runtime/capabilities'
import { buildBiography } from '../../game/core/biography' import { buildBiography } from '../../game/engine/narrative/biography'
export default function SettingsPanel() { export default function SettingsPanel() {
const world = useGameStore((s) => s.world) const world = useGameStore((s) => s.world)
+2 -2
View File
@@ -12,9 +12,9 @@ import ChroniclePanel from '../panels/ChroniclePanel'
import SettingsPanel from '../panels/SettingsPanel' import SettingsPanel from '../panels/SettingsPanel'
import { LogFeed } from '../components/LogFeed' import { LogFeed } from '../components/LogFeed'
import { UrgentBadges } from '../components/UrgentBadges' import { UrgentBadges } from '../components/UrgentBadges'
import { fmt as fmtNum } from '../../game/core/format' import { fmt as fmtNum } from '../../game/engine/kernel/format'
import { seasonOf } from '../../game/data/season' import { seasonOf } from '../../game/data/season'
import { seasonTint, yearRing, tideOf } from '../../game/core/timesense' import { seasonTint, yearRing, tideOf } from '../../game/engine/kernel/timesense'
import landscapeUrl from '../../assets/gen/landscape-gold.svg' import landscapeUrl from '../../assets/gen/landscape-gold.svg'
import { GuideStrip } from '../components/GuideStrip' import { GuideStrip } from '../components/GuideStrip'
+2 -2
View File
@@ -1,7 +1,7 @@
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { useGameStore } from '../store' import { useGameStore } from '../store'
import { SURNAME_POOL } from '../../game/core/names' import { SURNAME_POOL } from '../../game/engine/kernel/names'
import { RngHub } from '../../game/core/rng' import { RngHub } from '../../game/engine/kernel/rng'
export default function NewGame() { export default function NewGame() {
const go = useGameStore((s) => s.go) const go = useGameStore((s) => s.go)
+1 -1
View File
@@ -1,5 +1,5 @@
// 合成音效:鼓点·钟鸣·纸韵(Web Audio,零素材依赖) // 合成音效:鼓点·钟鸣·纸韵(Web Audio,零素材依赖)
import { RngHub } from '../game/core/rng' import { RngHub } from '../game/engine/kernel/rng'
let ctx: AudioContext | null = null let ctx: AudioContext | null = null
let enabled = true let enabled = true
+7 -7
View File
@@ -1,13 +1,13 @@
import { create } from 'zustand' import { create } from 'zustand'
import { World, WorldEventBus } from '../game/engine/world' import { World, WorldEventBus } from '../game/engine/runtime/World'
import { EventDef } from '../game/data/events' import { EventDef } from '../game/data/events'
import { findEvent, applyEventChoice } from '../game/engine/systems/events' import { findEvent, applyEventChoice } from '../game/engine/runtime/Systems/events'
import { BattleLog, ChronicleEntry, GameState, LogItem, SaveMeta, YearlyReport, SnapshotMeta } from '../game/types/domain' import { BattleLog, ChronicleEntry, GameState, LogItem, SaveMeta, YearlyReport, SnapshotMeta } from '../game/types/domain'
import { getSlotManager, getSaveSlot } from '../game/storage/db' import { getSlotManager, getSaveSlot } from '../game/storage/db'
import { metaFromState, updateSlotMeta } from './storeHelper' import { metaFromState, updateSlotMeta } from './storeHelper'
import { GameFacade, ActName } from '../game/engine/api' import { GameFacade, ActName } from '../game/engine/runtime/ApiFacade'
import { setSoundEnabled, sPaper, sGood, sBad, sWar, sBell, sGong, sClick, sTick } from './sound' import { setSoundEnabled, sPaper, sGood, sBad, sWar, sBell, sGong, sClick, sTick } from './sound'
import type { PhaseStat } from '../game/core/clock' import type { PhaseStat } from '../game/engine/kernel/clock'
import { seasonOf } from '../game/data/season' import { seasonOf } from '../game/data/season'
export type Screen = 'boot' | 'newgame' | 'game' export type Screen = 'boot' | 'newgame' | 'game'
@@ -63,7 +63,7 @@ export interface GameStore {
facade?: GameFacade facade?: GameFacade
advancing: boolean advancing: boolean
setNextToast: (msg: string) => void setNextToast: (msg: string) => void
act: (name: ActName, payload: import('../game/engine/api').ActPayload) => boolean act: (name: ActName, payload: import('../game/engine/runtime/ApiFacade').ActPayload) => boolean
} }
const LOG_CAP = 260 const LOG_CAP = 260
@@ -193,7 +193,7 @@ export const useGameStore = create<GameStore>((set, get) => ({
const elapsed = performance.now() - t0 const elapsed = performance.now() - t0
try { try {
const nextInv = { ...w.state.family.inventory, stones: w.state.family.stones } const nextInv = { ...w.state.family.inventory, stones: w.state.family.stones }
const FxGate = (await import('../game/core/fxqueue')).FxGate const FxGate = (await import('../game/engine/kernel/fxqueue')).FxGate
const deltas = FxGate.deltas(prevInv, nextInv) const deltas = FxGate.deltas(prevInv, nextInv)
const windowRef = window as unknown as { dispatchEvent: (e: Event) => void } const windowRef = window as unknown as { dispatchEvent: (e: Event) => void }
windowRef.dispatchEvent(new CustomEvent('fx:drift', { detail: deltas })) windowRef.dispatchEvent(new CustomEvent('fx:drift', { detail: deltas }))
@@ -454,7 +454,7 @@ function makeBus(st: GameStore): WorldEventBus {
} }
} }
function actDirect(w: World, name: ActName, payload: import('../game/engine/api').ActPayload): boolean { function actDirect(w: World, name: ActName, payload: import('../game/engine/runtime/ApiFacade').ActPayload): boolean {
if (name === 'legacy.resolve') return (w.resolveLegacyNow(), true) if (name === 'legacy.resolve') return (w.resolveLegacyNow(), true)
if (name === 'estate.rite') return w.ancestralRite() if (name === 'estate.rite') return w.ancestralRite()
if (name === 'estate.sutra') return w.seekSutra() if (name === 'estate.sutra') return w.seekSutra()
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { GameFacade, ACT_CATALOG, ActName } from '../src/renderer/game/engine/api' import { GameFacade, ACT_CATALOG, ActName } from '../src/renderer/game/engine/runtime/ApiFacade'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+6 -6
View File
@@ -1,11 +1,11 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { monthlyRate, resolveBreakthrough } from '../src/renderer/game/engine/systems/cultivation' import { monthlyRate, resolveBreakthrough } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { combatPowerOf } from '../src/renderer/game/engine/systems/combat' import { combatPowerOf } from '../src/renderer/game/engine/runtime/Systems/combat'
import { isFit } from '../src/renderer/game/data/aspirations' import { isFit } from '../src/renderer/game/data/aspirations'
import { needsTribulation, resolveTribulation, tribulationEventId } from '../src/renderer/game/engine/systems/tribulation' import { needsTribulation, resolveTribulation, tribulationEventId } from '../src/renderer/game/engine/runtime/Systems/tribulation'
import { buildBiography } from '../src/renderer/game/core/biography' import { buildBiography } from '../src/renderer/game/engine/narrative/biography'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+4 -4
View File
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { computeUrgency } from '../src/renderer/game/core/urgency' import { computeUrgency } from '../src/renderer/game/engine/kernel/urgency'
import { monthlyRate } from '../src/renderer/game/engine/systems/cultivation' import { monthlyRate } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+8 -8
View File
@@ -1,13 +1,13 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { newCharacter } from '../src/renderer/game/engine/pcgen' import { newCharacter } from '../src/renderer/game/engine/runtime/pcgen'
import { Rng, seedToRng } from '../src/renderer/game/core/rng' import { Rng, seedToRng } from '../src/renderer/game/engine/kernel/rng'
import { PACK } from '../src/renderer/game/data/registry' import { PACK } from '../src/renderer/game/data/registry'
import { buildApprentice } from '../src/renderer/game/engine/systems/tournament' import { buildApprentice } from '../src/renderer/game/engine/runtime/Systems/tournament'
import { sendMission } from '../src/renderer/game/engine/systems/missions' import { sendMission } from '../src/renderer/game/engine/runtime/Systems/missions'
import { buyItem, marketPrice } from '../src/renderer/game/engine/market' import { buyItem, marketPrice } from '../src/renderer/game/engine/sim/Market'
import { findEvent } from '../src/renderer/game/engine/systems/events' import { findEvent } from '../src/renderer/game/engine/runtime/Systems/events'
import { runTournament } from '../src/renderer/game/engine/systems/tournament' import { runTournament } from '../src/renderer/game/engine/runtime/Systems/tournament'
import { stateFingerprint, longRun } from './fingerprint.helper' import { stateFingerprint, longRun } from './fingerprint.helper'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+4 -4
View File
@@ -1,11 +1,11 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World, normalizeGameState } from '../src/renderer/game/engine/world' import { World, normalizeGameState } from '../src/renderer/game/engine/runtime/World'
import { import {
marryNpcFamily, marryNpcFamily,
makePeace makePeace
} from '../src/renderer/game/engine/systems/diplomacy' } from '../src/renderer/game/engine/runtime/Systems/diplomacy'
import { sendMission, recallAll } from '../src/renderer/game/engine/systems/missions' import { sendMission, recallAll } from '../src/renderer/game/engine/runtime/Systems/missions'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { GameState } from '../src/renderer/game/types/domain' import { GameState } from '../src/renderer/game/types/domain'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+9 -9
View File
@@ -1,13 +1,13 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { monthlyRate } from '../src/renderer/game/engine/systems/cultivation' import { monthlyRate } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { combatPowerOf } from '../src/renderer/game/engine/systems/combat' import { combatPowerOf } from '../src/renderer/game/engine/runtime/Systems/combat'
import { resolveBreakthrough } from '../src/renderer/game/engine/systems/cultivation' import { resolveBreakthrough } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { computeLegacy, resolveLegacy } from '../src/renderer/game/core/legacy' import { computeLegacy, resolveLegacy } from '../src/renderer/game/engine/narrative/legacy'
import { yearAxis } from '../src/renderer/game/core/yearaxis' import { yearAxis } from '../src/renderer/game/engine/narrative/yearaxis'
import { buildBiography } from '../src/renderer/game/core/biography' import { buildBiography } from '../src/renderer/game/engine/narrative/biography'
import { computeGenealogy } from '../src/renderer/game/core/genealogy' import { computeGenealogy } from '../src/renderer/game/engine/narrative/genealogy'
import { marketPrice, buyItem, sellItem } from '../src/renderer/game/engine/market' import { marketPrice, buyItem, sellItem } from '../src/renderer/game/engine/sim/Market'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+5 -5
View File
@@ -1,10 +1,10 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { GameClock, PHASE_ORDER } from '../src/renderer/game/core/clock' import { GameClock, PHASE_ORDER } from '../src/renderer/game/engine/kernel/clock'
import { buildClock } from '../src/renderer/game/engine/clocks' import { buildClock } from '../src/renderer/game/engine/runtime/clocks'
import { RngHub } from '../src/renderer/game/core/rng' import { RngHub } from '../src/renderer/game/engine/kernel/rng'
import { seasonOf, seasonMod, SEASON } from '../src/renderer/game/data/season' import { seasonOf, seasonMod, SEASON } from '../src/renderer/game/data/season'
import { yearAxis, decadeLabel } from '../src/renderer/game/core/yearaxis' import { yearAxis, decadeLabel } from '../src/renderer/game/engine/narrative/yearaxis'
import { stateFingerprint } from './fingerprint.helper' import { stateFingerprint } from './fingerprint.helper'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { stateFingerprint, longRun } from './fingerprint.helper' import { stateFingerprint, longRun } from './fingerprint.helper'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
/** /**
* 金钟罩:固定种子长跑 560 月的状态指纹。 * 金钟罩:固定种子长跑 560 月的状态指纹。
+3 -3
View File
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { combatPowerOf, resolveEncounter, resolveRaid, rollWarbooty } from '../src/renderer/game/engine/systems/combat' import { combatPowerOf, resolveEncounter, resolveRaid, rollWarbooty } from '../src/renderer/game/engine/runtime/Systems/combat'
import { ENEMIES } from '../src/renderer/game/data/secrets' import { ENEMIES } from '../src/renderer/game/data/secrets'
import { sendMission, recallAll } from '../src/renderer/game/engine/systems/missions' import { sendMission, recallAll } from '../src/renderer/game/engine/runtime/Systems/missions'
import { missionById } from '../src/renderer/game/data/secrets' import { missionById } from '../src/renderer/game/data/secrets'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { applyEventChoice, applyEffect } from '../src/renderer/game/engine/systems/events' import { applyEventChoice, applyEffect } from '../src/renderer/game/engine/runtime/Systems/events'
import { EffectDef } from '../src/renderer/game/data/events' import { EffectDef } from '../src/renderer/game/data/events'
import { Character } from '../src/renderer/game/types/domain' import { Character } from '../src/renderer/game/types/domain'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+1 -1
View File
@@ -22,7 +22,7 @@ import { NPCS, npcById } from '../src/renderer/game/data/npcs'
import { POSTS, POST_ORDER } from '../src/renderer/game/data/posts' import { POSTS, POST_ORDER } from '../src/renderer/game/data/posts'
import { EVENTS } from '../src/renderer/game/data/events' import { EVENTS } from '../src/renderer/game/data/events'
import { MAJOR_RATE, masteryRateOfMajor } from '../src/renderer/game/data/pacing' import { MAJOR_RATE, masteryRateOfMajor } from '../src/renderer/game/data/pacing'
import { SURNAME_POOL, MALE_GIVEN, FEMALE_GIVEN } from '../src/renderer/game/core/names' import { SURNAME_POOL, MALE_GIVEN, FEMALE_GIVEN } from '../src/renderer/game/engine/kernel/names'
import { TRAITS } from '../src/renderer/game/data/traits' import { TRAITS } from '../src/renderer/game/data/traits'
describe('realms 境界表', () => { describe('realms 境界表', () => {
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { applyEventChoice, eventRoll } from '../src/renderer/game/engine/systems/events' import { applyEventChoice, eventRoll } from '../src/renderer/game/engine/runtime/Systems/events'
describe('echo 四邻回声', () => { describe('echo 四邻回声', () => {
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { marketPrice, buyItem, sellItem, buyTechnique, techniquePrice } from '../src/renderer/game/engine/market' import { marketPrice, buyItem, sellItem, buyTechnique, techniquePrice } from '../src/renderer/game/engine/sim/Market'
import { ITEMS } from '../src/renderer/game/data/items' import { ITEMS } from '../src/renderer/game/data/items'
describe('economy 经济系统', () => { describe('economy 经济系统', () => {
+2 -2
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World, normalizeGameState } from '../src/renderer/game/engine/world' import { World, normalizeGameState } from '../src/renderer/game/engine/runtime/World'
import { EVENTS, EffectDef } from '../src/renderer/game/data/events' import { EVENTS, EffectDef } from '../src/renderer/game/data/events'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { POSTS } from '../src/renderer/game/data/posts' import { POSTS } from '../src/renderer/game/data/posts'
import { ASPIRATIONS } from '../src/renderer/game/data/aspirations' import { ASPIRATIONS } from '../src/renderer/game/data/aspirations'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+2 -2
View File
@@ -1,5 +1,5 @@
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { matchesCond } from '../src/renderer/game/engine/systems/events' import { matchesCond } from '../src/renderer/game/engine/runtime/Systems/events'
import { Cond } from '../src/renderer/game/data/events' import { Cond } from '../src/renderer/game/data/events'
export function matchesCondPub(w: World, cond?: Cond): boolean { export function matchesCondPub(w: World, cond?: Cond): boolean {
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { matchesCond, applyEventChoice, findEvent, eventRoll } from '../src/renderer/game/engine/systems/events' import { matchesCond, applyEventChoice, findEvent, eventRoll } from '../src/renderer/game/engine/runtime/Systems/events'
import { EVENTS } from '../src/renderer/game/data/events' import { EVENTS } from '../src/renderer/game/data/events'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+4 -4
View File
@@ -1,9 +1,9 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { GameFacade } from '../src/renderer/game/engine/api' import { GameFacade } from '../src/renderer/game/engine/runtime/ApiFacade'
import { SYSTEM_DEFS } from '../src/renderer/game/engine/capabilities' import { SYSTEM_DEFS } from '../src/renderer/game/engine/runtime/capabilities'
import { PACK, pack, DEFAULT_PACK } from '../src/renderer/game/data/registry' import { PACK, pack, DEFAULT_PACK } from '../src/renderer/game/data/registry'
import { marketPrice } from '../src/renderer/game/engine/market' import { marketPrice } from '../src/renderer/game/engine/sim/Market'
import { stateFingerprint, longRun } from './fingerprint.helper' import { stateFingerprint, longRun } from './fingerprint.helper'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+5 -5
View File
@@ -1,12 +1,12 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { buildReport, verdictLine } from '../src/renderer/game/core/legacyreport' import { buildReport, verdictLine } from '../src/renderer/game/engine/narrative/legacyreport'
import { migrateIfNeeded, exportEnvelope, parseImportEnvelope, CURRENT_SCHEMA, APP_ID } from '../src/renderer/game/storage/migrate' import { migrateIfNeeded, exportEnvelope, parseImportEnvelope, CURRENT_SCHEMA, APP_ID } from '../src/renderer/game/storage/migrate'
import { FORMATIONS, formationById, FormationId } from '../src/renderer/game/data/formations' import { FORMATIONS, formationById, FormationId } from '../src/renderer/game/data/formations'
import { resolveEncounter } from '../src/renderer/game/engine/systems/combat' import { resolveEncounter } from '../src/renderer/game/engine/runtime/Systems/combat'
import { ENEMIES } from '../src/renderer/game/data/secrets' import { ENEMIES } from '../src/renderer/game/data/secrets'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { sendMission } from '../src/renderer/game/engine/systems/missions' import { sendMission } from '../src/renderer/game/engine/runtime/Systems/missions'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+1 -1
View File
@@ -1,4 +1,4 @@
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { GameState } from '../src/renderer/game/types/domain' import { GameState } from '../src/renderer/game/types/domain'
export function stateFingerprint(s: GameState): string { export function stateFingerprint(s: GameState): string {
+2 -2
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { seasonOf } from '../src/renderer/game/data/season' import { seasonOf } from '../src/renderer/game/data/season'
import { tideOf, yearRing, seasonTint, seasonCssVars, TIDES } from '../src/renderer/game/core/timesense' import { tideOf, yearRing, seasonTint, seasonCssVars, TIDES } from '../src/renderer/game/engine/kernel/timesense'
import { FxGate, FxKind } from '../src/renderer/game/core/fxqueue' import { FxGate, FxKind } from '../src/renderer/game/engine/kernel/fxqueue'
describe('timesense 时间感知矩阵', () => { describe('timesense 时间感知矩阵', () => {
it.each([[1, 'spring'], [3, 'spring'], [4, 'summer'], [6, 'summer'], [7, 'autumn'], [9, 'autumn'], [10, 'winter'], [12, 'winter']] as const)( it.each([[1, 'spring'], [3, 'spring'], [4, 'summer'], [6, 'summer'], [7, 'autumn'], [9, 'autumn'], [10, 'winter'], [12, 'winter']] as const)(
+1 -1
View File
@@ -1,4 +1,4 @@
import { CotycPlugin } from '../../src/renderer/game/core/plugin' import { CotycPlugin } from '../../src/renderer/game/engine/kernel/plugin'
/** 示例内容插件:注入事件池 + 一个护山能力(开发范本) */ /** 示例内容插件:注入事件池 + 一个护山能力(开发范本) */
export const examplePlugin: CotycPlugin = { export const examplePlugin: CotycPlugin = {
+4 -4
View File
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { computeLegacy, resolveLegacy, peakRealmIndex, grandTechniqueCount } from '../src/renderer/game/core/legacy' import { computeLegacy, resolveLegacy, peakRealmIndex, grandTechniqueCount } from '../src/renderer/game/engine/narrative/legacy'
import { runTournament, buildApprentice, finalizeApprentice, apprenticeCandidates } from '../src/renderer/game/engine/systems/tournament' import { runTournament, buildApprentice, finalizeApprentice, apprenticeCandidates } from '../src/renderer/game/engine/runtime/Systems/tournament'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
const SEEDS = ['long-a', 'long-b', 'long-c'] const SEEDS = ['long-a', 'long-b', 'long-c']
+4 -4
View File
@@ -1,13 +1,13 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { import {
giftNpc, giftNpc,
marryNpcFamily, marryNpcFamily,
makePeace, makePeace,
arrangeWedding, arrangeWedding,
diplomacyTick diplomacyTick
} from '../src/renderer/game/engine/systems/diplomacy' } from '../src/renderer/game/engine/runtime/Systems/diplomacy'
import { yearStartMarriage } from '../src/renderer/game/engine/systems/marriage' import { yearStartMarriage } from '../src/renderer/game/engine/runtime/Systems/marriage'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
@@ -189,7 +189,7 @@ describe('genealogy 谱系结构', () => {
}) })
}) })
import { computeGenealogy } from '../src/renderer/game/core/genealogy' import { computeGenealogy } from '../src/renderer/game/engine/narrative/genealogy'
function computeGenealogyLocal(w: World) { function computeGenealogyLocal(w: World) {
return computeGenealogy(w) return computeGenealogy(w)
} }
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { calcGiftGain, GIFT_TIERS, giftNpc } from '../src/renderer/game/engine/systems/diplomacy' import { calcGiftGain, GIFT_TIERS, giftNpc } from '../src/renderer/game/engine/runtime/Systems/diplomacy'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
+5 -5
View File
@@ -1,9 +1,9 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { Rng, seedToRng } from '../src/renderer/game/core/rng' import { Rng, seedToRng } from '../src/renderer/game/engine/kernel/rng'
import { newCharacter, rollAttributes, rollRoots, rollPersonality, traitBonuses, calcLifespan } from '../src/renderer/game/engine/pcgen' import { newCharacter, rollAttributes, rollRoots, rollPersonality, traitBonuses, calcLifespan } from '../src/renderer/game/engine/runtime/pcgen'
import { monthlyRate, perAttemptChance } from '../src/renderer/game/engine/systems/cultivation' import { monthlyRate, perAttemptChance } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { lifespanOf } from '../src/renderer/game/engine/systems/lifecycle' import { lifespanOf } from '../src/renderer/game/engine/runtime/Systems/lifecycle'
function rng(): Rng { function rng(): Rng {
return new Rng(seedToRng('pcgen')) return new Rng(seedToRng('pcgen'))
+5 -5
View File
@@ -1,9 +1,9 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { GameFacade } from '../src/renderer/game/engine/api' import { GameFacade } from '../src/renderer/game/engine/runtime/ApiFacade'
import { installCoreSystems, buildClock } from '../src/renderer/game/engine/clocks' import { installCoreSystems, buildClock } from '../src/renderer/game/engine/runtime/clocks'
import { emptyClock } from '../src/renderer/game/engine/clocks' import { emptyClock } from '../src/renderer/game/engine/runtime/clocks'
import { CORE_PLUGINS } from '../src/renderer/game/engine/plugin-bootstrap' import { CORE_PLUGINS } from '../src/renderer/game/engine/runtime/plugin-bootstrap'
import { examplePlugin, brokenPlugin } from './helpers/examplePlugin' import { examplePlugin, brokenPlugin } from './helpers/examplePlugin'
import { stateFingerprint, longRun } from './fingerprint.helper' import { stateFingerprint, longRun } from './fingerprint.helper'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+5 -5
View File
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { monthlyRate } from '../src/renderer/game/engine/systems/cultivation' import { monthlyRate } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { MAJORS } from '../src/renderer/game/data/realms' import { MAJORS } from '../src/renderer/game/data/realms'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
@@ -73,8 +73,8 @@ describe('0.1.10 数值重建验收', () => {
}) })
}) })
import { resolveBreakthrough } from '../src/renderer/game/engine/systems/cultivation' import { resolveBreakthrough } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { perTribChance } from '../src/renderer/game/engine/systems/tribulation' import { perTribChance } from '../src/renderer/game/engine/runtime/Systems/tribulation'
describe('事件悬置与周期(0.1.10', () => { describe('事件悬置与周期(0.1.10', () => {
it('大比征召 FIFO 不被拍卖/传薪挤掉(20 年三年都触发)', () => { it('大比征召 FIFO 不被拍卖/传薪挤掉(20 年三年都触发)', () => {
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { Rng, seedToRng, RngHub } from '../src/renderer/game/core/rng' import { Rng, seedToRng, RngHub } from '../src/renderer/game/engine/kernel/rng'
describe('RNG 多种子矩阵', () => { describe('RNG 多种子矩阵', () => {
it.each([ it.each([
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { Rng, seedToRng } from '../src/renderer/game/core/rng' import { Rng, seedToRng } from '../src/renderer/game/engine/kernel/rng'
describe('Rng.sfc32 特性', () => { describe('Rng.sfc32 特性', () => {
it('同一种子产生的序列完全一致', () => { it('同一种子产生的序列完全一致', () => {
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { SaveSlot, SaveDbDriver } from '../src/renderer/game/storage/slots' import { SaveSlot, SaveDbDriver } from '../src/renderer/game/storage/slots'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
interface Row { interface Row {
[k: string]: unknown [k: string]: unknown
+1 -1
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { SaveSlot, SaveDbDriver } from '../src/renderer/game/storage/slots' import { SaveSlot, SaveDbDriver } from '../src/renderer/game/storage/slots'
import { GameState } from '../src/renderer/game/types/domain' import { GameState } from '../src/renderer/game/types/domain'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
interface Row { interface Row {
[k: string]: unknown [k: string]: unknown
+6 -6
View File
@@ -1,10 +1,10 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { combatPowerOf } from '../src/renderer/game/engine/systems/combat' import { combatPowerOf } from '../src/renderer/game/engine/runtime/Systems/combat'
import { marketPrice, buyItem, sellItem, buyTechnique } from '../src/renderer/game/engine/market' import { marketPrice, buyItem, sellItem, buyTechnique } from '../src/renderer/game/engine/sim/Market'
import { resolveBreakthrough, monthlyRate } from '../src/renderer/game/engine/systems/cultivation' import { resolveBreakthrough, monthlyRate } from '../src/renderer/game/engine/runtime/Systems/cultivation'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { computeGenealogy } from '../src/renderer/game/core/genealogy' import { computeGenealogy } from '../src/renderer/game/engine/narrative/genealogy'
import { matchesCondPub } from './events.helpers' import { matchesCondPub } from './events.helpers'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
+4 -4
View File
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { computeUrgency } from '../src/renderer/game/core/urgency' import { computeUrgency } from '../src/renderer/game/engine/kernel/urgency'
import { computeGuide, GUIDE_STEPS, guideAdvance } from '../src/renderer/game/core/guide' import { computeGuide, GUIDE_STEPS, guideAdvance } from '../src/renderer/game/engine/kernel/guide'
import { fmt } from '../src/renderer/game/core/format' import { fmt } from '../src/renderer/game/engine/kernel/format'
function baseWorld(seed: string): World { function baseWorld(seed: string): World {
return World.create({ seed, surname: '舒', familyName: '舒家', motto: 'm', difficulty: 'normal' }) return World.create({ seed, surname: '舒', familyName: '舒家', motto: 'm', difficulty: 'normal' })
+2 -2
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { createWorldState, NewGameOptions, findInheritor } from '../src/renderer/game/engine/creation' import { createWorldState, NewGameOptions, findInheritor } from '../src/renderer/game/engine/runtime/creation'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
function opts(seed: string, difficulty: 'easy' | 'normal' | 'hard' = 'normal', surname = '彭'): NewGameOptions { function opts(seed: string, difficulty: 'easy' | 'normal' | 'hard' = 'normal', surname = '彭'): NewGameOptions {
+3 -3
View File
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { stateFingerprint, longRun } from './fingerprint.helper' import { stateFingerprint, longRun } from './fingerprint.helper'
import { computeGenealogy } from '../src/renderer/game/core/genealogy' import { computeGenealogy } from '../src/renderer/game/engine/narrative/genealogy'
import { applyEventChoice } from '../src/renderer/game/engine/systems/events' import { applyEventChoice } from '../src/renderer/game/engine/runtime/Systems/events'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
describe('多 seed 长跑矩阵', () => { describe('多 seed 长跑矩阵', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { World, WorldEventBus } from '../src/renderer/game/engine/world' import { World, WorldEventBus } from '../src/renderer/game/engine/runtime/World'
import { LogItem, ChronicleEntry, BattleLog } from '../src/renderer/game/types/domain' import { LogItem, ChronicleEntry, BattleLog } from '../src/renderer/game/types/domain'
const sinks: Set<WorldEventBus> = new Set() const sinks: Set<WorldEventBus> = new Set()
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/world' import { World } from '../src/renderer/game/engine/runtime/World'
import { resetSaveBus, attachLogSink } from './world.helpers' import { resetSaveBus, attachLogSink } from './world.helpers'
describe('World engine', () => { describe('World engine', () => {