fix alternate view perf regression (#1734)

Have the diplomacy view only draw border, not interior tiles. Drawing
the interior tiles is a very expensive operation and caused main thread
cpu usage to spike to close to 100%.

Also change the color scheme so that neutral players are gray, and
embargoed players are red. I think long term embargo should be more of a
war state.

Added embargo update and cleaned it up to use Player instead of
PlayerID. There's no reason to pass ids around.

<img width="493" height="466" alt="Screenshot 2025-08-07 at 6 25 55 PM"
src="https://github.com/user-attachments/assets/75552036-42f1-4103-9537-234ff1c0464f"
/>

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I have read and accepted the CLA agreement (only required once).

regression is found:

evan
This commit is contained in:
evanpelle
2025-08-17 21:53:40 -04:00
committed by Scott Anderson
parent e6ff3c4ce3
commit 70b7464a4b
13 changed files with 118 additions and 65 deletions
+1
View File
@@ -188,6 +188,7 @@ export type Theme = {
// unit color for alternate view
selfColor(): Colord;
allyColor(): Colord;
neutralColor(): Colord;
enemyColor(): Colord;
spawnHighlightColor(): Colord;
};
+4
View File
@@ -32,6 +32,7 @@ export class PastelTheme implements Theme {
private _selfColor = colord({ r: 0, g: 255, b: 0 });
private _allyColor = colord({ r: 255, g: 255, b: 0 });
private _neutralColor = colord({ r: 128, g: 128, b: 128 });
private _enemyColor = colord({ r: 255, g: 0, b: 0 });
private _spawnHighlightColor = colord({ r: 255, g: 213, b: 79 });
@@ -169,6 +170,9 @@ export class PastelTheme implements Theme {
allyColor(): Colord {
return this._allyColor;
}
neutralColor(): Colord {
return this._neutralColor;
}
enemyColor(): Colord {
return this._enemyColor;
}
@@ -32,6 +32,7 @@ export class PastelThemeDark implements Theme {
private _selfColor = colord({ r: 0, g: 255, b: 0 });
private _allyColor = colord({ r: 255, g: 255, b: 0 });
private _neutralColor = colord({ r: 128, g: 128, b: 128 });
private _enemyColor = colord({ r: 255, g: 0, b: 0 });
private _spawnHighlightColor = colord({ r: 255, g: 213, b: 79 });
@@ -165,6 +166,9 @@ export class PastelThemeDark implements Theme {
allyColor(): Colord {
return this._allyColor;
}
neutralColor(): Colord {
return this._neutralColor;
}
enemyColor(): Colord {
return this._enemyColor;
}
+1 -1
View File
@@ -75,7 +75,7 @@ export class AttackExecution implements Execution {
this._owner.type() !== PlayerType.Bot
) {
// Don't let bots embargo since they can't trade anyway.
targetPlayer.addEmbargo(this._owner.id(), true);
targetPlayer.addEmbargo(this._owner, true);
this.rejectIncomingAllianceRequests(targetPlayer);
}
}
+5 -2
View File
@@ -3,6 +3,8 @@ import { Execution, Game, Player, PlayerID } from "../game/Game";
export class EmbargoExecution implements Execution {
private active = true;
private target: Player;
constructor(
private player: Player,
private targetID: PlayerID,
@@ -15,11 +17,12 @@ export class EmbargoExecution implements Execution {
this.active = false;
return;
}
this.target = mg.player(this.targetID);
}
tick(_: number): void {
if (this.action === "start") this.player.addEmbargo(this.targetID, false);
else this.player.stopEmbargo(this.targetID);
if (this.action === "start") this.player.addEmbargo(this.target, false);
else this.player.stopEmbargo(this.target);
this.active = false;
}
+2 -2
View File
@@ -100,12 +100,12 @@ export class FakeHumanExecution implements Execution {
player.relation(other) <= Relation.Hostile &&
!player.hasEmbargoAgainst(other)
) {
player.addEmbargo(other.id(), false);
player.addEmbargo(other, false);
} else if (
player.relation(other) >= Relation.Neutral &&
player.hasEmbargoAgainst(other)
) {
player.stopEmbargo(other.id());
player.stopEmbargo(other);
}
});
}
+4 -4
View File
@@ -492,7 +492,7 @@ export type TerraNullius = {
export type Embargo = {
createdAt: Tick;
isTemporary: boolean;
target: PlayerID;
target: Player;
};
export type Player = {
@@ -603,10 +603,10 @@ export type Player = {
// Embargo
hasEmbargoAgainst(other: Player): boolean;
tradingPartners(): Player[];
addEmbargo(other: PlayerID, isTemporary: boolean): void;
addEmbargo(other: Player, isTemporary: boolean): void;
getEmbargoes(): Embargo[];
stopEmbargo(other: PlayerID): void;
endTemporaryEmbargo(other: PlayerID): void;
stopEmbargo(other: Player): void;
endTemporaryEmbargo(other: Player): void;
canTrade(other: Player): boolean;
// Attacking.
+2 -2
View File
@@ -288,9 +288,9 @@ export class GameImpl implements Game {
// Automatically remove embargoes only if they were automatically created
if (requestor.hasEmbargoAgainst(recipient))
requestor.endTemporaryEmbargo(recipient.id());
requestor.endTemporaryEmbargo(recipient);
if (recipient.hasEmbargoAgainst(requestor))
recipient.endTemporaryEmbargo(requestor.id());
recipient.endTemporaryEmbargo(requestor);
this.addUpdate({
accepted: true,
+10 -1
View File
@@ -45,6 +45,7 @@ export enum GameUpdateType {
BonusEvent,
RailroadEvent,
ConquestEvent,
EmbargoEvent,
}
export type GameUpdate =
@@ -65,7 +66,8 @@ export type GameUpdate =
| AllianceExtensionUpdate
| BonusEventUpdate
| RailroadUpdate
| ConquestUpdate;
| ConquestUpdate
| EmbargoUpdate;
export type BonusEventUpdate = {
type: GameUpdateType.BonusEvent;
@@ -255,3 +257,10 @@ export type UnitIncomingUpdate = {
messageType: MessageType;
playerID: number;
};
export type EmbargoUpdate = {
type: GameUpdateType.EmbargoEvent;
event: "start" | "stop";
playerID: number;
embargoedID: number;
};
+4
View File
@@ -326,6 +326,10 @@ export class PlayerView {
return this.data.embargoes.has(other.id());
}
hasEmbargo(other: PlayerView): boolean {
return this.hasEmbargoAgainst(other) || other.hasEmbargoAgainst(this);
}
profile(): Promise<PlayerProfile> {
return this.game.worker.playerProfile(this.smallID());
}
+24 -11
View File
@@ -689,27 +689,40 @@ export class PlayerImpl implements Player {
return !embargo && other.id() !== this.id();
}
addEmbargo(other: PlayerID, isTemporary: boolean): void {
const embargo = this.embargoes.get(other);
getEmbargoes(): Embargo[] {
return [...this.embargoes.values()];
}
addEmbargo(other: Player, isTemporary: boolean): void {
const embargo = this.embargoes.get(other.id());
if (embargo !== undefined && !embargo.isTemporary) return;
this.embargoes.set(other, {
this.mg.addUpdate({
type: GameUpdateType.EmbargoEvent,
event: "start",
playerID: this.smallID(),
embargoedID: other.smallID(),
});
this.embargoes.set(other.id(), {
createdAt: this.mg.ticks(),
isTemporary: isTemporary,
target: other,
});
}
getEmbargoes(): Embargo[] {
return [...this.embargoes.values()];
stopEmbargo(other: Player): void {
this.embargoes.delete(other.id());
this.mg.addUpdate({
type: GameUpdateType.EmbargoEvent,
event: "stop",
playerID: this.smallID(),
embargoedID: other.smallID(),
});
}
stopEmbargo(other: PlayerID): void {
this.embargoes.delete(other);
}
endTemporaryEmbargo(other: PlayerID): void {
const embargo = this.embargoes.get(other);
endTemporaryEmbargo(other: Player): void {
const embargo = this.embargoes.get(other.id());
if (embargo !== undefined && !embargo.isTemporary) return;
this.stopEmbargo(other);