update meta

This commit is contained in:
evanpelle
2025-06-12 08:41:55 -07:00
parent e43fca3cd4
commit a32e9e48ef
6 changed files with 85 additions and 28 deletions
+3 -2
View File
@@ -123,8 +123,9 @@ export interface Config {
donateCooldown(): Tick;
defaultDonationAmount(sender: Player): number;
unitInfo(type: UnitType): UnitInfo;
tradeShipGold(dist: number): Gold;
tradeShipSpawnRate(numberOfPorts: number): number;
tradeShipGold(dist: number, numTradeShips: number): Gold;
tradeShipSpawnRate(numTradeShips: number): number;
tradeShipCap(): number;
safeFromPiratesCooldownMax(): number;
defensePostRange(): number;
SAMCooldown(): number;
+34 -13
View File
@@ -276,11 +276,32 @@ export class DefaultConfig implements Config {
infiniteTroops(): boolean {
return this._gameConfig.infiniteTroops;
}
tradeShipGold(dist: number): Gold {
return BigInt(Math.floor(10000 + 150 * Math.pow(dist, 1.1)));
tradeShipGold(dist: number, numPorts: number): Gold {
const baseGold = Math.floor(10000 + 150 * Math.pow(dist, 1.1));
const bonusPortNum = 25;
if (numPorts < bonusPortNum) {
return BigInt(baseGold);
} else {
return BigInt(Math.floor((numPorts / bonusPortNum) * baseGold));
}
}
tradeShipSpawnRate(numberOfPorts: number): number {
return Math.min(50, Math.round(10 * Math.pow(numberOfPorts, 0.6)));
// Chance to spawn a trade ship in one second,
tradeShipSpawnRate(numTradeShips: number): number {
const baseRate = 5;
if (numTradeShips <= 20) {
return baseRate;
}
if (numTradeShips > this.tradeShipCap()) {
return 1_000_000;
}
return numTradeShips - 15;
}
tradeShipCap(): number {
return 100;
}
unitInfo(type: UnitType): UnitInfo {
@@ -355,7 +376,7 @@ export class DefaultConfig implements Config {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0n
: 25_000_000n,
: 40_000_000n,
territoryBound: false,
};
case UnitType.MIRVWarhead:
@@ -498,7 +519,7 @@ export class DefaultConfig implements Config {
const type = gm.terrainType(tileToConquer);
switch (type) {
case TerrainType.Plains:
mag = 85;
mag = 80;
speed = 16.5;
break;
case TerrainType.Highland:
@@ -547,23 +568,23 @@ export class DefaultConfig implements Config {
}
}
let largeLossModifier = 1;
if (attacker.numTilesOwned() > 100_000) {
largeLossModifier = Math.sqrt(100_000 / attacker.numTilesOwned());
}
let largeSpeedMalus = 1;
if (attacker.numTilesOwned() > 75_000) {
// sqrt is only exponent 1/2 which doesn't slow enough huge players
largeSpeedMalus = (75_000 / attacker.numTilesOwned()) ** 0.6;
largeSpeedMalus = (75_000 / attacker.numTilesOwned()) ** 0.5;
}
if (defender.isPlayer()) {
let largeDefenderDebuff = 1;
if (defender.numTilesOwned() > 100_000) {
largeDefenderDebuff = Math.sqrt(100_000 / defender.numTilesOwned());
}
return {
attackerTroopLoss:
within(defender.troops() / attackTroops, 0.5, 2) *
mag *
0.8 *
largeLossModifier *
largeDefenderDebuff *
(defender.isTraitor() ? this.traitorDefenseDebuff() : 1),
defenderTroopLoss: defender.troops() / defender.numTilesOwned(),
tilesPerTickUsed:
@@ -676,7 +697,7 @@ export class DefaultConfig implements Config {
populationIncreaseRate(player: Player): number {
const max = this.maxPopulation(player);
let toAdd = 10 + Math.pow(player.population(), 0.7) / 4;
let toAdd = 10 + Math.pow(player.population(), 0.7) / 3;
const ratio = 1 - player.population() / max;
toAdd *= ratio;
+3 -2
View File
@@ -64,12 +64,13 @@ export class PortExecution implements Execution {
return;
}
const totalNbOfPorts = this.mg.units(UnitType.Port).length;
const numTradeShips = this.mg.units(UnitType.TradeShip).length;
if (
!this.random.chance(this.mg.config().tradeShipSpawnRate(totalNbOfPorts))
!this.random.chance(this.mg.config().tradeShipSpawnRate(numTradeShips))
) {
return;
}
console.log(`numTradeShips: ${numTradeShips}`);
const ports = this.player().tradingPorts(this.port);
+6 -1
View File
@@ -129,7 +129,12 @@ export class TradeShipExecution implements Execution {
private complete() {
this.active = false;
this.tradeShip!.delete(false);
const gold = this.mg.config().tradeShipGold(this.tilesTraveled);
const gold = this.mg
.config()
.tradeShipGold(
this.tilesTraveled,
this.mg.units(UnitType.TradeShip).length,
);
if (this.wasCaptured) {
this.tradeShip!.owner().addGold(gold);
+23
View File
@@ -0,0 +1,23 @@
import { DefaultConfig } from "../src/core/configuration/DefaultConfig";
import { createGameConfig } from "./util/Setup";
import { TestServerConfig } from "./util/TestServerConfig";
describe("Config", () => {
test("Trade ship spawn rate", async () => {
const config = new DefaultConfig(
new TestServerConfig(),
createGameConfig(),
null,
false,
);
expect(config.tradeShipSpawnRate(0)).toBe(5);
expect(config.tradeShipSpawnRate(1)).toBe(5);
expect(config.tradeShipSpawnRate(20)).toBe(5);
expect(config.tradeShipSpawnRate(21)).toBe(6);
expect(config.tradeShipSpawnRate(30)).toBe(15);
expect(config.tradeShipSpawnRate(50)).toBe(35);
expect(config.tradeShipSpawnRate(100)).toBe(85);
expect(config.tradeShipSpawnRate(151)).toBe(1_000_000);
});
});
+16 -10
View File
@@ -36,7 +36,21 @@ export async function setup(
// Configure the game
const serverConfig = new TestServerConfig();
const gameConfig: GameConfig = {
const config = new TestConfig(
serverConfig,
createGameConfig(_gameConfig),
new UserSettings(),
false,
);
return createGame(humans, [], gameMap, miniGameMap, config);
}
export function createGameConfig(
gameConfig: Partial<GameConfig> = {},
): GameConfig {
return {
gameMap: GameMapType.Asia,
gameMode: GameMode.FFA,
gameType: GameType.Singleplayer,
@@ -46,16 +60,8 @@ export async function setup(
infiniteGold: false,
infiniteTroops: false,
instantBuild: false,
..._gameConfig,
...gameConfig,
};
const config = new TestConfig(
serverConfig,
gameConfig,
new UserSettings(),
false,
);
return createGame(humans, [], gameMap, miniGameMap, config);
}
export function playerInfo(name: string, type: PlayerType): PlayerInfo {