mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-16 10:22:07 +00:00
chore(training): promote stage-4 retry2 to medium and open stage 5
20260816-2126-gen5-s4-handling-retry2 exhausted its three attempts and missed only the 0.80 training goal-rate floor, at 0.7731. Every evaluation gate passed: 65-22-13 versus promoted/easy.json, 87% non-draw against an 80% floor, 12.6% physical-side imbalance against a 20% ceiling, and both handling telemetry floors clear. The round improved the goal rate monotonically across attempts (0.537 -> 0.683 -> 0.773) and the checkpoint plays well by hand, so close Stage 4 by human override. Promote it to Game/bots/promoted/medium.json. Medium and Hard both point at the new policy: Hard stays a label-only duplicate until a stronger one earns hard.json, which keeps the tiers monotonic rather than leaving Hard weaker than Medium. generation5_state.json flips that log entry to "pass" with a decision_override block preserving the original verdict and reasoning, and advances to Stage 5 attempt 1. This is what passing_entry() needs to resolve Stage 5's resume checkpoint and evaluation reference, and what league_pool() will need at Stage 6; --skip-to-next-stage would advance the stage without marking anything as passing and die immediately. generation5.sh now pulls before launching. Each stage ends in commit_progress()'s push, which fails and kills the run hours in if the box is behind origin.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,14 +11,18 @@ extends Control
|
|||||||
|
|
||||||
const BOTS_DIR := "res://bots"
|
const BOTS_DIR := "res://bots"
|
||||||
|
|
||||||
# All three tiers deliberately point at the same promoted checkpoint at its
|
# Every tier runs its promoted checkpoint at full trained capability —
|
||||||
# full trained capability. The labels are placeholders until genuinely
|
# difficulty is a genuinely different policy, never the same policy
|
||||||
# stronger models are promoted as medium.json/hard.json; difficulty is not
|
# handicapped with reaction delay or action noise. Easy and Medium are now
|
||||||
# simulated with reaction delay or action noise in the meantime.
|
# distinct models (medium.json beats easy.json 65-22-13 head-to-head); Hard
|
||||||
|
# still points at medium.json, the strongest promoted policy, and stays a
|
||||||
|
# label-only duplicate until a stronger one earns hard.json. Keep the tiers
|
||||||
|
# monotonic: never leave a lower tier pointing at a stronger model than the
|
||||||
|
# one above it.
|
||||||
const DIFFICULTIES := [
|
const DIFFICULTIES := [
|
||||||
{"name": "Easy", "model": "res://bots/promoted/easy.json", "reaction_ticks": 8, "action_noise": 0.0},
|
{"name": "Easy", "model": "res://bots/promoted/easy.json", "reaction_ticks": 8, "action_noise": 0.0},
|
||||||
{"name": "Medium", "model": "res://bots/promoted/easy.json", "reaction_ticks": 8, "action_noise": 0.0},
|
{"name": "Medium", "model": "res://bots/promoted/medium.json", "reaction_ticks": 8, "action_noise": 0.0},
|
||||||
{"name": "Hard", "model": "res://bots/promoted/easy.json", "reaction_ticks": 8, "action_noise": 0.0},
|
{"name": "Hard", "model": "res://bots/promoted/medium.json", "reaction_ticks": 8, "action_noise": 0.0},
|
||||||
]
|
]
|
||||||
|
|
||||||
@onready var difficulty_dropdown: OptionButton = %DifficultyDropdown
|
@onready var difficulty_dropdown: OptionButton = %DifficultyDropdown
|
||||||
|
|||||||
+35
-5
@@ -164,7 +164,14 @@ flat files there, never touching subdirectories.
|
|||||||
actually referenced by the shipped game — currently `easy.json` (promoted
|
actually referenced by the shipped game — currently `easy.json` (promoted
|
||||||
2026-08-08 from generation 4's `20260806-1939-curric-s3-gauntlet`; this is
|
2026-08-08 from generation 4's `20260806-1939-curric-s3-gauntlet`; this is
|
||||||
the 320M-step MultiDiscrete policy and the foundation for the planned
|
the 320M-step MultiDiscrete policy and the foundation for the planned
|
||||||
generation-5 curriculum below) and `reference-grounded.json` (added for
|
generation-5 curriculum below), `medium.json` (promoted 2026-08-17 from
|
||||||
|
generation 5's `20260816-2126-gen5-s4-handling-retry2` — Stage 4 attempt 3,
|
||||||
|
which the pipeline recorded as a *fail* on the 80% training-goal-rate gate at
|
||||||
|
0.7731, but which beats `easy.json` 65-22-13 in the 100-episode paired
|
||||||
|
evaluation, 87% non-draw and 12.6% physical-side imbalance, both inside the
|
||||||
|
Stage-4 bars; promoted by hand on gameplay feel, so its recorded
|
||||||
|
`decision: "fail"` in `generation5_state.json` is expected and not a
|
||||||
|
bookkeeping error) and `reference-grounded.json` (added for
|
||||||
generation 4 — a copy of generation 3's `curric-s5-aggression`, made before
|
generation 4 — a copy of generation 3's `curric-s5-aggression`, made before
|
||||||
the flat `Game/bots/` dump was scrapped for the redesign, kept as the
|
the flat `Game/bots/` dump was scrapped for the redesign, kept as the
|
||||||
strongest grounded-era artifact and the fixed yardstick generations 1-3 were
|
strongest grounded-era artifact and the fixed yardstick generations 1-3 were
|
||||||
@@ -174,10 +181,12 @@ promoted file is never touched by training scripts, never overwritten by a
|
|||||||
same-named future export, and never disturbed by pruning old experiment
|
same-named future export, and never disturbed by pruning old experiment
|
||||||
files from the flat dump.
|
files from the flat dump.
|
||||||
|
|
||||||
Until distinct `medium.json` and `hard.json` policies earn promotion, the
|
Easy and Medium are now genuinely different policies. Hard still points at
|
||||||
three menu tiers all run this same `easy.json` policy at its full trained
|
`medium.json` and remains a label-only duplicate until a stronger policy earns
|
||||||
cadence (`reaction_ticks=8`, `action_noise=0`). The tiers are labels only;
|
`hard.json`. Every tier runs at full trained cadence (`reaction_ticks=8`,
|
||||||
the game does not manufacture difficulty gaps by handicapping this model.
|
`action_noise=0`) — the game does not manufacture difficulty gaps by
|
||||||
|
handicapping a model. When promoting, keep the tiers monotonic: a lower tier
|
||||||
|
must never point at a policy that beats the tier above it.
|
||||||
|
|
||||||
To promote a new bot into a tier: copy the chosen `Game/bots/<experiment>.json`
|
To promote a new bot into a tier: copy the chosen `Game/bots/<experiment>.json`
|
||||||
to `Game/bots/promoted/<tier>.json` (overwriting the old one), and note the
|
to `Game/bots/promoted/<tier>.json` (overwriting the old one), and note the
|
||||||
@@ -609,6 +618,27 @@ that fades to zero by 3m altitude. Its scoring gates deliberately run before
|
|||||||
Stage 5: becoming upright is not progress if the resulting policy stops
|
Stage 5: becoming upright is not progress if the resulting policy stops
|
||||||
finishing goals. Stage 5 adds moving high-ball intercept
|
finishing goals. Stage 5 adds moving high-ball intercept
|
||||||
starts aimed toward real goals rather than a standalone air-touch reward.
|
starts aimed toward real goals rather than a standalone air-touch reward.
|
||||||
|
|
||||||
|
**Stage 4 was closed by human override on 2026-08-17**, not by the automatic
|
||||||
|
gate. `20260816-2126-gen5-s4-handling-retry2` exhausted all three attempts and
|
||||||
|
the pipeline recorded `decision: "fail"`, on the training goal-rate floor alone
|
||||||
|
(0.7731 vs 0.80). Every other gate passed — 65-22-13 versus
|
||||||
|
`promoted/easy.json`, 87% non-draw against the 80% floor, 12.6% physical-side
|
||||||
|
imbalance against the 20% ceiling, and both handling telemetry floors clear
|
||||||
|
(`upright_fraction` 0.772 vs 0.45, `forward_motion_fraction` 0.315 vs 0.25) —
|
||||||
|
and the round's three attempts improved the training goal rate monotonically
|
||||||
|
(0.537 → 0.683 → 0.773). The same checkpoint also plays well enough by hand to
|
||||||
|
have been promoted to `medium.json`. `generation5_state.json` therefore has
|
||||||
|
that log entry's `decision` flipped to `"pass"` with a `decision_override`
|
||||||
|
block recording the original verdict and reasoning, and `stage_index`/
|
||||||
|
`attempt`/`status` advanced to Stage 5 attempt 1 — which is what
|
||||||
|
`passing_entry()` needs to resolve Stage 5's resume checkpoint and evaluation
|
||||||
|
reference, and what `league_pool()` will later need at Stage 6. Prefer this
|
||||||
|
edit over `--skip-to-next-stage`: that flag advances `stage_index` without
|
||||||
|
marking anything as passing, so the run dies immediately with `RuntimeError:
|
||||||
|
No passing generation-5 stage index 0`. Note that retry2 already clears Stage
|
||||||
|
5's own 0.75 goal-rate floor; the 0.80 Stage-4 figure was always the stricter
|
||||||
|
of the two.
|
||||||
Stage 6's `league` opponent mode samples a historical exported policy at each
|
Stage 6's `league` opponent mode samples a historical exported policy at each
|
||||||
episode reset. Each later stage preserves the preceding shaping and adds one
|
episode reset. Each later stage preserves the preceding shaping and adds one
|
||||||
new difficulty.
|
new difficulty.
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ if tmux has-session -t "$SESSION" 2>/dev/null; then
|
|||||||
exec tmux attach -t "$SESSION"
|
exec tmux attach -t "$SESSION"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Stage start and resume point both come from committed state, and each stage
|
||||||
|
# ends in commit_progress()'s `git push` — which fails, killing the run after
|
||||||
|
# hours of training, if the box is behind origin. Pull before starting, same as
|
||||||
|
# next_run.sh. Aborts here (set -e) on a dirty tree or a conflict, which is the
|
||||||
|
# point: fix it before spending the compute, not after.
|
||||||
|
git pull --rebase
|
||||||
|
|
||||||
tmux new-session -d -s "$SESSION" -n curriculum \
|
tmux new-session -d -s "$SESSION" -n curriculum \
|
||||||
".venv/bin/python generation5.py $*; echo; echo '=== generation5.py exited — press Enter to close ==='; read"
|
".venv/bin/python generation5.py $*; echo; echo '=== generation5.py exited — press Enter to close ==='; read"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"stage_index": 0,
|
"stage_index": 1,
|
||||||
"attempt": 2,
|
"attempt": 0,
|
||||||
"status": "blocked",
|
"status": "in_progress",
|
||||||
"log": [
|
"log": [
|
||||||
{
|
{
|
||||||
"stage_index": 0,
|
"stage_index": 0,
|
||||||
@@ -249,7 +249,15 @@
|
|||||||
"win_rate_a": 0.65
|
"win_rate_a": 0.65
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"decision": "fail"
|
"decision": "pass",
|
||||||
|
"decision_override": {
|
||||||
|
"date": "2026-08-17",
|
||||||
|
"original_decision": "fail",
|
||||||
|
"original_failures": [
|
||||||
|
"rollout/goal_rate=0.7731 < 0.8000"
|
||||||
|
],
|
||||||
|
"reason": "Human override. Only miss was the training goal-rate floor, at 0.7731 vs 0.80; every evaluation gate passed (65-22-13 vs promoted/easy.json, 87% non-draw, 12.6% physical-side imbalance) and the goal rate improved monotonically across all three attempts (0.537 -> 0.683 -> 0.773). Also promoted to Game/bots/promoted/medium.json on the same evidence. Stage 5 resumes from this checkpoint."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user