Remove workers & troop ratio bar, only have troops (#1676)

## Description:

The troop/worker ratio bar is almost never changed. so remove it and the
entire concept of workers. Now there is just troops.

Now players get a consistent 1k/s gold.

## Please complete the following:

- [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).

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
evanpelle
2025-08-01 16:06:59 -07:00
committed by GitHub
parent cba4baccbd
commit 3b8a36166a
22 changed files with 57 additions and 325 deletions
-1
View File
@@ -31,7 +31,6 @@ export class BotExecution implements Execution {
init(mg: Game) {
this.mg = mg;
this.bot.setTargetTroopRatio(0.7);
}
tick(ticks: number) {
+1 -1
View File
@@ -21,7 +21,7 @@ export class DonateTroopsExecution implements Execution {
this.recipient = mg.player(this.recipientID);
this.troops ??= mg.config().defaultDonationAmount(this.sender);
const maxDonation =
mg.config().maxPopulation(this.recipient) - this.recipient.population();
mg.config().maxTroops(this.recipient) - this.recipient.troops();
this.troops = Math.min(this.troops, maxDonation);
}
-3
View File
@@ -20,7 +20,6 @@ import { MoveWarshipExecution } from "./MoveWarshipExecution";
import { NoOpExecution } from "./NoOpExecution";
import { QuickChatExecution } from "./QuickChatExecution";
import { RetreatExecution } from "./RetreatExecution";
import { SetTargetTroopRatioExecution } from "./SetTargetTroopRatioExecution";
import { SpawnExecution } from "./SpawnExecution";
import { TargetPlayerExecution } from "./TargetPlayerExecution";
import { TransportShipExecution } from "./TransportShipExecution";
@@ -98,8 +97,6 @@ export class Executor {
);
case "donate_gold":
return new DonateGoldExecution(player, intent.recipient, intent.gold);
case "troop_ratio":
return new SetTargetTroopRatioExecution(player, intent.ratio);
case "embargo":
return new EmbargoExecution(player, intent.targetID, intent.action);
case "build_unit":
-7
View File
@@ -153,13 +153,6 @@ export class FakeHumanExecution implements Execution {
return;
}
if (
this.player.troops() > 100_000 &&
this.player.targetTroopRatio() > 0.7
) {
this.player.setTargetTroopRatio(0.7);
}
this.updateRelationsFromEmbargos();
this.behavior.handleAllianceRequests();
this.handleUnits();
+5 -15
View File
@@ -203,8 +203,8 @@ export class NukeExecution implements Execution {
const toDestroy = this.tilesToDestroy();
this.maybeBreakAlliances(toDestroy);
const maxPop = this.target().isPlayer()
? this.mg.config().maxPopulation(this.target() as Player)
const maxTroops = this.target().isPlayer()
? this.mg.config().maxTroops(this.target() as Player)
: 1;
for (const tile of toDestroy) {
@@ -218,17 +218,7 @@ export class NukeExecution implements Execution {
this.nukeType,
owner.troops(),
owner.numTilesOwned(),
maxPop,
),
);
owner.removeWorkers(
this.mg
.config()
.nukeDeathFactor(
this.nukeType,
owner.workers(),
owner.numTilesOwned(),
maxPop,
maxTroops,
),
);
owner.outgoingAttacks().forEach((attack) => {
@@ -239,7 +229,7 @@ export class NukeExecution implements Execution {
this.nukeType,
attack.troops(),
owner.numTilesOwned(),
maxPop,
maxTroops,
) ?? 0;
attack.setTroops(attack.troops() - deaths);
});
@@ -251,7 +241,7 @@ export class NukeExecution implements Execution {
this.nukeType,
attack.troops(),
owner.numTilesOwned(),
maxPop,
maxTroops,
) ?? 0;
attack.setTroops(attack.troops() - deaths);
});
+2 -7
View File
@@ -56,19 +56,14 @@ export class PlayerExecution implements Execution {
return;
}
const popInc = this.config.populationIncreaseRate(this.player);
this.player.addWorkers(popInc * (1 - this.player.targetTroopRatio()));
this.player.addTroops(popInc * this.player.targetTroopRatio());
const troopInc = this.config.troopIncreaseRate(this.player);
this.player.addTroops(troopInc);
const goldFromWorkers = this.config.goldAdditionRate(this.player);
this.player.addGold(goldFromWorkers);
// Record stats
this.mg.stats().goldWork(this.player, goldFromWorkers);
const adjustRate = this.config.troopAdjustmentRate(this.player);
this.player.addTroops(adjustRate);
this.player.removeWorkers(adjustRate);
const alliances = Array.from(this.player.alliances());
for (const alliance of alliances) {
if (alliance.expiresAt() <= this.mg.ticks()) {
@@ -1,31 +0,0 @@
import { Execution, Game, Player } from "../game/Game";
export class SetTargetTroopRatioExecution implements Execution {
private active = true;
constructor(
private player: Player,
private targetTroopsRatio: number,
) {}
init(mg: Game, ticks: number): void {}
tick(ticks: number): void {
if (this.targetTroopsRatio < 0 || this.targetTroopsRatio > 1) {
console.warn(
`target troop ratio of ${this.targetTroopsRatio} for player ${this.player} invalid`,
);
} else {
this.player.setTargetTroopRatio(this.targetTroopsRatio);
}
this.active = false;
}
isActive(): boolean {
return this.active;
}
activeDuringSpawnPhase(): boolean {
return false;
}
}
+3 -4
View File
@@ -59,8 +59,8 @@ export class BotBehavior {
}
private hasSufficientTroops(): boolean {
const maxPop = this.game.config().maxPopulation(this.player);
const ratio = this.player.population() / maxPop;
const maxTroops = this.game.config().maxTroops(this.player);
const ratio = this.player.troops() / maxTroops;
return ratio >= this.triggerRatio;
}
@@ -208,8 +208,7 @@ export class BotBehavior {
sendAttack(target: Player | TerraNullius) {
if (target.isPlayer() && this.player.isOnSameTeam(target)) return;
const maxPop = this.game.config().maxPopulation(this.player);
const maxTroops = maxPop * this.player.targetTroopRatio();
const maxTroops = this.game.config().maxTroops(this.player);
const reserveRatio = target.isPlayer()
? this.reserveRatio
: this.expandRatio;