The Darwin Game—Rounds 0 to 10

The most im­por­tant change be­tween my game and Zvi’s origi­nal is that bots can read each oth­ers’ source code. They can simu­late each other and pre­dict each oth­ers’ be­hav­ior. Within a day of the tour­na­ment launch­ing—and an en­tire week be­fore en­tries closed—Zack_M_Davis had already writ­ten a bot to simu­late op­po­nents and then open-sourced it to ev­ery­one.

That’s what hap­pens when a sig­nifi­cant con­trib­u­tor to an open source Lisp di­alect par­ti­ci­pates in a soft­ware com­pe­ti­tion.

Tale­un­tum wanted to write an even bet­ter simu­la­tor but was in­formed that it would take too many years to run.

Mu­ti­core solved the limited com­pute prob­lem and wrote a safe, effec­tive, obfus­cated simu­la­tor, with ran­dom­iza­tion.

The Phan­tom Menace

Three sep­a­rate peo­ple asked me what hap­pens if a bot crashes the game while simu­lat­ing an op­po­nent with malware in it. This turned out not to mat­ter be­cause no­body de­ployed malware to de­stroy simu­la­tors. Only one player, Mea­sure, de­ployed malware—and the malware didn’t crash the game. In­stead, it at­tempted to re­place its op­po­nent’s move method with a method that re­turned 0 in­stead. But the threat of get­ting dis­qual­ified seemed to scare away other po­ten­tial simu­la­tors.

Tale­un­tum did write a MatrixCrashingBot that crashes simu­la­tors but did not sub­mit it. This is a dis­ap­point­ment, as Tale­un­tum would have been al­lowed to sub­mit this bot as a sep­a­rate en­try on the grounds that it does not co­or­di­nate with Tale­un­tum’s CloneBot. To my knowl­edge, no­body else took ad­van­tage of this de­liber­ate loop­hole in the rules ei­ther.

RaterBot safely combed through its op­po­nent’s source code for “2”s and “3″s to es­ti­mate ag­gres­sion with­out the dan­gers as­so­ci­ated with run­ning un­trusted code.

Com­puter pro­grams at­tempt­ing to simu­late each other can pro­duce com­plex be­hav­ior. The be­hav­ior is so com­plex it is prov­ably un­de­cid­able—and that’s to­tally ig­nor­ing the real-world sand­box­ing prob­lem.

Nev­er­the­less, two con­tes­tants re­quested I write code to simu­late their op­po­nents. I re­fused these re­quests. Zvi[1] ac­cepted a sim­pler bot and the other con­tes­tant dropped out.

I’m sur­prised run­ning the en­emy is com­pli­cated though—it should just be a func­tion call.

―quote from the con­tes­tant who dropped out

The most sig­nifi­cant use of an op­po­nent’s source code came from Vanilla_cabs.

At­tack of the Clones

Zvi’s origi­nal game was dom­i­nated by a clique of play­ers who co­or­di­nated out-of-game to defeat the non-clique play­ers. It worked great—and then defec­tors within the clique dom­i­nated both the non-clique play­ers and the clique play­ers.

Vanilla_cabs ob­served that play­ers could use each other’s source code to de­tect (and there­fore pun­ish) defec­tion from a clique. Lev­er­ag­ing this in­sight, Vanilla_cabs cre­ated a CloneBot tem­plate that would co­op­er­ate only for the first 90 rounds—long enough to elimi­nate all non-clones—and then al­low play­ers to do what­ever they wanted af­ter­ward.

Brilli­antly, the CloneBots used the lex­o­graphic length of cus­tom code to break par­ity sym­me­try and guaran­tee perfect co­or­di­na­tion be­tween CloneBot in­stances in­stead of hav­ing to fum­ble around for the ini­tial rounds of each pairing.

At the same time, Vanilla_cabs wor­ried that some­one might at­tempt to by­pass the CloneBot’s self-recog­ni­tion sys­tem. As a first line of defense, Vanilla_cabs kept the source code se­cret from non-clon­ers. As a sec­ond line of defense, Vanilla_cabs de­liber­ately left open a weak­ness as a hon­ey­pot. Among the first co-con­spir­a­tors in the clone army, only Lan­rian re­ported this weak­ness.

Tale­un­tum, in con­trast, con­tributed two lies to the clique in­trigue.

I lied that I’ve already sub­mit­ted one pro­gram de­tect­ing and crash­ing simu­la­tors…ob­vi­ously I did not even plan to do so. Some time later…I added an­other lie that the method of de­tect­ing simu­la­tors was my friend’s idea (hope­fully sug­gest­ing that there is an­other con­tes­tant with the same method out­side the clique).


One player dis­cov­ered a way to defect from the CloneBots.


The origi­nal CloneBot tem­plate used splitlines() to parse source code. But the Python3 in­ter­preter be­haves slightly differ­ently from splitlines(). In par­tic­u­lar, splitlines() splits on the groups sep­a­ra­tor char­ac­ter 0x1D, which Python3 does not treat as a newl­ine. By plac­ing 0x1D group sep­a­ra­tor char­ac­ters in­side of a com­ment, Mul­ti­core’s Ear­lyBirdMimicBot by­passed the CloneBot self-recog­ni­tion sys­tem.

Mul­ti­core did a lot of things.

  • Wrote a simu­la­tor.

  • Op­ti­mized the simu­la­tor via a branch­ing al­gorithm to perform effi­cient searches.

  • Used ran­dom­iza­tion to dis­rupt op­pos­ing simu­la­tors.

  • Pro­tected the simu­la­tor from malware.

  • Joined the CloneBots.

  • Defected from the CloneBots via a zero-day ex­ploit in the CloneBot code.

  • Re­cruited two friends to sub­mit pass­word bots to serve as fod­der.

  • Ad­justed strat­egy based on the round num­ber.

When I hosted this tour­na­ment, I hadn’t ex­pected any­one to “[read] through the C code for the python lexer”.

For a com­plete write-up of Mul­ti­core’s strat­egy, in­clud­ing source code, see here.

On a side note, I re­ally love this site. I can’t re­ally re­call any other game I’ve been in get­ting this tan­gled.


The First Game

The first iter­a­tion of the game was run by Tale­un­tum who ran “a simu­la­tion of the whole tour­na­ment till the 160th round with 8 bots” de­spite the tour­na­ment’s source code not be­ing pub­lic at the time.

Tale­un­tum’s tour­na­ment was un­offi­cial and does not count.

The Real Game


In or­der to make sense of the 54 par­ti­ci­pat­ing bots, I have buck­eted them into teams.

  • [Blue] Clone Army. 10 play­ers pledged to sub­mit clone bots. 8 fol­lowed through, 1 didn’t and Mul­ti­core sub­mit­ted a [Red] mimic bot.

  • [Red] Mul­tics. Mul­ti­core’s friends sub­mit­ted 2 pass­word bots to aid Mul­ti­core’s mimic bot.

  • [Green] Norm En­forcers. Ben Pace joined forces with ja­cob­ja­cob to form their own lit­tle duo.

  • [Black] Chaos Army. 20 play­ers wrote in­di­vi­d­ual bots.

  • [Ma­genta] NPCs. I wrote 21 Silly Bots. Some of them had syn­er­gies.

The clones [Blue] be­gin the game out­num­bered 6-to-1.

Edit: Every­thing be­low this line is in er­ror. See here for de­tails.

Round 1

5 bots died on turn 1 in­clud­ing 4 NPCs and Team Norm En­forcers’ ja­cob­ja­cob bot.

Rounds 2-3

Another 4 NPCs died.

Rounds 4-10

S_A and BenBot die, along with 3 more NPCs. Thus ends team Norm En­forcers.

The clone army is mostly do­ing well, ex­cept for CloneBot which is do­ing poorly and Ab­strac­tSpyTreeBot which is do­ing al­most as well as the av­er­age clone.

Ear­lyBirdMimicBot is do­ing bet­ter than the av­er­age CloneBot but not by much. The MimicBot’s 0x1D ex­ploit suc­ceeded in defect­ing but the bot ap­pears not to have lev­er­aged its defec­tion to game­break­ing effect.

The clones have built up a crit­i­cal mass of >50%. If their co­or­di­na­tion mechanisms work then they ought to crush the rest of the com­pe­ti­tion.

If Zack_M_Davis’ Ab­strac­tSpyTreeBot can sur­vive in a world of clones un­til turn 90 when the clone treaty ex­pires then there may be some hope for Chaos Army.

If not then, be­gun, the clone wars have.

Every­thing so far

To­day’s Obituary

ja­cob­ja­cob-BotNorm En­forcer­sPlays ag­gres­sively while co­or­di­nat­ing with Ben.1
Silly 5 BotNPCsAlways re­turns 5.1
Silly 0 BotNPCsAlways re­turns 0.1
Silly In­vert Bot 0NPCsS­tarts with 0. Then always re­turns 5 - opponent_previous_move.1
Silly In­vert Bot 5NPCsS­tarts with 5. Then always re­turns 5 - opponent_previous_move.1
Silly 4 BotNPCsAlways re­turns 4. Then always re­turns 5 - opponent_previous_move.2
Silly In­vert Bot 1NPCsS­tarts with 0. Then always re­turns 5 - opponent_previous_move.2
Silly Chaos BotNPCsPlays com­pletely ran­domly.4
Silly In­vert Bot 4NPCsS­tarts with 4. Then always re­turns 5 - opponent_previous_move.4
S_AChaos ArmyPlays 1 79% of the time, 5 20% of the time and ran­domly 1% of the time5
Silly Ran­dom In­vert Bot 4NPCsS­tarts ran­domly. Then always re­turns 5 - opponent_previous_move.6
Silly 1 BotNPCsAlways re­turns 1.7
Ben BotNorm En­forcer­sCo­op­er­ates with ja­cob­ja­cob [de­ceased]. If not paired with ja­cob­ja­cob then this bot re­turns 3 for the first 100 turns and then does fancy stuff. Un­for­tu­nately for Ben, I picked 100 as the num­ber of turns per pairing.10
Silly 3 BotNPCsAlways re­turns 3.10

The next in­stal­l­ment of this se­ries will be posted on Oc­to­ber 26, 2020 at 5 pm Pa­cific Time.

Zvi’s speci­fi­ca­tion did ad­dress the halt­ing prob­lem, sand­box­ing prob­lems and un­pre­dictable re­source con­sump­tion. ↩︎