Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign up[WIP][CR]Home Base #22311
Conversation
Theundyingcode
added some commits
Oct 29, 2017
Theundyingcode
changed the title
[WIP]{CR]Home Base
[WIP][CR]Home Base
Oct 31, 2017
Coolthulhu
reviewed
Oct 31, 2017
| and pasted out on their bed. By writting on a piece of furnature, it and all contained items can be personally | ||
| claimed or designated for communal use. NPCs will consume food, reload and, rearm themselves from communal storages \ | ||
| and will deposit unwanted stuff there. Doors can also be marked \"No Access!\" to prevent unwanted intrusion.") ); | ||
| } |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
This is tolerable for testing, but it will be mandatory to push it to json before it's mergeable.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
??? is there a help.json? I literally just opened up help.cpp and copied how everything else was done.
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
help.cpp is badly written, old file. I guess adding this block to it will not make it any worse...
But do keep it for later. A help file shouldn't describe features that don't exist yet.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
For now I''l just delete the menu reference and leave the block as basically a giant comment.
Coolthulhu
reviewed
Oct 31, 2017
|
|
||
| //data members | ||
| std::unordered_map<ammotype_id, int> gun_count; /**stores <ammo_type, #guns_that_use_them>.*/ | ||
| std::unordered_map<ammotype_id, int> ammo_count; /**stores <ammo_types, amount>.*/ |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
This is much harder to keep updated than you think. Leave it for much later.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
won't actually be useful until based npcs are actually added so sure.
Coolthulhu
reviewed
Oct 31, 2017
| /** | ||
| * Stores capacities of command system and the auxiliary systems present. | ||
| */ | ||
| struct command_sys |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
Leave this whole structure for the very end. Don't define things like processing power until you have all the mundane stuff done.
Coolthulhu
reviewed
Oct 31, 2017
| desktop.addentry( 4, true, MENU_AUTOASSIGN, _("View Status.") ); | ||
| desktop.addentry( 5, true, MENU_AUTOASSIGN, _("Base Planner.") ) | ||
| if (base.get_level() > 2){//add lv.3 options | ||
| desktop.addentry( 6, true, MENU_AUTOASSIGN, _("Personel Managment.") ); |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
All of those things are perfectly mundane. They shouldn't need a computer. Only things like machinery settings and automatic security should require computers.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
I'll change them. The levels were kinda arbitrarily assigned anyways.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
I feel that there should be some recognition that while it's possible to do most things with pen/paper a lot of stuff just won't be worth the effort for a survivor without the help of a computer; You can make detailed construction plans on paper but it takes orders of magnitude more time than with CAD software. Maybe saying basic stuff like designating areas (crafting, sleeping etc./ define area to guard) would be for pen/paper but construction plans require software?
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
Leave limiting for much later. First get it to work completely with no limits on player's options, then break it up into levels in further PR.
Coolthulhu
reviewed
Oct 31, 2017
| * TODO: Finish writting. Change to uimenu. | ||
| */ | ||
| void iexamine::base_control( player &p, const tripoint &examp) { | ||
| #define base (p->home) |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
This looks like a bad approach. The player should not "own" a base, rather the base should "be owned" by the player.
You can save owner's ID in base structure - player has a getID (I might have misspelled it) function.
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
And please don't use macros like this. You can create a "local alias" via references:
auto &base = p->home;
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
•
Author
Contributor
Since it's already getting passed a reference to the player it seemed easier to just add a reference to the base in player. I'll definitely add an "owner" reference in base. Still feel player is going to want to have a reference to the base though... short term as long as you can access the base object from iexamine.cpp, a "has a base" boolean will suffice.
Coolthulhu
reviewed
Oct 31, 2017
| int x = coreloc.x; | ||
| int y = coreloc.y; | ||
|
|
||
| //TODO: Re-write. Previous implementation wasn't going to work. (immpossible to distinguish between underground and thick rock wall) |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
Scanning area isn't easy, but start_location.cpp has an implementation of flood fill that would work to find all the reachable area from current point.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
I'm about 90% sure one of my old homework assignments for AI class will work with only a few minor tweaks... and converting it from python. I haven't even opened start_location.cpp yet but I'll take a look before implementing something.
Coolthulhu
reviewed
Oct 31, 2017
| [ [ "scrap", 2 ] ] | ||
| ] | ||
| },{ | ||
| "result" : "notice_screen", |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
Adding recipes that are used in only one place leads to bloating of the crafting screen. Would be better if you just included the requirements in the construction.
This comment has been minimized.
This comment has been minimized.
Coolthulhu
reviewed
Oct 31, 2017
| "flags" : [ "BASE_CMD2", "BASE_CORE", "CMD_SYS", "FLAMMABLE" ] | ||
| },{ | ||
| "type:" : "furniture", | ||
| "id" : "f_base_cmd3", |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Oct 31, 2017
Contributor
Merge the first 3 levels - there is no need to keep them separate, especially not before getting the whole thing to work.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
•
Author
Contributor
I have basic levels of function in mind otherwise it's just a difference of power. Using pen and paper, having a computer and having a fancy console. Access to a computer should cause a pretty big increase in functionality. The console was going to be a requirement for most of the aux systems... I'll cut it down to 3 levels and decide priorities from there.
BevapDin
reviewed
Oct 31, 2017
| base::define_base_area(base_map, coreloc); | ||
| base_map.spawns.clear();//remove spawns so nothing apears in base just outside it. | ||
| base_level = 1; | ||
| food_ration_lv = ammo_ration_lv = med_ration_lv = 0; //no rationing to start |
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
Members should be initialized in the member initialization list, not assigned in the body of the constructor.
BevapDin
reviewed
Oct 31, 2017
| */ | ||
| bool base_home::has_base_flag(const tripoint &p, base_area_flag flag) | ||
| { | ||
| return(baflag[p.x][p.y]) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
BevapDin
reviewed
Oct 31, 2017
| @@ -0,0 +1,142 @@ | |||
| #pragma once | |||
| #ifndef BASE_HOME | |||
| #define BASE_HOME | |||
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
Please add a "_H" suffix to the define as it's done in all the other headers.
BevapDin
reviewed
Oct 31, 2017
| void change_lv(int new_level); | ||
| void run_design(); | ||
|
|
||
| inline int get_level() |
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
inline is redundant here. Functions defined inside a class definition are automatically inline.
This comment has been minimized.
This comment has been minimized.
BevapDin
reviewed
Oct 31, 2017
| p.home.set_med_ration(lv-1); | ||
| } | ||
| case 4: { | ||
| goto top_menu; |
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
Please don't use goto, ever. It considered to be one of the most awful features of the language. Seriously, google "c++ goto" and forget that it exists.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
Yeah, I figured that was hacky. I decided it should loop as an afterthought. Pretty sure that's the first time I have used goto since programing my calculator instead of paying attention in high school.
BevapDin
reviewed
Oct 31, 2017
| } | ||
| inline int get_max_pop() | ||
| { | ||
| return max(bunks.length, storage_open.length) + npcs.length; |
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
Is this supposed to call std::max? If so, you have to add the std:: prefix.
Also note: when you want to call functions, you must use brackets. bunks.length is not a function call. Yes, even if there are no parameters, the () are still required.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
function of this being first use of c++. That's how you do it in java.
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
When I learned Java (several versions ago) it required brackets for function calls as well. Accessing properties (called data members in C++) are done without them, but bunks is a std::list and length is a member function of it, not a data member.
Btw (I missed this previously): getter functions and generally all functions that don't change the object should be const, as in int get_max() const { ... }.
BevapDin
reviewed
Oct 31, 2017
| @@ -629,6 +629,8 @@ player::player() : Character() | |||
|
|
|||
| morale.reset( new player_morale() ); | |||
| last_craft.reset( new craft_command() ); | |||
|
|
|||
| home = NULL; | |||
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
player::home is an object of type base_home, not a pointer. You can't assign NULL to it.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
•
Author
Contributor
ment for player::home to be a way to reference base not the actual object.
This comment has been minimized.
This comment has been minimized.
BevapDin
reviewed
Oct 31, 2017
| * Mannage basic and security remote systems. (Lights! Cammera! Action...of connected turrets!) | ||
| */ | ||
| void iexamine::base_sec( player &p, const tripoint &examp ) { | ||
| add_msg("Not implemented yet.","(╮°-°)╮┳━━┳ ( ╯°□°)╯ ┻━━┻"); |
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
What are those additional arguments supposed to be? They are not used at all (there is no "%s" in the message).
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Oct 31, 2017
Author
Contributor
It;s someone flipping a table in frustration. It's just supposed to be another line and it won't be staying anyways.
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
It's just supposed to be another line
If you want another message line, either call add_msg again (each call generates one line), or add a line break to the message: add_msg("Line 1\nLine 2").
And another thing: string literals that should be translated must be surrounded by _( and ) - see examples all over the code.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 1, 2017
Author
Contributor
I noticed the _( ) thing and started putting it in without knowing the meaning. The line is just a placeholder until I actually write the method since an empty method looks weird to me.
BevapDin
reviewed
Oct 31, 2017
| @@ -1033,6 +1034,38 @@ A: Ask the helpful people on the forum at smf.cataclysmdda.com or at the irc cha | |||
| return text; | |||
| } | |||
|
|
|||
| std::vector<std::string> text_bases() | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 1, 2017
Contributor
It means you should scrap the function, though.
You can recover it from git history later, don't keep it commented out.
BevapDin
reviewed
Oct 31, 2017
| @@ -62,6 +62,7 @@ Press q or ESC to return to the game." ) ) + 1; | |||
| headers.push_back( _( "n: Unarmed Styles" ) ); | |||
| headers.push_back( _( "o: Survival Tips" ) ); | |||
| headers.push_back( _( "p: Driving" ) ); | |||
| headers.push_back( _( "q: Bases" ) ); | |||
This comment has been minimized.
This comment has been minimized.
BevapDin
reviewed
Oct 31, 2017
| class base_home | ||
| { | ||
|
|
||
| base(submap &base_map, const tripoint &coreloc); |
This comment has been minimized.
This comment has been minimized.
BevapDin
Oct 31, 2017
Contributor
Is this supposed to be the constructor? If so, it must have the same name as the class itself, in this case base_home.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
What Coolthulhu said. Don't try to implement everything at once. Make a simple implementation (no level, no caching, as basic as it gets). Than extend it with other PRs. |
This comment has been minimized.
This comment has been minimized.
Since I am essentially trying to add a whole new aspect to the game I was more concerned with getting my plans across properly. I'll trim out a bunch of stuff before it's rdy; in my experience, adding stubs and a lot of comments is much more effective than me trying to explain my thoughts. |
Theundyingcode
added some commits
Oct 31, 2017
Theundyingcode
added some commits
Nov 1, 2017
Coolthulhu
reviewed
Nov 2, 2017
| if (ter[temp.x][temp.y].has_flag("INDOORS") && !pushed.count(temp) ){ | ||
| q.push(temp); | ||
| pushed.push(temp); | ||
| } |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 2, 2017
Contributor
Rewrite this as a set of offsets and a simple loop:
static const std::array<point, 8> offsets = {{
{ 1, 0 }, { -1, 0 }, ... etc.
}};
for( const point &off : offsets ) {
tripoint cur_point = center + off;
// stuff
}
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
Author
Contributor
knew that wasn't right but was blanking for some reason so copied and pasted.
Coolthulhu
reviewed
Nov 2, 2017
| auto &frn = bmap.fur; | ||
| auto &bf = bmap.bflag[x][y]; | ||
| auto &in = base_flag::BASE_IN; | ||
| auto &wall = base_flag |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 2, 2017
Contributor
Don't use auto everywhere. It's useful when you have a giant structure, like std::map<tripoint, std::string>::iterator, but when it's just an int, it's much clearer when you just state it outright.
Coolthulhu
reviewed
Nov 2, 2017
| struct tripoint; | ||
| class ammunition_type; | ||
|
|
||
| //Furnature accepted as a storage place. |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
reviewed
Nov 2, 2017
| } | ||
|
|
||
| /** | ||
| * Contain's entire base map. Point is to merge base's submaps into one object. |
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 2, 2017
Contributor
Operating directly on submaps by a class that isn't map is a huge red flag that you're doing something wrong.
This will cause a lot of trouble and you really don't want to do that.
I'm not sure how you want to process the camps, but it would be much safer to do this:
- Remember the camps (all of them in given area) in
overmap(not submap) - In a camp, note its
tripoint origin- this would be the submap coordinate of its upper-left corner - When you need to process the camp, load a
tinymapcentered on camp's origin
For tinymap example, check mission_start::place_dog. For a more complex example, you can check place_caravan_ambush, but DON'T replicate that - placing tons of things that way is bad.
By noting the camps in overmap, you may be able to make them act even when the player isn't around.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
Author
Contributor
I don't think I have actually gotten my head around how all the map stuff actually works. My future plans basically have two requirements with the map: being able to add an additional set of flags to tiles in its area (npc keep out on doors, ownership to furniture etc); which I have done by adding bflag, another layer to the map grid. And, being able to to keep track of locations and get what's there (communal storage). As an extra I also want to disable the spawn points within the base because having hulks spawn inside your base is just dumb.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
Author
Contributor
Should I change base_home::overlay to be a tinymap with the extra bflag overlay? gen_overlay would then be the function call to create the tinymap.
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 3, 2017
Contributor
No
tinymap is for when the base does something. In your base structure, you only want to keep locations, not copy of the entire map.
For example, if you want to simulate a month of NPCs eating rations, you do this:
- Calculate NPC needs for this month
- Create a
tinymapin base's origin - Using
tinymap, go through food items in the base and delete those that the NPCs "ate" - Call
savefunction of thetinymap - Do NOT save the
tinymapstructure anywhere, it should be deleted after you finish this simulation
This comment has been minimized.
This comment has been minimized.
Coolthulhu
reviewed
Nov 2, 2017
| @@ -1564,6 +1564,8 @@ class player : public Character, public JsonSerializer, public JsonDeserializer | |||
| */ | |||
| void set_targeting_data( const targeting_data &td ); | |||
|
|
|||
| /**Pointer to player's home base*/ | |||
| base_home* home; | |||
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 2, 2017
Contributor
That's a bad way of doing this.
Instead, you want to specify ID of the owner in base's structure.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
Author
Contributor
There already is an owner ID in base... the point of the pointer (just wanted to say that) was that iexamine functions are passed a reference to player so referencing the base becomes really easy this way. The player is going to at least want a boolean "has_base" to prevent creating a slowdown opening the construction menu since they should be limited to one home base. (future plans for smaller outposts)
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
Author
Contributor
I.e. so I can do this: auto &base = *p.home in iexamine.cpp
This comment has been minimized.
This comment has been minimized.
Coolthulhu
Nov 3, 2017
Contributor
The player is going to at least want a boolean "has_base" to prevent creating a slowdown opening the construction menu since they should be limited to one home base.
The problem is, you have no way of properly setting it. The code in iexamine.cpp will only be processed when examining, so not after save load.
In order to find player's base after loading the game, you'd have to scan all overmaps in existence to find it. And overmaps may actually disappear in some cases, so simply saving a bool would be buggy.
If you want to refer to exactly one base, you should save its origin. If the base doesn't exist, you want it set to tripoint_min and comment that tripoint_min means there is no base. That way you can later (for example, when saving or loading the game) check if that base really exists.
This comment has been minimized.
This comment has been minimized.
BevapDin
Nov 3, 2017
Contributor
If the base doesn't exist,
You should use a cata::optional<tripoint> instead of some arbitrary magic value that requires documentation writing, reading and remembering
BevapDin
reviewed
Nov 3, 2017
|
|
||
| //Simple implementation for now | ||
| std::list<std::string> basicInfo; | ||
| basicInfo.push_back( string_format( _("%s's Home Sweet Base%n"), p.get_name(), int len ); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
Author
Contributor
I was going to use it to create the same underline that the other sections had. %n stores the number of characters written.
This comment has been minimized.
This comment has been minimized.
BevapDin
Nov 3, 2017
Contributor
Sure, but I was referring to the invalid syntax. And you don't need this. You can just examine the formatted string itself. And you don't actually care about the numbers of characters, you care about the display width (see utf8_width). There are for example Unicode combination marks that take up no additional space on the console.
This comment has been minimized.
This comment has been minimized.
BevapDin
reviewed
Nov 3, 2017
| rationInfo.push_back( _("Supply Rationing") ); | ||
| rationInfo.push_back( _("~~~~~~~~~~~~~~~~") ); | ||
| rationInfo.push_back( string_format( _("Food: %s"), base_home::ration_levels::base.get_food_ration() ); | ||
| rationInfo.push_back( string_format( _("Water: %s"), base_home::ration_levels::base.get_food_ration() ); |
This comment has been minimized.
This comment has been minimized.
BevapDin
Nov 3, 2017
Contributor
What do you want to achieve with base_home::ration_levels::? Does base.get_food_ration() not work?
Also: all 4 lines print the same number (call the same function).
This comment has been minimized.
This comment has been minimized.
Theundyingcode
Nov 3, 2017
•
Author
Contributor
ration levels is an enum... get food ration levels is an int... i'll look up enum syntax and make this better
BevapDin
reviewed
Nov 3, 2017
| auto &peeps = p->home.get_personnel(); | ||
| resInfo.push_back( _("Base Residents") ); | ||
| resInfo.push_back( _("~~~~~~~~~~~~~~") ); | ||
| basicInfo.push_back( _("") );//add blank line. |
This comment has been minimized.
This comment has been minimized.
BevapDin
Nov 3, 2017
•
Contributor
I forgot to mention this: empty strings should not be translated at all. Just use "" without the _().
And you can put this into one string, not a list (why a list and not a vector?) - and why output:: - there is no namespace output.
BevapDin
reviewed
Nov 3, 2017
| basicInfo.push_back( string_format( _("Communal Storage Locations: %d"), base.num_comm_storage() ) ); | ||
| std::list<std::string> rationInfo; | ||
| rationInfo.push_back( _("Supply Rationing") ); | ||
| rationInfo.push_back( _("~~~~~~~~~~~~~~~~") ); |
This comment has been minimized.
This comment has been minimized.
BevapDin
Nov 3, 2017
Contributor
Btw this should be generated by a function. And it should not be translated (how are translators supposed to know what this means / the context).
Theundyingcode
added some commits
Nov 3, 2017
Theundyingcode
added some commits
Nov 13, 2017
This comment has been minimized.
This comment has been minimized.
|
This PR is hard to review due to its size, and also it seems to be stalled and obsoleted. Feel free to re-open or, as even better option, to restart it as a bunch of much smaller PRs. |
illi-kun
closed this
Feb 23, 2018
This comment has been minimized.
This comment has been minimized.
|
yeah I haven't been involved with cdda since I got back to school... my git notifications is a scary 800+ |
This comment has been minimized.
This comment has been minimized.
TheEventHorizon
commented
Apr 4, 2018
|
Any chances of this being revived? |
This comment has been minimized.
This comment has been minimized.
|
I keep meaning to come back to it but at the same time I haven't opened cdda since going back to school in January and probably won't get around to it until late summer... |
Theundyingcode commentedOct 31, 2017
•
edited
Here is the long overdue PR to open my addition of bases up to review. Most of it is currently either partially implemented or just declarations especially since I have been frequently changing things including large mechanics change that just scrapped a lot of code the other day. However, it should be well documented and filled out enough for people to understand where I'm going. Also, I wrote a first draft of the help page so code reviewers: start there.
Essentially, the idea is construct a "command core" inside a building and that building gets designated as your base. The command core can be anything from a desk you write notes on to a super fancy computer console. A better core gives you more functionality and allows you to create a "command system" by adding "auxiliary systems." Remote systems like speakers and defenses can then be linked to the command system through the use of a network module. Network and CPU capacity are then added to prevent someone running NORAD from a desk with a laptop on it.
The end goal is to make an environment where NPCs can effectively live and be useful in the player's absence. For now I have said if someone is going to agree to live here then at minimum they will demand a place to sleep and stash there stuff resulting in a loose population limit.
I'm adding another layer to the map similar to traps and effects for flags specific to the base which isn't that useful at the moment but will be essential come time to add NPC base behavior.
NOTES:
This is my first time working in C++. A lot of the code is written by copying what other files are do. I started from scratch rather than using the base camp file because I wanted the learning experience.
I was under the assumption that submap = map tile which is apparently not the case. My implementation basically involves loading the base's map into the base object so I'm going to need some help here. Getting #22300 merged in would probably help.
Think adding additional json field for network and cpu consumption would be best. That way it won't be hard coded.
-I have yet to even look at the json parser for saving/loading the base.