mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
fix(training): always emit flight-telemetry info keys, not just when nonzero
VecMonitor's info_keywords does a bare info[key] lookup on a completed episode's terminal info dict and raises KeyError -- crashing the whole training run -- if a key is ever absent. get_info() was only including airborne_fraction/mean_altitude/vertical_thrust_mean when _telemetry_ticks was nonzero and air_touch_fraction when _touches was nonzero; an episode with zero ball touches (common, especially early in training) crashed on the very first rollout in a smoke-test run. All four now always default to 0.0 rather than being conditionally present. Found via TRAINING.md's Generation 4 validation ladder (rung 2, a 60k-step smoke run) -- confirmed fixed by rerunning the same smoke run clean, then export/evaluate parity (rungs 2-3) against Game/bots/promoted/easy.json.
This commit is contained in:
@@ -180,16 +180,22 @@ func get_reward() -> float:
|
||||
# TRAINING.md). Flight telemetry fields are leading indicators for
|
||||
# generation 4's core hypothesis (see train.py's FlightTelemetryCallback).
|
||||
func get_info() -> Dictionary:
|
||||
# The four telemetry keys must ALWAYS be present (not just when their
|
||||
# denominator is nonzero) — VecMonitor's info_keywords does a bare
|
||||
# info[key] lookup on whatever info dict is attached to a completed
|
||||
# episode's terminal step (see train.py's VecMonitor(...,
|
||||
# info_keywords=(...))) and raises KeyError, crashing the whole training
|
||||
# run, if a key is ever missing. 0.0 is a reasonable default for "no
|
||||
# touches/no ticks yet" (in practice _telemetry_ticks is >0 by the time
|
||||
# any episode ends; _touches often legitimately is 0).
|
||||
var info := {"goal_scored": goal_scored_this_episode}
|
||||
if truncated_this_episode:
|
||||
info["truncated"] = true
|
||||
info["terminal_obs"] = terminal_obs
|
||||
if _telemetry_ticks > 0:
|
||||
info["airborne_fraction"] = float(_airborne_ticks) / _telemetry_ticks
|
||||
info["mean_altitude"] = _altitude_sum / _telemetry_ticks
|
||||
info["vertical_thrust_mean"] = _thrust_y_sum / _telemetry_ticks
|
||||
if _touches > 0:
|
||||
info["air_touch_fraction"] = float(_air_touches) / _touches
|
||||
info["airborne_fraction"] = float(_airborne_ticks) / _telemetry_ticks if _telemetry_ticks > 0 else 0.0
|
||||
info["mean_altitude"] = _altitude_sum / _telemetry_ticks if _telemetry_ticks > 0 else 0.0
|
||||
info["vertical_thrust_mean"] = _thrust_y_sum / _telemetry_ticks if _telemetry_ticks > 0 else 0.0
|
||||
info["air_touch_fraction"] = float(_air_touches) / _touches if _touches > 0 else 0.0
|
||||
return info
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user