From fcaee000faf781cca0228908707c81694189dd34 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Wed, 8 Jul 2026 20:30:45 +0200 Subject: [PATCH] continue first full balancing round --- bin/app/data/config/modules.toml | 4 +- bin/app/data/config/ships.toml | 8 ++-- bin/balancing/data/balancing.toml | 24 +++++------ docs/content_design.md | 70 ++++++++++++++++++++++++++++--- docs/progression_design.md | 18 +++----- 5 files changed, 88 insertions(+), 36 deletions(-) diff --git a/bin/app/data/config/modules.toml b/bin/app/data/config/modules.toml index b409dab..cbcb62a 100644 --- a/bin/app/data/config/modules.toml +++ b/bin/app/data/config/modules.toml @@ -158,7 +158,7 @@ fill_color = "#808080" glyph = "A" [module.health] -added_hp = 1000 +added_hp = 1200 [[module]] @@ -222,7 +222,7 @@ fill_color = "#FF4040" glyph = "Ws" [module.weapon] -multiplied_attack_range_m = 1.5 +multiplied_attack_range_m = 1.3 multiplied_attack_rate_hz = 0.8 # ----------------------------------------------------------------------------- diff --git a/bin/app/data/config/ships.toml b/bin/app/data/config/ships.toml index 876f8a0..8349a45 100644 --- a/bin/app/data/config/ships.toml +++ b/bin/app/data/config/ships.toml @@ -179,7 +179,7 @@ materials = [{item = "battlecruiser_hull", amount = 1}] production_time_seconds = 5 [ship.health] -hp = 2700 +hp = 2200 [ship.movement] speed_mps = 20 @@ -222,7 +222,7 @@ materials = [{item = "battleship_hull", amount = 1}] production_time_seconds = 6 [ship.health] -hp = 7500 +hp = 6300 [ship.movement] speed_mps = 15 @@ -267,7 +267,7 @@ materials = [{item = "dreadnought_hull", amount = 1}] production_time_seconds = 8 [ship.health] -hp = 15500 +hp = 24000 [ship.movement] speed_mps = 10 @@ -308,7 +308,7 @@ materials = [{item = "carrier_hull", amount = 1}] production_time_seconds = 8 [ship.health] -hp = 15500 +hp = 24000 [ship.movement] speed_mps = 10 diff --git a/bin/balancing/data/balancing.toml b/bin/balancing/data/balancing.toml index 63b90ff..524bb43 100644 --- a/bin/balancing/data/balancing.toml +++ b/bin/balancing/data/balancing.toml @@ -18,7 +18,7 @@ [[arena]] name = "Mirror: drones 20v20" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -43,7 +43,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Mirror: cruisers 6v6" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -74,7 +74,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Mirror: battleships 2v2" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -111,7 +111,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Drone swarm vs cruisers (462 vs 467)" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -139,7 +139,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Frigates vs battleship (705 vs 723)" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -171,7 +171,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Destroyers vs dreadnought (1485 vs 1492)" -height_tiles = 40 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -207,7 +207,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Cruisers vs carrier (1401 vs 1437, carrier expected to lose)" -height_tiles = 40 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -240,7 +240,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Mixed mid vs battlecruisers (1394 vs 1418)" -height_tiles = 40 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -285,7 +285,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Two to one (must be decisive)" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -314,7 +314,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Armored vs glass destroyers (1188 vs 1196)" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -350,7 +350,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Repair escort vs raw numbers (444 vs 444)" -height_tiles = 30 +height_tiles = 10 player_buffer_width_tiles = 10 contest_zone_width_tiles = 50 enemy_buffer_width_tiles = 10 @@ -391,7 +391,7 @@ enemy_buffer_width_tiles = 10 [[arena]] name = "Station assault (2 stations + 105 vs 315)" -height_tiles = 60 +height_tiles = 10 player_buffer_width_tiles = 15 contest_zone_width_tiles = 40 enemy_buffer_width_tiles = 15 diff --git a/docs/content_design.md b/docs/content_design.md index 80533df..f72b8d7 100644 --- a/docs/content_design.md +++ b/docs/content_design.md @@ -455,14 +455,21 @@ verifies it empirically. Change the anchors first, re-derive stats second. survivability, range, no losses-to-attrition of own DPS) is worth paying for, so bigger guns get less raw DPS per threat. - **Hull HP = 15 per threat of hull contribution** (incl. ship base - time): drone 60, frigate 300, destroyer 550, cruiser 1500, - battlecruiser 2700, battleship 7500, dreadnought/carrier 15500. -- **Armor HP ≈ 31 per threat** — a strong premium over hull HP (15) + time) as the *prior*; per-hull HP is the empirical trim knob for + arena results (guns are shared across many hulls, so gun changes move + many matchups at once — hull HP moves exactly one). Current values + after round-4 trims: drone 60, frigate 300, destroyer 550, + cruiser 1500, battlecruiser 2200, battleship 6300, + dreadnought/carrier 24000. (The capital hulls sit well above the + 15/threat prior while their guns sit below the DPS prior — the arena + consistently prices big ships as tanks with taxed guns.) +- **Armor HP ≈ 37 per threat** — a strong premium over hull HP (15) because armor is pure HP with no capability, and fights snowball: killing enemies removes their DPS, while surviving merely delays — so a point of HP must be cheaper than a point of DPS. - armor_plates adds 1000 HP at 32 threat (arena round 1: at 640 the - all-guns destroyer beat the armored one). + armor_plates adds 1200 HP at 32 threat (raised from 640 → 1000 → + 1200: the all-guns destroyer beat the armored one in three + consecutive arena rounds). - **TTK check:** a mirror cruiser duel (51 DPS vs 2140 EHP) lasts ~42 s — inside the 30–60 s parity-fight band implied by the 25-ship fleet target. Capital mirrors run longer (~90 s), deliberately. @@ -482,7 +489,10 @@ verifies it empirically. Change the anchors first, re-derive stats second. - **Weapon modifiers are capital economy:** ×1.2 damage at 22.5 threat beats adding a gun once a ship carries more than ~68 threat of weapons — so modifiers pay off on gun-heavy big hulls and are a waste on small - ones. Kept at ×1.2/×1.2/(×1.5 range, ×0.8 rate) deliberately. + ones. Damage/rate kept at ×1.2; the stabilizer's range multiplier was + cut ×1.5 → ×1.3 after round 2 — range is the strongest stat in the + orbit-AI's hands (free approach fire), and the stabilized battleship + was the one loadout still overperforming. - **Stations:** a fresh player station (3000 HP, 25 dmg × 1 Hz, range 120) holds one early parity wave unaided; the enemy station at level 0 matches it exactly and scales per push level @@ -507,6 +517,54 @@ DPS (17→14, 70→52 damage), armor 640→1000, repair 25→12, station range still win flawlessly in round 2, the range ladder (kiting) is the next suspect, ahead of further DPS cuts. +**Arena round 4 results (2026-07-04) and convergence policy:** mirrors +at 0–3%; swarm vs cruisers +7%; glass vs armored resolved at +3% for +armored (armor 1200 confirmed after four rounds of signal). Noise +floor established: the battleship held +23% straight through a −10% +EHP cut, and repair drifted 14→24% with no repair changes — single-run +margins move ~±10% on a re-roll. Policy from here: only act on signals +that persist two rounds; treat anything inside ±20% as converged for +v1 (real-game playtests refine further). Armor-coupling overshoots +corrected in round 5: battlecruiser 2000→2200, dreadnought/carrier +22500→24000 (two-round persistent deficit vs destroyers). **Accepted, +not chased:** the stabilized battleship beats a pure frigate fleet by +~23% — the edge survived a stat cut, so it is mechanical (range), and +"the extreme smallest-ship fleet modestly loses to a range-fitted +capital" is desirable doctrine texture; the fair anti-capital answer +is the mixed fleet, whose arena is balanced. + +**Arena round 3 results (2026-07-04, narrow lanes):** arenas were +narrowed (height 10) so fleets can no longer pass each other — arena +geometry is part of the fixture from here on; margins are only +comparable within the same geometry. Results: mirrors healthy (1–7%); +dreadnought closed to −11%; battleship improved to +22% (still over); +drone swarm now beats cruisers by 14% (full engagement in the narrow +lane favors numbers); mixed vs battlecruisers +18%; glass beat armored +for the third consecutive round (+12%); repair 14%, two-to-one 78%, +station set cracked at 51% by the 3× swarm (geometry changed under the +stations — watch before touching stats). Round-4 knob changes: +armor_plates 1000→1200 (the persistent glass signal; also lifts the +armor-carrying cruiser/BC/destroyer/DN loadouts), battlecruiser hull +2500→2000 (net −300 EHP after its armor gain), battleship 7000→6300 +(no armor in its loadout, clean −10%), dreadnought/carrier +19000→22500 (the opposing destroyers gain armor too, so the DN needs +the larger step). + +**Arena round 2 results (2026-07-04, with EHP-margin logging):** the +mirror "bias" was noise — repeated runs split randomly, and winners +finish at 5–7% EHP (near-mutual annihilation, healthy). Drones vs +cruisers 10% and mixed vs battlecruisers 14% — near parity. The two +capital fights diverged: battleship beat frigates at +33% while the +dreadnought lost to destroyers at −37% — same guns, so the difference +is the destroyers carrying the buffed armor plus the battleship's +stabilizer putting all its guns at 75–150 m against 50 m opponents. +Glass vs armored narrowed to 11% (watch; if it persists, armor +1000→1200). Repair escort 11% — fair. Two-to-one decisive at 80%; +station assault cracked by the 3× swarm at 13% (stations strong but +breakable). Round-3 knob changes: stabilizer range ×1.5→×1.3, and +per-hull HP trims — battlecruiser 2700→2500, battleship 7500→7000, +dreadnought/carrier 15500→19000. + ## Balancing targets (first pass, July 2026) The six root numbers for the balancing pass. Every derived value (threat diff --git a/docs/progression_design.md b/docs/progression_design.md index 564f941..e6f755d 100644 --- a/docs/progression_design.md +++ b/docs/progression_design.md @@ -373,15 +373,9 @@ in `requirements.md` and the git history). Still open: one matching deposit tile). Touches REQ-BLD-MINER ("every asteroid tile is equivalent" no longer holds), REQ-GW-ASTEROID-EXPAND / REQ-EXP-*, `world.toml`, and `visuals.toml`. -6. **Investigate team-1 bias in balancing arenas.** In arena round 1 - (July 2026), team 1 won all three mirror matches with large margins - (8/20, 3/6, 1/2 survivors). Re-run mirrors repeatedly; if team 1 - wins consistently, find and fix the asymmetry (spawn geometry, tick - processing order, target-selection tie-breaking). Mirror matches - must be statistically symmetric or every arena result carries a - side-dependent error. -7. **Log remaining HP in the balancing arena results.** Win/loss alone - hides the margin ("1/1 battleship" can mean 95% or 5% HP left). Add - the surviving entities' remaining HP fraction (or a per-team total - EHP percentage) to the arena end state, so equal-threat matchups can - be tuned toward near-draws quantitatively. +6. **Verify the balancing arena end condition.** Arena round 1's + station-assault log showed the arena "(running)" with every ship on + both sides destroyed — per REQ-BAL-SIM-END the station-less team + should have lost the moment its last ship died. Round 2 ended + correctly, so it may only be a log-snapshot artifact; confirm, and + fix the end condition if it can genuinely idle in that state.