feat(ai): add autorun policies for general and nation management

- Introduced `policies.ts` to define AI policies for generals and nations, including priority actions and flags.
- Implemented `AutorunGeneralPolicy` class to manage general-specific actions based on AI options and server/nation policies.
- Implemented `AutorunNationPolicy` class to handle nation-specific actions, including resource requirements and combat strategies.
- Added types for AI context and world view in `types.ts` to facilitate interaction with game state and entities.
This commit is contained in:
2026-01-11 14:49:42 +00:00
parent cc41d1538e
commit 550910811c
10 changed files with 3623 additions and 4 deletions
+19 -2
View File
@@ -20,6 +20,7 @@ import { createReservedTurnStore } from './reservedTurnStore.js';
import { createTurnDaemonCommandHandler } from './worldCommandHandler.js';
import { loadTurnCommandProfile } from './turnCommandProfile.js';
import { loadTurnWorldFromDatabase } from './worldLoader.js';
import { shouldUseAi } from './ai/generalAi.js';
export interface TurnDaemonRuntimeOptions {
profile: string;
@@ -116,14 +117,30 @@ export const createTurnDaemonRuntime = async (options: TurnDaemonRuntimeOptions)
worldRef = world;
const stateStore = new InMemoryTurnStateStore(world);
const prefetchedNationTurns = new Set<string>();
const processor = new InMemoryTurnProcessor(world, {
tickMinutes,
beforeExecuteGeneral: reservedTurnStoreHandle
? async (general) => {
await reservedTurnStoreHandle.store.refreshGeneralTurns(general.id);
const promises: Promise<unknown>[] = [];
promises.push(reservedTurnStoreHandle.store.refreshGeneralTurns(general.id));
if (general.nationId > 0 && general.officerLevel >= 5) {
await reservedTurnStoreHandle.store.refreshNationTurns(general.nationId, general.officerLevel);
promises.push(
reservedTurnStoreHandle.store.refreshNationTurns(general.nationId, general.officerLevel)
);
}
if (general.nationId > 0 && general.officerLevel >= 5 && shouldUseAi(general, world.getState())) {
const key = `${general.nationId}:${world.getState().currentYear}:${world.getState().currentMonth}`;
if (!prefetchedNationTurns.has(key)) {
prefetchedNationTurns.add(key);
const generalIds = world
.listGenerals()
.filter((candidate) => candidate.nationId === general.nationId)
.map((candidate) => candidate.id);
promises.push(reservedTurnStoreHandle.store.prefetchGeneralTurns(generalIds));
}
}
await Promise.all(promises);
}
: undefined,
});