GUI Map loading in 2 player mods.

Starting a 2 player game with the GUI

A DOOM Eternal mod can be optimized for 2 players. However, the ready up system will only work with 3 players in the lobby, so an alternative method of loading the maps is needed. The loaddevmenuoption console command can forcefully load a multiplayer mod even with 1 or 2 players. Since many players will not want to enter commands, this guide will outline a more convenient graphical method.

Modifying the lobby menu to set a cvar.

HUD and menu modding in DOOM Eternal is very limited. While executing commands from a SWF is not known to be possible, there is an ActionScript function in Eternal's flash interpreter for setting Console Variables. Here's how to do this with Free Flash Decompiler:

Mandatory - code for cvar output.

internal function frame41() : *
      {
         if(this.label.txtVal.text == "Forsaken")
         {
            setCVarInteger("g_demonSelect",1);
         }
         if(this.label.txtVal.text == "Penance")
         {
            setCVarInteger("g_demonSelect",2);
         }
         if(this.label.txtVal.text == "Tundra")
         {
            setCVarInteger("g_demonSelect",3);
         }
	}

The code will detect the string's contents, not the identifier. Either modify the strings referenced by the map info decls such that the maps have the same name consistently across localizations, or add individual translations to the ActionScript code. If you neglect this step, the code will not be effective for players that run the game in a language other than the one your multiplayer mod was tested with.

g_demonSelect was chosen because it does not have an impact on anything in the game engine, it appears to have only been added to be checked by the logic entity in the demon tutorial, which a player is not likely to enter while a multiplayer mod is installed.

Optional - code to split the map list into two columns.

      internal function frame2() : *
      {
         this.itemIndex = strReplace(this.name,"item","") * 1;
         this.wrapIndex = 8;
         if(this.itemIndex > this.wrapIndex)
         {
            if(this.x == 0)
            {
               this.x = 900;
               this.y -= 110 * (this.wrapIndex + 1);
            }
         }
      }
      internal function frame78() : *
      {
         this.itemIndex = strReplace(this.name,"item","") * 1;
         this.wrapIndex = 8;
         if(this.itemIndex > this.wrapIndex)
         {
            if(this.x == 0)
            {
               this.x = 900;
               this.y -= 110 * (this.wrapIndex + 1);
            }
         }
      }

Editing the Logic Entity.

In the shell entities file, add an idTarget_Command entity for each map to load using the loaddevmenuoption command. You should also add an idTarget_Command executing any variables that optimize your mod if you have not done so already. Append g_demonSelect 0 to it such that a map loading command does not get executed prematurely when the players exit a map back to the lobby menu. In the logic entity editor, add the following nodes to execute these command entities:

Optional - add a "random map" entry.

If your mod contains several levels, you can add options for selecting a random map, just for fun. In the logic entity editor's properties dialog, add a variable of the type Entity/List, and add all the target command entities. If desired, you can add multiple variables, for example, a separate option that picks only the Battlemode maps. Add your node for each custom variable you added. Connect your custom variable node to a get random entity node, then connect it's entity pin to another activate entity node, which is triggered by the corresponding integer that was added for the random option.

See also


Revision #1
Created 8 September 2026 00:43:05 by Alby
Updated 8 September 2026 00:50:24 by Alby