Hubs not drubs
How to logically connect maps and use puzzle pieces
In this article we will discuss the various ways the maps within an episode can be connected together in order to form such a whole unit.
Going back and forth
The first and most evident trait of an Hexen II episode is that the maps don't form a forward-only succession but can be navigated back and forth, allowing as many backtrackings as you wish (and sometimes more that you actually wish if you have no idea what to do next, but that's another topic which is enough covered in Follow the Yellow Brick Road).Quitting one map to the next is pretty simple. Basically you need
- A trigger_changelevel in map #1 (origin) whose map property contains the name of map #2 (actually the name of its bsp file without extension)
- An info_player_start in map #2 (destination) where the player will spawn
Puzzle pieces
Some doors or triggers require a "puzzle piece", otherwise they will refuse to open or do anything. That makes a PP (puzzle piece) very similar to a key in Doom or Quake, except that it can take the form of a more fancy artefact (bones, potion, lens, scepter...) which offers a pleasant variety and more interesting/meaningful puzzles to solve.The entities susceptible to be made PP-dependent are: func_door, func_door_rotating, func_door_secret, trigger_activate, trigger_multiple and trigger_once.
Each of them is told which puzzle piece it needs by setting the corresponding PP name in its puzzle_piece_1 property. Actually an entity can be told to need up to four PPs thanks to the puzzle_piece_1 to puzzle_piece_4 properties! Sounds a bit too much? Yes it is, and they at Raven did never use that feature actually. But it does work, I found a use for it in Ice Lake to deal with the net + catch fisherman's puzzle.
The PP-dependent entities also feature additional interesting features:
- What message they should display as long as the player doesn't have the needed PP yet (no_puzzle_msg property)
- Whether firing the entity takes the PP off the player's inventory ("Remove puzzle" spawnflag): the only reason why it shouldn't be checked is that the same PP will trigger multiple things, but as long as the player won't need the PP anymore the good practice is to make sure it's taken out of their inventory, otherwise it could cause a long lasting confusion and inventory mess. Multi-use PP is a weird concept anyway, better stay out of it.
- Whether firing the entity needs the player NOT having the PP ("No puzzle" spawnflag). Doesn't seem anyone felt like using it so far, but still an interesting concept (the lack of the key could not only prevent the door from opening but also trigger a deadly trap, who knows).
⚠ Caution with names, tho. There is a largely ignored Hexen II feature cryptically called Info / Frags bound to the 'Q' key to display the player's current puzzle pieces inventory with their names (unlike the traditional HUD showing pictures only without names). The problem is: the names don't come from the netname properties but from the puzzles.txt file instead! So if you use custom names for stock PPs or add your own custom PPs, be sure to bring your custom puzzles.txt as well. Its structure is simple: The first line tells how many lines follow, the others lines are puzzle_id netname (with a regular space between them; the netname itself can contain additional spaces). The file can be sorted for convenience: the lines order is not relevant.
Comprehensive list of all the puzzle pieces of vanilla Hexen II + Portal Of Praevus with the corresponding puzzle_id
(Click on the picture to enlarge)
In order to view the PP 3D model directly in TrenchBroom, replace the puzzle_piece entity definition in your hexen2.fgd file by the one below. Thanks to this definition, you can change the PP's puzzle_id property and see the 3D model instantly updated in the editor. Very handy!
@PointClass base(Appearflags, Targetname, Target) size(-8 -8 -8, 8 8 16) color(80 0 200) model({ "path": "models/puzzle/"+puzzle_id+".mdl" })= puzzle_piece : "Puzzle piece" [ spawnflags(Flags) = [ 1 : "Spawn" : 0 2 : "Floating" : 0 4 : "Auto get" : 0 ] puzzle_id(string) : "Puzzle id (no path/.mdl)" message(string) : "Message" netname(string) : "Puzzle piece name displayed when picked up" ]
A PP may take a few spawnflags:
- "Spawn": The PP is not there from the beginning waiting for the player to pick it up; it only spawns to existence when triggered (like in demo1 - Blackmarsh with the Bones of Loric and the Mithril Transmutation).
- "Floating": ???
- "Auto get": To get the PP the player won't actually pick it up like a normal artefact but trigger it instead. Not used in vanilla maps but very useful for some complex settings where the actual PP is not directly something the player can normally pick up (like a catch for the fisherman in Wheel Of Karma's Ice Lake). Beware it will only work if the player is less than 200 units away from the puzzle_piece entity when they trigger it.
Confusing at first, another entity called puzzle_static_piece also exists. Similarly, puzzle_id is used to specify the 3D model. But this time the entity is only decorative stuff. It's used when the PP picked up by the player had to be brought by them to their final resting place (like the skulls from Mazaera or the crowns of Egypt). When the player arrives to where the PP must be dropped off, what happens behind the scene if that they trigger a PP-dependent trigger_once which removes the PP from the player's inventory and triggers the puzzle_static_piece to make the model spawn at the right place.
Having spoken several times about the player's inventory, it's time to make it clear that there's a separate inventory for PPs which is not the one used for the various boosters like Quartz flasks, Craters of Might, Glyphs of the Ancients, etc. Although being two distinct storage spaces, they share a common characterics which is that they follow the player wherever they go, and notably from one map to another.
And that's how we come full circle back to our core problematics which is connecting maps together: PPs are an essential part of the connection since they are objects the player is able to pick up in one map and carry to another map to trigger things there. That is actually the most common and straightforward way to set up cross-maps puzzles.
Cross-level triggers
Cross-level triggers are the other possible way to go. It's what you use when you want a player's action in map #1 (like pressing a button) trigger something in map #2 (like a new section of that map opening). Obviously it doesn't especially require any PP.It's fairly simple to set up:
- In map #1 put a trigger_crosslevel entity and check any of its "Trigger 1" to "Trigger 8" spawnflags.
- In map #2 put a trigger_crosslevel_target entity and check the same "Trigger 1" to "Trigger 8" spawnflag.
When the trigger in map #1 is fired, it sets a server flag corresponding to its checked spawnflag. When the player enters a new map, the game checks all the possible trigger_crosslevel_target entities there and triggers them if their own spawnflag correspond to a server flag previously set.
Since the activation depends on a server flag, it's not a map-specific thing: the same trigger_crosslevel may trigger several trigger_crosslevel_targets throughout the whole episode. You have no way to specify that only the trigger_crosslevel_target located in such or such map should be fired: all of them will be fired anyways upon player arrival. So don't trust the presence of the map property sometimes found in incorrect fgd files: it's useless.
Another thing concerning trigger_crosslevels is that there are only 8 available flags. Hopefully that would be enough for your needs but if you plan to rely a lot on cross-level activations, 8 might feel short. It's all the more true if you consider implementing cross-episode triggers (not a vanilla thing, but read Ending on a high note to learn how to do that, along with many other interesting things!). It seems that Raven had considered implementing (and actually coded) a way to reset the server flags and allow some reuse of the slots without changing episode, but the code involving a trigger_check entity looks pretty weird and was never used in the game, so there's no guarantee it's anything more than the forgotten vestige of a trashed idea. Better leave that away and do with what we have. Eight available flags per episode are really not so bad already, and you can always use puzzle pieces on top of that for even more (and more diversified) cross-maps interactions.
Touch
Let's not leave this page without a few lines about the touch.Although Quake's start map might technically be considered a kind of hub map where the runes play the role of puzzle pieces, it doesn't really fit the common acceptation of the term because it's rather used like a "playable menu" at game level. Concerning Doom or Heretic, they obviously lack any hub system or similar mechanics. Yet each one of those games' episodes has its own coherence brought by a common overall theme, matching ambiences, textures and architectures, relevant monsters, and an increasing difficulty as the player gets closer to the end of the episode (and in all probability a boss battle or any kind of climactic ending).
Each Hexen II episode has a very strong identity thanks to its maps representing places all located in the same continent. They share the same kind of visuals, use the same sets of buttons, the same distinctive cross-map portals (skull doors in Blackmarsh, trapezoid doors in Mazaera, etc.), feature specific unique monsters and tell a small story of their own through various plaques and successive puzzles conveying sub narrative arcs (quest for the bones of Loric and the Castle key, then quest to get to the Altar of Hunger then quest of the Crystal Golem...). On top of that, each episode in Hexen II has its own flavor as far as gameplay is concerned: clever interwoven puzzles in Blackmarsh, lots of platforms and jumps in Mazaera, straightforward puzzles and hidden rewards in Septimus, etc.
Those things are all about atmosphere, distinctive touch, and direct or indirect storytelling. And they are what tie a bunch of maps together into an episode at least as much as the cross-level mechanics described above. Don't underrate that aspect when working on an episode. A set of maps doesn't automatically make an episode in its own right just because they're connected by portals: they might as well form a mismatched hodgepodge if you don't pay attention.
What if you'd like to make an episode out of heterogeneous maps, tho? Then take the vanilla Hexen II way: make your storyline revolve around items dispatched in very different parts of the world and needing to be gathered. That trick tied a whole game together allowing it to feature Middle Ages, Ancient Egypt, Mesoamerica and Greece seamlessly. Why not your own content, then?
Want to ask for clarification, report an issue with this trick or propose another one? Drop me an email
If you use the trick please credit me and put a link to this website.
