fix: Ref 게임 로직과 시나리오 풀 호환을 보정

월 경계, 전투 기술 상한, 연감과 베팅·설문·경매 정산 순서를 Ref 계약에 맞춘다.\n\n시나리오 일반 풀을 ENGINE mutation과 logical tick 기반으로 직렬화하고 914·915 catalog 및 조건부 100기 pool 실행 경계를 추가한다.\n\n경매 worker는 세대별 durable event만 만들고 ENGINE이 row lock 후 상태 전이와 정산을 단일 transaction으로 소유한다.
This commit is contained in:
2026-08-23 16:26:14 +00:00
parent bf6b7be7b0
commit 85591c68ad
114 changed files with 13327 additions and 901 deletions
+57 -1
View File
@@ -8,7 +8,7 @@ import type { UnitSetDefinition } from '../src/world/types.js';
import { resolveWarAftermath } from '../src/war/aftermath.js';
import type { WarAftermathConfig } from '../src/war/types.js';
import { LogFormat } from '../src/logging/types.js';
import { buildWarAftermathConfig } from '../src/actions/turn/actionContextHelpers.js';
import { buildWarAftermathConfig, buildWarConfig } from '../src/actions/turn/actionContextHelpers.js';
import type { ScenarioConfig } from '../src/scenario/types.js';
const buildUnitSet = (): UnitSetDefinition => ({
@@ -137,6 +137,62 @@ describe('war aftermath', () => {
expect(config.maxTechLevel).toBe(12);
});
it('propagates the scenario maximum tech level to battle and aftermath configs', () => {
const scenarioConfig: ScenarioConfig = {
stat: { total: 0, min: 0, max: 0, npcTotal: 0, npcMax: 0, npcMin: 0, chiefMin: 0 },
iconPath: '',
map: {},
const: { maxTechLevel: 15 },
environment: { mapName: 'test', unitSet: 'test' },
};
expect(buildWarConfig(scenarioConfig, buildUnitSet()).maxTechLevel).toBe(15);
expect(buildWarAftermathConfig(scenarioConfig, 999).maxTechLevel).toBe(15);
});
it('uses the scenario maximum tech level for supply-city rice consumption', () => {
const attackerNation = buildNation(1);
const defenderNation = buildNation(2);
defenderNation.meta.tech = 15_000;
const attackerCity = buildCity(1, 1);
const defenderCity = buildCity(2, 2);
defenderCity.meta.supply = 1;
const attacker = buildGeneral(1, 1, 1);
resolveWarAftermath({
battle: {
attacker,
defenders: [],
defenderCity,
logs: [],
conquered: false,
reports: [
{
id: defenderCity.id,
type: 'city',
name: defenderCity.name,
isAttacker: false,
killed: 100,
dead: 0,
phase: 1,
},
],
},
attackerNation,
defenderNation,
attackerCity,
defenderCity,
nations: [attackerNation, defenderNation],
cities: [attackerCity, defenderCity],
generals: [attacker],
unitSet: buildUnitSet(),
config: { ...buildConfig(), maxTechLevel: 15 },
time: { year: 200, month: 1, startYear: 180 },
});
expect(defenderNation.rice).toBe(985);
});
it('updates tech and diplomacy deltas', () => {
const attackerNation = buildNation(1);
const defenderNation = buildNation(2);