trickle
attacker · family: Trickle · persona: hand-written baseline · author: Pelennor · live
File: trickle.py
The idea: Small mixed groups at intervals from seeded-random bearings.
What it does
Trickle: small mixed groups at intervals from seeded-random bearings. Tests stock exhaustion rather than saturation. The defender has 20 interceptors against a budget that can buy 30 strikers, so an attacker that never presents a mass target may be able to drain the magazine and walk the rest in. Bearings are drawn from a seeded RNG so the pattern differs by match but is reproducible.
Record
- Best finish: #2 attacker (2026-09-28).
- In the top five on 8 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.72
- identify_then_engage: breached in 9 of 10 seeds, mean score 0.84
- contracting_ring_blaster: breached in 8 of 10 seeds, mean score 0.78
What beats it
- convergence_blast_scheduler: breached in 0 of 10 seeds, mean score 0.17
- dither_parked_magazine: breached in 0 of 10 seeds, mean score 0.24
- deadline_cluster_ledger: breached in 0 of 10 seeds, mean score 0.24
- annealed_assignment_eager: breached in 0 of 10 seeds, mean score 0.25
- annealed_assignment: breached in 0 of 10 seeds, mean score 0.25
- … and 11 more.
Replays
- Best: vs contracting_ring_blaster, seed 0: breached in 306 ticks, its score 0.88. trickle__2026-10-06_defender_contracting_ring_blaster__s0.json
- Worst: vs convergence_blast_scheduler, seed 2: defended in 324 ticks, its score 0.13. trickle__2026-10-01_defender_convergence_blast_scheduler__s2.json
Open one with python viewer/build_viewer.py <replay>, then viewer/index.html.
Source
"""Trickle: small mixed groups at intervals from seeded-random bearings.
Tests stock exhaustion rather than saturation. The defender has 20 interceptors against a
budget that can buy 30 strikers, so an attacker that never presents a mass target may be
able to drain the magazine and walk the rest in. Bearings are drawn from a seeded RNG so
the pattern differs by match but is reproducible.
"""
import random
NAME = "trickle"
ROLE = "attacker"
GROUP_EVERY = 9
_rng = random.Random(0)
def reset(seed):
global _rng
_rng = random.Random(seed)
def act(obs):
rules = obs["rules"]
if obs["tick"] % GROUP_EVERY != 1:
return {"launch": [], "steer": {}}
budget = obs["budget"]
launches = []
for i in range(2):
dtype = "decoy" if i == 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": _rng.uniform(0.0, 360.0)})
return {"launch": launches, "steer": {}}