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
@@ -31,6 +31,7 @@ import {
createItemModuleRegistry,
loadItemModules,
resolveUniqueConfig,
readScenarioGeneralPoolClaim,
rollUniqueLottery,
getNextTurnAt,
getBillByLevel,
@@ -509,6 +510,7 @@ type WorldView = {
listNations(): Nation[];
listTroops(): Troop[];
listDiplomacy(): TurnDiplomacy[];
listGeneralPoolCandidates(claimedAt: Date): ReturnType<InMemoryTurnWorld['listGeneralPoolCandidates']>;
};
const mergeStats = (base: TurnGeneral['stats'], patch: Partial<TurnGeneral['stats']>): TurnGeneral['stats'] => ({
@@ -614,6 +616,20 @@ const createWorldOverlay = (world: InMemoryTurnWorld) => {
...entry,
meta: { ...entry.meta },
})),
listGeneralPoolCandidates: (claimedAt) => {
const candidates = world.listGeneralPoolCandidates(claimedAt);
if (!candidates) {
return candidates;
}
const overlayClaimedIds = new Set<number>();
for (const general of generalOverrides.values()) {
const claim = readScenarioGeneralPoolClaim(general.meta);
if (claim) {
overlayClaimedIds.add(claim.poolEntryId);
}
}
return candidates.filter((candidate) => !overlayClaimedIds.has(candidate.poolEntryId));
},
};
return {
@@ -1080,6 +1096,7 @@ export const createReservedTurnHandler = async (options: {
: {}),
rng: actionRng,
time: actionTime,
maxTechLevel: env.maxTechLevel,
uniqueLottery,
};
let specificContext = buildActionContext(
@@ -1113,6 +1130,7 @@ export const createReservedTurnHandler = async (options: {
nation: currentNation,
rng: actionRng,
time: actionTime,
maxTechLevel: env.maxTechLevel,
};
specificContext = baseContext;
}
@@ -2418,6 +2436,7 @@ export const createImmediateGeneralActionExecutor = async (options: {
month: state.currentMonth,
startYear,
},
maxTechLevel: env.maxTechLevel,
uniqueLottery,
};
const actionContext =