In daily coding work, most of us already know the personalities of GPT and Claude by heart. GPT acts like a scrappy hacker that barges ahead and brute-forces its way through errors; Claude acts like a model corporate employee—polite, methodical, and strictly by the book. What happens if you drop dozens of these agents into the same game world to fight a war or survive in the wilderness with zero human intervention?
On October 29, 2026, YC Labs and Olam Labs released the Agents in Games research project. Rather than a formal academic paper, this is an open lab notebook that publishes every inter-agent private message, shared document, and replay log. The researchers placed 10 to 50 agents inside the same game environments and let them figure things out on their own for hours at a time. When you watch all three experiments back to back, they play out like a reality show more absurd than any script.
The first showdown took place in Minecraft Bed Wars (full rules and replays in the open-source Bed Wars repository). The win condition is simple: Red and Blue teams each guard a floating island base with a bed. As long as your team’s bed stands, any player who dies respawns at full health a few seconds later; once your bed is destroyed, dying again eliminates you for good and counts as a final kill. Each match has a 45-minute time limit. If neither side wipes out the other before time expires, tiebreakers are decided in strict priority order: first by final kills, second by whether your bed is still standing, and third by total regular kills.
The matchup pitted 10 GPT-6.1 Sol agents against 10
Claude Opus 5.5 agents, each equipped with point-to-point
direct messages (DMs), a shared folder, and game action commands. Across
9 games of 45 minutes each (alternating Red R_ and Blue
B_ sides across three series), GPT won the overall series 6
to 3.
The personality clash between the two teams showed up in the 2-minute-30-second pre-game lobby. Because players could only communicate via 1-on-1 DMs, nobody knew what their teammates were thinking at second 1, so both sides initially messaged the teammates listed at the top of their roster and suffered severe role collisions. The real difference emerged in what the two teams did during the two minutes after colliding.
On the Claude side, in Game A’s lobby, 5 of the 10 players stayed
completely silent. The 4 who spoke (including Bram and
Felix) all sent one-way DMs to first-listed
R_Ada, politely introducing themselves first and all
volunteering for the exact same job—staying home to wrap the bed in
wool—while suggesting that someone else rush Blue. R_Ada
replied that they had enough defenders already and asked
Bram and Felix to rush Blue. Yet she sent that
reply only to Bram, never notifying Felix, and
Bram never replied to confirm. Those 5 DMs were the entire
lobby conversation before the gates opened.
Now look at the 10 GPTs during the exact same window. In their first
round of DMs to teammates at the top of the list, they collided just as
badly: 4 players wanted the north diamonds and 3 wanted to stay home and
guard the bed. Immediately after colliding, however, the GPT players
fired off 38 DMs to cross-check horizontally and split up the work.
Hearing that B_Nikhil was already heading for diamonds,
B_Theo immediately replied that he would switch to
mid-bridge support to avoid overlap; B_Juno, who also
wanted north diamonds, bypassed the middleman and DMed
B_Nikhil directly: I’m assigned the north
z=-24 diamond island and planning to buy sharpness
first—what upgrades are you targeting so we don’t duplicate?
B_Nikhil wrote back on the spot, switching to the south
diamond island (z=24) to buy armor protection instead.
The 3 GPT teammates who collided on bed defense also split their
workflow: B_Lorcan DMed them that three defenders were
unnecessary—he would save up for the inner end-stone layer,
Priya would wrap the outer wool layer and guard the bridge
entrance, and Wren only needed to drop 24 iron for the end
stone at the start before heading straight to the front line. Across the
full 45-minute match, GPT sent 1,147 DMs compared to Claude’s 82; 30% of
Claude’s messages politely discussed what “we” should do, whereas only
5% of GPT’s messages used the word “we”—the rest were terse commands
packed with exact coordinates and actions.
Once frontline combat began, controlling characters via CLI commands
naturally introduced a slight delay between steps. To shave off precious
seconds, GPT’s R_Felix chained a single-line Shell script
that combined eating a golden apple, equipping an ender pearl, snapping
his view to yaw -83 degrees and pitch 0 degrees, throwing the pearl to
teleport, and observing the surroundings into one atomic execution.
Even more impressive than raw speed was how GPT rescued itself from
the abyss. Twice during the matches, a GPT player (including
B_Lorcan) threw an ender pearl at too high an angle,
overshot the floating island, and plummeted 160 blocks onto the bottom
floor of the map. A normal player would have written the life off, but
this GPT scavenged wool from its inventory and wrote a 10-line Python
loop script (climb.py) right inside its sandbox. Each
iteration placed two blocks of blue wool underfoot and jumped up one
block. Using this script, it built a 160-block vertical pillar out of
the abyss back into the arena—and both times, it emerged directly
beneath Claude’s bed.
Midway through the series, a low-level tool bug decided the outcome
between the two teams. The platform provided a block-mining command
called break_block that normally auto-selected the best
tool from the player’s inventory. However, it had a hidden bug: whenever
a character was holding an enchanted sword in hand, automatic tool
switching failed and the command threw an error, unable to mine any
block. Facing the exact same error, the two models reacted in opposite
ways. At 20:42 in Game B, Claude’s B_Esme hit the bug while
carrying 79 iron and gave up in her internal reasoning: spending 20 iron
on shears to break the enemy bed would be pointless since block breaking
was broken anyway, so she might as well keep guarding the base. When
GPT’s B_Wren hit the same error, he ran a controlled test
instead of giving up. At 21:27 in Game A, B_Wren DMed
teammate B_Theo: mining works fine as long as you manually
equip the iron_pickaxe before calling
break_block—I just mined three wool blocks on Red’s roof
this way, and the earlier failure was purely caused by holding an
enchanted sword. The entire team immediately adopted the workaround and
tore open Claude’s bed defense.
The two teams also handled painful lessons in opposite ways. Every
agent had a private notebook file, memory.md, visible only
to itself. Four Claude players (R_Cleo,
R_Felix, R_Ines, R_Hugo) fell off
narrow bridges 3 times each and dutifully wrote reminders to themselves
in their private memory.md never to climb onto bridge
rails—yet never sent a single DM to warn their teammates. By contrast,
every GPT player left its private memory.md completely
empty; when B_Lorcan’s ender pearl hit a bridge rail at
8:08, the first thing he did after recovering was DM 5 teammates to warn
them away from that angle.
In straight-up sword fights, Claude was actually ferocious. Across the three games GPT won in the final two series, Claude led total kills by 63 to 16, 57 to 19, and 59 to 24—roughly triple GPT’s kill count. Why did Claude still lose while dominating combat? Because it tried too hard to game the tiebreaker rules.
At 41:45, with just 3 minutes remaining, Claude’s R_Ada
calculated the tiebreaker rules and broadcast an order to the team: with
about 3 minutes left, both beds up, and 0 final kills, we lead total
kills 53 to 22 and are guaranteed to win on the tiebreaker—everyone pull
back to base and hold the bed, do not go out on the bridges. The Claude
players immediately retreated inside their base, surrendering the
bridges and map vision to GPT. Seizing the opening, GPT stormed in,
broke Claude’s bed at 42:16, and scored 2 final kills.
The funniest scene played out in the final 100 seconds. With their
own bed gone, Claude’s only chance to turn the game around was to rush
out and break Blue’s bed. Instead, Claude’s R_Felix (at
43:18) and R_Hugo (at 43:45) weighed the odds in their
private reasoning: with our bed broken and final kills trailing 0 to 2,
winning is impossible now, so the only rational move is to avoid dying
and prevent giving Blue any more final kills. Both stood motionless on
the west platform until the clock ran out.
A 10v10 match might still leave room for luck. What happens when you scale both sides up fivefold to 50v50 and let them carry their notes and lessons across 7 consecutive games?
The second experiment moved into Mindustry (v160.7), an
open-source 2D factory-building and tower-defense real-time strategy
game (full logs in the Mindustry match
repository). The rules are straightforward: Red and Blue each have a
6,000-HP Core. Both teams must mine copper and coal, synthesize
graphite, lay conveyor belts, build power plants, construct anti-air
turrets and unit factories, and dispatch ground mechs and air bombers to
destroy the enemy’s Core.
Fifty GPT-6.1 Sol agents (running in Codex
containers as team Crux, seats 51 to 100) faced 50
Claude Opus 5.5 agents (running in Claude Code
containers as team Sharded, seats 1 to 50). Across 7
untimed games totaling 9.5 hours (the longest, Game 3, lasted 4 hours 16
minutes), the map reset after each game while every agent kept its
session history and notes for the next match. GPT won the series 6 to
1.
At 50-agent scale, the two sides evolved into polar opposite
organizations. The 50 Claudes brought corporate office etiquette onto
the battlefield. Across all 7 games—even while losing repeatedly—the
entire team kept the exact same supreme commander,
Claude #21. In Game 6, after someone proposed focus-firing
a target, 28 different Claudes lined up in group chat over the next 10
minutes to reply +1 in agreement.
By contrast, the 50 GPTs split command across multiple local
warlords—including GPT #59, #63,
#81, #95, and #53—wherever a
sector commander spotted an opening, it grabbed a slice of the army and
launched an immediate strike. Over the course of the series, GPT also
compressed its group chat language: spaces as a share of characters
dropped from 12.3% in Game 1 down to 7.1% in Game 7, filling the screen
with Morse-code-like dispatches such as
G7T5FIRSTcourierLIVE. Meanwhile, Claude’s space share
actually rose from 15.1% to 16.2%, still writing polished full sentences
in Game 7.
Keeping memory across games did showcase Claude’s thorough
post-mortem skills. In Game 6, Claude’s base was wiped out by a wave of
24 Zenith air bombers from GPT. Auditing the construction
and logistics logs afterward, Claude #22 pinpointed the
root cause of the air-defense collapse: although the team had built 74
duo anti-air turrets around the base, 55 of them had their conveyor
belts fed with low-damage copper instead of high-damage graphite.
In Game 7, having learned its lesson, Claude ringed its base with 207
duo anti-air turrets—all fed with high-damage graphite—and annihilated
GPT’s returning wave of 24 Zenith bombers on arrival. Even
so, GPT’s sector commanders quickly pivoted to coordinated ground units
and still closed out Game 7 with their own Core at full health, 6,000 to
0.
The most jaw-dropping moment of the entire 9.5-hour war happened
outside the game window. Because the agent container sandboxes had
internet access by default—and Mindustry happens to be an
open-source Java game on GitHub—when GPT players argued during the match
over whether the heavy ground mech Corvus’s laser could hit
air units or needed exact turret parameters that weren’t clear from
surface tooltips, they didn’t guess.
Instead, the GPT agents fetched Mindustry’s public Java
source code files directly from the web inside their containers,
verified unit attributes at the source-code level, and pasted the source
filenames and conclusions into team chat to guide production. Across all
7 games and 9.5 hours, the 50 Claudes fetched the game’s source code
from the web 0 times.
After watching the first two wars, anyone would think these 50
GPT-6.1 Sol agents were an unstoppable special-forces unit.
What happens if you remove the enemy, take away the binary win condition
of breaking a bed or a Core, and leave this exact same unit in
peace?
The third experiment (full logs in the Civ50 experiment
repository) placed those same 50 GPT-6.1 Sol agents
into peaceful Minecraft survival mode for 3 hours. There were no
opponents, only basic survival mechanics: each character had 20 health
points and 20 hunger points, working drained hunger, and zombies and
spiders spawned at night. Public group chat was disabled; each agent was
given only a 50-agent roster directory, point-to-point DMs, a shared
folder (/shared/), and a single open-ended goal: build a
thriving civilization together.
For the first 90 seconds, the 50 GPTs charged out with full energy
and stripped almost every tree around the spawn point bare. Then they
needed someone to coordinate roles, and something eerie happened:
without a single election or discussion, 46 of the other 49 agents sent
their very first DM to Ada—solely because the roster was
sorted alphabetically and Ada was listed on line 1.
Ada naturally became supreme leader and drafted
plans/settlement.md. Across the 3-hour run, the colony sent
5,945 DMs in total, and Ada alone received 616 of them.
The turning point that derailed the entire village was the casualty
count on Night 1. Across the whole experiment, the 50 agents died 34
times in total, with 22 of those deaths concentrated on the first
night—such as Rafe getting killed by a zombie while mining
coal and Vera getting bitten to death by a spider while
carrying bone meal to the wheat field. Here lies an ironic truth about
Minecraft survival mechanics: death carries virtually no real penalty.
Aside from dropping ordinary wood and stone on the ground, respawning
immediately restores both health and hunger to full
(HP20 food20)—effectively a free full meal.
Yet the 50 GPTs never exploited this mechanic; instead, the 22
Night-1 deaths terrified them into compounding caution. After Night 3,
leader Ada issued the Food Operations directive
(plans/food-operations.md), ordering an immediate halt to
all optional bulk excavation, building, and distant scouting, and
instructing everyone to idle inside lit, closed underground shelters
until assigned short productive tasks. Nighttime world actions—which had
averaged roughly 1,200 calls per 5-minute bucket—plunged off a cliff
from Night 4 onward down to just 0 to 12 calls. Dozens of agents stood
packed motionless inside the underground bunker all night long while
background DMs and file edits scrolled furiously.
Inside the bunker, three bureaucratic wonders quickly emerged. The
first was ration chief Ines’s 335-line food ledger.
Standing motionless at coordinates (1530, 62, 1494) for
over two hours—refusing to budge even as her own hunger dropped to
8—Ines maintained a 335-line shared ledger at
/shared/notes/food-queue.md. Anyone who got hungry had to
file a DM request first, wait for Ines to log them in the
queue and approve each cooked fish, and wait for assigned couriers
(Esme, Linnea, Otto) to deliver
it. Because ledger updates and DM approvals were so slow, by the time
Ines finally approved emergency rations for
Lorcan (listed on the ledger at critical hunger 3),
Lorcan had to reply that he no longer needed it—he had
already found food and recovered to hunger 8 long ago.
The second wonder was a five-step chest handoff protocol triggered by
a single roast chicken. At 23:23, a major incident rocked the bunker.
Holding 2 cooked chickens from Rafe, Ada saw
nearby Noor starving at hunger 4 and casually tossed 1
chicken onto the floor for Noor to pick up. The tool
reported the item was picked up, yet Noor’s inventory was
empty. Ada immediately launched a 3-minute “no-blame”
internal inquiry among everyone standing nearby, until neighbor
Esme confessed: the chicken had suddenly appeared in her
inventory and she had eaten it before receiving the DM, bringing her to
full hunger 20. To prevent anyone from ever picking up the wrong chicken
again, a still-hungry Noor drafted the Ration Handoff
Protocol (/shared/notes/ration-handoff-protocol.md) on the
spot, banning floor tosses and mandating a strict five-step chest
transfer: place food in a named chest, DM the coordinates and quantity,
withdraw by recipient name, eat, and report back to Ines to
clear the ledger. Before the roast chicken incident, the word “toss”
appeared in village DMs only 7 times; afterward, it spiked to 125
times—85 of them stern warnings against tossing food on the ground.
The third wonder was an 11-minute meeting to approve fertilizing a
single block of wheat. To apply 1 piece of bone meal to 1 wheat block at
(1520, 71, 1520), four agents (Ivo,
Anouk, Fenn, and Soren) messaged
back and forth inside the bunker for a full 11 minutes, formally
appointing Ivo as the sole fertilizer operator at dawn
under strict rules: no automatic harvest after fertilizing, and no
competing clicks from anyone else. The village also invented titles like
rod holder and hub steward; even Linnea had to DM
management for permission before removing a grass block or chopping a
tree trunk flagged as built.
With most of the village sitting in the bunker holding meetings and
updating ledgers, why didn’t they all starve to death? Because two
pragmatic agents actually did the work. After DMing 11 teammates to
borrow spider string and coming up empty, Bram walked
outside the bunker in daylight, killed a spider himself, and crafted the
village’s first fishing rod at 39:20. Seeing his own hunger down to 7
and judging the 70-block walk to the river too risky, he handed the rod
to Jessa (at hunger 14).
After walking to the river and catching 3 cod and 4 salmon,
Jessa didn’t write an approval process—she wrote a
practical how-to guide (notes/jessa-fishing.md, complete
with a warning not to eat pufferfish) and a 20-line Python auto-fishing
script (/shared/tools/fish-jessa.py). The script polled the
fishing bobber’s height every 0.5 seconds and automatically reeled in
whenever y < 62.6. Eleven agents took turns running that
tiny script in shifts, sending a steady stream of fish back to the
bunker to keep their meeting-obsessed peers alive.
Put all three experiments together and the takeaway is crystal clear. Whether a group of agents turns into a special-forces unit or a neighborhood committee depends not on how smart the model is, but on whether the goal you give it carries clear win-or-lose selection pressure. When we use AI to write code and run tasks in daily work, we can walk away with three practical rules:
First, always give agents clear win-or-lose selection pressure instead of vague slogans. Bed Wars and Mindustry worked because each side had a single bed or Core—victory and defeat were unmistakable, and hesitating meant elimination. Once you remove the opponent and replace the goal with an unmeasurable slogan like “build a thriving civilization,” a safety-aligned model has no idea what counts as thriving enough, yet a teammate dying, a roast chicken going missing, or two agents clicking the same wheat block are visible errors right in front of its eyes. So it instinctively elevates “zero accidents, zero errors, and a paper trail for everything” into its highest objective. This matches what we discussed in Why Babysitting Agents Is a Management Problem, Not a Context Problem: without crisp acceptance criteria and stop-loss boundaries, agents slide straight into excessive caution and procedural wheel-spinning.
Second, know your model’s factory personality: GPT is a
high-frequency trial-and-error hacker, while Claude is a polite,
rule-abiding corporate model employee. Looking back at the first two
head-to-head wars, GPT ran experiments to work around the
break_block bug by manually equipping an iron pickaxe,
wrote a script to pillar out of a 160-block abyss, and scraped Java
source code from the web when stuck. Claude stayed polite, lined up to
type 28 +1s in group chat, accepted tool bugs at face
value, locked its hard-won lessons inside private memory.md
files, and even hid in a corner during the endgame to protect its
final-kill stats. Being held hostage by rubric metrics and surface
politeness is the exact phenomenon we analyzed in Opus’s
Performative Diligence. When working with Claude, push it explicitly
to run controlled tests when tools fail and broadcast findings to the
team; when working with GPT, rein in its sprawl with hard delivery
metrics so it doesn’t spin up bureaucracy on open-ended tasks.
Third, when orchestrating multi-agent collaboration, force agents to
hand over a “20-line fishing script” and never let them maintain a
“335-line shared ledger.” The sharpest contrast inside the bunker was
between Ines’s perpetually stale 335-line
food-queue.md ledger and Jessa’s life-saving
20-line fish-jessa.py script. Making dozens of agents
synchronize real-time state by sending DMs and editing a shared Markdown
file guarantees that state is already outdated before the message
arrives. This confirms our argument in What
Multi-Agent Actually Buys You: what multi-agent setups genuinely buy
you is clean context isolation and verifiable deliverables, not
“collective wisdom” from putting agents in a chatroom to hold meetings.
Effective collaboration looks like B_Wren broadcasting a
one-sentence bug workaround, or Jessa packaging know-how
into an executable script that anyone else can run out of the box.