mark trade ships plan-driven on spawn

Add `Game.markUnitPlanDriven()` so executions can suppress per-step Unit updates
before the first motion plan is recorded.

Use it in TradeShipExecution to drop the spawn-time placeholder motion plan, and
align TransportShipExecution re-plan `startTick` with `ticksPerMove`.
This commit is contained in:
scamiv
2026-02-25 03:17:33 +01:00
parent 79292fe8f9
commit f336c667f3
4 changed files with 14 additions and 16 deletions
+4 -15
View File
@@ -8,7 +8,6 @@ import {
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { MotionPlanRecord } from "../game/MotionPlans";
import { PathFinding } from "../pathfinding/PathFinder";
import { PathStatus, SteppingPathFinder } from "../pathfinding/types";
import { distSortUnit } from "../Util";
@@ -35,7 +34,6 @@ export class TradeShipExecution implements Execution {
}
tick(ticks: number): void {
let spawnedThisTick = false;
if (this.tradeShip === undefined) {
const spawn = this.origOwner.canBuild(
UnitType.TradeShip,
@@ -50,19 +48,10 @@ export class TradeShipExecution implements Execution {
targetUnit: this._dstPort,
lastSetSafeFromPirates: ticks,
});
// This unit can move immediately, but plan-driven units don't emit per-step Unit updates.
// Mark it plan-driven up-front so its first move doesn't generate redundant traffic.
this.mg.markUnitPlanDriven(this.tradeShip.id());
this.mg.stats().boatSendTrade(this.origOwner, this._dstPort.owner());
spawnedThisTick = true;
const placeholderPlan: MotionPlanRecord = {
kind: "grid",
unitId: this.tradeShip.id(),
planId: this.motionPlanId,
startTick: ticks + 1,
ticksPerStep: 1,
path: [spawn],
};
this.mg.recordMotionPlan(placeholderPlan);
this.motionPlanDst = this._dstPort.tile();
}
if (!this.tradeShip.isActive()) {
@@ -146,7 +135,7 @@ export class TradeShipExecution implements Execution {
}
const dst = this._dstPort.tile();
if (spawnedThisTick || dst !== this.motionPlanDst) {
if (dst !== this.motionPlanDst) {
this.motionPlanId++;
const from = this.tradeShip.tile();
const path = this.pathFinder.findPath(from, dst) ?? [from];
+1 -1
View File
@@ -282,7 +282,7 @@ export class TransportShipExecution implements Execution {
kind: "grid",
unitId: this.boat.id(),
planId: this.motionPlanId,
startTick: ticks + 1,
startTick: ticks + this.ticksPerMove,
ticksPerStep: this.ticksPerMove,
path: fullPath,
});
+5
View File
@@ -768,6 +768,11 @@ export interface Game extends GameMap {
inSpawnPhase(): boolean;
executeNextTick(): GameUpdates;
drainPackedTileUpdates(): Uint32Array;
/**
* Marks a unit as "plan-driven" so its per-tile `Unit` updates can be suppressed.
* The client is expected to advance the unit position via motion plans.
*/
markUnitPlanDriven(unitId: number): void;
recordMotionPlan(record: MotionPlanRecord): void;
drainPackedMotionPlans(): Uint32Array | null;
setWinner(winner: Player | Team, allPlayersStats: AllPlayersStats): void;
+4
View File
@@ -433,6 +433,10 @@ export class GameImpl implements Game {
return packed;
}
markUnitPlanDriven(unitId: number): void {
this.planDrivenUnitIds.add(unitId);
}
recordMotionPlan(record: MotionPlanRecord): void {
switch (record.kind) {
case "grid":