decoy_screen
attacker · family: Decoy screening · persona: hand-written baseline · author: Pelennor · live
File: decoy_screen.py
The idea: A wall of decoys first, strikers following behind it.
What it does
Decoy screen: a wall of decoys first, strikers following behind it. Tests whether cheap drones can absorb interceptors. Decoys and strikers move at the same speed, so before the identification range the defender cannot tell them apart -- the screen is only wasted if the defender waits until 150 u to commit.
Record
- Best finish: #5 attacker (2026-09-28).
- In the top five on 1 of the 13 nights it played.
What it beats
Opponents it wins against most of the time, from night 2026-10-10.
- nearest_first: breached in 10 of 10 seeds, mean score 0.89
- gun_only: breached in 10 of 10 seeds, mean score 0.77
What beats it
- convergence_blast_scheduler: breached in 0 of 10 seeds, mean score 0.14
- deadline_cluster_ledger: breached in 0 of 10 seeds, mean score 0.16
- layered: breached in 0 of 10 seeds, mean score 0.20
- backscheduled_blast_packer: breached in 0 of 10 seeds, mean score 0.20
- annealed_assignment: breached in 0 of 10 seeds, mean score 0.21
- … and 13 more.
Replays
- Best: vs nearest_first, seed 9: breached in 123 ticks, its score 0.91. decoy_screen__nearest_first__s9.json
- Worst: vs convergence_blast_scheduler, seed 4: defended in 119 ticks, its score 0.11. decoy_screen__2026-10-01_defender_convergence_blast_scheduler__s4.json
Open one with python viewer/build_viewer.py <replay>, then viewer/index.html.
Source
"""Decoy screen: a wall of decoys first, strikers following behind it.
Tests whether cheap drones can absorb interceptors. Decoys and strikers move at the same
speed, so before the identification range the defender cannot tell them apart -- the
screen is only wasted if the defender waits until 150 u to commit.
"""
NAME = "decoy_screen"
ROLE = "attacker"
BEARING = 45.0
SCREEN_TICKS = 4
def act(obs):
rules = obs["rules"]
budget = obs["budget"]
per_tick = int(rules["attacker_launches_per_tick"])
if obs["tick"] <= SCREEN_TICKS:
dtype, cost = "decoy", rules["decoy_cost"]
else:
dtype, cost = "striker", rules["striker_cost"]
n = min(per_tick, int(budget // cost))
spread = [-6.0, -2.0, 2.0, 6.0]
return {"launch": [{"type": dtype, "bearing": BEARING + spread[i % len(spread)]}
for i in range(n)],
"steer": {}}