feat(abilities): add migration & refugees lever (v0.42.0, #64)
CI / build + unit + e2e (pull_request) Successful in 2m12s
CI / build + unit + e2e (pull_request) Successful in 2m12s
Add the 10th modular LLM ability: a turn-transient TurnResult.migration lever declaring population flows between nations (migration / refugees / diaspora / exodus). The source loses a little population + economy, the destination gains a little (a large influx also strains its stability), and the from<->to relation is nudged one step toward the positive end of the ally/neutral/rival/hostile ladder (capped by kind; a war is never touched). Deterministic per-scale tables, no hidden randomness, clamped 0-100, mirrored to owned regions, re-derived aggregates; never moves territory. Registered last in ABILITIES; user prompt unchanged (user.txt golden byte-identical), system goldens re-baselined. Fixes #64.
This commit is contained in:
@@ -650,6 +650,63 @@ export interface DisastersOps {
|
||||
events: DisasterEvent[];
|
||||
}
|
||||
|
||||
// --- Migration & refugees (v0.42.0, #64) --------------------------------------
|
||||
//
|
||||
// People moving between nations each turn: ordinary migration, refugee flows
|
||||
// (fleeing a war or disaster), a spreading diaspora, and an exodus (people
|
||||
// leaving with no destination). Each op names a `kind`, a source `from` (the
|
||||
// nation people leave), a destination `to` (required for every kind except
|
||||
// `exodus`), and a `scale` (small / moderate / large). The engine applies a
|
||||
// DETERMINISTIC effect chosen from the per-`scale` tables
|
||||
// `MIGRATION_SOURCE_EFFECTS` / `MIGRATION_DESTINATION_EFFECTS` (defined in
|
||||
// `server/abilities/migration.ts`) — no hidden randomness: the LLM chooses the
|
||||
// kind and scale, the tables decide the magnitude. The source LOSES a small
|
||||
// amount of population and economy, the destination GAINS a small amount of
|
||||
// population and economy (a `large` influx additionally strains the
|
||||
// destination's stability), both clamped to 0–100, mirrored to each side's
|
||||
// regions (`regionStats`), and each side's derived `stats` re-derived
|
||||
// afterwards (the same 0-region / no-entry guards as the hybrid / economy /
|
||||
// disasters layers). The from↔to relation moves one step toward the positive
|
||||
// end of the ally/neutral/rival/hostile ladder (`shiftRelationTowardPositive`)
|
||||
// — capped at `ally` for `refugees`, `neutral` for `migration` / `diaspora`,
|
||||
// and not at all for `exodus` — and a `war` relation is never touched. It is
|
||||
// **turn-transient** like the hybrid / disasters layers: there is NO `GameState`
|
||||
// field, no durable list, and no `db.ts` change — a continuing flow is simply
|
||||
// re-declared each turn it persists. It never moves territory (sole ownership
|
||||
// is untouched) and never creates or escalates a war.
|
||||
|
||||
/** The kind of population flow a migration op describes (v0.42.0, #64). */
|
||||
export type MigrationKind = 'migration' | 'refugees' | 'diaspora' | 'exodus';
|
||||
|
||||
/** The size of a migration flow (v0.42.0, #64). */
|
||||
export type MigrationScale = 'small' | 'moderate' | 'large';
|
||||
|
||||
/**
|
||||
* A single migration / refugee flow (v0.42.0, #64): the `kind`, the source
|
||||
* `from` (a nation id / name — the nation people leave), the destination `to`
|
||||
* (a nation id / name — required for every kind except `exodus`, which has no
|
||||
* destination), the `scale`, and an optional short `detail`. The deterministic
|
||||
* stat effects are looked up from `MIGRATION_SOURCE_EFFECTS` /
|
||||
* `MIGRATION_DESTINATION_EFFECTS` by `scale`.
|
||||
*/
|
||||
export interface MigrationOp {
|
||||
/** The kind of flow (one of {@link MigrationKind}). */
|
||||
kind: MigrationKind;
|
||||
/** The source nation (by id or name) people leave. */
|
||||
from: string;
|
||||
/** The destination nation (by id or name). Required for every kind except `exodus`. */
|
||||
to?: string;
|
||||
/** How many people moved (one of {@link MigrationScale}). */
|
||||
scale: MigrationScale;
|
||||
/** Optional short annotation (≤300 chars). */
|
||||
detail?: string;
|
||||
}
|
||||
|
||||
/** The migration block of a `TurnResult`. Required; default `{ ops: [] }`. */
|
||||
export interface MigrationOps {
|
||||
ops: MigrationOp[];
|
||||
}
|
||||
|
||||
/** The exact JSON object the world-simulator LLM must return for a turn. */
|
||||
export interface TurnResult {
|
||||
date: string;
|
||||
@@ -819,6 +876,29 @@ export interface TurnResult {
|
||||
* `{ events: [] }`.
|
||||
*/
|
||||
disasters: DisastersOps;
|
||||
/**
|
||||
* (v0.42.0, #64) Migration & refugee flows this turn — people moving between
|
||||
* nations: ordinary `migration`, `refugees` fleeing a war or disaster, a
|
||||
* spreading `diaspora`, and an `exodus` (people leaving with no destination).
|
||||
* Each op names a `from` (the source nation, by id or name) and, for every
|
||||
* kind except `exodus`, a `to` (the destination nation, by id or name), plus
|
||||
* a `scale` (small / moderate / large). Applied directly by `applyTurnResult`
|
||||
* (like the disasters / hybrid layers): the source LOSES a small amount of
|
||||
* population and economy, the destination GAINS a small amount of population
|
||||
* and economy (a `large` influx additionally strains the destination's
|
||||
* stability by 2), both clamped to 0–100, mirrored to each side's regions,
|
||||
* and each side's derived `stats` re-derived afterwards; the from↔to
|
||||
* relation moves one step toward the positive end of the
|
||||
* ally/neutral/rival/hostile ladder (capped at `ally` for `refugees`,
|
||||
* `neutral` for `migration` / `diaspora`, not at all for `exodus`; a `war`
|
||||
* relation is never touched). The layer is turn-transient (no `GameState`
|
||||
* field, no `db.ts` change) — a continuing flow is simply re-declared each
|
||||
* turn it persists. It never moves borders (sole ownership is untouched) and
|
||||
* never creates or escalates a war. At most 1–2 per turn, each narrated in
|
||||
* `events` (a `social` or `diplomatic` event). Required; default
|
||||
* `{ ops: [] }`.
|
||||
*/
|
||||
migration: MigrationOps;
|
||||
/**
|
||||
* (v0.27, #44) Map-marker ops this turn. `add` places new named markers
|
||||
* (the engine positions each at its region's centroid + a small
|
||||
|
||||
Reference in New Issue
Block a user