feat: add financial metrics endpoint and optimize economy tick with aggregate building calculations
This commit is contained in:
+32
-40
@@ -1,6 +1,8 @@
|
||||
from server.game_state import GameState
|
||||
from server.models import BUILDING_CONFIGS, BuildingType
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from server.logger import logger
|
||||
|
||||
class EconomyEngine:
|
||||
"""Handles all economy calculations and ticks"""
|
||||
@@ -9,55 +11,45 @@ class EconomyEngine:
|
||||
self.game_state = game_state
|
||||
|
||||
def tick(self):
|
||||
"""Process one economy tick for all players"""
|
||||
current_time = time.time()
|
||||
"""
|
||||
Process one economy tick for all players using an efficient aggregate calculation.
|
||||
"""
|
||||
logger.debug("Processing economy tick...")
|
||||
start_time = time.perf_counter()
|
||||
|
||||
for player in self.game_state.players.values():
|
||||
# Calculate power factor (10% if offline, 100% if online)
|
||||
time_diff = current_time - player.last_online
|
||||
if player.is_online:
|
||||
power_factor = 1.0
|
||||
else:
|
||||
power_factor = 0.1
|
||||
|
||||
# Process player economy
|
||||
self._process_player_economy(player, power_factor)
|
||||
|
||||
def _process_player_economy(self, player, power_factor: float):
|
||||
"""Process economy for a single player"""
|
||||
total_income = 0
|
||||
total_population = 0
|
||||
|
||||
# Get all player buildings
|
||||
buildings = self.game_state.get_player_buildings(player.player_id)
|
||||
|
||||
for building in buildings:
|
||||
player_money_deltas = defaultdict(int)
|
||||
player_total_population = defaultdict(int)
|
||||
|
||||
# 1. Single pass over all buildings to aggregate their effects
|
||||
for building in self.game_state.buildings.values():
|
||||
config = BUILDING_CONFIGS[building.building_type]
|
||||
owner_id = building.owner_id
|
||||
|
||||
# Calculate base income
|
||||
base_income = config.income
|
||||
|
||||
# Apply connectivity bonus for income-generating buildings
|
||||
if base_income > 0:
|
||||
zone_size = self.game_state.get_building_zone_size(building.x, building.y)
|
||||
connectivity_bonus = 1.0 + (zone_size * 0.05) # 5% per road in zone
|
||||
connectivity_bonus = 1.0 + (zone_size * 0.05)
|
||||
base_income = int(base_income * connectivity_bonus)
|
||||
|
||||
# Add to totals
|
||||
total_income += base_income
|
||||
total_population += config.population
|
||||
player_money_deltas[owner_id] += base_income
|
||||
player_total_population[owner_id] += config.population
|
||||
|
||||
# 2. Apply the aggregated deltas to each player
|
||||
for player_id, player in self.game_state.players.items():
|
||||
power_factor = 1.0 if player.is_online else 0.1
|
||||
|
||||
money_delta = player_money_deltas.get(player_id, 0)
|
||||
player.money += int(money_delta * power_factor)
|
||||
|
||||
total_population = player_total_population.get(player_id, 0)
|
||||
player.population = max(0, total_population)
|
||||
|
||||
if player.money < -100000:
|
||||
player.money = -100000
|
||||
|
||||
# Apply power factor
|
||||
total_income = int(total_income * power_factor)
|
||||
|
||||
# Update player stats
|
||||
player.money += total_income
|
||||
player.population = max(0, total_population)
|
||||
|
||||
# Prevent negative money (but allow debt for realism)
|
||||
if player.money < -100000:
|
||||
player.money = -100000
|
||||
|
||||
duration = time.perf_counter() - start_time
|
||||
logger.debug(f"Economy tick processed in {duration:.4f} seconds for {len(self.game_state.players)} players.")
|
||||
|
||||
def calculate_building_stats(self, player_id: str, building_type: BuildingType) -> dict:
|
||||
"""Calculate what a building would produce for a player"""
|
||||
config = BUILDING_CONFIGS[building_type]
|
||||
|
||||
Reference in New Issue
Block a user