Re-run on 2026-10-16 with OpenCode (DeepSeek V4 Pro via OpenRouter) against the updated starter (scoped picture bundle, answer scrub, moveButton, key_input clocks, check_env.py). No hardcoded demo code. Cursor did not edit workspace/.
2026-10-16 · task CRztSzH8CvBF · opencode · openrouter/deepseek/deepseek-v4-pro-0813
Build a lunar-lander style game that runs smoothly in the page. A ship falls under gravity toward a green pad on the coast. I do not get a thruster for every direction. I tilt the nose left or right, and I fire one main engine that pushes the way the nose is pointing. Holding a tilt key and the engine together is how I steer. I need to touch down on the pad, slowly, and nearly upright. Landing anywhere else, landing hard, or landing tipped over is a crash and ends the round. A real landing also ends the round, as a win. Running out of time ends the round too. Burning uses fuel. Show the coast, the ocean with waves, the pad, the ship with its tilt, the flame when the engine is on, and the score. Two tilt keys and one engine key. Different starts can begin higher, faster, or off to the side. The same start should fall the same way.
Running the prompt-created workspace on this machine — not a mock. Save an episode, then open Replay below to scrub the timeline.
opening · 0 ms
Exact files the agent wrote — not rewritten by hand.
from __future__ import annotations
import math
from typing import Any, Dict, List, Tuple
from helpers import base_observation, clamp01, key_input, pick_task, rng_for, seed_from_task, task_ids
GAME_CLASS = "LunarLander"
W = 100.0
H = 100.0
COAST_X = 42.0
WATER_Y = 18.0
GROUND_Y = 24.0
PAD_LEFT = 52.0
PAD_RIGHT = 68.0
DT = 0.05
GRAVITY = 1.6
THRUST = 3.0
TILT_RATE = 1.5
MAX_TILT = 1.5
MAX_SPEED = 14.0
FUEL0 = 120.0
BURN_RATE = 9.0
TIME_LIMIT = 35.0
SAFE_SPEED = 1.4
SAFE_TILT = 0.35
STARTS: List[Tuple[str, float, float, float, float, float]] = [
("Gentle", 60.0, 82.0, 0.0, 0.0, 0.0),
("High", 60.0, 94.0, 0.0, -0.4, 0.0),
("Fast", 57.0, 88.0, 0.0, -3.0, 0.0),
("Far side", 28.0, 82.0, 0.0, 0.0, 0.0),
("Drifting", 24.0, 88.0, 1.5, -0.8, 0.10),
("Tilted", 72.0, 78.0, -0.6, -0.3, 0.40),
("High drift", 38.0, 95.0, 1.2, -2.2, -0.08),
("Deep water", 13.0, 90.0, 1.8, -0.9, -0.15),
]
FLIGHT_MOVES = ["up", "left", "right", "up left", "up right", "stay"]
class LunarLander:
def __init__(self) -> None:
self._catalog = task_ids(8, "s")
def reset(self, task_id: str = "") -> Dict[str, Any]:
picked = pick_task(task_id, self._catalog, default="s1")
if picked in self._catalog:
idx = self._catalog.index(picked)
else:
idx = seed_from_task(task_id) % len(STARTS)
name, x, y, vx, vy, theta = STARTS[idx]
self.task_id = picked
self.start = name
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.theta = theta
self.fuel = FUEL0
self.t = 0.0
self.engine_on = False
self.done = False
self.result = ""
self.score = 0.0
self.reward = 0.0
self.message = "Land slowly and upright on the green pad."
self.last_move = None
self.wave_seed = rng_for(picked).uniform(0.0, 6.283)
return self._obs()
def step(self, action: Any) -> Tuple[Dict[str, Any], bool, str]:
move = getattr(action, "move", "") or ""
self.last_move = move
if self.done:
return self._obs(), True, ""
engine, tilt = self._parse(move)
self.theta += tilt * TILT_RATE * DT
self.theta = max(-MAX_TILT, min(MAX_TILT, self.theta))
ax = 0.0
ay = 0.0
if engine and self.fuel > 0.0:
ax = THRUST * math.sin(self.theta)
ay = THRUST * math.cos(self.theta)
self.fuel -= BURN_RATE * DT
if self.fuel < 0.0:
self.fuel = 0.0
self.engine_on = engine and self.fuel > 0.0
ay -= GRAVITY
self.vx += ax * DT
self.vy += ay * DT
self.vx = max(-MAX_SPEED, min(MAX_SPEED, self.vx))
self.vy = max(-MAX_SPEED, min(MAX_SPEED, self.vy))
self.x += self.vx * DT
self.y += self.vy * DT
self.x = max(0.5, min(W - 0.5, self.x))
self.y = min(H - 0.5, self.y)
self.t += DT
surface = WATER_Y if self.x < COAST_X else GROUND_Y
if self.y <= surface:
self._land(surface)
elif self.t >= TIME_LIMIT:
self.done = True
self.result = "timeout"
self.reward = -1.0
self.score = 0.0
self.message = "Out of time — the round ended."
return self._obs(), True, ""
def _parse(self, move: str) -> Tuple[bool, int]:
parts = (move or "").strip().split()
engine = "up" in parts
tilt = 0
if "left" in parts:
tilt -= 1
if "right" in parts:
tilt += 1
return engine, tilt
def _land(self, surface: float) -> None:
self.y = surface
self.done = True
on_pad = PAD_LEFT <= self.x <= PAD_RIGHT and self.x >= COAST_X
downward = -self.vy
upright = abs(self.theta)
if on_pad and downward <= SAFE_SPEED and upright <= SAFE_TILT:
self.result = "win"
speed_q = clamp01(1.0 - max(0.0, downward) / SAFE_SPEED)
tilt_q = clamp01(1.0 - upright / SAFE_TILT)
fuel_q = self.fuel / FUEL0
quality = 0.45 * speed_q + 0.35 * tilt_q + 0.20 * fuel_q
quality = max(0.05, min(1.0, quality))
self.score = round(quality * 100.0)
self.reward = quality
self.message = "Safe landing! Score %d." % self.score
else:
self.result = "crash"
self.reward = -1.0
self.score = 0.0
if not on_pad:
if self.x < COAST_X:
self.message = "Splashed into the ocean — crashed."
else:
self.message = "Missed the pad — crashed."
elif downward > SAFE_SPEED:
self.message = "Too fast — the ship was destroyed."
else:
self.message = "Tipped over on landing — crashed."
def _obs(self) -> Dict[str, Any]:
if self.done:
moves: List[str] = []
inputs: List[Dict[str, Any]] = []
else:
moves = list(FLIGHT_MOVES)
inputs = [
key_input(
"Tilt",
"tip the nose left or right",
{
"a": "left",
"ArrowLeft": "left",
"d": "right",
"ArrowRight": "right",
},
hold=True,
every_ms=50,
idle="stay",
),
key_input(
"Engine",
"fire the main engine",
{" ": "up", "w": "up", "ArrowUp": "up"},
hold=True,
),
]
return base_observation(
reward=self.reward,
done=self.done,
legal_moves=moves,
last_move=self.last_move,
task_id=self.task_id,
start=self.start,
ship_x=round(self.x, 3),
ship_y=round(self.y, 3),
ship_vx=round(self.vx, 3),
ship_vy=round(self.vy, 3),
ship_theta=round(self.theta, 4),
engine=self.engine_on,
fuel=round(self.fuel, 1),
time_left=round(max(0.0, TIME_LIMIT - self.t), 2),
score=self.score,
message=self.message,
result=self.result,
time=round(self.t, 3),
wave_seed=round(self.wave_seed, 3),
pad={"left": PAD_LEFT, "right": PAD_RIGHT, "y": GROUND_Y},
coast={"x": COAST_X, "water_y": WATER_Y, "ground_y": GROUND_Y},
world={"w": W, "h": H},
inputs=inputs,
)