Jump to content
  • Advertisement
Sign in to follow this  
Nickie

Asset Data Structure

This topic is 2220 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I've got some kind of idea for my engine, however I have no idea does it worth or maybe I'm in the phase "OMG OOP is so cool I shoud keep everything inherited from somewhere and make sure I have 5x times more objects than I need!!!"

I'm currently working on the part where you load and parse data. The idea of the engine is close to the one from Game coding complete 3.
GCC3's code isn't actually engine so I had to write on my own almost everything.

Currently I've got a resource cache. It has a list of resource files. Resource file is for example zip. I can load a file this way:

ResCache::Get()->AddResourceFile(ResourceFilePtr(new NoResourceFile("test.txt"))); // This way I can load files directly if there are not in resource file, however I wanted to keep the same "pattern" so I inhrerited and make this thing
char buffer[256];
Resource res("test.txt\ est.txt"); // doesn't look really intelligent however it means "Load test.txt, located in test.txt"...Yeah but it would look much better : Resource res("mainmenu.zip\\background.png");
memcpy(buffer, ResCache::Get()->GetHandle(res)->GetBuffer(), ResCache::Get()->GetHandle(res)->GetSize());
buffer[ResCache::Get()->GetHandle(res)->GetSize()] = '\0';
cout << buffer;


The problem is how to turn this data into something useful for my engine without everything becomming mess, and still to use the same way to transfer data like any other asset.

I came to something like this:
AssetData class which can store everything. Just inherite from AssetData, for example to XML (which will store my level/map data). Then I would call AssetData : XML_Data::Restore(res); and it would fill itself in its unique way. If I want I could pass the XML_Data to my logic and it would load the map as it is written in there. If it was a mesh I could easily call AssetData : Mesh::Render(const IRenderer &r);
However in my mind AssetData appear to be a tree structure where each assetdata can have children. There comes the problem how to fill the children and to pass the exact data they need to fill.

So my questions at the end are:
How you would do this?
Where would u parse the data? In class AssetManager, by list of supported formats? In the AssetData? Or A completely different way?

Edit: Sorry for not beeing enough direct. I wanted to explain everything from the beginning so you don't need to check the whole source code I've got. However the SC is can be found here if you need something: http://code.google.c.../ random-engine Edited by Nickie

Share this post


Link to post
Share on other sites
Advertisement
One approach to designing such features is to "test first":
Write a unit test that uses the feature. Ignore your current interface, write against the interface you wish you had.
Mock out the interface so that it compiles/links
All your tests should fail!
Now try really implement that interface.
Get the unit tests passing.[/quote]
This is the way I used with the resource cache, but for some reason I didn't even tough to use it because I can't imagine the things in my head. However I'll try to do it this way. I believe it will work. Thanks.

I understand that the engine is really complex system(if it was easy this thread would not exist, hehe) and I can't just start coding the game without it.
I think it would be better idea to work on the engine and the game at the same time, and give the engine the functionality it needs, when it is needed.
While I'm coding the engine I imagine a situations in a real game that would need certain feature and how would it use it. Or at least I try to.

without experience, makes no sense[/quote]
In the process of writing I learned much more than I knew when I start it. Which means it already did its job. Edited by Nickie

Share this post


Link to post
Share on other sites

How you would do this?
Where would u parse the data? In class AssetManager, by list of supported formats? In the AssetData? Or A completely different way?
As first, I'd stay away from text files. Try to make everything binary if possible. In my opinion, that's easier to load and validate.
But somebody needs to read text somehow. Perhaps in a filter stage first, or a "direct loading" path later. I suggest to fit the data in JSON (or XML). This way the parser is ready to go and you only need the interpretation.
It's still quite some work for complex stuff, but it's an interesting middle ground in my opinion. Integrating a JSON parsing took less than a day for me. As soon as one of my current filters breaks, it's going to be replaced by a JSON-enabled version.

My current line of thinking about the future is that I might be doing something like that:

  1. Runtime resource can be built, they don't load themselves directly (to keep interfaces under control)
  2. Runtime manager loads resource X by assuming binary stream representation. The stream is accessed through a [font=courier new,courier,monospace]Transformer[/font].
  3. If binary is there, [font=courier new,courier,monospace]Transformer [/font]is identitity. If not, it's a parser based object.

So yes, it's in your [font=courier new,courier,monospace]AssetManager [/font]class, except the optional text parsing.


One approach to designing such features is to "test first":

  1. Write a unit test that uses the feature. Ignore your current interface, write against the interface you wish you had.

I'd like to change that to "the interface you need ("whish" is a fairly broad concept). For the rest, I totally agree.
I want to stress the need. I have some features which looked nice to have but they were left a stub for a while. In the meanwhile, I have iterated the design and found a way to replace some of them with much more powerful combinations of ready to go functionality.

Engineering and design are a product of experience which I lacked in the beginning. I therefore strongly suggest for some incremental, iterative process: if your first level only needs features X,Y,Z make them work first, make the first level work, make it work smooth. This gives a few "known to work" things you'll hopefully find useful in successive stages. In short, I am strongly confirming your intention to "work on the engine and the game at the same time, and give the engine the functionality it needs, when it is".

Share this post


Link to post
Share on other sites

I'd like to change that to "the interface you need ("whish" is a fairly broad concept). For the rest, I totally agree.
[/quote]
Yes, good distinction. My main point was to try to think outside of the implementation one already has. However, another important point is to try to make the interface convenient and easy to understand, not excessively ugly or burdensome to the client.

But yes, one should limit this to what one needs at the moment lest the tendency to over-engineer take over the design process.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!