Map Mod Data: What is it and how is it implemented?

hangman

almost-scientist
Joined
Dec 31, 2010
Messages
776
Location
New Yoronavirus
For a number of reasons, I would like to begin implementing code that makes use of the Map Mod Data, and I may convert this thread into a tutorial if I can make enough sense of it. But alas, my coding skills are more geared toward science applications than video games, so I'd like to start a discussion on it.

So getting started from Worldbuilder, we see that are two categories of map mod data: global data and plot data. Each can be of the types 'number,' 'boolean,' 'enumeration,' or 'text.' Numbers appear to be able to accept decimals, so they are not exclusive to integers. Enumerations appear to accept any of a predefined vector of numbers, which also don't need to be integers. Based on my limited experience with Civ4, the primary use for numbers would be for a predefined plot value, like if your mod had a variable that would decrease a unit's strength by a certain amount based on the plot it was in. By contrast, an enumeration would be of greater interest for selecting from a list of units, buildings, etc., like if settling different plots would grant you different free units. Booleans and texts seem straightforward so I won't discuss them here.

whoward69 explained here that global data is used to call map scripts. I imagine the global map mod data could also be useful for differentiating between multiple maps in the same mod, if there were some quantities that needed to be defined seperately, but I don't imagine it's terribly useful otherwise.

So how exactly do we implement map mod data? It's still a bit of a mystery to me, but looking at CvWorldBuilderMapLoader.cpp, we can get an idea of what should happen in LUA. Starting on line 1408 (in the BNW version), there is a function called LoadModData, which seems to be what we're looking for. The next function down deals with implementing the map script functionality of map mod data, but that seems pretty specific.

There don't seem to be any existing references to map mod data other than these two functions and a header file, so I guess the question is, what LUA function will read map mod data?
 
what LUA function will read map mod data?

Any in the post-process script. The map mod data is available as a table within the context it runs in - see CvGame::InitMap()
 
Is this at all related to MapModData? Sorry if the question seems ridiculous, but I know nothing about Worldbuilder or map scripts. I use MapModData extensively in game (so I can comment on that with some expertise) but I have no idea if it relates in any way to "Map Mod Data".
 
Is this at all related to MapModData? Sorry if the question seems ridiculous, but I know nothing about Worldbuilder or map scripts. I use MapModData extensively in game (so I can comment on that with some expertise) but I have no idea if it relates in any way to "Map Mod Data".

Yep, same thing, the spaces are gratuitous hehe. In-game, MapModData for worldbuilder variables appears like so:

attachment.php
 

Attachments

  • mapmoddata.jpg
    mapmoddata.jpg
    111.8 KB · Views: 1,439
Ah! I was wondering why it existed in the first place, given that it was unlikely added for my modding purposes.

Well, as I said above, I know nothing about WorldBuilder or map creation so probably can't say much useful for your purposes. What I do know is that is is a table, or more accurately, a table pointer (which is what "tables" really are in Lua). All Lua states seem to recognize "MapModData" as a global pointing to this table. So it is a very useful place to put info that you want to communicate between Lua states -- i.e., sending info to or getting info from UI without need for LuaEvents, which is what I use it for.

I thought that this table was empty when a player enters the game (is above screenshot really "in-game" or is it during WorldBuilder session?). I do know that it is not emptied on regeneration of map or loading a game from within a game, which is a potential source of mod bugs if a modder doesn't know that.
 
Ah! I was wondering why it existed in the first place, given that it was unlikely added for my modding purposes.

Well, as I said above, I know nothing about WorldBuilder or map creation so probably can't say much useful for your purposes. What I do know is that is is a table, or more accurately, a table pointer (which is what "tables" really are in Lua). All Lua states seem to recognize "MapModData" as a global pointing to this table. So it is a very useful place to put info that you want to communicate between Lua states -- i.e., sending info to or getting info from UI without need for LuaEvents, which is what I use it for.

Interesting. I believe the reason Firaxis included it in the first place was to prevent the kind of map-specific data tables nightmare that was necessary for the RFC mods in Civ 4 to function. The problem wasn't so much that we needed to construct matrices; rather, it was that it was extremely difficult to visualize without carefully constructed excel worksheets as you can find here, which would then be copied and pasted into the DLL source code (or python for embryodead's SoI and genetically related mods).

As far as worldbuilder is concerned, all MapModData plot data is is a matrix that you can edit on selected plots. Beyond that, all the functionality should be in the code. In the picture I posted, the numbers refer to the x and y coordinates, I think. I guess the critical step needed in using MapModData is a Lua method for retrieving tables, and the data at a given plot. Would you be interested in writing it?

I thought that this table was empty when a player enters the game (is above screenshot really "in-game" or is it during WorldBuilder session?).

Well, by default, MapModData is empty in the worldbuilder, so maybe that's why...

do know that it is not emptied on regeneration of map or loading a game from within a game, which is a potential source of bugs if a modder doesn't know that.

Eep! Well how do I clear it out?
 
I guess the critical step needed in using MapModData is a Lua method for retrieving tables, and the data at a given plot. Would you be interested in writing it?
Not sure what you mean. Variables in Lua don't really hold tables, they hold table pointers. So,
Code:
local MapModData = MapModData
gets you a local variable pointing to that same table (which isn't necessary at all but provides a small optimization). According to structure in your screenshot, you can get a city name with
Code:
local cityName = MapModData.Plots[<x>][<y>].CityName
and assign to it just as easily (though I don't know what WorldBuilder does with this).

Maybe all you're looking for is this?:
Code:
local plotInfo = MapModData.Plots[<x>][<y>]
After that, plotInfo is (as always for Lua) a table pointer. So you can assign to it as well as getting info from it.


Eep! Well how do I clear it out?
I have this in my mod's init code (runs for any new or loaded game):
Code:
for k, v in pairs(MapModData) do
	MapModData[k] = nil
end
Note that Lua will automatically garbage collect any nested tables that were pointed to by MapModData and not by anything else. An interesting point about garbage collection is that Lua does not shrink tables. It grows them as needed (by doubling) but never shrinks. Not a big deal I guess but huge maps have a lot of plots... [Edit: never mind. This is a non-issue because when you assign MapModData.Plots = nil then that whole table and all nested tables get garbage collected.]
 
I am not in front of my home computer right now so excuse the "try figuring it out yourself' question.

If I am understanding this correctly, does it mean we can assign static info to plots in Worldbuilder or via initialization using lua?

I ask as I spent countless hours a while back assign region names to each plot on my scenario map. The method I utilized was a dirty big array of all plots (not my most brilliant moment of coding madness :blush:).

If I can allocate things in Wiorldbuilder then it would simplify things much more from a maintenance point of view.
 
To answer my own question, yes it seems to do exactly what I need.

The only problem is it is quite tedious and there is no way to easily track the data aside from clicking on each tile. Then again I do ask for too much from Worldbuilder :mwaha:

EDIT:
The only problem is it is quite tedious and there is no way to easily track the data aside from clicking on each tile.
Actually I accidentally found out that holding CTRL down will allow multi-hex selection. Then it is a simple case of adding the mod value across all the selected tiles.

I am currently going through and adding names and values across my map. This info could have saved me a lot of time and lua processing if I had known about it sooner :(

Thanks for bringing this up hangman :goodjob:
 
Actually I accidentally found out that holding CTRL down will allow multi-hex selection. Then it is a simple case of adding the mod value across all the selected tiles.

Wow, that's certainly good to know! I wonder what other hotkeys might be assigned...
 
, does it mean we can assign static info to plots in Worldbuilder or via initialization using lua?
Why not use plot:SetScenarioData("string") for that, with corresponding GetScenarioData function? It's even persisted in gamesave file, which MapModData most definitely isn't. It sounds like all you need is a string, or maybe a number that can be converted to a string.
 
, my impression is that MapModData is primarily for variables that will remain constant throughout the game.
But it's not. It is used in WorldBuilder (something I learned in this thread) and not after that, except by modders. If you start any Civ5 game (loaded or new) it will be empty when you enter the game. Any data assigned to it in WorldBuilder will have been lost. It's just an ordinary (empty) Lua table at that point. (The only thing not ordinary is that it is defined across states, but you could do that to a table yourself if you wanted.)
 
But it's not. It is used in WorldBuilder (something I learned in this thread) and not after that, except by modders. If you start any Civ5 game (loaded or new) it will be empty when you enter the game. Any data assigned to it in WorldBuilder will have been lost. It's just an ordinary (empty) Lua table at that point. (The only thing not ordinary is that it is defined across states, but you could do that to a table yourself if you wanted.)

Unless I did something different, all the fields and data values were available for reference in firetuner once I used my scenario map. I am in the process of allocating landmark names (TXT_KEY values) and scenario data to the map which will eventually replace the countless map arrays I have created to store this information via lua.

In my view, this will change the way we do things like tracking original owners of tiles, place names other than cities and providing the ability to quickly show this information in tooltips for scenario purposes.

EDIT: It also opens the opportunity to set tile owners across different civs in instances such as Ryes and Fall which, from what I understand, was the purpose of the MapModData in the link above. Thus through lua we can reallocate whole sets of tiles based on triggers such as the collapse of the Holy Roman Empire and birth of smaller states across multiple civs (of course keeping players alive even when not in play is a separate topic)
 
Unless I did something different, all the fields and data values were available for reference in firetuner once I used my scenario map. I am in the process of allocating landmark names (TXT_KEY values) and scenario data to the map which will eventually replace the countless map arrays I have created to store this information via lua.

Confirmed, I've gotten firetuner to echo some text keys I assigned in WorldBuilder.
 
While doing something unrelated, I discovered CvWorldBuilderMapModData.h, which includes a friendly note from Firaxis:

Code:
//---------------------------------------------------------------------------------------
//
//  *****************   CIV 5 World Builder Map   ********************
//
//  FILE:    CvWorldBuilderMapModData.h
//
//  AUTHOR:  Eric Jordan  --  5/13/2010
//
//  PURPOSE:
//		This little monstrosity was created to support the Civ 5 World Builder map format.
//		It's designed to allow modders to inject custom data formats into their map files.
//
//      If you are a modder looking at this then run!  You can access this functionality
//      from the world builder UI and script.
//
//---------------------------------------------------------------------------------------
//  Copyright (c) 2010 Firaxis Games, Inc. All rights reserved.
//---------------------------------------------------------------------------------------

So it appears that indeed, the intended purpose of MapModData is to add data directly from the worldbuilder.
 
Back
Top Bottom