saumwacht-godot/scripts/luneraria/core/lune_balance.gd
Martin Stickelbroeck b565546c37 M1: autoritativer Drei-Lane-Kern (Karte, Kampf, Partie, Wellen, Bots)
LuneMap spiegelsymmetrisch mit 16 Türmen und 2 Ancients, LuneCombat mit
reihenfolgeunabhängigem Zweiphasenschritt und Gebäudesperren für jede
Schadensquelle, LuneMatch mit Planungsentwürfen, atomarer Übernahme,
Einmal-Belohnung und Kernsieg/Unentschieden, endlose LuneWaves, Bots über
dieselbe Befehlsschnittstelle. 87 Kernprüfungen bestanden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:57:37 +02:00

69 lines
2.9 KiB
GDScript

class_name LuneBalance
extends Resource
## Every tunable number of Champions of Luneraria. The default instance lives in
## data/luneraria/balance_default.tres; tests may load variants, bots never get extras.
@export_group("Simulation")
## Fixed combat step in seconds.
@export var sim_step: float = 0.05
## Ends only the current combat phase, never the match (see REGELWERK).
@export var combat_time_limit: float = 180.0
## Lane marching speed relative to the catalogue speed of a unit.
@export var march_speed_factor: float = 1.6
@export var aggro_radius: float = 7.0
## Targets further away than this are dropped and re-acquired.
@export var leash_radius: float = 10.0
@export var lane_half_width: float = 2.6
@export_group("Economy")
@export var start_gold: int = 220
@export var base_income: int = 70
@export var income_per_round: int = 4
@export var income_growth_cap: int = 80
@export var supply_cap: int = 12
@export_range(0.0, 1.0) var sell_refund: float = 0.75
## Share of lane kill gold for the responsible lane player; the rest splits evenly in the team.
@export_range(0.0, 1.0) var lane_share: float = 0.5
@export_group("Waves")
@export var wave_base_count: int = 3
## One more monster per lane every N rounds, up to wave_max_count.
@export var wave_count_every: int = 3
@export var wave_max_count: int = 7
@export var wave_hp_growth: float = 0.11
@export var wave_damage_growth: float = 0.07
@export var wave_growth_quadratic: float = 0.0015
@export var monster_bounty_scale: float = 2.0
@export var bounty_growth: float = 0.04
## Monster types in rotation order; later indices unlock later (see LuneWaves).
@export var monster_pool: PackedStringArray = PackedStringArray(["e01", "e02", "e04", "e03", "e06", "e05"])
@export_group("Buildings")
@export var tower_outer_hp: float = 6000.0
@export var tower_inner_hp: float = 7500.0
@export var base_tower_hp: float = 9000.0
@export var core_hp: float = 12000.0
@export var tower_damage: float = 90.0
@export var base_tower_damage: float = 120.0
## Must exceed the longest unit reach (6.5 m + building radius) so towers cannot be out-ranged.
@export var tower_range: float = 8.6
@export var tower_attack_interval: float = 1.0
@export var building_radius: float = 1.3
@export var bounty_outer_tower: int = 150
@export var bounty_inner_tower: int = 210
@export var bounty_base_tower: int = 270
@export_group("Map")
## Inner / outer tower position as a fraction of the lane length from the own base.
@export var inner_tower_fraction: float = 0.17
@export var outer_tower_fraction: float = 0.35
@export var tower_side_offset: float = 3.4
static func default_balance() -> LuneBalance:
var path := "res://data/luneraria/balance_default.tres"
if ResourceLoader.exists(path):
return load(path) as LuneBalance
return LuneBalance.new()
func round_income(round_number: int) -> int:
return base_income + mini(income_growth_cap, income_per_round * maxi(0, round_number - 1))