시나리오 기본 시작 연도와 출병 제한 기준 통일

This commit is contained in:
2026-09-17 00:53:24 +00:00
parent 581ecd6a7b
commit d89bdc439f
16 changed files with 393 additions and 34 deletions
@@ -10,6 +10,8 @@ import {
import { GameClock, asNumber, asRecord, type GameClockMode, type GameClockPhase } from '@sammo-ts/common';
import {
buildScenarioBootstrap,
resolveScenarioStartYear,
LEGACY_DEFAULT_OPENING_PART_YEAR,
resolveScenarioGeneralDeathMonth,
type GeneralMeta,
type ScenarioBootstrapWarning,
@@ -29,7 +31,6 @@ import { applyInitialChangeCityEvents } from '../turn/monthlyChangeCityAction.js
const DEFAULT_TICK_SECONDS = 120 * 60;
const DEFAULT_GENERAL_GOLD = 1000;
const DEFAULT_GENERAL_RICE = 1000;
const DEFAULT_OPENING_PART_YEAR = 3;
const INTEGRATION_WORLD_SEED_ENV = 'INTEGRATION_WORLD_SEED';
const MINUTES_TO_MS = 60_000;
@@ -148,7 +149,7 @@ const resolveStartState = (
turnTermMinutes: number,
sync: boolean
): { startTime: Date; currentYear: number; currentMonth: number } => {
const startYear = scenarioStartYear ?? 0;
const startYear = resolveScenarioStartYear(scenarioStartYear);
if (!sync) {
return {
startTime: cutTurn(now, turnTermMinutes),
@@ -294,7 +295,7 @@ export const seedScenarioToDatabase = async (options: ScenarioSeedOptions): Prom
const scenarioConst = asRecord(seed.scenarioConfig.const);
if (typeof scenarioConst.openingPartYear !== 'number' || Number.isNaN(scenarioConst.openingPartYear)) {
scenarioConst.openingPartYear = DEFAULT_OPENING_PART_YEAR;
scenarioConst.openingPartYear = LEGACY_DEFAULT_OPENING_PART_YEAR;
}
const scenarioConfig = {
...seed.scenarioConfig,
@@ -328,7 +329,7 @@ export const seedScenarioToDatabase = async (options: ScenarioSeedOptions): Prom
killturn: install?.npcMode === 1 ? Math.trunc(4800 / turnTermMinutes / 3) : 4800 / turnTermMinutes,
// Ref seeds game_env.develcost before the first general turn. The
// monthly pre-handler recalculates the same value at each boundary.
develcost: (startState.currentYear - (scenario.startYear ?? startState.currentYear) + 10) * 2,
develcost: (startState.currentYear - resolveScenarioStartYear(scenario.startYear) + 10) * 2,
starttime: formatDateTime(startState.startTime),
turntime: formatDateTime(gameClockMode === 'manual' ? now : initialClock.baseTime),
opentime: formatDateTime(initialClockWallAnchor),
@@ -1,3 +1,4 @@
import { resolveScenarioStartYear } from '@sammo-ts/logic';
import type { ScenarioMeta, TurnCommandEnv } from '@sammo-ts/logic';
import type { TurnWorldState } from '../../types.js';
@@ -9,8 +10,8 @@ export const resolveConstraintEnv = (
scenarioMeta: ScenarioMeta | undefined,
env: TurnCommandEnv
): ConstraintEnv => {
const startYear = typeof scenarioMeta?.startYear === 'number' ? scenarioMeta.startYear : undefined;
const relYear = typeof startYear === 'number' ? world.currentYear - startYear : undefined;
const startYear = resolveScenarioStartYear(scenarioMeta?.startYear);
const relYear = world.currentYear - startYear;
const worldMeta = world.meta as Record<string, unknown>;
const rawKillturn = worldMeta.killturn;
const killturn =
@@ -12,6 +12,7 @@ import {
LEGACY_RANDOM_GENERAL_FIRST_NAMES,
LEGACY_RANDOM_GENERAL_LAST_NAMES,
LEGACY_DEFAULT_MAX_LEVEL,
LEGACY_DEFAULT_OPENING_PART_YEAR,
loadGeneralTurnCommandSpecs,
loadNationTurnCommandSpecs,
loadActionModuleBundle,
@@ -33,7 +34,6 @@ const DEFAULT_SABOTAGE_PROB_COEF = 300;
const DEFAULT_SABOTAGE_DEFENCE_COEF = 0.04;
const DEFAULT_SABOTAGE_DAMAGE_MIN = 100;
const DEFAULT_SABOTAGE_DAMAGE_MAX = 800;
const DEFAULT_OPENING_PART_YEAR = 3;
const DEFAULT_MAX_GENERAL = 500;
const DEFAULT_INITIAL_NATION_GEN_LIMIT = 10;
const DEFAULT_MAX_TECH_LEVEL = 12;
@@ -103,7 +103,7 @@ export const buildCommandEnv = (config: ScenarioConfig, unitSet?: UnitSetDefinit
),
sabotageDamageMin: resolveNumber(constValues, ['sabotageDamageMin'], DEFAULT_SABOTAGE_DAMAGE_MIN),
sabotageDamageMax: resolveNumber(constValues, ['sabotageDamageMax'], DEFAULT_SABOTAGE_DAMAGE_MAX),
openingPartYear: resolveNumber(constValues, ['openingPartYear'], DEFAULT_OPENING_PART_YEAR),
openingPartYear: resolveNumber(constValues, ['openingPartYear'], LEGACY_DEFAULT_OPENING_PART_YEAR),
maxGeneral: resolveNumber(constValues, ['defaultMaxGeneral', 'maxGeneral'], DEFAULT_MAX_GENERAL),
defaultNpcGold: resolveNumber(constValues, ['defaultNpcGold', 'defaultGold'], DEFAULT_GENERAL_GOLD),
defaultNpcRice: resolveNumber(constValues, ['defaultNpcRice', 'defaultRice'], DEFAULT_GENERAL_RICE),
@@ -20,6 +20,7 @@ import type {
UnitSetDefinition,
} from '@sammo-ts/logic';
import {
resolveScenarioStartYear,
DEFAULT_TURN_COMMAND_PROFILE,
INTERNAL_GENERAL_TURN_COMMAND_KEYS,
GeneralTurnCommandLoader,
@@ -277,8 +278,8 @@ const resolveConstraintEnv = (
worldConfig: Record<string, unknown>
): Record<string, unknown> => {
const worldMeta = asRecord(world.meta);
const startYear = typeof scenarioMeta?.startYear === 'number' ? scenarioMeta.startYear : undefined;
const relYear = typeof startYear === 'number' ? world.currentYear - startYear : undefined;
const startYear = resolveScenarioStartYear(scenarioMeta?.startYear);
const relYear = world.currentYear - startYear;
const joinModeRaw = worldConfig.join_mode ?? worldConfig.joinMode ?? worldMeta.join_mode ?? worldMeta.joinMode;
const joinMode = joinModeRaw === 'onlyRandom' ? 'onlyRandom' : 'full';
const killturnRaw = worldMeta.killturn;
+9 -4
View File
@@ -5,7 +5,12 @@ import { createPlayAuditHandler, initializeAuditCollection } from '../playAudit/
import { randomUUID } from 'node:crypto';
import { createRuntimePauseGate } from './runtimePauseGate.js';
import { loadActionModuleBundle, type TurnCommandProfile, type TurnSchedule } from '@sammo-ts/logic';
import {
resolveScenarioStartYear,
loadActionModuleBundle,
type TurnCommandProfile,
type TurnSchedule,
} from '@sammo-ts/logic';
import {
buildGameEventChannel,
buildGameReadModelDomainRevisionKey,
@@ -447,7 +452,7 @@ const createMonthlyCalendarRuntime = async (options: {
});
const monthlyBoundaryPreHandler = createMonthlyBoundaryPreHandler({
getWorld: options.getWorld,
startYear: options.snapshot.scenarioMeta?.startYear ?? options.currentYear,
startYear: resolveScenarioStartYear(options.snapshot.scenarioMeta?.startYear),
commandEnv: options.commandEnv,
});
const monthlyNationStatsHandler = createMonthlyNationStatsHandler({
@@ -493,7 +498,7 @@ const createMonthlyCalendarRuntime = async (options: {
createMonthlyWarSettingHandler({ getWorld: options.getWorld }),
createMonthlyWanderHandler({
getWorld: options.getWorld,
startYear: options.snapshot.scenarioMeta?.startYear ?? options.currentYear,
startYear: resolveScenarioStartYear(options.snapshot.scenarioMeta?.startYear),
commandEnv: options.commandEnv,
}),
createMonthlyNationCountHandler({ getWorld: options.getWorld }),
@@ -749,7 +754,7 @@ const createTurnDaemonRuntimeWithLease = async (
});
const monthlyEventHandler = createMonthlyEventHandler({
getWorld: () => worldRef,
startYear: snapshot.scenarioMeta?.startYear ?? state.currentYear,
startYear: resolveScenarioStartYear(snapshot.scenarioMeta?.startYear),
actions: eventActions,
});
const {