
Zugnaex is an open-source multiplayer DOOM-compatible mod that uses a Python-based battle service to manage zones. Here are some technical details for anyone interested.
The pentagram part is intentional. This tech defines boundaries (zones), coordinates processes, and controls complex behavior across a distributed system. Without boundaries, you can’t control the system. The daemons from the technical side are the processes. The demons from the story are not discussed here.
With this approach you move the game rules out of the game engine. So instead of one server equals one match at a time, there is a service layer that manages gameplay across multiple servers.
Example: Kneed Time Battle Mode
The code clip below is the zone setup and game rules. There are also server configuration files that define variables like time limits. For display on the client, there are battle info and status variables defined with a simple markup language that supports formatted text, timers, and borders so players know what to do. Super basic but effective and efficient.
# Kneed Time battle mode example
# License: MIT (please see full source for licensing & copyright)
# ...
class KneedTime(Battle):
name = 'Kneed Time'
desc = 'Finish a random Episode 1 map in par.'
def start_battle(self):
super().start_battle()
pick = random.randint(1, 9) if not self.debug else 1
par = [ None, 30, 75, 120, 90, 165, 180, 180, 30, 165 ][pick]
map = f'E1M{pick}'
# LOBBY L1 M1
self.start_zone('zone1', 'z1', 10666, 'L1M1', 'doom.wad dbz-lobby-v2.wad')
# DOOM E1 M1-M9
self.start_zone('zone2', 'z2', 11666, map, 'doom.wad', f'+set sv_level_seconds {par}')
def on_exit_level(self, zone, playerinfo):
super().on_exit_level(zone, playerinfo)
if zone == 'zone1':
self.transfer_player('zone2')
elif zone == 'zone2':
# you win the battle!
self.battle_over(zone, True)
This mode spawns a lobby and a random E1 map with an exit timer equal to par then waits for the player to zone. If a player makes it out of the last zone in time, that player wins the battle. If time runs out or the player dies, that player loses the battle (handled in the base class). There is more code to handle battle requests from the clients, manage the zones, dynamically load battles, issue commands, and track player state. You put common functionality in the base Battle class then the modes you create stay simple.
The goal of this mod is to allow you to play, learn and create. You can play and experience the story we created by connecting online, if you're able. You can learn the tech by reading the source code and running the battles on your PC. And you can create your own stories using the examples for reference. In the stories you create, you can destroy reality too or maybe have a happy ending instead.
Your feedback is very welcome!