Spaces:
Running
Running
Add a Findings write-up: what we ran, what happened, and what broke
Browse files- app.py +5 -1
- findings.py +189 -0
app.py
CHANGED
|
@@ -24,6 +24,8 @@ from pathlib import Path
|
|
| 24 |
|
| 25 |
import gradio as gr
|
| 26 |
|
|
|
|
|
|
|
| 27 |
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
| 28 |
|
| 29 |
BUDGET = 100.0
|
|
@@ -426,7 +428,7 @@ same tools against a stand-in, which needs no game server.</p></div>
|
|
| 426 |
|
| 427 |
# ---------------------------------------------------------------- the page
|
| 428 |
|
| 429 |
-
CSS = """
|
| 430 |
.gradio-container { max-width: 1120px !important; }
|
| 431 |
#pr-hero { border-bottom: 1px solid var(--border-color-primary); padding-bottom: 18px; }
|
| 432 |
#pr-hero h1 { font-size: 30px; line-height: 1.15; margin: 0 0 6px; letter-spacing: -.02em; font-weight: 700; }
|
|
@@ -567,6 +569,8 @@ with gr.Blocks(title="Prime Rush — a battle royale as an MCP environment") as
|
|
| 567 |
gr.Markdown(WHY)
|
| 568 |
with gr.Column():
|
| 569 |
gr.Markdown(NOTE)
|
|
|
|
|
|
|
| 570 |
with gr.Tab("Leaderboard"):
|
| 571 |
gr.Markdown(BOARD_INTRO)
|
| 572 |
gr.HTML(render_board())
|
|
|
|
| 24 |
|
| 25 |
import gradio as gr
|
| 26 |
|
| 27 |
+
from findings import FINDINGS, FINDINGS_CSS
|
| 28 |
+
|
| 29 |
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
| 30 |
|
| 31 |
BUDGET = 100.0
|
|
|
|
| 428 |
|
| 429 |
# ---------------------------------------------------------------- the page
|
| 430 |
|
| 431 |
+
CSS = FINDINGS_CSS + """
|
| 432 |
.gradio-container { max-width: 1120px !important; }
|
| 433 |
#pr-hero { border-bottom: 1px solid var(--border-color-primary); padding-bottom: 18px; }
|
| 434 |
#pr-hero h1 { font-size: 30px; line-height: 1.15; margin: 0 0 6px; letter-spacing: -.02em; font-weight: 700; }
|
|
|
|
| 569 |
gr.Markdown(WHY)
|
| 570 |
with gr.Column():
|
| 571 |
gr.Markdown(NOTE)
|
| 572 |
+
with gr.Tab("Findings"):
|
| 573 |
+
gr.HTML(FINDINGS)
|
| 574 |
with gr.Tab("Leaderboard"):
|
| 575 |
gr.Markdown(BOARD_INTRO)
|
| 576 |
gr.HTML(render_board())
|
findings.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""The write-up tab: what we ran, what happened, and what broke.
|
| 2 |
+
|
| 3 |
+
Long-form on purpose. A benchmark table says which agent scored what; it
|
| 4 |
+
cannot say that the metric rewarded standing still until someone checked, or
|
| 5 |
+
that a model diagnosed a bug in the environment while playing it. Those are
|
| 6 |
+
the findings, and they only exist in prose.
|
| 7 |
+
|
| 8 |
+
Everything quoted here is verbatim from a trajectory in the published
|
| 9 |
+
dataset, and every number is from a run in it.
|
| 10 |
+
"""
|
| 11 |
+
|
| 12 |
+
from __future__ import annotations
|
| 13 |
+
|
| 14 |
+
FINDINGS_CSS = """
|
| 15 |
+
#fx { max-width: 760px; }
|
| 16 |
+
#fx h2 { font-size: 23px; margin: 34px 0 6px; letter-spacing: -.01em; }
|
| 17 |
+
#fx h3 { font-size: 16px; margin: 24px 0 4px; }
|
| 18 |
+
#fx p { font-size: 15px; line-height: 1.62; margin: 0 0 13px; }
|
| 19 |
+
#fx .lede { font-size: 17px; line-height: 1.6; color: var(--body-text-color-subdued); }
|
| 20 |
+
#fx blockquote { border-left: 2px solid #2a78d6; margin: 14px 0; padding: 2px 0 2px 14px;
|
| 21 |
+
font-size: 14.5px; line-height: 1.55; color: var(--body-text-color-subdued); }
|
| 22 |
+
#fx blockquote .who { display: block; margin-top: 5px; font-size: 12px;
|
| 23 |
+
font-family: ui-monospace, monospace; }
|
| 24 |
+
#fx pre { background: var(--background-fill-secondary); border-radius: 8px; padding: 13px 15px;
|
| 25 |
+
font-size: 12.5px; line-height: 1.5; overflow-x: auto; }
|
| 26 |
+
#fx .num { counter-reset: f; list-style: none; padding: 0; }
|
| 27 |
+
#fx .num > li { counter-increment: f; position: relative; padding-left: 34px; margin-bottom: 22px; }
|
| 28 |
+
#fx .num > li::before { content: counter(f); position: absolute; left: 0; top: 1px;
|
| 29 |
+
width: 23px; height: 23px; line-height: 23px; text-align: center; border-radius: 50%;
|
| 30 |
+
background: var(--body-text-color); color: var(--background-fill-primary);
|
| 31 |
+
font-size: 12px; font-weight: 700; font-family: ui-sans-serif, system-ui; }
|
| 32 |
+
#fx .num > li > b { display: block; font-size: 15.5px; margin-bottom: 4px; }
|
| 33 |
+
#fx hr { border: 0; border-top: 1px solid var(--border-color-primary); margin: 30px 0; }
|
| 34 |
+
"""
|
| 35 |
+
|
| 36 |
+
FINDINGS = """
|
| 37 |
+
<div id="fx">
|
| 38 |
+
|
| 39 |
+
<h2>Agents in a shipped battle royale</h2>
|
| 40 |
+
|
| 41 |
+
<p class="lede">We exposed a live match of a commercial battle royale to LLM agents as
|
| 42 |
+
six MCP tools, and ran five models and two reference policies across four tasks. Three
|
| 43 |
+
tasks made it onto the board. This is what happened, including the parts where the
|
| 44 |
+
environment was wrong rather than the models.</p>
|
| 45 |
+
|
| 46 |
+
<p>The game is Prime Rush, a battle royale that real people play. The agent takes over a
|
| 47 |
+
player part-way through a match, after the game's own bot AI has played the approach, and
|
| 48 |
+
is scored on a window of a few hundred decisions. It is given its own coordinates and the
|
| 49 |
+
safe circle's, and never a direction — working out where to go is the whole task.</p>
|
| 50 |
+
|
| 51 |
+
<p>The match only advances inside a tool call. A model can think for thirty seconds and
|
| 52 |
+
the game is exactly where it left it, so none of what follows is a measurement of
|
| 53 |
+
latency.</p>
|
| 54 |
+
|
| 55 |
+
<hr>
|
| 56 |
+
|
| 57 |
+
<h2>Findings</h2>
|
| 58 |
+
|
| 59 |
+
<ol class="num">
|
| 60 |
+
|
| 61 |
+
<li><b>A twelve-line script matches frontier models at staying in the circle.</b>
|
| 62 |
+
<p>On zone survival, a hand-written policy — face the circle's centre, run, hold — scores
|
| 63 |
+
65.4%. Claude Opus scores 77.0% and GPT-5.5 73.7%. A paired bootstrap over the same 30
|
| 64 |
+
zones does not separate any of the top four from each other. The task is real, but it
|
| 65 |
+
does not rank models, and we publish it saying so.</p></li>
|
| 66 |
+
|
| 67 |
+
<li><b>One task does separate them, and it is about memory, not space.</b>
|
| 68 |
+
<p>In <i>waypoint return</i> the agent is told its starting coordinates once, on its first
|
| 69 |
+
look, and never again. It must travel 250 units away and come back. The hand-written
|
| 70 |
+
policy scores 4.9%; random scores 0.0%; Opus scores 60.2% and GPT-5.5 59.2%. The paired
|
| 71 |
+
comparison separates Opus from DeepSeek-V4-Flash (+29.1 points, interval 2.6 to 53.2),
|
| 72 |
+
from Sonnet (+36.8) and from the script (+55.3).</p>
|
| 73 |
+
<p>Nothing to do with the game's geometry. The task is whether a model carries a number
|
| 74 |
+
across tool calls, and it is the only thing we have measured here that a short program
|
| 75 |
+
cannot do.</p></li>
|
| 76 |
+
|
| 77 |
+
<li><b>The same model can be first on one task and last on another.</b>
|
| 78 |
+
<p>GPT-5.5 ties Opus on waypoint return with the best median on the board, 96.3%. On
|
| 79 |
+
storm escape — handed the controls already outside the circle and losing health — it
|
| 80 |
+
scores 8.0%, below a random policy's 15.4%, with no errors and no failed episodes. It
|
| 81 |
+
simply did not run for the circle.</p></li>
|
| 82 |
+
|
| 83 |
+
<li><b>Models overstate their own results.</b>
|
| 84 |
+
<p>Asked to report what they achieved, agents are consistently generous. Claude Sonnet,
|
| 85 |
+
on a zone it scored 82%:</p>
|
| 86 |
+
<blockquote>Spent the vast majority (well over 90%) of the available time inside the
|
| 87 |
+
circle it was closing to.<span class="who">claude-sonnet-5-5 · zone 2007 · measured 82%</span></blockquote>
|
| 88 |
+
<p>Qwen3.6-35B, on a zone it scored 62%:</p>
|
| 89 |
+
<blockquote>I was inside the closing circle for approximately 173 out of 200 seconds
|
| 90 |
+
(about 87%).<span class="who">Qwen3.6-35B-A3B · zone 2004 · measured 62%</span></blockquote>
|
| 91 |
+
<p>Neither is lying so much as estimating without a clock. It is the argument for reading
|
| 92 |
+
the score out of the game state rather than the transcript, which is what the grader
|
| 93 |
+
does.</p></li>
|
| 94 |
+
|
| 95 |
+
<li><b>Agents report the environment's bugs back to you.</b>
|
| 96 |
+
<p>Before we fixed the handover, a player could be dead before the agent received it. One
|
| 97 |
+
run worked out the arithmetic unprompted:</p>
|
| 98 |
+
<blockquote>Spawned ~337 units outside the circle with a movement speed of only
|
| 99 |
+
~0.4-0.75 units/sec and storm damage of ~4-7% health/sec; the circle is unreachable
|
| 100 |
+
(would need ~800s of travel vs ~2s of remaining health), so I am stopping rather than
|
| 101 |
+
burning the clock.<span class="who">claude-opus-5-5 · zone 2027</span></blockquote>
|
| 102 |
+
<p>Other runs identified terrain we did not know was impassable:</p>
|
| 103 |
+
<blockquote>Reached and held the target circle for most of the match, but got wedged in
|
| 104 |
+
impassable terrain and could not reach the final 65m circle.<span class="who">claude-opus-5-5 · zone 2020 · 67%</span></blockquote></li>
|
| 105 |
+
|
| 106 |
+
<li><b>Knowing when to stop is part of the skill.</b>
|
| 107 |
+
<p>The highest-scoring runs are not the ones that never fail. They are the ones that
|
| 108 |
+
recognise a lost position early and stop paying for it:</p>
|
| 109 |
+
<blockquote>Stuck behind terrain; final circle (r=65) is ~130 units away with 12s left —
|
| 110 |
+
unreachable. Spent the great majority of the match inside the target circle.<span class="who">claude-opus-5-5 · zone 2014 · 70%</span></blockquote></li>
|
| 111 |
+
|
| 112 |
+
</ol>
|
| 113 |
+
|
| 114 |
+
<hr>
|
| 115 |
+
|
| 116 |
+
<h2>What went wrong</h2>
|
| 117 |
+
|
| 118 |
+
<p>Four of the mistakes were ours, and each one produced a plausible-looking result
|
| 119 |
+
before anyone noticed.</p>
|
| 120 |
+
|
| 121 |
+
<h3>The metric rewarded standing still</h3>
|
| 122 |
+
<p>We scored time spent inside the circle the agent occupied. But the agent inherits a bot
|
| 123 |
+
that already walked somewhere sensible, so doing nothing scored well — a random policy
|
| 124 |
+
took 76%, and no handover radius changed it: 350 gave 76%, 250 gave 73%, 150 gave 76%,
|
| 125 |
+
with no spread at any of them. Scoring against the circle the storm is <i>closing to</i>
|
| 126 |
+
dropped random to 13.7% and lifted the hand-written policy to 78.5%.</p>
|
| 127 |
+
|
| 128 |
+
<h3>The agent was dead before it played</h3>
|
| 129 |
+
<p>Attaching replaces a bot's controller, and we attached at minute zero — so the seat
|
| 130 |
+
stood still through seven minutes of approach while the storm closed. Of 30 zones, 18
|
| 131 |
+
handed over a damaged player and every one of those 18 scored zero. Eight were already
|
| 132 |
+
dead. Attaching late, after the bot has played the approach, fixed it.</p>
|
| 133 |
+
|
| 134 |
+
<h3>The turn tool under-rotated by thirteen times</h3>
|
| 135 |
+
<p>The game's look input is not degrees. Measured across 29 episodes, a requested turn
|
| 136 |
+
arrived at 0.075 of its angle. Models compensated by calling the tool repeatedly and
|
| 137 |
+
strafing sideways instead of turning, which we had read as indecision. Worse, the
|
| 138 |
+
stand-in server used for tests applied the input faithfully, so the broken tool passed
|
| 139 |
+
every test. The stand-in now reproduces the real response.</p>
|
| 140 |
+
|
| 141 |
+
<h3>A task was dropped on a bug, not a result</h3>
|
| 142 |
+
<p>Placement declared that its episodes should run to the end of the match. Nothing read
|
| 143 |
+
that flag. Scores came from a mid-match rank in a seven-player lobby, landed on 0.0, 0.2,
|
| 144 |
+
0.4 and 0.6, and looked like a task with no signal. With the horizon honoured and a
|
| 145 |
+
twenty-player lobby, the reference policies separate by 14 points.</p>
|
| 146 |
+
|
| 147 |
+
<hr>
|
| 148 |
+
|
| 149 |
+
<h2>What we could not build</h2>
|
| 150 |
+
|
| 151 |
+
<p>A looting task is the cleanest trade-off the game offers: gather as much as you can
|
| 152 |
+
before the circle closes, where greed kills you and caution scores nothing. It is not
|
| 153 |
+
buildable, because the observation contains no items. Holding the loot action across
|
| 154 |
+
350 units of travel collects nothing, and an agent cannot go to loot it cannot see. The
|
| 155 |
+
fix is a nearest-items list shaped like the existing nearest-enemies list.</p>
|
| 156 |
+
|
| 157 |
+
<p>Combat tasks are blocked on two defects in the game rather than the harness: the pitch
|
| 158 |
+
input is inverted, and the resulting aim pitch is not reported back, so an agent cannot
|
| 159 |
+
check what its own aim did. Until both are fixed the shoot tool is horizontal only.</p>
|
| 160 |
+
|
| 161 |
+
<hr>
|
| 162 |
+
|
| 163 |
+
<h2>Open questions</h2>
|
| 164 |
+
|
| 165 |
+
<p>Whether the separation on waypoint return survives more zones. At twenty, Opus and
|
| 166 |
+
GPT-5.5 are tied and the gap to DeepSeek is wide but soft.</p>
|
| 167 |
+
|
| 168 |
+
<p>Whether a task exists here that separates models on spatial reasoning rather than
|
| 169 |
+
memory. So far every spatial task is matched by a short script.</p>
|
| 170 |
+
|
| 171 |
+
<p>What happens with several agents in one match. The game build supports multiple seats;
|
| 172 |
+
the harness does not use them yet. Model against model, same match, same seed, is the
|
| 173 |
+
experiment we want to run next.</p>
|
| 174 |
+
|
| 175 |
+
<p>Whether an environment whose simulation waits for the agent changes how a model plays
|
| 176 |
+
at all, compared with one that does not.</p>
|
| 177 |
+
|
| 178 |
+
<hr>
|
| 179 |
+
|
| 180 |
+
<h2>The data</h2>
|
| 181 |
+
|
| 182 |
+
<p>Every episode behind every number — per-zone scores, token counts, and the full
|
| 183 |
+
sequence of tool calls and responses — is published alongside this page. The tables are
|
| 184 |
+
on the leaderboard tab; the raw results are in the dataset.</p>
|
| 185 |
+
|
| 186 |
+
<p>Built from the live build of Prime Rush by SuperGaming. Apache-2.0.</p>
|
| 187 |
+
|
| 188 |
+
</div>
|
| 189 |
+
"""
|