Welcome, Guest. Please login or register.

Pages: [1] 2 3
Print
Author Topic: Design Tasks  (Read 14019 times)
tZee
Community member

Posts: 190


View Profile Email
« on: June 23, 2009, 03:22:32 PM »

There are some design tasks that have to be done and I want you to participate in the design process. Smiley

I have three in mind right now:

1. Working out the map class, where it should be located, how it should be handled and how to tell the engine to render the one we want.

2. Working out how our abstract objects interact with the engine on the rendering side. On which basis will be decided which image has to be drawn, how to trigger a change etc.

3. The object loader. Work out a loading/storing strategy that is flexible. I already proposed something, but an outline. I guess together with this it has to be evaluated how the engine handles sound and music files and how to store them in memory only once. (Objects should share them if they use the same image/sound)
Also there needs to be some thinking about flexibility in terms of dynamic loading done. We wont be able to have all game data at once in memory in the future, so a loading strategy in terms of when will the game load what has to be evaluated. (How long does it take to load a fully fledged map with lots of agents, images, sounds etc.? How to minimize loading time without influencing the performance too much?)
Don't know, maybe I am thinking too far here. Cheesy


@Meggie and Imons_:
If you feel like it I'd like you to choose one of those tasks and give it a try. You both said you are not very experienced in this area, but you are willing to learn. I think this would be a good exercise for you. Smiley
If you need help on how to get started - we're all here to help you. Smiley The tool I used is StarUML, but you can use the UML editor of your preference. Wink
Logged

meggie
Community member

Posts: 30

Python programming looking for some C++ experience

un1meg
View Profile
« Reply #1 on: June 23, 2009, 05:05:23 PM »

Sorry tZee, where was the loader discussion? I'd like to look it over before thinking much more about it.

As far as maps go, there are two separate elements that make a map:
1) stuff in a map.xml file
2) stuff in a map_objects.xml file

We don't really care about 1, we'll need to have the engine load it for us each time (all it needs is the filename), but it doesn't take long. Each map should have an id, and the id should match the filename (not currently the case, but an easy stipulation). This way, we can extract the filename from just storing the map ids as target maps in the doors. I also don't see us ever having to change the information stored in these files.

And 2 is more or less inextricable from the object loader, which is why I'd like to see its discussion ^_^.
Logged

-Meggie
maximinus
Community member

Posts: 694



View Profile Email
« Reply #2 on: June 23, 2009, 05:10:23 PM »

3. The object loader. Work out a loading/storing strategy that is flexible. I already proposed something, but an outline. I guess together with this it has to be evaluated how the engine handles sound and music files and how to store them in memory only once. (Objects should share them if they use the same image/sound)
Also there needs to be some thinking about flexibility in terms of dynamic loading done. We wont be able to have all game data at once in memory in the future, so a loading strategy in terms of when will the game load what has to be evaluated. (How long does it take to load a fully fledged map with lots of agents, images, sounds etc.? How to minimize loading time without influencing the performance too much?)
Don't know, maybe I am thinking too far here. Cheesy

I'm thinking that the memory issue will be in gfx and sound, not the game objects. Let's say we have 10,000 game objects at 1k bytes each that's only 10 Meg and I'd say I'm being pretty liberal on both figures. On music, we only need to store at least 2 pieces at any one time (current piece is 4.5MB) and gfx could be huge depending on animation (although less than 1MB right now). But I'm assuming we'll be running on a machine that has 128MB of spare RAM. According to free() PARPG uses about 56 Meg currently on my machine, so that's still over 70MB of storage space. Not a major issue right now then to remember all game items and states.
Fife also loads maps quick, although it loads previous maps even quicker; this could be the OS caching previous disk reads but even a 'fresh' map loads pretty quick (although none of maps are 'huge' yet).
Logged

Science is open-source religion
tZee
Community member

Posts: 190


View Profile Email
« Reply #3 on: June 23, 2009, 05:17:21 PM »

I never said to change the file format. It's the loader class and how it handles the loading. Ideally it loads the xml data and presents it to the rest of the game code in an independent format, which then get's converted into whatever object classes there are. (I'm thinking of a simple dict here, for each object.)

The "outline" is less than I remembered.. Cheesy It's on the lower left of the class design draft I did.

2 and 3 are different tasks. 2 is about the object after it has been loaded and when interacted with. I currently do not know when/how the engine loads the image files and how it is decided which image is drawn. That's the point of this task, to find it out and see how to fit it in the design in a practical way. Smiley

@Maximus: If you want to keep 10000 objects in memory we need to see how fast the dictionaries/lists are in terms of finding objects. It's not a good idea to have so many objects in memory when we do list transformations on a regular basis.

Well, if the user only has 128MB of free memory his machine will be accordingly slow. My machine is pretty fast and I have no problems with the loading times, but you have to consider slower machines as well. Too, in terms of search-times of objects.
Logged

maximinus
Community member

Posts: 694



View Profile Email
« Reply #4 on: June 23, 2009, 05:38:18 PM »

@Maximus: If you want to keep 10000 objects in memory we need to see how fast the dictionaries/lists are in terms of finding objects. It's not a good idea to have so many objects in memory when we do list transformations on a regular basis.

Not really an issue. Having 10,000 items in memory doesn't mean you search them all, you can easily just scan a subsection (i.e. the ones on the current map).

The worst case scenario is that you build a new data structure when a new map loads that consists only of objects on the current map, and that you may have to sync parts of that with the global data when you change map.
Logged

Science is open-source religion
meggie
Community member

Posts: 30

Python programming looking for some C++ experience

un1meg
View Profile
« Reply #5 on: June 23, 2009, 05:57:05 PM »

Hmm. I meant my definition of 2, when I said 2...that is, loading things from the map_objects.xml files is inextricable from the object loader. Sorry...

As far as I know, each object requires an id, which we can store in a dictionary (python dict = hashmap, so in answer to your post @maximinus, fast lookup). Question is *what* to store.

I would suggest having calls to the constructors and storing the objects directly in the dictionary keyed to their id. Possibly also have another dictionary with lists of objects keyed to map ids so that we can look up all the objects on a map really easily. The loader can pass these to the gameData object, which seems possibly redundant with the Engine class, maybe?

object dictionary = {id : the actual object}
map dictionary = {map id : [pointers to object] OR [object ids]}

So, objectloader:
1) read the xml files, object by object
2) for each object
 * call the appropriate constructor(s)
 * add the object to the objects dictionary
 * add the object's id or a pointer to the object to the appropriate object list in the map dictionary (makes it really easy to scan current map objects)

I feel like this setup makes either the gamedata or the engine class unnecessary.
Logged

-Meggie
tZee
Community member

Posts: 190


View Profile Email
« Reply #6 on: June 23, 2009, 06:38:38 PM »

@Maximus: If you want to keep 10000 objects in memory we need to see how fast the dictionaries/lists are in terms of finding objects. It's not a good idea to have so many objects in memory when we do list transformations on a regular basis.

Not really an issue. Having 10,000 items in memory doesn't mean you search them all, you can easily just scan a subsection (i.e. the ones on the current map).

The worst case scenario is that you build a new data structure when a new map loads that consists only of objects on the current map, and that you may have to sync parts of that with the global data when you change map.

My idea was to have one "global" object array (in the GameData class) and such selections, like only items of map xyz or only items of class Wearable, are said list transformations.

Hmm. I meant my definition of 2, when I said 2...that is, loading things from the map_objects.xml files is inextricable from the object loader. Sorry...

Oups.. Cheesy

As far as I know, each object requires an id, which we can store in a dictionary (python dict = hashmap, so in answer to your post @maximinus, fast lookup). Question is *what* to store.

Yeah, that is my question: How fast are dictionaries in Python? HashMaps are not exactly fast. Cheesy

I would suggest having calls to the constructors and storing the objects directly in the dictionary keyed to their id. Possibly also have another dictionary with lists of objects keyed to map ids so that we can look up all the objects on a map really easily. The loader can pass these to the gameData object, which seems possibly redundant with the Engine class, maybe?

The disadvantage of this is that anytime you change the objects you have to change the objLoader as well. Having the objLoader call a ObjectFactory to create the objects is the closest I'd couple it with the object format. Even that might be not good enough, because it would require the objLoader to know about the format/structures in which we store the objects.

object dictionary = {id : the actual object}
map dictionary = {map id : [pointers to object] OR [object ids]}

Good idea actually. I was thinking about something like this to get the object of a map: [i for i in objList if i.currentMap == "map xyz"], but i guess that is slower than keeping something like a index list. (What you suggested.)
Logged

maximinus
Community member

Posts: 694



View Profile Email
« Reply #7 on: June 23, 2009, 06:58:28 PM »

@Maximus: If you want to keep 10000 objects in memory we need to see how fast the dictionaries/lists are in terms of finding objects. It's not a good idea to have so many objects in memory when we do list transformations on a regular basis.

Not really an issue. Having 10,000 items in memory doesn't mean you search them all, you can easily just scan a subsection (i.e. the ones on the current map).

The worst case scenario is that you build a new data structure when a new map loads that consists only of objects on the current map, and that you may have to sync parts of that with the global data when you change map.

My idea was to have one "global" object array (in the GameData class) and such selections, like only items of map xyz or only items of class Wearable, are said list transformations.

So you'd only need a transformations on a map change - making any slight delay no problem.

How fast are dictionaries in Python? HashMaps are not exactly fast. Cheesy

Slow. Everything is pretty slow. Is it fast enough? Probably. That's how a lot of Python works  Cheesy
Logged

Science is open-source religion
tZee
Community member

Posts: 190


View Profile Email
« Reply #8 on: June 23, 2009, 07:01:35 PM »

How fast are dictionaries in Python? HashMaps are not exactly fast. Cheesy

Slow. Everything is pretty slow. Is it fast enough? Probably. That's how a lot of Python works  Cheesy

http://wiki.python.org/moin/DictionaryKeys not as slow as i thought. Smiley
Logged

meggie
Community member

Posts: 30

Python programming looking for some C++ experience

un1meg
View Profile
« Reply #9 on: June 23, 2009, 08:01:29 PM »

Quote
The disadvantage of this is that anytime you change the objects you have to change the objLoader as well. Having the objLoader call a ObjectFactory to create the objects is the closest I'd couple it with the object format. Even that might be not good enough, because it would require the objLoader to know about the format/structures in which we store the objects.

Yeah, I kind of brushed this consideration off a little because I wasn't sure the best way to do it. I've also been thinking of the objLoader as a loader from the _objects.xml files. In that sense of the loader, every time we change the objects (or the format in which objects are stored as well as how their constructors are called) we'll need to change something, somewhere in code. And the data from the xml files will be relatively messy (that was one of your original complaints, the mysterious unlabeled lists), so we might as well keep all the mess in the loader, which was why I suggested we call the constructors there.

As for changing objects in game, we don't need to change the loader at all, we just need to call the same constructors in where-ever the objects are being changed, and reassign the new object to the existing id for the object in the dictionary for the gameData/Engine class.
Logged

-Meggie
tZee
Community member

Posts: 190


View Profile Email
« Reply #10 on: June 23, 2009, 09:23:19 PM »

we'll need to change something, somewhere in code. And the data from the xml files will be relatively messy (that was one of your original complaints, the mysterious unlabeled lists), so we might as well keep all the mess in the loader, which was why I suggested we call the constructors there.

That's where you usually use factory classes. They do the dirty work. And the array would be a mess, because it's wont be an array with arbitrary values at index X but a dictionary with key:value pairs.

It works like this:
1. objLoader fills an array with dictionaries which contain the xml data. E.g.: [{name=asdf, type=door, posx=0.0, posy=1.0}, {name=barrel, type=container, posx=1.0, posy=20.0}]
2. The array entries are passed to static function ObjectFactory.create() (or getInstance() or whatever name you prefer).
3. This is the "dirty" part. create() does a lookup on the type. Will be a switch statement or a large if construct. When it matches it will create the appropriate object and return it. E.g. if array["type"] == "door": return Door(array["name"], array["posx"], array["posy"])

For your reference: http://en.wikipedia.org/wiki/Factory_method_pattern
Logged

meggie
Community member

Posts: 30

Python programming looking for some C++ experience

un1meg
View Profile
« Reply #11 on: June 23, 2009, 09:32:12 PM »

Hmm. That sounds good. So we have:

1) objLoader reads from .xml file, makes a dictionary, passes dictionary to factory
2) factory makes an object messily (but we'll need the mess somewhere, so no big deal), returns it to the loader
3) the loader either attempts to add it to the gameState/Engine dictionary then, or adds it to a local dictionary which is later merged with the gameState/Engine dictionaries
Logged

-Meggie
tZee
Community member

Posts: 190


View Profile Email
« Reply #12 on: June 23, 2009, 10:04:27 PM »

hmm.. originally i wanted step 3 to be in the engine, because of the loading strategy, but actually i like it better your way. the loader should be the one deciding about the loading strategy, so it should be the one handling the safegames and adjusting the objects accordingly..

I think when we load a safegame, all we have to do is to clear the objects in memory, unpickle the GameData of the safegame and change to the specified map. (Because loading the GameData would restore the game to the exact state it was in at saving time.) Only when we load new maps that haven't been loaded previously we need to check for exiting objects in the GameData object. What do you think?
Logged

tZee
Community member

Posts: 190


View Profile Email
« Reply #13 on: June 25, 2009, 09:33:23 PM »

Is actually anyone working on the tasks?

And we should wikify our result, meggie. Smiley
Logged

meggie
Community member

Posts: 30

Python programming looking for some C++ experience

un1meg
View Profile
« Reply #14 on: June 26, 2009, 02:12:46 AM »

Depends what you mean by working on. I've thought about them, and think that we can do 1 and 3. I can wikify this. Which result did you have in mind, tZee?
Logged

-Meggie
Pages: [1] 2 3
Print
Jump to: