Nerdy creations with numbers, words, sounds, and pixels

Art, Games, Science

Billennium

Upper grid controls:

  • swiping left/right changes the hue (color) of the tribes, food sources, and backgrounds
  • tapping twice makes the hue jump to the next preset value, all of which my sister selected (TODO)

Lower grid controls:

  • swiping left/right changes the overall tick rate (speed)
  • tapping twice allows you to jump between five preset speeds (or back to the slowest speed if the current is not among the preset values, because I felt that a brake function was needed at extreme speeds)

Background

This cellular automaton is a gift for my sister, who wanted art for her birthday. For the sole reason of being cryptic, I hid the easter egg ⓝⓐⓝⓞⓒⓛⓞⓤⓣ in there, meaning “tiny influence,” a reference to my her moniker on Instagram. However, Billennium also is heavily inspired by a previous ant colony simulation I developed in MATLAB, mostly for science and a good grade in English B2. Therefore, I find it difficult to categorize this post. I will focus mostly on design decisions and provide technical details on occasion. The codebase was created with Gemini Pro 3.1, amounting to 2,000 lines of code, while the cellular rules and input data (script header, animation files) were made by me. This narrowed down development to:

  1. a far too long period of creative contemplation,
  2. lots of wasted tokens due to aggregated incommunicability,
  3. and, ultimately, balancing issues. That’s why Billennium is—apart from art and science project—also a game. Only I got to play it, though.

The old colony featured a large polar grid of pixel-like “ants,” gathering food from accidentally found sources. Except for a "scout" variable that made some ants remember the location of the nest (“Guys, it was [0,0] all along!”), there were only one type of ants. Now there are six, and they are not even ants anymore. Where there used to be four tribes competing, only two remain, the One on the bottom vs. the Zero on top. However, the old simulation was unbalanced and would always end up with either all ants dying or all tribes so buried in food that nothing was ever at stake between them. By comparison, the old map was also sparsely populated, whereas I wanted a small, compact grid that could be filled with une grosse douzaine of Unicode symbols.

Additionally, the old ants used a pheromone compass similar to the real deal, which I cut in favor of rules similar to chess. It ended up slightly more complex because the “pieces” (fka. “ants” ((I now call them “Antoids”))) are often composed of multiple cells—a molecular system of heads and tails—and have different cell counts, depending on the state they are in: unless Antoids are idle, which rarely happens, they search until they find either food or enemy, which they gather or fight. When attacked, they can consume their own food to heal, or fellow Antoids bring some over, creating accidental supply chains that may decide over victory or defeat whenever the heavies clash in battle. They attempt to flee when their health falls below a threshold, but also return collected food to their nests. (The breed systems only concerns types C and F.) Killed enemies are looted, and what does not fit into an Antoid’s inventory is left behind as a secondary food source.

Antoids

Since the main focus lay on designing the six different Antoid types, I will go over them but leave it up to you to identify them by all their states in the animation:

✶ Workers (type A) are small, quick, and inexpensive. They cannot attack, focusing entirely on swarming the board in large numbers (up to 8 per tribe) and gathering small amounts of food. Because they consist of just a single cell, they can easily navigate tight spaces on the grid but get pushed around a lot.

✠ Warriors (type B) are basic, two-segmented combat units that prioritize fighting and looting fallen enemies rather than harvesting natural food. Late during development, I added a “slithering” mechanic that allows them to smoothly glide around corners to squeeze through one-cell gaps. When critically injured, they can quickly swap their head and tail positions to instantly reverse direction and flee, which makes them surprisingly hard to kill despite their mediocre stats.

⚯ Drones (type C) are the fastest units in the game, often switching between single and dual cell configurations, but their movement is restricted to vertical and diagonal steps. They have combat abilities, although their primary purpose is to fertilize their Queen, which is a requirement for the tribe to breed high-tier units of type D or E. Drones also possess a special mobility trait, allowing them to sacrifice a piece of carried food to leap directly over obstacles.

⛥ Hydras (type D) are aggressive mid-tier units, great for harvests, raids, or defense. When healthy and engaged with targets, they can spawn a second head to execute multi-directional pincer attacks. This second head also allows them to gather at twice the speed, even from different food sources.

✪ Tanks (type E) are slow-moving 2×2 juggernauts with the highest health, attack, and defense stats of all standard units. They move using a cumbersome two-step chain mechanism, during which they take double damage, but they aggressively lock onto any enemy that strikes them. Due to their sheer size, they do not gather food normally but instead automatically crush any food they roll over, only picking up the spoils.

◒ Queens (type F) are the colossal leaders of the tribe that have immense health and coordinate all base logistics. They can only move sideways, never leaving the bottom or top row, and they move their two heads independently, to make room if necessary. Queens automatically consume the tribe’s food stocks to heal injured units or themselves and spawn new Antoids based on a dynamic calculation of the current army’s deficits. If a Queen dies, her tribe is doomed to go extinct, thereby finishing the current cycle.

Initially planned starting positions of all Antoids; obsolete now, but shows how many units there are at most and which shape they assume in idle state.

My original idea was to lay out the Antoids in a tightly packed initial array, with only the central battlefield as a buffer, like in chess. Out of fear it might overwhelm the observer, I let myself be inspired by Age of Empires and let the Queen (“her royal Town Center?”) start out with morsels of food to spawn all her units from scratch. In a moment of cunning, I also ruled that a Queen can only spawn a particular type if she has all lower-tier types on the field. This requires the Antoids to flee and heal more often, as the Queen would otherwise always be occupied with respawning cannon fodder. No need to mention that the costs increase progressively with each type.

Refinements

Another feature I borrowed from my previous ant simulation is the seasons system; the total number of food sources on the field varies during the course of a “year” (150,403 ticks), following a cosine curve that starts with plenty sources in summer, but gradually makes it harder for the tribes to prosper and spawn new Antoids during winter. After I eliminated some directional biases causing the Zero tribe to win like cheaters, I fine-tuned many variables, such as attack, defense, health, and inventory capacity of every Antoid type, to get into the sweet spot where Queens would die from time to time, but never too quickly.

This still felt a bit boring, as the winner would always be determined early on, always being the tribe that gathered more food in the beginning due to luck at RNG. This reminded me of Age of Empires again (all but boring, in fact rather stressful), where you are similarly screwed in multiplayer if you forget to collect all lost sheep within 40-or-so seconds. Hence, I introduced a simple yet highly effective system to rebalance the odds: whenever a tribe is close to losing (i.e., it has no Antoids except the Queen or less food than the amount it started with), all food sources are spawned one cell closer to their Queen. More often than not, this allows a tribe to recover, supersede the other tribe, and almost annihilate it, until the switch is flicked again, eventually.

I was surprised to see that the automaton could run at a million frames per second because the logic loop is decoupled from the render loop. Since this is only useful for detecting edge cases, I limited the maximum tick rate in the release version to 65,536 Hz, which is still a lot faster than necessary, reducing a simulated year to 2.3 real world seconds.

⋆⁺₊⋆ ☀︎ ⋆⁺₊⋆12

To sum it up, Billennium is equally art, science, and game—borth birthday present and testament to how broken and utterly unnecessary humanoid wars are in 2026. Let’s end the post with this lament in mind and decide not to be controlled by algorithms wherever possible.

← Return to “Simulation”

← Return to “Science”

  1. Subtle cue to Made In Text, a site I like to use for my Unicode automata. ↩︎
  2. This is the second footnote I ever used on my website, but it looks like the twelfth. ↩︎

Leave a Reply