【P0 修复(0.1.24 遗留)】worldGen.npcs defs 落档 + normalize 幂等重注册——读档后
动态家族(n-g-*)npcById 永命中;MOD 卸载后存档世界仍完整(存档世界永稳)
【MOD 系统四层】
- M2 内容层:modSchema.ts(ModPack 全 JSON:manifest+data{events/npcs/worldgen/pills/forges};
modParse 纯解析校验 id/name/version/事件模板合法性)
- M3 管理器:modToPlugin(MOD→CotycPlugin 一等子类——插件持久化/双闸/启停/回滚全复用)
- M1 传输层:main IPC mods:scan/read(userData/mods/*.json|*.cotymod)+ preload + env.d.ts
+ store refreshMods/installModByName/installModText
- M4 UI:SettingsPanel「MOD 层」卡(扫描目录/候选列表/安装);内置示例包通路
【世界/插件协同】
- WorldGenPools 聚合词库池(默认不变→基准世界不变;reset() 供隔离);MOD 于新档参与生成
- items.ts 配方聚合注册表(PILL/FORGE base+扩展);PluginContext addPillRecipe/addForgeRecipe/addWorldGenPool
【边界(明注)】灾因/世界数值表注入归平衡版;脚本型 MOD 不做;MOD 只影响新档世界(老档不变形)
【测试】1040 全绿(46 套件):worldGen 存档 1 例 + mod-system 5 例(解析/转换/模板/依赖/基准指纹);
金钟罩 0.1.24 基线未漂(世界生成默认池不变);build 通过
67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
import { GameClock, SystemHook } from './clock'
|
||
import { DataPack } from '../../data/registry'
|
||
import { EventDef } from '../../data/events'
|
||
import type { World } from '../runtime/World'
|
||
|
||
export type PluginKind = 'system' | 'data' | 'events' | 'content'
|
||
|
||
export interface PluginHookGuard {
|
||
onLoad?(): void
|
||
onDisable?(): void
|
||
onEnable?(): void
|
||
onUninstall?(): void
|
||
}
|
||
|
||
export interface CotycPlugin {
|
||
id: string
|
||
name: string
|
||
version: string
|
||
author?: string
|
||
description: string
|
||
kind: PluginKind
|
||
dependencies?: string[]
|
||
conflicts?: string[]
|
||
install(ctx: PluginContext): void
|
||
uninstall?(ctx: PluginContext): void
|
||
hooks?: PluginHookGuard
|
||
protected?: boolean
|
||
}
|
||
|
||
export interface PluginContext {
|
||
world: World
|
||
clock: GameClock
|
||
register: (phase: Parameters<GameClock['register']>[0], fn: SystemHook) => () => void
|
||
onYearStart: (fn: SystemHook) => () => void
|
||
/** 时轮 anchor:phase 前/后挂勾(0.1.24;卸载时全摘) */
|
||
beforePhase: (phase: Parameters<GameClock['register']>[0], fn: SystemHook) => () => void
|
||
afterPhase: (phase: Parameters<GameClock['register']>[0], fn: SystemHook) => () => void
|
||
/** 世界生成钩子:插件可注入 NPC 模板(worldgen 词库插件化) */
|
||
addNpcTemplate: (def: import('../../data/npcs').NpcFamilyDef) => void
|
||
/** 配方注册(MOD/内容包扩展丹药/铸器表) */
|
||
addPillRecipe: (r: { output: string; name: string; danfangLevel: number; stones: number; lingcao: number; beastcore: number; desc: string }) => void
|
||
addForgeRecipe: (r: { output: string; name: string; stones: number; lingkuang: number; beastcore: number; desc: string }) => void
|
||
/** 世界生成词库池注入(styles/regions/fams/suffixes) */
|
||
addWorldGenPool: (part: { styles?: string[]; regions?: string[]; fams?: string[]; suffixes?: string[] }) => void
|
||
addCapability: (cap: { id: string; name: string; version: string; desc: string }) => void
|
||
removeCapability: (id: string) => void
|
||
enableCapability: (id: string, enabled: boolean) => void
|
||
overridePack: (partial: Partial<DataPack>) => void
|
||
resetPack: () => void
|
||
addEventPool: (id: string, events: EventDef[]) => void
|
||
removeEventPool: (id: string) => void
|
||
}
|
||
|
||
export interface PluginStatus {
|
||
id: string
|
||
name: string
|
||
version: string
|
||
kind: PluginKind
|
||
installed: boolean
|
||
enabled: boolean
|
||
protected: boolean
|
||
description: string
|
||
dependencies?: string[]
|
||
}
|
||
|
||
export type PluginChange = { id: string; action: 'install' | 'remove' | 'enable' | 'disable' }
|