@@ -20,7 +20,7 @@ import { PlayerView } from "../game/GameView";
2020import { UserSettings } from "../game/UserSettings" ;
2121import { GameConfig , GameID , TeamCountConfig } from "../Schemas" ;
2222import { NukeType } from "../StatsSchemas" ;
23- import { assertNever , sigmoid , simpleHash , within } from "../Util" ;
23+ import { assertNever , sigmoid , simpleHash , toInt , within } from "../Util" ;
2424import { Config , GameEnv , NukeMagnitude , ServerConfig , Theme } from "./Config" ;
2525import { Env } from "./Env" ;
2626import { PastelTheme } from "./PastelTheme" ;
@@ -297,52 +297,24 @@ export class DefaultConfig implements Config {
297297 return 120 ;
298298 }
299299
300- tradeShipGold ( dist : number , numPorts : number ) : Gold {
301- // Sigmoid: concave start, sharp S-curve middle, linear end - heavily punishes trades under range debuff.
302- const debuff = this . tradeShipShortRangeDebuff ( ) ;
303- const baseGold =
304- 100_000 / ( 1 + Math . exp ( - 0.03 * ( dist - debuff ) ) ) + 100 * dist ;
305- const numPortBonus = numPorts - 1 ;
306- // Hyperbolic decay, midpoint at 5 ports, 3x bonus max.
307- const bonus = 1 + 2 * ( numPortBonus / ( numPortBonus + 5 ) ) ;
308- const multiplier = this . goldMultiplier ( ) ;
309- return BigInt ( Math . floor ( baseGold * bonus * multiplier ) ) ;
300+ tradeShipGold ( dist : number ) : Gold {
301+ return toInt ( 10000 + 150 * Math . pow ( dist , 1.1 ) ) ;
310302 }
311303
312304 // Probability of trade ship spawn = 1 / tradeShipSpawnRate
313305 tradeShipSpawnRate (
306+ tradeShipSpawnRejections : number ,
314307 numTradeShips : number ,
315- numPlayerPorts : number ,
316- numPlayerTradeShips : number ,
317308 ) : number {
318- // Geometric mean of base spawn rate and port multiplier
319- const combined = Math . sqrt (
320- this . tradeShipBaseSpawn ( numTradeShips , numPlayerTradeShips ) *
321- this . tradeShipPortMultiplier ( numPlayerPorts ) ,
322- ) ;
309+ const decayRate = Math . LN2 / 50 ;
323310
324- return Math . floor ( 25 / combined ) ;
325- }
311+ // Approaches 0 as numTradeShips increase
312+ const baseSpawnRate = 1 - sigmoid ( numTradeShips , decayRate , 200 ) ;
326313
327- private tradeShipBaseSpawn (
328- numTradeShips : number ,
329- numPlayerTradeShips : number ,
330- ) : number {
331- if ( numPlayerTradeShips < 3 ) {
332- // If other players have many ports, then they can starve out smaller players.
333- // So this prevents smaller players from being completely starved out.
334- return 1 ;
335- }
336- const decayRate = Math . LN2 / 10 ;
337- return 1 - sigmoid ( numTradeShips , decayRate , 55 ) ;
338- }
314+ // Pity timer: increases spawn chance after consecutive rejections
315+ const rejectionModifier = 1 / ( tradeShipSpawnRejections + 1 ) ;
339316
340- private tradeShipPortMultiplier ( numPlayerPorts : number ) : number {
341- // Hyperbolic decay function with midpoint at 10 ports
342- // Expected trade ship spawn rate is proportional to numPlayerPorts * multiplier
343- // Gradual decay prevents scenario where more ports => fewer ships
344- const decayRate = 1 / 10 ;
345- return 1 / ( 1 + decayRate * numPlayerPorts ) ;
317+ return Math . floor ( ( 100 * rejectionModifier ) / baseSpawnRate ) ;
346318 }
347319
348320 unitInfo ( type : UnitType ) : UnitInfo {
0 commit comments