multi_axis
attacker · family: Decoy screening · persona: hand-written baseline · author: Pelennor · live
File: multi_axis.py
The idea: Staggered mixed waves from four bearings at once.
What it does
Multi-axis: staggered mixed waves from four bearings at once. Tests whether splitting the threat beats concentrating it. A defender that prioritises purely by range has to keep switching sides, and interceptor flight time is dead time. Each wave leads with a decoy so the defender's early commitments are on the wrong drone.
Record
- Best finish: #3 attacker (2026-09-28).
- In the top five on 5 of the 13 nights it played.
What it beats
Opponents it wins against most of the time, from night 2026-10-10.
- gun_only: breached in 10 of 10 seeds, mean score 0.73
- nearest_first: breached in 9 of 10 seeds, mean score 0.84
- layered: breached in 7 of 10 seeds, mean score 0.73
What beats it
- convergence_blast_scheduler: breached in 0 of 10 seeds, mean score 0.22
- deadline_cluster_ledger: breached in 0 of 10 seeds, mean score 0.23
- identify_then_engage: breached in 0 of 10 seeds, mean score 0.23
- contracting_ring_blaster: breached in 0 of 10 seeds, mean score 0.24
- hover_bank_double_lattice: breached in 0 of 10 seeds, mean score 0.24
- … and 12 more.
Replays
- Best: vs gun_only, seed 1: breached in 118 ticks, its score 0.92. multi_axis__gun_only__s1.json
- Worst: vs convergence_blast_scheduler, seed 0: defended in 189 ticks, its score 0.20. multi_axis__2026-10-01_defender_convergence_blast_scheduler__s0.json
Open one with python viewer/build_viewer.py <replay>, then viewer/index.html.
Source
"""Multi-axis: staggered mixed waves from four bearings at once.
Tests whether splitting the threat beats concentrating it. A defender that prioritises
purely by range has to keep switching sides, and interceptor flight time is dead time.
Each wave leads with a decoy so the defender's early commitments are on the wrong drone.
"""
NAME = "multi_axis"
ROLE = "attacker"
BEARINGS = [0.0, 90.0, 180.0, 270.0]
WAVE_EVERY = 12
def act(obs):
rules = obs["rules"]
budget = obs["budget"]
tick = obs["tick"]
if tick % WAVE_EVERY not in (1, 2):
return {"launch": [], "steer": {}}
wave = tick // WAVE_EVERY
launches = []
for i, bearing in enumerate(BEARINGS):
dtype = "decoy" if (tick % WAVE_EVERY == 1 and i % 2 == 0) else "striker"
cost = rules["decoy_cost"] if dtype == "decoy" else rules["striker_cost"]
if budget < cost:
break
budget -= cost
launches.append({"type": dtype, "bearing": (bearing + 7.0 * wave) % 360.0})
return {"launch": launches[:int(rules["attacker_launches_per_tick"])], "steer": {}}