v1.5.0: shared-world spawn quality rule — max reputation across players (ISS-111)
CI / build + unit + e2e (pull_request) Successful in 13m53s

This commit is contained in:
2026-09-26 19:07:50 +00:00
parent c3fa5bf613
commit eae680c002
6 changed files with 79 additions and 17 deletions
+6 -6
View File
@@ -1,7 +1,7 @@
import { randomInt, randomUUID } from 'node:crypto';
import { eq, sql } from 'drizzle-orm';
import { getGameDb, persist, type GameDb } from '@/lib/db/client';
import { getLocalPlayer, getPlayer, updatePlayerEconomy } from '@/lib/db/localPlayer';
import { getSharedWorldReputation, getPlayer, updatePlayerEconomy } from '@/lib/db/localPlayer';
import * as schema from '@/lib/db/schema';
import { loadAirportsGeoJson } from '@/lib/airports';
import { haversineKm, initialBearingDeg } from '@/lib/geo';
@@ -385,10 +385,10 @@ export async function spawnPoolPackages(
}));
const rand = rng ?? mulberry32(randomInt(0, 2 ** 31));
// v0.38.0 (ISS-072): spawned jobs carry a reputation-based job quality — read once per spawn batch.
// ponytail: stays on the seeded 'local' row — pools are SHARED world state (packages have no
// owner), so there is no single owning player whose rep should set job quality; per-player job
// quality is a later multiplayer step.
const player = await getLocalPlayer(inst);
// v1.5.0 (ISS-111), the #101 decision point: pools are SHARED world state, so quality follows the
// agreed shared-world rule — MAX reputation across all players — and scales to the best-progressed
// player instead of the seeded local row.
const reputation = await getSharedWorldReputation(inst);
let n = 0;
for (const originIcao of pool) {
@@ -418,7 +418,7 @@ export async function spawnPoolPackages(
clockMs,
id: randomUUID(),
createdRealMs: real,
reputation: player.reputation,
reputation,
}),
);
openByBand[bandIdx]++;