Okay so i have a map with hexes on it. My game is a strategy game so you add point values to each hex to display the size of your army on the hex. Think exactly risk the board game.
Now theres a few other blends i need to go to and come back from. When i do i need to pick up where i left off on each hex and how many points they have and who owns them.
So being a n00b i made a bge.globalDict and added every hex and those two values into it.
For hex in all_hexes:
Bge.logic.globalDict[hex] = hex[‘owner’], hex[‘points’]
I was delighted with myself until i found out game objects apparantly cant be marshalled.
Not all Python object types are supported; in general, only objects whose value is independent from a particular invocation of Python can be written and read by this module. The following types are supported: booleans, integers, long integers, floating point numbers, complex numbers, strings, Unicode objects, tuples, lists, sets, frozensets, dictionaries, and code objects, where it should be understood that tuples, lists, sets, frozensets and dictionaries are only supported as long as the values contained therein are themselves supported; and recursive lists, sets and dictionaries should not be written (they will cause infinite loops). The singletons None, Ellipsis and StopIteration can also be marshalled and unmarshalled.
It does not include own classes or BGE objects.
You could use pickle to save/store. It supports more formats.
(be aware you will never be able to save and load game objects. This is because they are no Python objects and Python can’t create them. But you can apply stored data to an existing game object with your own Python code.)
So, I know I can apply stored data. but where would I store that data?
for I need to let every one of these countries know every time I come back to this map from another blend;
how many points were on it last time I was in this blend.
who’s ownership the country was under last time I was in this blend.
The map I’m using have somewhere near 2000 hexagon shaped territories and so I would like to be able to run a ‘for loop’ to get those two pieces of info and then run another loop to retrieve those pieces of info. Now since I can’t just jam it into a dictionary. I’m kind of at a loss.
This point has been made elsewhere recently, but I’ll outline it again for simplicity.
You need to separate your “what” from your “how”. The BGE does many things, including rendering your models. As a user, you don’t care exactly how it does this, you just give it the colour you want, and mesh data. Apply the same logic to your game state.
The easiest way of thinking about this is to have your game state expressed some data object (class / dictionaries, whatever), and pass those to a draw_game method. This draw game method will take your “generic” gamestate data and make it interactive and visual inside the BGE.
For some games this can be taken too far, but if it’s a long term project, keeping some separation between the BGE types and your own gamestate really helps.
So, what to do…
Represent your game as some combination of Python types where your tiles are stored by some ID. This ID could be their position (in some coordinate system that doesn’t rely on floating point precision), or a generic random number, or sequential number. Each tile has a position, and other data that the game relies on for the game mechanics (like who owns it, for example). You can read/write this to disk easily with JSON (which is a better suggestion than pickle for most applications).
Design some specific systems to represent the game-state in the BGE. You can imagine that you’re keeping things really generic so you could easily port your game to another Python-based game engine, that helps you to keep the separation you need.
These systems accept the gamestate (which could be a list of Tile objects (which might be simple dictionaries if you’re using a more functional programming style (which is common with people writing games in the BGE))), and generate / find the game objects associated with them and move them if they move, or update their colours etc. You can make this more performant and have your game code keep track of changes and only update the tiles with those changes, or just do things naively and update every tile every frame (expensive).
This is a sweeping overview, but you’ll be able to find out more yourself.
In short - don’t loop over gameobjects. Loop over data. If you design the map in Blender, then loop over the game objects once at the start of the game, to produce your generic gamestate data.
This is based upon the MVC (model view controller) design pattern
I use pickle, because I still need to save the game at some point*
I make many little lists that contain only 1 type of systems information
enemies, lamps, components etc, it makes it much easier to get your hooks into stuff, (at least for me) and you can itterate through the smaller lists without blowing up logic usage*.
You do not need pickle unless you save your data to a file. (You could use it to verify that your data is pickle-able - but if it is not you have a design problem already.)
I pickle the actor data (one actor) and send that to the inventory overylay by pickeling it, it seems to work pretty well, and speed is not a problem at all,
I save, open overlay, load pickle, and effectively sent a very large list as a message kinda, I don’t ever really use global dictionary, as most systems that store data also need to have logic to operate on the data*
Ultimately what I’m really trying to build is a proof of concept for a kickstarter or something like that so being able to legitimately save your game will have to come later. I just need to show full iterations are possible.