feat(03-03): assemble CoreState replay registry

- Bind the L2 pathfinder to each fresh hero state
- Give each CoreState an independent ReplaySystem
- Assert all eight stable commands are assembled at the top level
This commit is contained in:
unanmed 2026-09-10 16:44:46 +08:00
parent e7714894a0
commit 09481451d4
3 changed files with 52 additions and 2 deletions

View File

@ -20,7 +20,8 @@ import {
IItemStore,
ItemStore,
IMapStore,
MapStore
MapStore,
IReplaySystem
} from '@user/data-common';
import {
EnemyManager,
@ -42,8 +43,11 @@ import {
GameEventSystem,
IEnemyContext,
IGameEventSystem,
MapDamage
MapDamage,
IPathfindingSystem,
PathfindingSystem
} from '@user/data-system';
import { ReplaySystem } from '../../data-common/src/replay/system';
import {
CommonAuraConverter,
GuardAuraConverter,
@ -73,6 +77,7 @@ import { isNil } from 'lodash-es';
import { DirectionMapper, IDirectionMapper, logger } from '@motajs/common';
import { DefaultHeroMoveTopImpl } from './hero';
import { createEventBuiltinRegistrations } from './event';
import { createReplayCommandItems, registerReplayCommandItems } from './replay';
export class CoreState implements ICoreState {
// Layer 0 公共层,最底层的接口,不会依赖任何其他内容,一般是工具性接口及不需要存档的数据
@ -94,6 +99,10 @@ export class CoreState implements ICoreState {
// Layer 2 执行层,游戏逻辑对象都在这,包括一些需要操作数据层的逻辑系统等
readonly enemyContext: IEnemyContext<IEnemyAttr, IHeroAttr>;
readonly eventSystem: IGameEventSystem;
/** 已绑定勇士移动器的寻路系统 */
readonly pathfinding: IPathfindingSystem;
/** 当前 CoreState 独立拥有的录像系统 */
readonly replaySystem: IReplaySystem;
// Layer 3 用户层,也就是最顶层的内容,一般仅用于初始化以及仅供渲染端调用的顶层模块
readonly loadProgress: ILoadProgressTotal;
@ -232,6 +241,17 @@ export class CoreState implements ICoreState {
const heroMoveTopImpl = new DefaultHeroMoveTopImpl(this);
this.hero.location.mover.useTopImplementation(heroMoveTopImpl);
const pathfinding = new PathfindingSystem(this);
pathfinding.useMover(this.hero.location.mover);
this.pathfinding = pathfinding;
const replaySystem = new ReplaySystem();
registerReplayCommandItems(
replaySystem,
createReplayCommandItems(this)
);
this.replaySystem = replaySystem;
//#endregion
}

View File

@ -1,6 +1,7 @@
export * from './enemy';
export * from './event';
export * from './hero';
export * from './replay';
export * from './core';
export * from './ins';

View File

@ -67,6 +67,35 @@ describe('replay commands', () => {
).toThrow('Duplicate replay command code');
});
// 验证每个 CoreState 都独立装配八个稳定 command 与寻路访问边界
it('assembles an independent top-level registry for every CoreState', () => {
const first = createCoreState();
const second = createCoreState();
expect(first.replaySystem).not.toBe(second.replaySystem);
expect(first.pathfinding).not.toBe(second.pathfinding);
expect(
REPLAY_COMMAND_ORDER.map(code =>
first.replaySystem.getCommand(code)
).length
).toBe(8);
expect(
REPLAY_COMMAND_ORDER.map(code =>
second.replaySystem.getCommand(code)
).length
).toBe(8);
expect(
REPLAY_COMMAND_ORDER.every(
code => first.replaySystem.getCommand(code) !== null
)
).toBe(true);
expect(
REPLAY_COMMAND_ORDER.every(
code => second.replaySystem.getCommand(code) !== null
)
).toBe(true);
expect(first.replaySystem.route).not.toBe(second.replaySystem.route);
});
// 验证四向移动在 controller.onEnd 兑现前不会完成 command
it('awaits a directional movement controller', async () => {
const state = createCoreState();