From 9775887a4e3197c19edd456f17e59352b636e11b Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Thu, 18 Jun 2026 22:33:37 +0200 Subject: More Tremulous content, rewrite mapcat --- site/content/software/mapcat.typ | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'site/content/software/mapcat.typ') diff --git a/site/content/software/mapcat.typ b/site/content/software/mapcat.typ index 049c40c..ad90def 100644 --- a/site/content/software/mapcat.typ +++ b/site/content/software/mapcat.typ @@ -1,25 +1,30 @@ -#import "/common.typ": post +#import "/common.typ": post, link-self #show: post.with( title: "mapcat", - author: "GPT 5.5", - date: datetime(year: 2026, month: 6, day: 15), + date: datetime(year: 2026, month: 6, day: 18), ) -#emph[(I generated this article with AI from mapcat's source code, so this text is in the public domain.)] +mapcat is a tool that concatenates Tremulous maps. -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 was created for #link-self("software/tremulous#an-almango")[An Almango], a map that was made in collaboration with MaeJong. We worked on smaller segments in parallel, then the tool assembled them into the complete map. -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: += Usage + +The source code is available #link("https://redman.xyz/git/mapcat/")[here]. Usage is simply: ``` -mapcat maps/p0_master.map maps/p1_bases.map ... -o maps/analmango.map +mapcat part_1.map part_2.map ... -o whole.map ``` -= Usage += Designing parts + +This tool wouldn't be very useful if all it did was join all the brushes and entities together. + +Individual parts are meant to be playable in isolation. To achieve this, cover holes (where other parts connect) with `common/discard`. All brushes with this texture are completely deleted by `mapcat`. -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`. +Entities are dealt with using the `mapcat_prefix` key in each of the part's `worldspawn`. The prefix will be added to `target`s, `targetname`s and `team`s, so entities from different parts won't interfere with each other. -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. +Names starting with `global_` don't get this prefix, so you can wire entities across the entire map if you need to. -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. +See #link("https://redman.xyz/git/an_almango")[an_almango] source files for how this is all done. -- cgit