Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
de27314
BDSP maps: the story's maps as JSON, generated from the Diamond decomp
dayfine Nov 1, 2026
3a67d56
BDSP maps: load the built-in maps, with their points and regions, and…
dayfine Nov 1, 2026
796dd56
BDSP maps: the five interiors of 00.01 to 00.03
dayfine Nov 1, 2026
e7ead80
BDSP maps: Route 202's training and exit areas as regions
dayfine Nov 1, 2026
45a2eaf
BDSP maps: the loader takes names as string_view
dayfine Nov 1, 2026
7c21897
Merge nav/story-steps (e67d36ccb, #122: code health) into bdsp/maps-v4
dayfine Nov 1, 2026
a0a71c8
Merge nav/story-steps (b966c5d93, #122) into bdsp/maps-v4
dayfine Nov 1, 2026
1c0ffea
BDSP maps: the house's 1F row 8 is open at x 4 (console)
dayfine Nov 2, 2026
2a21276
Revert "BDSP maps: the lab's door mat in Sandgem, a row below its door"
dayfine Nov 2, 2026
ed3b0b0
BDSP maps: Sandgem's row 11 has no door at the lab's mat after all
dayfine Nov 2, 2026
29b51da
Merge origin/nav/story-steps into bdsp/maps-v4
dayfine Nov 2, 2026
cc0bd03
BDSP maps: read a warp's destination from MapData's optional `to`
dayfine Nov 2, 2026
cc669ea
BDSP maps: list every cell a map's rectangle touches in its source
dayfine Nov 2, 2026
5d60152
BDSP maps: PlayerHouse1F and Route201's console fixes as generator pa…
dayfine Nov 2, 2026
45144bf
BDSP maps: write each map's coord events from the decomp
dayfine Nov 2, 2026
eb0df85
Merge nav/story-steps into bdsp/maps-v4
dayfine Nov 2, 2026
20b518e
Merge nav/story-steps (24444f0fc: verify mode from #122) into bdsp/ma…
dayfine Nov 3, 2026
7e1bc25
Merge commit 'bb6db58990bd528ef9f0c54534ea3492dbbcf1e3' into HEAD
dayfine Nov 5, 2026
4958325
Merge origin/nav/story-steps into bdsp/maps-v4
dayfine Nov 6, 2026
2039872
BDSP AutoStory maps: align with PR #231 lint conventions
dayfine Nov 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ add_library(SerialProgramsLib STATIC ${CORE_LIBRARY_SOURCES} ${LIBRARY_SOURCES})
include(cmake/EmbedTextFiles.cmake)
pa_embed_text_files(SerialProgramsLib Source/Pokemon/Navigation/TestMaps
Pokemon/Navigation/Pokemon_Navigation_Tests.h PokemonAutomation::Pokemon navigation_test_map_json)
pa_embed_text_files(SerialProgramsLib Source/PokemonBDSP/Programs/AutoStory/Maps
PokemonBDSP/Programs/AutoStory/Data/PokemonBDSP_AutoStory_Maps.h PokemonAutomation::NintendoSwitch::PokemonBDSP bdsp_map_json)


# Create binary target
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include "Pokemon/AutoStory/Pokemon_AutoStory_Tests.h"
#include "Pokemon/Navigation/Pokemon_Navigation_Tests.h"
#include "PokemonBDSP/PokemonBDSP_Tests.h"
#include "VideoGames/PokemonHome/PokemonHome_Tests.h"
#include "VideoGames/PokemonSwSh/PokemonSwSh_Tests.h"
#include "VideoGames/PokemonLA/PokemonLA_Tests.h"
Expand All @@ -51,7 +52,7 @@



UnitTestDatabase make_UNIT_TESTS_ALL(){

Check warning on line 55 in SerialPrograms/Source/ComputerPrograms/ComputerPrograms_UnitTestRunner.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health (advisory)

PokemonAutomation::ComputerPrograms::make_UNIT_TESTS_ALL(): function_lines=40 (advisory above 25, limit 50)
UnitTestDatabase ret;

add_tests_QtEventThreadPool(ret, GlobalThreadPools::computation_normal());
Expand Down Expand Up @@ -80,6 +81,7 @@
NintendoSwitch::add_tests_FailedToConnectDetector(ret);
NintendoSwitch::add_tests_UpdatePopupDetector(ret);
NintendoSwitch::Typewriter::add_tests_TypewriterTextMapping(ret);
NintendoSwitch::PokemonBDSP::add_tests(ret);
NintendoSwitch::PokemonFRLG::add_tests(ret);
NintendoSwitch::PokemonRSE::add_tests(ret);
NintendoSwitch::PokemonHome::add_tests(ret);
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/Source/PokemonBDSP/PokemonBDSP_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include "Common/Cpp/TestRunners/UnitTestDatabase.h"
#include "Programs/AutoStory/PokemonBDSP_AutoStory_Maps_Tests.h"
#include "PokemonBDSP_Tests.h"

namespace PokemonAutomation{
Expand All @@ -14,6 +15,7 @@ namespace PokemonBDSP{


void add_tests(UnitTestDatabase& database){
add_tests_AutoStory_Maps(database);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* BDSP AutoStory - Maps
*
* From: https://github.com/PokemonAutomation/
*
*/

#include <format>
#include <map>
#include "Common/Cpp/Exceptions.h"
#include "Common/Cpp/Json/JsonValue.h"
#include "PokemonBDSP_AutoStory_Maps.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonBDSP{

using Pokemon::MapData;
using Pokemon::TilePos;


namespace{

const std::map<std::string, MapData, std::less<>>& story_maps_by_name(){
static const std::map<std::string, MapData, std::less<>> maps = []{
std::map<std::string, MapData, std::less<>> parsed;
for (const auto& [name, json] : bdsp_map_json()){
MapData map = Pokemon::parse_map(parse_json(json), name + ".json");
if (map.name != name){
throw ParseException(std::format("{}.json: name is \"{}\".", name, map.name));
}
parsed.emplace(name, std::move(map));
}
return parsed;
}();
return maps;
}

} // namespace


const MapData& story_map(std::string_view name){
const auto& maps = story_maps_by_name();
if (auto iter = maps.find(name); iter != maps.end()){
return iter->second;
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, std::format("No BDSP story map named \"{}\".", name));
}

TilePos map_point(std::string_view map, std::string_view point){
const MapData& data = story_map(map);
if (auto iter = data.points.find(std::string(point)); iter != data.points.end()){
return iter->second;
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, std::format("{} has no point \"{}\".", map, point));
}

std::vector<TilePos> map_region(std::string_view map, std::string_view region){
const MapData& data = story_map(map);
std::vector<TilePos> tiles;
while (true){
const auto iter = data.points.find(std::format("{}.{}", region, tiles.size() + 1));
if (iter == data.points.end()){
break;
}
tiles.push_back(iter->second);
}
if (tiles.empty()){
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, std::format("{} has no region \"{}\".", map, region));
}
return tiles;
}



} // namespace PokemonBDSP
} // namespace NintendoSwitch
} // namespace PokemonAutomation
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* BDSP AutoStory - Maps
*
* From: https://github.com/PokemonAutomation/
*
* The maps the story walks, as JSON files in the shared map schema
* (Pokemon_MapData.h): PokemonBDSP/Programs/AutoStory/Maps, written by
* devtools/maps/bdsp_maps.py from the Diamond decompilation and built into
* the program by CMake. Each is named as its file ("Route202").
*
* A map's named tiles are its points. A region, a list of tiles, is the
* points "<region>.1", "<region>.2", ... in order: the schema has
* single-tile points only.
*
* TODO: move the maps to PokemonAutomation/Packages (Resources/PokemonBDSP/Maps) when ready
*
*/

#ifndef PokemonAutomation_PokemonBDSP_AutoStory_Maps_H
#define PokemonAutomation_PokemonBDSP_AutoStory_Maps_H

#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "Pokemon/Navigation/Pokemon_Grid.h"
#include "Pokemon/Navigation/Pokemon_MapData.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonBDSP{


// (name, JSON text) of each map in PokemonBDSP/Programs/AutoStory/Maps/,
// built into the program by pa_embed_text_files() (cmake/EmbedTextFiles.cmake).
const std::vector<std::pair<std::string, std::string>>& bdsp_map_json();

// The map `name`, read from bdsp_map_json() on first use, with its patches
// applied. Throws InternalProgramError for a name it does not have, and
// ParseException if a map does not parse or is not named as its file.
// The name is a string_view so that a temporary string argument is not
// mistaken (by GCC's -Wdangling-reference) for what the result refers to.
const Pokemon::MapData& story_map(std::string_view name);

// The point `point` of the map `map`. Throws InternalProgramError for an
// unknown map or point.
Pokemon::TilePos map_point(std::string_view map, std::string_view point);

// The tiles of the region `region` of the map `map`, in order. Throws
// InternalProgramError for an unknown map, or a region with no tiles.
std::vector<Pokemon::TilePos> map_region(std::string_view map, std::string_view region);



} // namespace PokemonBDSP
} // namespace NintendoSwitch
} // namespace PokemonAutomation
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "FloaromaTown",
"source": {"decomp_file": "pret/pokediamond: files/fielddata/land_data/land_data_release/narc_0032.bin; zone_event narc_0404", "revision": "default branch", "date": "2026-10-31"},
"tiles": [
"######........................##",
"##..##........................##",
"..............................##",
"..............................##",
"..............................##",
"..............................##",
"..............................##",
"..................#####.......##",
"..................#####.......##",
"..................#####.......##",
"..................#####.......##",
"..........####...S##.##.......##",
"..........####................##",
"..........####................##",
"..........#D##................##",
".......................####..S##",
".......................####...##",
".......................#D##...##",
"..............................##",
".............S..................",
"................................",
"................................",
"................................",
"..............#####....####...##",
"..............#####....####...##",
"..............#####....####...##",
"..............##D##....#D##...##",
"..............................##",
"..............................##",
"..............................##",
"########.#...###################",
"########.#...###################"
],
"points": {
"route_204_arrival": [11, 29],
"old_woman": [3, 25],
"old_man": [2, 25],
"pokemon_center_door": [16, 26]
},
"objects": [
{"name": "pokemon_breeder_f_0", "kind": "npc", "x": 19, "y": 21},
{"name": "lass_1", "kind": "npc", "x": 10, "y": 5, "wander": {"x0": 9, "y0": 5, "x1": 11, "y1": 5}},
{"name": "school_kid_m_2", "kind": "npc", "x": 16, "y": 16, "wander": {"x0": 15, "y0": 15, "x1": 17, "y1": 17}},
{"name": "cyrus_3", "kind": "npc", "x": 11, "y": 26},
{"name": "lass_4", "kind": "npc", "x": 23, "y": 11, "facing": "west"},
{"name": "grunt_m_7", "kind": "npc", "x": 2, "y": 1, "facing": "east"},
{"name": "grunt_m_8", "kind": "npc", "x": 3, "y": 1, "facing": "west"},
{"name": "camper_12", "kind": "npc", "x": 6, "y": 10},
{"name": "old_woman", "kind": "npc", "x": 3, "y": 25},
{"name": "old_man", "kind": "npc", "x": 2, "y": 25}
],
"coord_events": [
{"name": "coord_event_0", "x": 10, "y": 29, "width": 3, "length": 1, "var": "VAR_UNK_0x4072", "value": 0, "source": "pret/pokediamond files/fielddata/eventdata/zone_event_release/narc_0404.bin coord_events[0] (170, 669), script 2"}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
{
"name": "JubilifeCity",
"source": {"decomp_file": "pret/pokediamond: files/fielddata/land_data/land_data_release/narc_0015.bin, files/fielddata/land_data/land_data_release/narc_0016.bin, files/fielddata/land_data/land_data_release/narc_0017.bin, files/fielddata/land_data/land_data_release/narc_0018.bin; zone_event narc_0002", "revision": "default branch", "date": "2026-10-31"},
"tiles": [
"##########################################..............########",
"##########################################..............########",
"############################################.....###############",
"############################################......##############",
"############################################......##############",
"############################################......##############",
"############################################......##############",
"#############################################....###############",
"############################....#########.......S.##############",
"############################....#########.........##############",
"#########..#########..######....#########.........##############",
"#########..#########..######....#########.........##############",
"#########..#########..######....#########.........##############",
"#########..#########..######....#########.........##############",
"#########..#########..######....#########.........##############",
"#########..##D###D##..######....####D####.........##############",
"#########.............######...............#.....#######....####",
"#########.............######......................######....####",
"..#######.............######......................######....####",
"..###########S......########...........S.........S##D###....####",
"..#.S.#.......................#..........................#.S####",
"................................................................",
"D...............................................................",
"D...............................................................",
"................................................................",
"..#...#.......................#..........................#..####",
"..############.............####......####...................####",
"..############.............####......####................#######",
"##############.################...##.####..#.....######..#######",
"##############.################...##.####.........#####..#######",
"##############.################...................#D############",
"################################.........................#######",
"################################.........................##D####",
"################################.........................#######",
"################################.........................#######",
"###############............#####.........................#######",
"###############............#####......#####..............#######",
"###############..#########.#####.##########.......######.#######",
"###############..#########.#####.##########.......######.#######",
"###############..#########.#####.###########.....#######.#######",
"##################################..S.##D##.......##D###########",
"###############..#########.#####.........................#######",
"##############...####D####..###..........................#######",
"##############...........................................#######",
"##############.....S.....................................#######",
"##############...........................................#######",
"##############.............#########.....................#######",
"###############............#########.#####...............#######",
"###############............#########.#####...............#######",
"###############.####..####.###############...............#######",
"###############.####..####.###############...............#######",
"###############.####..####.###############...........###########",
"############D##.####..####.############D##...........###########",
"##########.................#########.......#.....#...########.##",
"##########.................#########.................########.##",
"##########............#..#.#########......S..........########.##",
"##########............#..#.#########.................########.##",
"##########.................#########.................########.##",
"###########################################.......##############",
"###########################################.......##############",
"########################################.##.......##############",
"########################################.####...################",
"########################################..........##############",
"########################################..........##############"
],
"points": {
"trainers_school_door": [40, 40],
"pokemon_center_door": [52, 40],
"tv_station_door": [36, 15],
"poketch_president": [46, 35],
"clown_mart": [55, 33],
"clown_tv_station": [36, 16],
"clown_poketch_company": [15, 18],
"up_the_steps.1": [46, 58],
"up_the_steps.2": [47, 58],
"up_the_steps.3": [46, 59],
"up_the_steps.4": [47, 59],
"up_the_steps.5": [46, 60],
"up_the_steps.6": [47, 60],
"east_entrance.1": [61, 21],
"east_entrance.2": [62, 21],
"east_entrance.3": [63, 21],
"east_entrance.4": [61, 22],
"east_entrance.5": [62, 22],
"east_entrance.6": [63, 22],
"east_entrance.7": [61, 23],
"east_entrance.8": [62, 23],
"east_entrance.9": [63, 23],
"east_entrance.10": [61, 24],
"east_entrance.11": [62, 24],
"east_entrance.12": [63, 24],
"north_road.1": [44, 16],
"north_road.2": [45, 16],
"north_road.3": [46, 16],
"north_road.4": [47, 16],
"north_road.5": [48, 16],
"north_road.6": [44, 17],
"north_road.7": [45, 17],
"north_road.8": [46, 17],
"north_road.9": [47, 17],
"north_road.10": [48, 17],
"north_road.11": [44, 18],
"north_road.12": [45, 18],
"north_road.13": [46, 18],
"north_road.14": [47, 18],
"north_road.15": [48, 18],
"north_road.16": [44, 19],
"north_road.17": [45, 19],
"north_road.18": [46, 19],
"north_road.19": [47, 19],
"north_road.20": [48, 19],
"north_road.21": [44, 20],
"north_road.22": [45, 20],
"north_road.23": [46, 20],
"north_road.24": [47, 20],
"north_road.25": [48, 20]
},
"objects": [
{"name": "ace_trainer_f_0", "kind": "npc", "x": 22, "y": 20, "wander": {"x0": 21, "y0": 20, "x1": 23, "y1": 20}},
{"name": "ace_trainer_m_1", "kind": "npc", "x": 46, "y": 21, "wander": {"x0": 45, "y0": 21, "x1": 47, "y1": 21}},
{"name": "school_kid_m_2", "kind": "npc", "x": 17, "y": 55},
{"name": "twin_3", "kind": "npc", "x": 33, "y": 18, "wander": {"x0": 32, "y0": 17, "x1": 34, "y1": 19}},
{"name": "expert_m_4", "kind": "npc", "x": 44, "y": 44},
{"name": "school_kid_m_5", "kind": "npc", "x": 51, "y": 34, "wander": {"x0": 51, "y0": 33, "x1": 51, "y1": 35}},
{"name": "pokefan_m_6", "kind": "npc", "x": 41, "y": 30, "wander": {"x0": 40, "y0": 29, "x1": 42, "y1": 31}},
{"name": "ace_trainer_m_22", "kind": "npc", "x": 36, "y": 25},
{"name": "poketch_president", "kind": "npc", "x": 46, "y": 35},
{"name": "clown_mart", "kind": "npc", "x": 55, "y": 33},
{"name": "clown_poketch_company", "kind": "npc", "x": 15, "y": 18},
{"name": "cashier_m_27", "kind": "npc", "x": 26, "y": 42},
{"name": "clown_tv_station", "kind": "npc", "x": 36, "y": 16},
{"name": "kid_with_nds_29", "kind": "npc", "x": 52, "y": 46},
{"name": "kid_with_nds_30", "kind": "npc", "x": 54, "y": 46}
],
"coord_events": [
{"name": "dawn_at_the_steps", "x": 45, "y": 60, "width": 4, "length": 1, "var": "VAR_JUBILIFE_CITY_STATE", "value": 0, "source": "pret/pokediamond files/fielddata/eventdata/zone_event_release/narc_0002.bin coord_events[0] (173, 796), script 2"},
{"name": "coord_event_1", "x": 45, "y": 7, "width": 3, "length": 1, "var": "VAR_JUBILIFE_CITY_STATE", "value": 3, "source": "pret/pokediamond files/fielddata/eventdata/zone_event_release/narc_0002.bin coord_events[1] (173, 743), script 4"},
{"name": "coord_event_2", "x": 60, "y": 21, "width": 1, "length": 4, "var": "VAR_JUBILIFE_CITY_STATE", "value": 1, "source": "pret/pokediamond files/fielddata/eventdata/zone_event_release/narc_0002.bin coord_events[2] (188, 757), script 3"},
{"name": "coord_event_3", "x": 27, "y": 43, "width": 1, "length": 3, "var": "VAR_GTS_ACCESS_STATE", "value": 0, "source": "pret/pokediamond files/fielddata/eventdata/zone_event_release/narc_0002.bin coord_events[3] (155, 779), script 19"},
{"name": "poketch_president", "x": 44, "y": 40, "width": 5, "length": 1, "var": "VAR_POKETCH_CAMPAIGN_STATE", "value": 1, "source": "pret/pokediamond files/fielddata/eventdata/zone_event_release/narc_0002.bin coord_events[4] (172, 776), script 17"}
]
}
Loading
Loading