diff options
| author | Paweł Redman <pawel.redman@gmail.com> | 2026-06-16 00:59:44 +0200 |
|---|---|---|
| committer | Paweł Redman <pawel.redman@gmail.com> | 2026-06-16 00:59:44 +0200 |
| commit | 171ffcfb9b3c9aaf180e40af9e9956bf92f9c5ff (patch) | |
| tree | 3d739d9bf8251d5bfd11611af072bd125d6abdd6 /site/content/software | |
| parent | 6ecf59b7a764a1ec03289473a9735c10a9896211 (diff) | |
The Tremulous saga
Diffstat (limited to 'site/content/software')
| -rw-r--r-- | site/content/software/mapcat.typ | 25 | ||||
| -rw-r--r-- | site/content/software/tremulous.typ | 232 |
2 files changed, 255 insertions, 2 deletions
diff --git a/site/content/software/mapcat.typ b/site/content/software/mapcat.typ new file mode 100644 index 0000000..049c40c --- /dev/null +++ b/site/content/software/mapcat.typ @@ -0,0 +1,25 @@ +#import "/common.typ": post + +#show: post.with( + title: "mapcat", + author: "GPT 5.5", + date: datetime(year: 2026, month: 6, day: 15), +) + +#emph[(I generated this article with AI from mapcat's source code, so this text is in the public domain.)] + +mapcat is a tiny C program I wrote in 2016 for #link("https://redman.xyz/git/an_almango/")[An Almango], a Tremulous map made collaboratively with MaeJong. The problem was simple: GtkRadiant stores a whole map in one text file, which is not a great format for two people editing different rooms at the same time. So we split the map into parts and used mapcat to glue them back together before compiling. + +It is not clever. It parses Quake 3 `.map` files, appends all entities and brushes, keeps the first `worldspawn`, and writes out one big `.map` file. In An Almango's Makefile it was used like this: + +``` +mapcat maps/p0_master.map maps/p1_bases.map ... -o maps/analmango.map +``` + += Usage + +The source code is available at #link("https://redman.xyz/git/mapcat/")[mapcat]. Build it with the Makefile and put the resulting binary somewhere in your `PATH`. + +Each map part can define a `mapcat_prefix` key in its `worldspawn`. mapcat applies it to `target`, `targetname`, and `team` values so that two parts can both have an entity named `door_trigger` without breaking each other. Names starting with `global_` are left alone, which is how parts can intentionally talk to shared entities from the master map. + +There is also a small discard mechanism. An entity with `mapcat_discard` is thrown away, and any brush or patch textured with `common/discard` is skipped. This let us put editor-only helper geometry in a part without it showing up in the final map. diff --git a/site/content/software/tremulous.typ b/site/content/software/tremulous.typ index ba586ac..61076a0 100644 --- a/site/content/software/tremulous.typ +++ b/site/content/software/tremulous.typ @@ -1,10 +1,238 @@ -#import "/common.typ": post +#import "/common.typ": post, static, img, link-self #show: post.with( title: "Tremulous", date: datetime(year: 2026, month: 6, day: 15), ) -Tremulous was #footnote[testing the footnote] +Tremulous was a truly fascinating game. TODO: expand += The beginning +I discovered Tremulous in summer of 2006 through a random Polish forum. Coincidentally, it wasn't long after its 1.1.0 release, the version that held onto players until the very end. + +I was immediately hooked. TODO: expand + += Paint + +I very quickly got interested in how the game worked. At the age of 10, I believed I was too dumb to learn programming. I understood nothing about what an .exe even was. I'd open one in Notepad and wonder, "who writes this?!" + +Instead, I turned to mapping. Mapping is the art of designing and building the playable area of a video game. In Tremulous this meant arranging 3D shapes in GtkRadiant into walls, floors, doors, obstacles, and so on. You'd then wallpaper the shapes with images (textures), place lights, compile and load the finished file into the game to playtest. + +In 2007, I released "Paint." It was arguably the most polarizing map in the game's history. It had fierce hates -- for obvious reasons -- but also many people loved it. I'll let screenshots speak for themselves. + +#figure( + img(static("software/tremulous/shot0022.jpg")), + caption: [Paint, main area (October 2007)], +) + +The idea for the first Paint wasn't actually original. I basically copied an Unreal Tournament map with the same name, of which I can't find any traces anymore. + +I kept iterating and made many more Paints over the years. I quickly outgrew the "flat houses" idea from that UT map with each Paint getting progressively more ambitious/deranged. + +#figure( + img(static("software/tremulous/shot0023.jpg")), + caption: [Paint 5, expanded main area (December 2007)], +) + +I found an #link("https://forum.tremulous.net/index.php?topic=7427.0")[an ancient forum thread] of me announcing Paint 7 on tremulous.net. Nothing too interesting, but it's cool to see how much better my English has gotten since. + +#figure( + img(static("software/tremulous/shot0024.jpg")), + caption: [Paint 7, tech/fog hall (2008)], +) + +#figure( + img(static("software/tremulous/shot0025.jpg")), + caption: [Paint 7, bouncy space room], +) + +Paint 7 was the most played of the series by a good margin. It had a special, secret control room. If you raced the other team to it and built your base there first, you'd be undefeatable. Also, you'd had a button that played the Benny Hill theme song and shook the entire map. Each game was a trainwreck. + +In later Paints, I tried improving playability, removed the control room and essentially ruined the fun. Worse still, I decided Paint 10 should be serious, disabled fullbright and used photorealistic textures. + +#figure( + img(static("software/tremulous/unvanquished_2026-06-15_211812_000.jpg")), + caption: [Paint 10, alien outside], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-15_211740_000.jpg")), + caption: [Paint 10, main area (2011)], +) + +In retrospect, Paint 7 was a perfect comedic relief to play in-between serious games and I inadvertently left my niche by trying to make a proper map. + += Redfusion + +Tremfusion was an improved client for Tremulous. To me, the best feature was advanced scripting. + +At some point, I learned enough programming to mod the game's client. I expanded Tremfusion's scripting language and sent the source to a couple of friends as Redfusion. Unfortunately, it most likely has been lost to the sands of time. + += Cuboid + +I spent a lot of time playing on Rotačák's R Unlimited CZ. He later went on to release #link("https://store.steampowered.com/app/634070/Murnatan/")[Murnatan] on Steam, a remake of Tremulous, which sadly completely flopped. + +His mod let players build as many buildings as they wanted (stock Tremulous is very conservative), build them on top of each other, and also added structural buildings like crates. Games got quite sophisticated with both teams building elaborate forts. + +I wanted to expand on the idea and created #link("https://github.com/enneract/cuboid")[Cuboid] in 2013. This was also my first ever Git repository. You can tell I had barely any clue what I was doing from how I would make one commit per release. + +Cuboid added scalable buildings to the game. You could build cuboids out of concrete, slime (alien counterpart), glass, and so on. This gave you enough freedom to build rooms, bridges, whatever you could imagine. I also tried #link("https://www.youtube.com/watch?v=WLgi1Eo_ugg")[redesigning the power system for humans] by turning it into a physically-accurate electrical circuit simulator. + +It was completely overengineered and didn't gain much popularity. Still, I have very fond memories of no-lifing the first version in two weeks over a spring break. + += Unvanquished + +Around 2014-2015, I was an active contributor to #link("https://unvanquished.net/")[Unvanquished], the spiritual successor to Tremulous. I implemented beacons, Borderlands-style damage indicators and helped artists import a whole bunch of models into the game. + +The project was under very active development until kharnov, the project head, suddenly had to leave due to personal reasons. I lost interest shortly after. + += New EDGE + +New EDGE was a continuation of EDGE, which itself was a continuation of Rotačák's mod. New buildings, new aliens, new guns, many new original and high-quality assets. It was a lot of fun. + +TODO: add screenshots + +I eventually became a quite prolific contributor, adding many more new ideas. #link("https://github.com/mtiusane/new-edge")[The repository] is still up. + += GrangerHub + +By 2015 or so, the playerbase had been divided between the old 1.1.0 and the never-finished 1.2.0 for years. The former was much more active with New EDGE being the only populated 1.2 server left. + +At some point, GrangerHub developed multiprotocol server software -- one Tremulous daemon could serve both 1.1 and 1.2 players. Unfortunately, the community was led by bad actors who kept the server code to themselves. It would only be shared with New EDGE if GrangerHub took control over it. We refused. + +Predictably, New EDGE was soon starved of players and we all resentfully switched to GrangerPub, the multiprotocol server running 1.1. I remember spending countless hours arguing on the GrangerHub forum, lamenting how badly against the spirit of open-source their actions were. (They never distributed server binaries, so legally they never had to release the GPL code.) + +They kept stalling, saying the code wasn't ready and that they would release the mythical "1.3.0" soon. + += An Almango + +In 2016, I met MaeJong, a mapper and one of GrangerPub's top admins. We teamed up to create the only (as far as I know) collaborative map. For this purpose, I created #link-self("software/mapcat")[mapcat]. We worked on smaller segments of the map in parallel and used the tool to automatically join them all together. + +The end result is An Almango (no, not "anal mango"), a very strange map that was never really meant to be played, but rather to be explored. It's essentially a much more ambitious Paint, made by adults (if you can believe it) with an eccentric sense of humor. It was finished in 2018. + +Some areas are genuinely well-made and look nice: + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_001338_000.jpg")), + caption: [MaeJong's alien base], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000313_000.jpg")), + caption: [Hydraulic press room], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000339_000.jpg")), + caption: [Grated catwalks leading to the reactor, modelled in Blender then imported into NetRadiant], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000412_000.jpg")), + caption: [The reactor], +) + +#figure( + img(static("software/tremulous/shot0026.jpg")), + caption: [MaeJong's plant room above the alien base], +) + +However, most of the map is "stream of consciousness" type of nonsense: + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000145_000.jpg")), + caption: [Main area], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_001649_000.jpg")), + caption: [A different view on the main area with a Gaussian surface visible in the distance], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000208_000.jpg")), + caption: [The common area, a pun on the `common/` texture pack used internally by the game engine], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000235_000.jpg")), + caption: [Weird maze with scrolling textures and one-way passages], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000537_000.jpg")), + caption: [Dretch Pwner, a minigame where a Dretch (a small alien) would enter the contraption and other players would try to crush them using the red buttons. If the Dretch survives, they get into a Paint-style control room with dumb and obnoxious buttons to press.], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_000516_000.jpg")), + caption: [Unable to determine context or content of above screenshot], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_004028_000.jpg")), + caption: [The first and last time I ever drew anime], +) + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_001329_000.jpg")), + caption: [An homage to #link("https://www.youtube.com/watch?v=ebba3zVktX0")[PacificSound3003]], +) + + +#figure( + img(static("software/tremulous/unvanquished_2026-06-16_001602_000.jpg")), + caption: ["Nevermind, the sausage was fine after all" -- a reference to Transit, a classic Tremulous map], +) + +The map has been ported to Unvanquished and is still playable there. + += Zittrig / Der Bunker + +It turned out that the source code debate was just one issue. The whole GrangerHub was grossly mismanaged. MaeJong, other top admins and even DevHC --- multiprotocol's author --- all defected. Together we created Der Bunker, a new multiprotocol server. + +To quickly move players over, we launched Operation 137. MaeJong and DevHC, who still had access to GrangerPub's server console, set the server framerate so low that the game was barely playable. Players stuttered heavily, the scoreboard bugged out and displayed everyone's pings as 137 milliseconds, hence the name. GH leads had no idea what was going on, the server depopulated within days and never recovered. + +It was a nasty, hostile takeover. + +Not long after, I publicly released the multiprotocol server code. I still host a copy of it at #link("https://redman.xyz/git/zittrig-4/")[zittrig-4] (and #link("https://github.com/enneract/AA-QVM")[AA-QVM] for the QVM/gamelogic side). + +Der Bunker's history was mostly uneventful after this drama blew over. I'll give myself some credit for its stability and longevity. I insisted that, from the very beginning, we'd have: + +- No benevolent dictator for life. Four people (DevHC, Kai, Majeong and I) had full access and authority over the server. +- Minimal moderation. Everything was allowed unless it actively disrupted gameplay (killing your teammates, destroying your own base, etc.) or was illegal IRL. Leadership had to be transparent and open to criticism, otherwise we'd end up with another GrangerHub situation. + +#link("https://www.youtube.com/watch?v=y2-tbdolriU")[ZdrytchX] uploaded many gameplay videos from this era (and earlier years) to his YouTube channel. + += Schachtmeister + +Speaking of minimal moderation, the flip side was that we went #emph[hard] on people who purposefully ruined the game for others. + +In particular, we had one very special player. Desala would routinely cause serious problems, get banned then quickly evade the ban using a VPN, over and over again. He was by far the most persistent troll I've ever encountered. You could ban him 10 times over and he'd still come back, somehow. + +So, I went scorched-earth and developed #link-self("software/schachtmeister2")[Schachtmeister], together with DevHC who integrated it with Tremulous. The idea was quite simple but surprisingly effective. Schachtmeister looked up every player's WHOIS and reverse DNS records, and compared them with a known-bad database. This way, we could ban #emph[entire] VPN providers all at once. Even ISPs with dynamic IPs like UPC (apparently Desala's home internet provider) wouldn't save you --- Schachtmeister flagged those and gave all admins a heads-up. + +The database grew very quickly. Desala either ran out of VPNs, money or patience and stared behaving. RIP, bozo. + +Fun aside: Schachtmeister is a deliberate misspelling of Schachmeister (German for "chess master"). Yalt, a German mapper/modder, named one of the areas in one of his maps "Ventillationsschacht" ("ventilation shaft"). This comically long name would often appear in team chats and we eventually started using "schacht" as a generic insult, basically meaning "dumbass". Hence, the "master of dumbasses". + += The pandemic + +Tremulous saw a resurgence during the pandemic. It wasn't uncommon to see the server so full that it was barely playable. Like in the good old days. + +Around that time, Der Bunker hosted a couple of special events. I have two videos from April Fools' Day in 2021 when we turned the game into absolute brainrot: #link("https://www.youtube.com/watch?v=iwV8kzOahBM")[glourno_2021] and #link("https://www.youtube.com/watch?v=jMbMUVjzCkI")[glourno_2021: Aliens]. The Christmas mod in 2020 was even dumber, but I don't have any clips at hand. + += The end + +I eventually lost interest and handed Kai full control over the server. Around 2025, Der Bunker died a natural death as the last Tremulous server. + +As of writing, Kai still hosts Der Bunker in Unvanquished, and I very occassionally contribute to the project. + +#figure( + img( + static("software/tremulous/unvanquished_2026-06-15_225811_000.jpg"), + alt: "A grave with a tombstone that reads: Tremulous / 2006 - 2019 / Forever in our hearts. Screenshot from An Almango.", + ), + caption: [This prediction probably would've been accurate had it not been for the pandemic (An Almango, 2018).], +) |
