Files
SirStone 5e32ec16df j142 retire the ADE+SBC gun (rack id 17): the owner watched it, it does not learn, throw it away
Remove guns/bitbrain_net.nim (+README), test_bitbrain_net.nim,
measure_bitbrain_scaling.nim, rack id 17 and all of its plumbing in
selector.nim / ModularBot.nim / env_report.nim, the TR_BITBRAIN_NET switch
and the NEW-NETWORK TR_BITBRAIN_* knobs, and the BitBrainNet arm of
run_prediction_quality.nim.

With id 17 gone there is nothing to disambiguate, so the legacy namespace
becomes the ONLY one: TR_RACK_BITBRAIN always selects id 16 LEADGAIN and
every TR_BITBRAIN_<X> in the frozen 14-suffix alias set always means
TR_LEADGAIN_<X>. The alias layer and its [depr] line stay.

KEPT: the common_libs/bitbrain/ SBC library (learned_surfer imports
bitbrain/sbc), lead_gain at id 16 with env TR_LEADGAIN_* and log tag [lg],
and the c9b6753 crash fix (NumRackGuns widths + test_rack_stat_width).

Tombstone: docs/bitbrain_campaign.md ## RETIRED and one cross-reference line
in docs/gun_campaign.md. Shipped defaults unchanged: clean env -> rack
active 1v1 = PATTERN, movement default strafe.
2026-09-26 19:20:23 +02:00

141 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# lead_gain — quick recap (inputs / outputs)
Recap card. Everything below is read off `common_libs/guns/lead_gain.nim`.
## The name
This gun is **LEADGAIN** (rack id 16, `TR_LEADGAIN_*`). It used to be called
`BITBRAIN` and to live in `guns/bitbrain_gun.nim`, but the ADE+SBC network was
removed when it was rebuilt into what it actually is: **it learns a multiplier
for Pattern's lead, separately per range band.** The rack id is unchanged, and
it OWNS the `BITBRAIN` name and the `TR_BITBRAIN_*` prefix unconditionally:
the ADE+SBC gun that briefly took both (rack id 17, `guns/bitbrain_net.nim`) was
RETIRED and removed — see `docs/bitbrain_campaign.md` §RETIRED.
### Backward compatibility (read this before editing your `.env`)
The `TR_BITBRAIN_*` names your `.env` already contains still work, and still
select **this** gun. There is nothing to disambiguate any more, so the alias
layer is unconditional:
| name | meaning |
|---|---|
| `TR_BITBRAIN_<X>` (14 frozen suffixes) | always a legacy alias for `TR_LEADGAIN_<X>` |
| `TR_RACK_BITBRAIN` | always selects LEADGAIN (rack id 16) |
| `TR_BITBRAIN_NET` | **RETIRED** — no longer read; a stale value in a `.env` is an unrecognised variable and the boot report warns about it |
So the owner's existing `TR_RACK_LEADGAIN=both TR_BITBRAIN_GAINS=… TR_BITBRAIN_MEM=decay
TR_BITBRAIN_LOG=1` keeps behaving exactly as before, and one `[depr]` line on
stderr names the new `TR_LEADGAIN_*` spelling of each knob it honoured. The two
name sets are disjoint by construction, so no name is ever claimed twice.
Migrated names are `TR_LEADGAIN_GAINS`, `_MEM`, `_MIN_OBS`, `_DECAY`,
`_DECAY_FRAC`, `_LOG`, `_RESET_ON_TARGET`, `_N`, `_NADE`, `_RANGE`, `_WARMUP`,
`_ADAPT`, `_CALIB`, `_SEED` and `TR_RACK_LEADGAIN`.
## What it is today
- A **lead-gain corrector on top of Pattern's prediction**. It scales Pattern's lead over the line of sight by a learned gain.
- The **ADE/SBC neural network is REMOVED from this gun and the project**. The generic `common_libs/bitbrain/` library is intact and tested separately (`test_bitbrain.nim`, 56 checks) — `movements/learned_surfer.nim` still imports `bitbrain/sbc`, so the LIBRARY is not the gun.
## INPUTS
| Input | Source in code |
|---|---|
| World state (self pos, enemy pos, tick) | `WorldState state` |
| **Base aim** — Pattern's prediction | `g.tmh.pattern.predict(state, bulletSpeed)`: `TmHorizonGun.pattern`, a `PatternMatcherGun` (`guns/pattern_matcher`) |
| Range band (5 bands: 0/100/200/300/450) | `lgBandOf(dist)`, `LG_BAND_LO/HI` |
| **Gate** — gain applies only from band 3 up | `LG_GAIN_BAND_MIN = 3` → range **≥ ~300 px** |
| **Label / feedback** — deferred observation lookup | at fire time store lead + tolerance; `h = round(dist/speed)` ticks later `tmhObservedAt(g.tmh, state.tick, selfX, selfY)` returns the enemy's OBSERVED bearing |
| Aim tolerance (target's angular half-width) | `lgTolDeg(dist) = atan(18/range)` in degrees |
| Config knobs | env, resolved once in `initLeadGainGun` (see table) |
## OUTPUTS
| Output | Formula / meaning |
|---|---|
| Aim point | `aim = LOS + gain * (patternAim - LOS)` — applied as angular `shift = (gain - 1.0) * lead` deg via `tmhApplyShift`; when `gain == 1.0` the base prediction is returned unchanged |
| `gain` | argmax **hit rate** per band over the candidate list; `LG_CAND` default has **5 candidates** `{0.0, 0.25, 0.5, 0.75, 1.0}` (0 = HeadOn, 1 = Pattern); one candidate = fixed gain, no learning |
| `[lg]` log line (only if `TR_LEADGAIN_LOG=1`; emitted only when `(gain, band)` changes) | see below |
| Does **NOT** output | a predicted angle / bearing. It never aims on its own — it only rescales Pattern's lead. |
`[lg]` fields, one at a time:
| field | meaning |
|---|---|
| `t` | current tick |
| `band` | lower edge of the range band in use (e.g. `300+`) |
| `gain` | the gain being applied to Pattern's lead |
| `shift` | angular shift actually applied = `(gain-1)*lead`, degrees |
| `rate` | hit rate of the chosen gain in this band |
| `n` | resolved samples in this band |
| `ncand` | number of candidate gains |
| `trained` | total resolved samples this battle |
| `pend` | deferred labels still waiting |
| `dropped` | labels that could not be resolved (stale / out-of-order) |
| `mode` | memory mode: perRound / retained / decay |
## KNOB TABLE (`TR_LEADGAIN_*`)
Every old `TR_BITBRAIN_<X>` in the **LIVE** and **INERT** tables below is still
honoured as an alias, and one `[depr]` line on stderr names the `TR_LEADGAIN_*`
spelling (see "The name" above). The ADE+SBC gun uses a **different** set of
`TR_BITBRAIN_*` names (`TR_BITBRAIN_INPUT`, `_NCLASSES`, `_NADES`, …) plus
`TR_BITBRAIN_MODE` / `_DECAY_EVERY` / `_DECAY_SHIFT` from the library; the two
sets are disjoint, so nothing is claimed twice.
**LIVE** — the resolved field is read by the learner/predict path:
| Env (new / legacy alias) | Meaning |
|---|---|
| `TR_LEADGAIN_GAINS` / `TR_BITBRAIN_GAINS` | comma-separated candidate gains (replaces `LG_CAND`) |
| `TR_LEADGAIN_MEM` / `TR_BITBRAIN_MEM` | perRound / retained / decay memory |
| `TR_LEADGAIN_MIN_OBS` / `TR_BITBRAIN_MIN_OBS` | samples before a band is trusted (in `lgGainFor`) |
| `TR_LEADGAIN_DECAY` / `TR_BITBRAIN_DECAY` | decay interval in resolved samples (`resolvePending`) |
| `TR_LEADGAIN_DECAY_FRAC` / `TR_BITBRAIN_DECAY_FRAC` | per-decay shrink of the hit counts (`lgApplyDecay`) |
| `TR_LEADGAIN_LOG` / `TR_BITBRAIN_LOG` | `1` = emit the `[lg]` line |
| `TR_LEADGAIN_RESET_ON_TARGET` / `TR_BITBRAIN_RESET_ON_TARGET` | wipe learning when the enemy id changes (`targetChanged`) |
| `TR_RACK_LEADGAIN` / `TR_RACK_BITBRAIN` | the rack admission switch (the legacy name is unconditional) |
**INERT** — kept only so old configs and the boot report don't warn; never touch the gain learner:
| Env | Stored as (only read by boot report / guard test) |
|---|---|
| `TR_LEADGAIN_N` / `TR_BITBRAIN_N` | `nClasses` |
| `TR_LEADGAIN_NADE` / `TR_BITBRAIN_NADE` | `nAde` |
| `TR_LEADGAIN_RANGE` / `TR_BITBRAIN_RANGE` | `maxDeg` |
| `TR_LEADGAIN_WARMUP` / `TR_BITBRAIN_WARMUP` | `warmupN` |
| `TR_LEADGAIN_ADAPT` / `TR_BITBRAIN_ADAPT` | `adaptEvery` |
| `TR_LEADGAIN_CALIB` / `TR_BITBRAIN_CALIB` | `calibEvery` |
| `TR_LEADGAIN_SEED` / `TR_BITBRAIN_SEED` | `seed` |
## HOW TO TURN IT ON
Default is **off**; the shipped rack never calls it. Minimal `.env`:
```
TR_RACK_LEADGAIN=both
TR_RACK_PATTERN=off
TR_LEADGAIN_GAINS=1.0 # 1.0 = identity = aims EXACTLY like Pattern
TR_LEADGAIN_MEM=decay
TR_LEADGAIN_LOG=1
```
⚠️ **`TR_LEADGAIN_GAINS=1.0` is the identity** — with one candidate at 1.0 the gun aims **exactly like Pattern**.
**Do not read the candidate list as a recommendation.** Measured live: fixed gains **above** 1.0 are
*decisively harmful* (1.5 → −93.8 dmg/run, p=0.0006; 1.25 → −34.2 dmg/run), a learner restricted to **≤ 1.0**
is a **wash** (−2.5 dmg/run, p=0.87), and zero lead (= HeadOn) is **catastrophic** (14 vs 279 dmg/run).
So the default set `{0, 0.25, 0.5, 0.75, 1.0}` is **not** a recommendation either — it merely *allows* the gun
to shrink the lead toward HeadOn. Multi-candidate lists are for running the experiment, not for playing.
## MEASURED VERDICT (measured under the old `BITBRAIN` name)
- **Neutral vs Pattern** across many opponents: damage/run 214.5 vs 210.9, round wins 49.4% vs 49.8% over 32 opponents (`docs/gauntlet_bitbrain_vs_pattern.md`).
- **Specifically worse on DrussGT** alone: −18.1 damage/run (`docs/gauntlet_bitbrain_vs_pattern.md`, `docs/bitbrain_gun_verdict.md`).
- The **lead-amplitude (gain) axis is CLOSED** — nothing beats Pattern in either direction (`docs/bitbrain_campaign.md` §Phase 2 / §2.6).
## PROVENANCE
- **Derived from code (this file):** what it is today, all inputs, the output formula, the `[lg]` fields, the LIVE/INERT split, and the "how to turn it on" env lines.
- **Taken from the named evidence docs:** the numbers in MEASURED VERDICT above — see `docs/gauntlet_bitbrain_vs_pattern.md`, `docs/bitbrain_gun_verdict.md`, `docs/bitbrain_campaign.md`.