// Phase 11 helpers for forging FlatBuffers report payloads in e2e // tests. Mirrors the engine's `report.Report` shape so the mocked // gateway can return realistic data without standing up the real // engine container. // // Phase 11 only renders planets, so the helpers keep the report shape // minimal (turn / dimensions / planet vectors). Phase 13 extended the // fixture with the optional rich planet fields (size, resources, // stockpiles, population, industry, colonists, production, free // industry) so the inspector e2e can drive the read-only display // against realistic values. Later phases extend the helper as ships, // fleets, sciences, etc. land. import { Builder } from "flatbuffers"; import { LocalPlanet, OtherPlanet, Report, UnidentifiedPlanet, UninhabitedPlanet, } from "../../../src/proto/galaxy/fbs/report"; export interface PlanetFixture { number: number; name: string; x: number; y: number; size?: number; resources?: number; capital?: number; material?: number; } export interface InhabitedFixture extends PlanetFixture { population?: number; colonists?: number; industry?: number; production?: string; freeIndustry?: number; } export interface OtherPlanetFixture extends InhabitedFixture { owner: string; } export interface ReportFixture { turn: number; mapWidth?: number; mapHeight?: number; localPlanets?: InhabitedFixture[]; otherPlanets?: OtherPlanetFixture[]; uninhabitedPlanets?: PlanetFixture[]; unidentifiedPlanets?: { number: number; x: number; y: number }[]; } export function buildReportPayload(fixture: ReportFixture): Uint8Array { const builder = new Builder(512); const localOffsets = (fixture.localPlanets ?? []).map((planet) => { const name = builder.createString(planet.name); const production = planet.production !== undefined ? builder.createString(planet.production) : null; LocalPlanet.startLocalPlanet(builder); LocalPlanet.addNumber(builder, BigInt(planet.number)); LocalPlanet.addX(builder, planet.x); LocalPlanet.addY(builder, planet.y); LocalPlanet.addName(builder, name); LocalPlanet.addSize(builder, planet.size ?? 10); LocalPlanet.addResources(builder, planet.resources ?? 0.5); LocalPlanet.addCapital(builder, planet.capital ?? 0); LocalPlanet.addMaterial(builder, planet.material ?? 0); LocalPlanet.addPopulation(builder, planet.population ?? 0); LocalPlanet.addIndustry(builder, planet.industry ?? 0); LocalPlanet.addColonists(builder, planet.colonists ?? 0); if (production !== null) LocalPlanet.addProduction(builder, production); LocalPlanet.addFreeIndustry(builder, planet.freeIndustry ?? 0); return LocalPlanet.endLocalPlanet(builder); }); const otherOffsets = (fixture.otherPlanets ?? []).map((planet) => { const name = builder.createString(planet.name); const owner = builder.createString(planet.owner); const production = planet.production !== undefined ? builder.createString(planet.production) : null; OtherPlanet.startOtherPlanet(builder); OtherPlanet.addNumber(builder, BigInt(planet.number)); OtherPlanet.addX(builder, planet.x); OtherPlanet.addY(builder, planet.y); OtherPlanet.addName(builder, name); OtherPlanet.addOwner(builder, owner); OtherPlanet.addSize(builder, planet.size ?? 9); OtherPlanet.addResources(builder, planet.resources ?? 0.5); OtherPlanet.addCapital(builder, planet.capital ?? 0); OtherPlanet.addMaterial(builder, planet.material ?? 0); OtherPlanet.addPopulation(builder, planet.population ?? 0); OtherPlanet.addIndustry(builder, planet.industry ?? 0); OtherPlanet.addColonists(builder, planet.colonists ?? 0); if (production !== null) OtherPlanet.addProduction(builder, production); OtherPlanet.addFreeIndustry(builder, planet.freeIndustry ?? 0); return OtherPlanet.endOtherPlanet(builder); }); const uninhabitedOffsets = (fixture.uninhabitedPlanets ?? []).map( (planet) => { const name = builder.createString(planet.name); UninhabitedPlanet.startUninhabitedPlanet(builder); UninhabitedPlanet.addNumber(builder, BigInt(planet.number)); UninhabitedPlanet.addX(builder, planet.x); UninhabitedPlanet.addY(builder, planet.y); UninhabitedPlanet.addName(builder, name); UninhabitedPlanet.addSize(builder, planet.size ?? 6); UninhabitedPlanet.addResources(builder, planet.resources ?? 0.5); UninhabitedPlanet.addCapital(builder, planet.capital ?? 0); UninhabitedPlanet.addMaterial(builder, planet.material ?? 0); return UninhabitedPlanet.endUninhabitedPlanet(builder); }, ); const unidentifiedOffsets = (fixture.unidentifiedPlanets ?? []).map( (planet) => { UnidentifiedPlanet.startUnidentifiedPlanet(builder); UnidentifiedPlanet.addNumber(builder, BigInt(planet.number)); UnidentifiedPlanet.addX(builder, planet.x); UnidentifiedPlanet.addY(builder, planet.y); return UnidentifiedPlanet.endUnidentifiedPlanet(builder); }, ); const localVec = localOffsets.length === 0 ? null : Report.createLocalPlanetVector(builder, localOffsets); const otherVec = otherOffsets.length === 0 ? null : Report.createOtherPlanetVector(builder, otherOffsets); const uninhabitedVec = uninhabitedOffsets.length === 0 ? null : Report.createUninhabitedPlanetVector(builder, uninhabitedOffsets); const unidentifiedVec = unidentifiedOffsets.length === 0 ? null : Report.createUnidentifiedPlanetVector(builder, unidentifiedOffsets); const totalPlanets = (fixture.localPlanets ?? []).length + (fixture.otherPlanets ?? []).length + (fixture.uninhabitedPlanets ?? []).length + (fixture.unidentifiedPlanets ?? []).length; Report.startReport(builder); Report.addTurn(builder, BigInt(fixture.turn)); Report.addWidth(builder, fixture.mapWidth ?? 4000); Report.addHeight(builder, fixture.mapHeight ?? 4000); Report.addPlanetCount(builder, totalPlanets); if (localVec !== null) Report.addLocalPlanet(builder, localVec); if (otherVec !== null) Report.addOtherPlanet(builder, otherVec); if (uninhabitedVec !== null) Report.addUninhabitedPlanet(builder, uninhabitedVec); if (unidentifiedVec !== null) Report.addUnidentifiedPlanet(builder, unidentifiedVec); const reportOff = Report.endReport(builder); builder.finish(reportOff); return builder.asUint8Array(); }