Creating the game JSON file
Before we can get started with loading a game into ap_gen_tool, we first need to create a JSON file to tell it what the name of the game is, and what WAD files and levels it should be looking for. Though game JSONs are relatively versatile (and thus, relatively complex), for now we're just going to focus on the bare minimum we need to get something loaded into ap_gen_tool.
Let's get started by creating an empty file named "zone300.game.json". Zone 300 is the game we're going to be working with for this tutorial, and ".game.json" is the extension for game JSON files.
After creating the new file, open it in a text editor and add a set of curly braces, { }; like so:
Now, we need to start adding some fields to this object.
Let's get started by creating an empty file named "zone300.game.json". Zone 300 is the game we're going to be working with for this tutorial, and ".game.json" is the extension for game JSON files.
After creating the new file, open it in a text editor and add a set of curly braces, { }; like so:
{
// When adding things, they should go between these outer braces
// Remember to add commas after every element except the last one
}
Now, we need to start adding some fields to this object.
Names
The first four fields we need to add are various names for the game, used to help identify it throughout Archipelago, Archipelago Doom, and ap_gen_tool.
- "short_name": A short, unique name for the game; usually the name of the wad file itself.
Determines where save files are stored, among many other things. - "full_name": The full name of the game, complete with subtitles, if any are present.
This is the name shown to players in the launcher. - "ap_name": The name that Archipelago will refer to the game by.
It should be prefixed with the name of the base game, and shouldn't contain subtitles. - "ap_world_name": The name of the generated APWorld file, without the .apworld extension.
It should also be prefixed with the short name of the base game.
{
"short_name": "zone300",
"full_name": "Zone 300",
"ap_name": "DOOM II - Zone 300",
"ap_world_name": "doom2_zone300"
}
WAD Files
The next two fields we need to add to the game JSON file tell Archipelago Doom and ap_gen_tool what files contain the game data for our game.
- "iwad": The WAD file of the base game.
This would be "DOOM.WAD" for Doom 1993, "DOOM2.WAD" for Doom 2, etc. - "required_wads": Which additional WAD file (or files) are necessary for your game.
Can either be a single string, or if more than one file is necessary, an array of strings.
{
"short_name": "zone300",
"full_name": "Zone 300",
"ap_name": "DOOM II - Zone 300",
"ap_world_name": "doom2_zone300",
"iwad": "DOOM2.WAD",
"required_wads": "zone300.wad"
}
Episodes
The last bit of information that we need to load a new game into ap_gen_tool is a list of episodes and their containing levels. To do this, we'll need to lay out our episodes and maps in the "episodes" field.
The "episodes" field is an array containing Episode objects. Inside each of those objects is a "maps" field containing an array of Map objects; these indicate what maps get loaded ("lump") and what their level names are ("name").
For example:
As you might expect, Episode and Map objects have more fields for special cases and advanced uses, but this is all we need for ap_gen_tool to load our new game.
In almost all cases, the level name should also include the lump name in parenthesis at the end of it. This not only helps players figure out which level name corresponds to which map slot, but it is also used for a few things like item name groups.
Some games may not have clean "episodes" that you can break up their levels into, like Doom 2. It is still best to separate levels out into smaller episodes regardless, but there isn't a single "correct" way to do that. A few ideas are:
The "episodes" field is an array containing Episode objects. Inside each of those objects is a "maps" field containing an array of Map objects; these indicate what maps get loaded ("lump") and what their level names are ("name").
For example:
"episodes": [ { "maps": [ { "lump": "E1M1", "name": "Hangar (E1M1)" }, { "lump": "E1M2", "name": "Nuclear Plant (E1M2)" } // ... insert more maps here ... ] }, { "maps": [ { "lump": "E2M1", "name": "Deimos Anomaly (E2M1)" }, { "lump": "E2M2", "name": "Containment Area (E2M2)" } // ... insert more maps here ... ] } // ... insert more episodes here ... ]
As you might expect, Episode and Map objects have more fields for special cases and advanced uses, but this is all we need for ap_gen_tool to load our new game.
In almost all cases, the level name should also include the lump name in parenthesis at the end of it. This not only helps players figure out which level name corresponds to which map slot, but it is also used for a few things like item name groups.
Some games may not have clean "episodes" that you can break up their levels into, like Doom 2. It is still best to separate levels out into smaller episodes regardless, but there isn't a single "correct" way to do that. A few ideas are:
- Split up maps based on intermission screens; Maps 01-11, 12-20, 21-30, and then any secret maps.
This is how the Doom 2 world in Archipelago handles episodes. - Split up maps into 10 level chunks; Maps 01-10, 11-20, 21-30.
This mimics how DSDA handles single episode speedruns when no other episode information is provided. - Split up maps where there are forced death exits / pistol starts.
Some games may do this to make "fake" episodes. - Split up maps arbitrarily based on what levels feel best to play from a pistol start.
Putting it all together
Once we add in all of the episode information for Zone 300, we should get a JSON file that looks something like this:
As you might expect, there are lots more things that we can do with game JSON files; but for now, this is all we need to start creating logic within ap_gen_tool. We should now be able to open it up and load our new game through the menu.
{
"short_name": "zone300",
"full_name": "Zone 300",
"ap_name": "DOOM II - Zone 300",
"ap_world_name": "doom2_zone300",
"iwad": "DOOM2.WAD",
"required_wads": "zone300.wad",
"episodes": [
{ // Episode 1
"maps": [
{ "lump": "MAP01", "name": "The Spaceport (MAP01)" },
{ "lump": "MAP02", "name": "Control Facility (MAP02)" },
{ "lump": "MAP03", "name": "The Alleyway (MAP03)" },
{ "lump": "MAP04", "name": "Canyon Hub (MAP04)" },
{ "lump": "MAP05", "name": "Skybase 300 (MAP05)" },
{ "lump": "MAP06", "name": "Whispering Corridor (MAP06)" },
{ "lump": "MAP07", "name": "Heavyweight (MAP07)" },
{ "lump": "MAP08", "name": "Waste Disposal Plant (MAP08)" },
{ "lump": "MAP09", "name": "Nuclear Power Station (MAP09)" },
{ "lump": "MAP10", "name": "Cargo Bay (MAP10)" }
]
},
{ // Episode 2
"maps": [
{ "lump": "MAP11", "name": "Simbattle (MAP11)" },
{ "lump": "MAP12", "name": "Villa of Pain (MAP12)" },
{ "lump": "MAP13", "name": "Dark Crypt (MAP13)" },
{ "lump": "MAP14", "name": "The Circle (MAP14)" },
{ "lump": "MAP15", "name": "Trouble Town (MAP15)" },
{ "lump": "MAP16", "name": "Bruiser Fortress (MAP16)" },
{ "lump": "MAP17", "name": "Constriction (MAP17)" },
{ "lump": "MAP18", "name": "Zombie Hideout (MAP18)" },
{ "lump": "MAP19", "name": "The Invasion (MAP19)" },
{ "lump": "MAP20", "name": "Death Row (MAP20)" }
]
},
{ // Episode 3
"maps": [
{ "lump": "MAP21", "name": "Blood Lust (MAP21)" },
{ "lump": "MAP22", "name": "Firestorm Tomb (MAP22)" },
{ "lump": "MAP23", "name": "Dungeon of Inferno (MAP23)" },
{ "lump": "MAP24", "name": "Cavern of the Evil Spirit (MAP24)" },
{ "lump": "MAP25", "name": "Hellucination (MAP25)" },
{ "lump": "MAP26", "name": "Valley of Brimstone (MAP26)" },
{ "lump": "MAP27", "name": "Dissect (MAP27)" },
{ "lump": "MAP28", "name": "Unholy Demise (MAP28)" },
{ "lump": "MAP29", "name": "Den of Torture (MAP29)" },
{ "lump": "MAP30", "name": "Eternal Core (MAP30)" }
]
},
{ // Episode 4
"maps": [
{ "lump": "MAP31", "name": "Creepy (MAP31)" },
{ "lump": "MAP32", "name": "Condemnation (MAP32)" }
]
}
] // End of Episodes
}
As you might expect, there are lots more things that we can do with game JSON files; but for now, this is all we need to start creating logic within ap_gen_tool. We should now be able to open it up and load our new game through the menu.