Vom Sink- und Sturzflug

Im Januar fanden wieder einmal Studierendenparlamentswahlen statt. Und das Ergebnis war höchst interessant.

Um die Bedeutung des diesjährigen Wahlergebnisses zu verstehen, blicken wir zunächst ein paar Jahre in die Vergangenheit. Damals, man mag es heute kaum glauben, war der Ring Christlich-Demokratischer Studenten (sic), kurz RCDS, noch die stärkste Liste im Studierendenparlament.

In öffentlich zugänglichen Quellen lassen sich die Wahlergebnisse der Studierendenparlamentswahlen seit 2008 nachvollziehen, für die Zeit davor müsste man vermutlich in verstaubte AStA-Archive hinabsteigen. In diesem Artikel soll es vor allem um die Entwicklung der Stimmanteile gehen, daher betrachten wir überwiegend Prozentwerte (gefährlich, ich weiß) statt Sitzzahlen. Das ist gleich doppelt praktisch: Die Verschiebungen im Kräfteverhältnis bei der Abbildung der Stimm- auf Sitzzahlen betreffen uns so nicht. Auch die Verkleinerung des Studierendenparlaments von 51 auf 43 Sitze im Jahr 2013 können wir so ignorieren. Schon zu Beginn des Artikels eine gute Entscheidung! Mega.

Hier sehen wir die Entwicklung der Stimmanteile des RCDS von 2008 bis 2020:

Vom Sink- und Sturzflug
Wusstet ihr eigentlich, dass die Summe aller Stimmanteile einer Wahl 100 % betragen muss?

Viele Jahre lag der RCDS stabil um oder über 25 Prozent, was immerhin ein Viertel der abgegebenen Stimmen ausmacht. Seit 2017 geht es aber sanft abwärts. Was ist passiert? Daran, dass der RCDS Wahlplakate mit RAF-Logo aufgehangen und damit möglicherweise seine Stammwählenden vergrault hat, kann es nicht alleine liegen – die gab es schließlich erst im Wahlkampf 2018. Ich bin mir lediglich sicher, dass der RCDS selbst auch gerne eine Antwort auf diese Frage hätte.

Doch bei der Frage, wer die Macht hat im Studierendenparlament, geht es nicht nur um einzelne Listen, sondern auch um Koalitionen. Die einzige RCDS-Koalition des betrachteten Zeitraums, die einen AStA stellen konnte, gab es 2009 zwischen RCDS, der Unabhängigen Liste der Fachschaften (ULF) und der Re(h)-Partei. In der jüngeren Vergangenheit war dann eigentlich die Liberale Hochschulgruppe (LHG) die Liste, mit denen man sich eine RCDS-Koalition am ehesten vorstellen konnte: Der RCDS definiert sich über eine Ablehnung von allem, was “links” ist, beziehungsweise er nennt alles “links”, was er nicht mag; die LHG daneben kennzeichnet ihr Hass auf alles, was “Ideologie” ist, beziehungsweise sie bezeichnet alles als “Ideologie”, was ihr suspekt ist. Super Voraussetzungen also, um gemeinsam gegen die Links-Ideologie zu kämpfen!

Eine zweite Grafik zeigt uns geschwind, wie sich die Stimmanteile der RCDS-Koalitionen über die Jahre entwickelt haben. Dafür stapeln wir einfach die Stimmanteile von ULF, Re(h)-Partei und LHG auf die RCDS-Balken.

Vom Sink- und Sturzflug
Keine Ahnung, was ULF und REH für Farben gehabt hätten – die bunte Sitzverteilungsgrafik haben erst wir 2013 im Wahlergebnis eingeführt.

Im Jahr 2009 hat die Koalition aus RCDS, ULF und Re(h)-Partei erwartungsgemäß einen Stimmanteil von über 50 Prozent, was dann auch zu einer Parlamentsmehrheit führt. Im Jahr darauf tritt jedoch einmalig die “Offene Liste der Bildungsproteste (OL:B!)” an, die – man korrigiere mich bitte, wenn ich da falsch liege, das war vor meiner Zeit – ein ähnliches fachschaftsnahes Klientel ansprach wie die Unabhängige Liste der Fachschaften. Die ULF stürzt von 17 auf 7 Prozent ab und ward in den folgenden Jahren nicht mehr gesehen, während die OLB – in diesem Kontext höchst verdächtige – 10,x Prozent holt und danach ebenfalls nicht mehr antritt.

In den folgenden Jahren übernimmt die LHG die Rolle des potenziellen Koalitionspartners, und gemeinsam halten sich die beiden regelmäßig über 30 Prozent. Seit 2017 sieht es so aus, als gebe es da möglicherweise eine Wählendenwanderung vom RCDS zur LHG. Das ist aber reine Spekulation, da die Datenlage nichts besseres hergibt.

2020 dann: Der Absturz. Hatte die LHG noch 2019 den RCDS überholt, was Stimmanteil und Sitze anging, stürzte sie bei der Wahl 2020 von 19 auf 10 Prozent ab – und riss den kombinierten Stimmanteil mit dem RCDS von 35 auf 22,7 Prozent mit sich hinab. Wir erinnern uns: Früher™ holte der RCDS noch mehr als das – und zwar alleine.

Was ist 2020 passiert? Nun, zwei Dinge sind dafür wichtig.

Zunächst: Es gibt zwei Arten von Stimmen – Personenstimmen und Listenstimmen.

  • Viele Personenstimmen bekommt man, weil man Kandidierende hat, die viele Leute kennen1.
  • Viele Listenstimmen bekommt man, wenn man durch (mutmaßliche) Inhalte überzeugen kann.

Stellt man für RCDS und LHG den Anteil der Listenstimmen an ihrer jeweiligen Gesamtstimmzahl dar, ergibt sich ein klares Bild:

Vom Sink- und Sturzflug
2019 scheint die LHG mit irgendwelchen Inhalten viele Neuwählende überzeugt zu haben?

Die LHG wird offenbar stärker wegen ihrer Inhalte gewählt als das beim RCDS der Fall ist.

Prinzipiell ist das gut, weil Inhalte ja prinzipiell gut sind. So läuft man auch weniger Gefahr, plötzlich in der Wählendengunst abzustürzen, weil eine beliebte Kandidatin plötzlich mit dem Studium fertig wird und nicht mehr kandidieren kann.

Der Nachteil dabei ist allerdings auch, dass es passieren kann, dass eine andere Liste bessere Inhalte anbietet, und schwupp landen die Kreuze woanders auf dem Stimmzettel.

Fügen wir der Grafik mal zwei weitere Listen hinzu: Die “Liste Poppelsdorf” (LP) und die Volt-Hochschulgruppe.

Vom Sink- und Sturzflug
Schauns’, da ganz rechts oben sind jetzt zwei Markierungen überanand.

Die Liste Poppelsdorf und die Volt-HSG haben sich 2020 ganz neu zur Wahl beworben. Beide Listen haben einen Listenstimmenanteil von knapp über 68 Prozent, wurden also 2020 noch stärker wegen ihrer mutmaßlichen Inhalte gewählt als die LHG. Dass der Anteil der LHG 2020 wieder abfällt spricht für die vorhin skizzierte Wählendenwanderung aus inhaltlichen Gründen: Möglicherweise war das Angebot von LP und VOLT für viele Wahlberechtigte, die 2019 noch ihr Kreuzchen bei der LHG gemacht haben, interessanter?

Die Liste Poppelsdorf ist ohnehin ein hochinteressanter Fall. Sie ist im Betrachtungszeitraum die einzige Liste, die schon im Namen ein örtlich begrenztes Wahlprogramm propagiert: Für den Campus Poppelsdorf.

Man könnte jetzt den Urnenplan teilen: In die Urnen, die auf dem Campus Poppelsdorf stehen, und die Urnen, die dies nicht tun. Und dann mal schauen, was sich bei den “Poppelsdorf-Urnen” in den letzten Jahren so getan hat. Ich schreibe “könnte” – und habe es natürlich getan.

Als “Poppelsdorf-Urnen” zählen wir mal die beiden Urnen der Mensa Poppelsdorf, die MNL, Mathematik, Anatomie, Math.-Nat. 1-3 (Wegelerstraße 10, Geographie, AVZ I), das Hörsaalzentrum Poppelsdorf und die Informatik – auch für die Zeit, in der sie noch in der Römerstraße einquartiert war – und die Wanderurnen Physik / Institut für Geschichtswissenschaft (stand immerhin zu 50 % in Poppelsdorf) und die Wanderurne Poppelsdorf von 2019. Nicht jede dieser Urnen gab es jedes Jahr, aber wir wollen sowieso nur die Summe über alle Urnen in Poppelsdorf betrachten. Wir betrachten die Jahre 2017 – 2020, da wir in diesem Zeitraum den Niedergang des RCDS festgestellt haben und vor allem weil ich irgendwann keine Lust hatte, noch mehr Zahlen abzutippen.

Der Anteil dieser Urnen an der Gesamtstimmzahl bewegt sich in diesen Jahren zwischen 35 und 39 Prozent, außer 2019, da lag er lediglich bei knapp unter 30 Prozent. Betrachten wir nun, wie wichtig diese Urnen für die einzelnen Listen waren, indem wir ihren Anteil an den Stimmen für die Liste berechnen:

Vom Sink- und Sturzflug
Oooooh. Ha!

Die Grafik liest sich etwas komplizierter als die vorherigen, daher ein Beispiel: Wären die Stimmen über alle Urnen gleich verteilt, dann hätte jede Liste 2017 ca. 39 Prozent ihrer Stimmen aus Poppelsdorf-Urnen erhalten, da 2017 ca. 39 Prozent aller Stimmzettel aus Poppelsdorf-Urnen kamen. Der RCDS hat 2017 aber etwas weniger als 35 Prozent seiner Stimmen aus Poppelsdorf-Urnen erhalten. Bei der LHG hingegen kamen im gleichen Jahr ca. 43 Prozent ihrer Stimmen aus Poppelsdorf-Urnen. Das bedeutet, dass man im Vergleich zur Gesamtwählendenschaft in Poppelsdorf stärker empfänglich für LHG-Wahlkampf als für RCDS-Botschaften, in welcher Form auch immer, ist.

Der Einbruch bei LHG und RCDS im Jahr 2019 geht damit einher, dass lediglich 30 Prozent aller Stimmen aus diesen Poppelsdorf-Urnen kamen, lässt sich also teilweise damit erklären.

Doch dann kommt 2020. Der Anteil der Poppelsdorf-Urnen an den Gesamtstimmen steigt wieder auf 37 Prozent. Man würde also prinzipiell erwarten, dass die Anteile von RCDS und LHG wieder auf das Niveau von 2018 steigen. Doch das ist nicht der Fall: Der Anteil der RCDS-Stimmen stagniert, der Anteil der LHG-Stimmen sinkt weiter ab.

In diesem Jahr kommen jedoch zwei neue Listen hinzu, die in Poppelsdorf offenbar starken Anklang finden. Die Volt-HSG bezieht über die Hälfte ihrer Stimmen aus Poppelsdorf-Urnen, was recht viel ist. Aber das ist noch wenig im Vergleich zu den 86,8 Prozent der Liste Poppelsdorf!2 Wir haben hier ganz klar das Muster einer Regionalpartei.

Ändern wir einmal mehr den Betrachtungswinkel. Eben haben wir gesehen, dass Poppelsdorf ein wichtiges Gebiet für die Liste Poppelsdorf zu sein scheint. Doch wie stark ist die Liste Poppelsdorf in Poppelsdorf? Stellt sich heraus: Sehr stark. Wir betrachten die Stimmanteile aller Listen, nur bezogen auf die Poppelsdorf-Urnen:

Vom Sink- und Sturzflug
Irgendwann strick ich mir nen Schal mit dem Muster.

Die Liste Poppelsdorf holt 2020 an den Poppelsdorf-Urnen aus dem Stand 25 Prozent aller Stimmen. Das sind die zweitmeisten Stimmen an den Poppelsdorf-Urnen hinter der GHG, die dort lediglich vier Stimmen mehr bekommen hat. Nimmt man die Chemie-Urne noch dazu, herrscht sogar Gleichstand zwischen GHG und LP. Absolut beeindruckend.

Betrachtet man die obige Grafik, sieht es aus, als haben VOLT und LP fast allen Listen Stimmanteile abgenommen. Die LHG allerdings wurde geradezu dezimiert. Da werden bestimmt einige Stimmen von der LHG zur LP gewandert sein.

Meine Vermutung: Die mathematisch-naturwissenschaftlichen Studierenden haben sich gefreut, dass endlich eine Liste den W-Lan-Ausbau an der Universität fordert, die nicht diesen ganzen nervigen Ideologie-Kram dabei stehen hat. Oder lag es an peinlichen LHG-Slogans wie “Du wolltest schon immer mal mit deinem Prof ins Bett?” Wer weiß das schon.

Die Frage für RCDS und LHG müsste nun lauten: Sind LP und VOLT passende potenzielle Koalitionspartnerinnen, die ihre Stimmverluste kompensieren können?

Mein Tipp, wenn ich mir deren Personal so ansehe, lautet ja: Nö.

Rohdaten (ods-Datei)

  1. Also sowohl Kandidierende die viele Leute selbst kennen und die dadurch von vielen Leuten gekannt werden als auch Kandidierende, die lediglich von vielen Leuten gekannt werden.
  2. Wenn man noch die Urne der Chemie am Campus Endenich dazunimmt, werden es über 90 Prozent.

Nametags for NAC3

The year 2020 started with a bang: Nili’s Apartment Cup 3 (NAC3) was the first major Age of Empires 2 tournament that was played on the new Definitive Edition, with a prize pool of over 30.000 dollars. It took place over the second week of January in Nili‘s apartment (hence the name) in Hamburg.

The weekend of the finals was to be accompanied by a public viewing event at a location in Hamburg. There was also a meet and greet event for the community, players, and casters on saturday evening at said location.

Community meetups are a great way to assign real faces to the names you meet online in Twitch chats and Discord servers. I am regularly astonished by the huge amount of good-looking people in the Age of Empires 2 community. From the way they act online, you would expect a horde of literal trolls to show up. But no!

In order to facilitate matching names to faces, I offered to provide nametags for everyone attending. The technical setup for this was rather simple: I borrowed a Dymo-450 label printer from my mother1, ordered some rolls of sticky labels on the internet, and brought my laptop to connect to the printer and print the labels from it.

My main concern was to avoid long wait times for people longing for nametags. The location was open to the public with no entry fee and no pre-registration required, so we did not know how many people would attend the event in the end. From the activity in the dedicated meet and greet Discord server I expected a few hundred people to show up at least.

The absolute worst-case scenario that I calculated with would have been around a hundred people showing up at the same time, right as the printer breaks down. Such a situation should be handled as smoothly as possible.

In case the printer decided to refuse further printing, I brought ten felt markers with which people would have been able to write their names onto the printer labels by hand. It would not have been as pretty, but the main goal of the nametags, telling people who you are without having to spell out your name all night long, would still be achieved. Problem solved!

Avoiding long queues while still printing beautiful name tags required a bit more preparation. We decided on a label design which included the name in bold at the top, a set of spoken languages in smaller print below (so you could decide in which language to address a person), a tagline in italics, also in small print, below that, which you could use to tell everyone your favourite joke or whatever you liked (as long as it still fit on the label), and finally a small bootleg NAC3 logo at the bottom right.

Nametags for NAC3
A sample nametag.

The absolute minimal amount of time needed to create one label is the time it takes to print and tear the label, which is about five seconds.
The things that take significantly longer are:

  • Having people think of a name they want to wear
  • Having people remember all the languages they can speak
  • Having people decide on a funny tagline (or decide they don’t want one)
  • Explaining to people all the textual elements of the nametag
  • Waiting for people to type everything into the computer to create the label

As you can easily see, people are the main issue. As usual.

A few points made my job easier on the technical level:

  • Using a library provided by pdfmake.org, we can take inputs from a html form and create a pdf file
  • Modern web browsers allow embedding pdf files in websites
  • Modern web browsers allow printing those embedded pdf files directly from the browser
  • You can print pdf files in the right format on the label printer, so I did not have to use dedicated label printing software

So I created just that: A html page where you can input your username, languages and tagline into a form. The page then creates a nametag pdf file that you can directly print if you have the right printer. Which I coincidentally2 had!

Not all usernames are equal though: Some are longer than others. Which makes them break onto two lines, and suddenly all that text on your nametag does not fit onto one single label anymore.

Nametags for NAC3
Poor platypus: One character too much! The little logo has been pushed down even further.

So I added an option to adjust the name’s text size. Easy fix!

Nametags for NAC3
Yaaaay!

One 1,80 m tall participant3 informed me that he mistook the “Size” input for a prompt to input the body height in centimeters. An interesting interpretation that I did not think of before. Remember, kids: Always label your input fields precisely!

Now on to the people issues we noticed earlier.

If we had a way to let people fill out the form somewhere else – at home, on a train, on the loo – and could just load them up and print them directly, that would solve all of our time problems.

In order to achieve this I wrote a small php script that did nothing else than take a json representation of a person’s nametag, generate a random five-digit number, store the json in a file with that number as the filename, and return the number. I also added a Save button to the html page that collected the data from the form, sent it to the php script, and displayed the number that it got as a response.

The second part was an input field where I could enter such a number and it would load the stored nametag information and put it back into the form fields and generate the nametag.

Aaaand we are basically done! Just get all the people to create their nametags in advance and write down their number, and I could use that number at the location to print their personal nametag. People could even just create another one and write down the new number if they wanted to change something.

Ok, maybe we are not done yet. Have you ever tried to make hundreds of people do what you want them to do?

I tried my best at least. I added the instructions at the top of the page. Tried to formulate them as simple and clear as possible. Then I put the thing online and advertised it in the meet and greet discord server multiple times.

And it kind of worked: We ended up with around 170 preconfigured nametags (some of which were duplicates).

There were obviously going to be people at the meetup who did not configure their nametag in advance. Still fearful of long queues, I decided they would be asked to fill out the form on their mobile device at the location and could then print it with the code they would get. The little issue with that: The location did not provide wifi. This means I could only ask that from people from the EU who have data roaming on their mobile devices. Luckily, the majority of attendees would match that criterion. In order to get their nametag data from the server I would have to get my laptop connected to the internet somehow as well. Opening a wifi hotspot on my mobile phone turned out to be sufficient for that task. Otherwise we would really have had to ask people to type their stuff directly on the laptop, since I would have had no way to get their nametag from the internet onto the label printer.

Days of truth

I arrived early at the public viewing location and successfully managed to procure a table for my setup pretty quickly. The internet connection for my laptop via wifi hotspot from my phone worked flawlessly.

Nametags for NAC3
The nametag printing station.

The longest queue I remember was maybe five to six people, and it was less a queue and more a group of friends getting their nametag printed one after the other.

Amazingly, most people had a number ready for me. It turned out I should have made that thing not just a javascript alert();, but actually a bit bigger. It was hard to read those tiny numbers on various variants of screenshots that people showed me. But those Age of Empires 2 fans seem to be a well organised bunch!

The people who did not have a number for me usually just ended up filling out the form on my laptop directly, since there was basically never a rush. This went against all of my concerns for which I planned, but I guess just being afraid of a horde of angry people is in this case better than actually being run over by a horde of angry people.

The biggest issue turned out to be the printer. Sometimes it was a little bit too generous, and did not only spit out one label, but then another blank label, and another blank label, and then another blank half label. Which is a bit annoying when you’re trying to run a free printed label business. Customers do not want their printing be distributed over two labels! So I spent a lot of time trying to fix the printer.

In the end I feeded it the single blank labels from previous “misprints”, which worked fine I guess. But in general you want a printer that prints just what you tell it to print. Dymo 450, you let me down.

And the people? They were happy with the nametags. Many told me it was a “cool idea” and thanked me for doing it. Which is all that counts, really ❤

The whole nametag website thing is free to re-use and can be found over on GitHub.

  1. Shoutout to my mother! Without her, this would not have been possible!
  2. Very coincidence. Much wow.
  3. No, I did not verify that information. But you thought I did, didn’t you.

Building the maps for Regicide Rumble 3

Last weekend, Regicide Rumble 3 happened. Regicide Rumble 3 (abbreviated RR3) was an Age of Empires 2 event organized and casted by T90Official on Twitch that had players of different skill levels compete for some prize money over three days in Regicide games1 of Age of Empires 2.

In this blog post, we will not focus too much on the (amazing) event, but on how we built the maps that have been used in that event.

The Task

About one month ago T90Official gathered a bunch of channel moderators and map makers and laid out his plans for the event: There should be multiple games over three days on different maps. Since the focus should be on Regicide, anything that makes sniping Kings easier should be done. That included removing HP bonuses and technologies for buildings that could protect the King, as well as disabling alternative win conditions like Relic or Wonder victory.

In the Regicide Rumble 1 and 2 events, there have been matches that took multiple hours to finish and that blew up the planned schedule for the games. To prevent this from happening again this time, a weakened version of a Battle Royale storm should push out players from the edges of the maps towards the center after a certain amount of time.

Battle Royale in Age of Empires 2 is not a novel idea, a few maps have been created already (mainly by HenkDeSuperNerd) that contain an area effect which damages units and buildings and grows over time, forcing players towards the middle of the map. We will not go into the details of the actual mechanism that creates the “storm” in this article – the relavant part is that the mechanic is based on chains of decaying animals which are placed around the edges of the map. Once the initial animal fully decays, it spawns a loop of other units that repeatedly cause blast damage to an area around them. Having all the edges full of these animals with different decay times creates “storm zones” that get activated one after another.

Slide 1
You can clearly see the storm zones in this screenshot of the Battle Royale Land Nomad map.

Those existing Battle Royale map scripts are highly specialized and a lot of work went into their creation. Creating and testing ten new map scripts with a similar but weaker version of the storm within a month and out of thin air2 would be totally unfeasible, as much was clear from the beginning.

Now we had to decide between two alternatives: Create a generic snippet that we can add to an existing random map script which turns it into a Battle Royale like map (with our custom weak storm). Or create ZR maps and place the animals that spawn the storm directly in the scenario file.

Excursus: ZR maps

Regular random map scripts are just text – in a strange markup format, yes, but still just text. They define everything about how the map shall look in vague generic terms. Their goal is to procedurally generate maps that look similar, but not the same.

ZR maps are different: They usually contain a scenario file that exactly defines the positions of terrains, possibly some other objects, and the starting positions of players, and a slimmed down random map script that defines all the rest in the usual vague terms, bringing variation onto the scenario. Unlike in regular scenarios, Triggers are ignored in ZR maps, so we can’t do shenanigans with those unfortunately.

Automation Is King3

The first option we had was tempting: The grandmaster of Age of Empires 2 Battle Royale maps, HenkDeSuperNerd, already had a snippet ready that could supposedly add the Battle Royale ring of decaying animals around any map. It was largely untested though and the effects it could have on the map generation were not investigated yet.

In contrast, the mechanics of ZR maps are well understood and controllable. For this reason, we went with the second option, which seemed to be the safer one regarding the time frame of less than a month.

Our process looked as follows:

  1. Select maps
  2. Adapt maps (like removing some spawn conditions for certain resources or removing animals)
  3. Add features: Custom regicide, Nerfs (for defensive buildings and civilisations), Storm constants
  4. Split script into Scenario and RMS part (one script to generate the scenario file from, one script to put into the final ZR map)
  5. Generate scenario file
  6. Add storm to scenario
  7. Create ZR map from scenario and RMS part

Having to do that for ten or more maps is tedious work. Also, at the time we did not even know which maps would be selected in the end. Without automation, that would have been a few unhappy hours of monotonous error-prone work for a few of us. And if we wanted to change something, we would have to do many of the steps again.

We had to change a lot of things. More on that in a bit.

Going through the above steps with each new iteration would have been an absolute pain. Luckily, we were able to automate some steps:

Building the maps for Regicide Rumble 3
M: manual work, A: automatable

I created a python script that automatically patched the code for our desired custom features into the maps that we had selected and adapted manually beforehand. The script also separated the sections of the rms that were needed for the scenario generation from the sections that were to be put into the ZR map.

The scenario generation had to be done by hand unfortunately. Since the scenario files are static and we desire fair starting positions for all players, a manual review would be needed anyway before continuing. Luckily, the rms part for generating scenarios does usually not change at all while testing custom map features, so we could generate those once and then use them again and again in the final steps.

Adding the storm spawners to the scenarios was a bit tricky. Our first approach was to manually “paint” a zone of terrain around the generated scenarios on which the map script would then place the storm spawners, like it is done in the existing Battle Royale maps. That would have meant monotonous repetetive work.

Luckily though, we had a breakthrough after a few days: I was able to use the agescx python library to modify the generated scenario programmatically! What would have taken at least multiple minutes per map before was now a matter of seconds. And not only that: We were suddenly able to place arbitrary objects at arbitrary positions on the map. Something that can hardly be achieved in random map scripts alone. We basically had full control. I wrote a second python script that created copies of our scenarios and modified them to our specifications. Mainly: placing the storm spawners precisely at the edges, with a specific distance to each other.

The last part, combining the scenario and the RMS file, is also easily automated, since ZR maps are just zip files without compression that contain the scenario file and the rms file.

We finally had a semi-automated pipeline in which we could tweak a script and and produce 17 new versions of our maps within seconds. Now it was just a matter of making it all work.

It Would Be A Lot Of Fun, Were It Not For The Players

During testing on community games friday, we found out that the features we initially used had some issues. For example we tried to disable Relic victory by spawning in the Relics after the game start, by placing Priests with 0 HP that hold a relic. When the priest dies (which he does immediately), he drops the relic, and it looks like it has been there all along. Turns out that Burmese can see the locations of the relics on the map, and they converted the dead priests while they died. Due to a bug in the game, this led to the dead priests taking up population space for the Burmese player, who had to build a few extra houses at the start of the game in order to produce own units. A similar thing happened when the storm was active and players converted some of the Gaia units on the edge which we used to deal the damage. The dead units took up population space, and CaptureAge showed us the discrepancy between units and used up population space clear as day, making us wonder if we were suddenly unable to do simple maths.

The relic issue was simply fixed by disabling Relic victory in a differenty way: By just placing 504 relics into an inaccessible corner. Can’t get all relics if you can’t get to all relics! The storm however we had to revamp multiple times until we had a conversion resistant version that worked reliably.

Tweaks, Tweaks, Tweaks

To understand why the final maps look like they look, we have to dive into the issues we had along the way. Our biggest concern has always been players messing with the storm mechanic. They could disable or speed up storm spawners, intentionally or unintentionally, or break a whole lot of other things. So we put a ring on it. Or rather around it. To prevent players from accessing the storm spawners with units.

Building the maps for Regicide Rumble 3
An early iteration. The jesus deer are storm spawners, the rocks prevent players from accessing the deer.

The first iteration of our storm had six waves, but did unfortunately not reliably damage units. So we switched up the storm units a bit and got it to do damage reliably, but only with three waves.

This also brought a new issue: Players were suddenly able to convert one of the gaia towers (wtf) used in the storm cycle. This led to deforestation on the map and annoying “Tower built!” noises and chat spam, making it impossible for the unfortunate player to read chat messages from the other players. That would be deadly in a game mode where communication with the players to plot against others is essential for success.

Our first attempt to solve this new issue was to move the barrier further away from the storm spawners, so that players could not get close enough to convert them anymore. Taking away more space from the already crammed map would shrink it way to much, so instead we increased the map size by ten tiles in each direction and moved the storm spawners outwards, effectively turning a “Large”map (220×220 tiles) into a “Giant” map (240×240 tiles). The resulting empty space was filled with deep water (to prevent resources like gold, stone, wood, or relics from spawning there) and stone heads on top (just for looks). I also had to fix “holes” in the map that resulted from moving the whole map down and to the right by ten tiles after increasing the map size. Looking at those “holes” for more than one second would reliably crash the game – not a good thing in general, and especially if you want to stream to an audience of 2000+ people around the world. The fix led to hills in the water, but it worked. Good enough for me!

Building the maps for Regicide Rumble 3
The water has hills, but at least the hills don’t have eyes.
The flying panthers are part of the storm spawners.

Now that we had that “dead space” around the outside, we could also have some fun with it, and write the name of the event with haystacks or something silly like that. We also placed three rings of torches on the map that indicated how far each “storm wave” would reach, since the storm currently lacks a visual indicator (apart from slowly killing units I guess).

Sadly, ten tiles is not enough to prevent for example a Cannon Galleon with a line of sight of 15 or a Trebuchet with a line of sight of 18 from converting those damn towers. In the end, we managed to fix the issue by replacing the bear in the damage cycle with a macaw. Nobody knows exactly why that worked, but it worked! Good enough for me.

The last week before the event was spent fixing small issues in the map scripts (our step 2), like resources not spawning in the center island on Migration, and adding a large patch of wood in the center of the scenario files of Grand Bara, Chaos Pit, Steppe, and King of Kings, to prevent players from running out of wood if the game goes long. We even managed to fit Pilgrims with a custom storm layout that only storms from two of the four sides, and has storm spawners on the eight starting islands in the corner of the map.

The morning before the start of the event, somebody noticed that players start with five out of five population after we had removed the spawns of extra villagers and houses the night before. This meant that players cannot start creating villagers right away, but would have to build a house first – a big deviation from the usual build order at the start of the game. That issue could luckily be fixed manually by replacing the scout with a horse, which does not take up population space, bringing it down to four out of five with room for one more. That was a (preventable) close call, but it worked out in the end.

Thank You

Before we go into what could be done better I would like to thank the whole team of Regicide Rumble 3. It was a pleasure working with so many motivated people of different skill levels across time zones. It’s quite funny when you wake up at eight in the morning to a new storm mechanic suggestion and reply with “I will try that out after work in about 10-12 hours, thanks”. Together, we did things I think had never been done before. Certainly, somebody will prove me wrong about that in the comments.

Light And Shadow

I used a git repository on GitHub for managing the scripts that were used. Sadly, not many in the map making community are proficient with git, so we could not use that directly to collaborate. Also, the python scripts were probably not usable for non-programmers. Making the whole process more accessible for non-programmers would be desirable.

During the whole time, I was the only one to have access to the unpatched scenario files since they were in the non-versioned output folder. That turned out to bite us when we added the clumps of wood in the centers of some scenario files. Motivated team members edited what they had access to – the patched scenario files from the ZR maps. Those were then not suitable to use in the pipeline because they already contained the storm spawners and torches. The work and had to be redone with the plain scenario files. The unpatched scenarios should definitely have been versioned and published in the git repository.

Also, due to my shallow understanding of what to look for when generating the scenario files, some maps had generations that were let’s say not ideal in the end.

Finally, it would probably have been sufficient to only place the storm spawners and torches in the scenario files, since we got the storm pretty tamper-proof. No stone barriers needed, no extra large maps with pixelated text on the border necessary.

You live and you learn. The Kings are dead, long live the Snipers!

  1. Regicide is the game mode where you lose the game if your King unit dies. See also.
  2. not thin air exactly, since the base scripts are there already, but still a lot of work to be done
  3. An obvious pun to make when writing about Regicide.
  4. In this case, 50 was an arbitrarily selected “high enough” number.