Team-Magmas-Regions / pokeemerald-expansion-regions

Feature branches for the pokeemerald decompilation focused around adding multiregion support. See the wiki for more info.
0 stars 0 forks source link

Option to store wild encounters per map instead of a single file #4

Open traeighsea opened 2 months ago

traeighsea commented 2 months ago

Description

Motivation

Currently wild encounters are stored in a single list in the src/data/wild_encounters.json directory. This has a couple complications. If you want to update this file, you need to deserialize the whole file, change what you need to, and then serialize it again. This is costly considering this is a large file and as you add more maps to the game, the list becomes rather cumbersome to manage at scale.

Additionally, if you have individual wild_encounters.json data per maps, this allows the maps to be more modular and allows users to for example declare multiple versions of wild encounters for a map that can be configured and chosen as a pre compile step, at a granular level.

So I propose you can store these files as pieces, and then amalgamate them in this single file as a precompile step in the makefile.

Design

There were 2 designs that would work for separating this information into individual map wild encounters.

  1. The first option was to store only the "encounters" array, which has a key on the map and base_label that would then list all of ya know the encounters for that map. This would require reading the map specific wild encounters differently than the "common" file (I'll get to the wild_encounters_common.json later) and compiling into a list assuming this went into the gWildMonHeaders.
  2. The second option was to keep the wild_encounters.json data structure/format entirely intact per map, but only include the data you needed for those encounters. By which I mean someone could chose and add different wild_encounter_groups and add the encounter data to a different label instead of assuming gWildMonHeaders.

I decided to move forward with option 2 as this would allow for a more robust system depending on what the user wants to do with data, therefore more freedom. So with this in mind, the wild_encounters.json data could look something like this:

{
  "wild_encounter_groups": [
    {
      "label": "gWildMonHeaders",
      "encounters": [
        {
          "map": "MAP_ROUTE101",
          "base_label": "gRoute101",
          "land_mons": {
            "encounter_rate": 20,
            "mons": [
              ...
            ]
          }
          "water_mons": {
            "encounter_rate": 20,
            "mons": [
              ...
            ]
          }
          ...
       }
      ]
    }
  ]
}

So after extracting all of this data out you're left with a couple wild_encounter_groups not stored by map as notated by the for_maps variable. This data that gets "left behind" is still needed, and my solution to this is to store a new file called data/maps/wild_encounters_common.json. This stores encounter groups not associated with any map, though technically you could store any arbitrary amount of encounter data you want. Think of this like your global data that's stored at the top level map directory. It's free real estate.

So your data looks more like this now: data/maps/*/wild_encounters.json data/wild_encounters_common.json src/data/wild_encounters.json.txt --> data/wild_encounters.json.txt src/data/wild_encounters.json: Removed

This data when compiled gathers all of those data/maps/*/wild_encounters.json files as well as the data/maps/wild_encounters_common.json and amalgamates this into one single git ignored compiled json file at data/wild_encounters.json which gets used by jsonproc as was performed before. This amalgamation of json files is done as a precompile step in the makefile done with the new tool jsonamal.

An option in the makefile called OPTION_INDIVIDUAL_MAP_WILD_ENCOUNTERS was added to enable/disable using this directory structure.

Design - Migration Tool: separate-wild-encounters

The encounter objects in the json can be grouped by the map and base_label in the json as you iterate through. The map in this case can be obtained from the data/maps/*/map.json files, from which we can then export that map in the master list into this directory as a sibling. All of the maps we don't find a key on, we keep as a list to store in the wild_encounters_common.json.

This is added as a make option called run-separate-wild-encounters-json which takes in your wild_encounters.json as well as all of your map files like so data/maps/*/map.json.

Design - Amalgamate Tool: jsonamal

This tool adds 2 modes of operation. The first is a simple generic json merge tool, that may come in handy for other efforts that want to combine json files into one list. It's not used in this code, but it may have its uses for those who know it's available.

There's a limitation to using the base merge of the json library, because of our use of identifiers as siblings to data. By which I mean the map and base_label are siblings to the encounters array. So you can't simply merge the data on those keys, because you will need some specialized logic to check those unique identifiers first to know if the encounters should be merged. Thus a second mode was born; encounters.

Porymap

This change requires changes to porymap. This will be a toggle to check that you're using individual encounter files stored with the map directory. PR to come soon.

Other Considerations

I added a lib directory in the tools directory for any shared libraries to be used by other projects. nlohmann json is a common C++ library that is used in the jsonproc as well. We should try to keep these lib files up to date and in a shared space if possible. So technically this does update jsonproc's nlohmann library to a newer version.

Discord contact info

Traeighsea