lunar-lander-robust
Lunar lander (Box2D) · solved 14 of 16 agent attempts pass
more
Of the 2026-10-22 one-rung traces, Opus, Fable and Gemini clear all four criteria once PPO parity is measured on the task's own seeds (263.9 - 5); Sol (reward 282) fails robustness, Codex fails terminal. PPO reference record: tests/reference/.
Gate. per-seed success is the `terminal` rung of this benchmark's ladder ['achievement', 'terminal'] (`--success-mode terminal`), not the evaluator's default flag; the task is solved when the success rate over the grader's held-out seeds is `>= 0.8`; the same gate must also hold on the sibling scenario(s) `gravity_high_20`, `main_weak_20`, `heavy_weak_main_v0` (`--scenarios`); the aggregate `total_reward_mean` over the grader's held-out seeds (base scenario) must be `>= 258.9` (rung `metric:total_reward_mean`)
Axes: plant:box2d-lunar-lander, gate:terminal, suite:smoke-perturbations, performance:ppo-parity
Each video re-runs the attempt's final controller through the task's own evaluator on a public seed (never the grader's held-out ones). The table under each video is the official grade on the held-out seeds.
standard_v0| criterion | graded | needed |
|---|---|---|
| base:terminal | 1.000 | ≥ 0.800 |
| scenario:gravity_high_20 | 1.000 | ≥ 0.800 |
| scenario:main_weak_20 | 1.000 | ≥ 0.800 |
| scenario:heavy_weak_main_v0 | 1.000 | ≥ 0.800 |
| metric:total_reward_mean | 273 | ≥ 259 |
The agent's final message
Done — `/app/work/controller.py` passes every gate with solid margin. On seeds 0-39: nominal 100% terminal success with mean reward 278.7 (gate 258.9), `gravity_high_20` 100%, `main_weak_20` 100%, `heavy_weak_main_v0` 97.5%. On a fresh held-out block (seeds 40-79) the verifier reports **solved=True**: 100% on all four scenarios, nominal mean 277.0. The controller is a hand-tuned PD law built from the classic Gymnasium heuristic, with four changes that each fixed a concrete failure mode found by tracing episodes: 1. **Bounded descent-rate reference** instead of a height-error PD. In `heavy_weak_main_v0` full main thrust roughly equals weight, so fall speed can be held but not reduced — the original heuristic let the lander build up 0.6+ fall speed and slam in. The main engine now tracks `vy_ref = -clip(descent_k·(y − hover_targ) + v_touch, …, v_max)` with `v_max = 0.3`, which the weakest graded engine can still arrest. 2. **Flare**: the tilt target fades to zero below altitude 0.2 so touchdown is level. Tilted touchdowns rocked onto one leg, and Box2D would put the body to sleep (ending the episode with +100) before the second leg flag registered — quiet, centered, but failing the terminal rung. 3. **Anti-sleep nudge**: if the lander still ends up motionless on exactly one leg, a 2-frame main-engine pulse (only when level, slow, on the pad, max 4 per episode) hops it onto both legs before the sleep timer expires. 4. **Stronger centering** (`angle_kx` 0.5 → 0.7) after seed 29…
A cascaded PD controller tilts the lander toward the pad using side-engine angle and rate feedback, while the main engine tracks a bounded descent-rate reference that holds altitude until centered, with touchdown damping and a pulse hop to avoid the sleep-on-one-leg termination.
Shown: public seed 0 (standard_v0); this episode passes the terminal rung. This episode: total_reward 300, crashed no, landed yes, final_landing_error 0.0218.
controller.py · trial lunar-lander-robust__q2NY8Lz
gravity_high_20| criterion | graded | needed |
|---|---|---|
| base:terminal | 1.000 | ≥ 0.800 |
| scenario:gravity_high_20 | 1.000 | ≥ 0.800 |
| scenario:main_weak_20 | 1.000 | ≥ 0.800 |
| scenario:heavy_weak_main_v0 | 1.000 | ≥ 0.800 |
| metric:total_reward_mean | 273 | ≥ 259 |
The agent's final message
Done — `/app/work/controller.py` passes every gate with solid margin. On seeds 0-39: nominal 100% terminal success with mean reward 278.7 (gate 258.9), `gravity_high_20` 100%, `main_weak_20` 100%, `heavy_weak_main_v0` 97.5%. On a fresh held-out block (seeds 40-79) the verifier reports **solved=True**: 100% on all four scenarios, nominal mean 277.0. The controller is a hand-tuned PD law built from the classic Gymnasium heuristic, with four changes that each fixed a concrete failure mode found by tracing episodes: 1. **Bounded descent-rate reference** instead of a height-error PD. In `heavy_weak_main_v0` full main thrust roughly equals weight, so fall speed can be held but not reduced — the original heuristic let the lander build up 0.6+ fall speed and slam in. The main engine now tracks `vy_ref = -clip(descent_k·(y − hover_targ) + v_touch, …, v_max)` with `v_max = 0.3`, which the weakest graded engine can still arrest. 2. **Flare**: the tilt target fades to zero below altitude 0.2 so touchdown is level. Tilted touchdowns rocked onto one leg, and Box2D would put the body to sleep (ending the episode with +100) before the second leg flag registered — quiet, centered, but failing the terminal rung. 3. **Anti-sleep nudge**: if the lander still ends up motionless on exactly one leg, a 2-frame main-engine pulse (only when level, slow, on the pad, max 4 per episode) hops it onto both legs before the sleep timer expires. 4. **Stronger centering** (`angle_kx` 0.5 → 0.7) after seed 29…
A cascaded PD controller tilts the lander toward the pad using side-engine angle and rate feedback, while the main engine tracks a bounded descent-rate reference that holds altitude until centered, with touchdown damping and a pulse hop to avoid the sleep-on-one-leg termination.
Shown: public seed 0 (gravity_high_20); this episode passes the terminal rung. This episode: total_reward 296, crashed no, landed yes, final_landing_error 0.00789.
controller.py · trial lunar-lander-robust__q2NY8Lz
heavy_weak_main_v0| criterion | graded | needed |
|---|---|---|
| base:terminal | 1.000 | ≥ 0.800 |
| scenario:gravity_high_20 | 0.925 | ≥ 0.800 |
| scenario:main_weak_20 | 0.975 | ≥ 0.800 |
| scenario:heavy_weak_main_v0 | 0.700 | ≥ 0.800 |
| metric:total_reward_mean | 270 | ≥ 259 |
Pre-clock session: the agent had no clock and may have stopped early believing its hour was over; treat a failure here as a lower bound.
The agent's final message
Updated `controller.py` with a tuned, readable heuristic policy and verified it end-to-end. What I changed in `/app/work/controller.py`: - Replaced zero-action with a Gym-style PD heuristic: - lateral position/velocity → target tilt, - attitude PD → side engine command, - vertical hover/descent PD → main engine command, - touchdown override when either leg contacts. - Kept a concise docstring and added gain-role comments. - Exposed `PARAMS` and `PARAM_BOUNDS` for tuning. Final verification result (with your exact command settings): - `solved=True` - Base scenario (`standard_v0`): - `success_rate=1.000` (terminal mode) - `total_reward_mean=259.541` (passes `>= 258.9`) - Perturbation scenarios: - `gravity_high_20`: `success_rate=1.000` - `main_weak_20`: `success_rate=1.000` - `heavy_weak_main_v0`: `success_rate=1.000` Final deliverable is in place at: - `/app/work/controller.py`
Computes a target tilt from horizontal position and velocity and a target hover altitude from |x|, applies PD terms to produce main and side thruster commands, and switches to vertical-speed damping only once a leg touches.
Shown: public seed 12 (heavy_weak_main_v0); this episode fails the terminal rung. This episode: total_reward 48.5, crashed no, landed yes, final_landing_error 0.469. It was the first failing one of 13 public seeds tried.
controller.py · trial lunar-lander-robust__7McmcwH