• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
  • entries
    4
  • comments
    7
  • views
    8791

Lost in Asset Management

Sign in to follow this  
Followers 0
Tocs1001

1182 views

So I've been contemplating a good way to manage assets used by my game and so far I've been losing the mental battle.

My current idea is a custom smart pointer much like shared_ptr, in addition to reference counting it keeps track of which files have been loaded and simply returns a reference if its already loaded.

This makes loading files worry free as it looks like this.Asset tex = Asset::Load("UglyTexture.png");
And if you load it twice.Asset tex1 = Asset::Load("UglyTexture.png");Asset tex2 = Asset::Load("UglyTexture.png");//UglyTexture.png is only loaded once.
It won't waste CPU or GPU memory.

And preloading commonly used things is easy too, it just adds the texture to the table with an extra reference so it never gets unloaded.Asset::PreLoad("UglyTexture.png");
Things get tricky though if I generate some sort of texture at runtime, it becomes a question of who should own the Texture object.

If an object is dynamically allocated, it's rather simple to say Asset should determine when it's deleted with something like.Texture2D *proceduraltex= new Texture2D (100,100,...);//Do something to proceduraltexAsset tex = Asset::Manage(proceduraltex,"ProceduralTex");//Somewhere elseAsset texagain = Asset::Load("ProceduralTex");
But than I began to wonder about the case of the Texture2D object belonging to something else, and how i would use it.void SomeAssetFunction (const Asset &asset) {}class Foo{ Texture2D footex; Foo () { SomeAssetFunction(Asset::Wrap (footex)); }};
But since the "Wrapped" asset doesn't own the texture it could go out of scope and suddenly the Asset<>'s promise of the texture existing is meaningless.

So my thought was to only use Asset<>'s as member variables, it could easily cause a problem of loading a texture every frame if the Asset<> is used as a local variable.void SomeFunctionCalledEveryFrame (){ Asset tex = Asset::Load("NonPreloadedTex.png"); //use tex}//NonPredloadedTex.png gets destroyed.
And that any function that needed a Texture2D simply took a Texture2D reference.void SomeFunctionThatTakesATexture (const Texture2D &);Asset tex = Asset::Load("UglyTexture.png");SomeFunctionThatTakesATexture(tex.Get ());
Overall I'm just mildly happy with the system. On one hand its nice to have the separation between the resource object (Texture2D, Mesh, Shader, etc) and the asset handling it seems to reduce cruft and redundancy in each file. On the other hand the disconnect between generated assets and file loaded assets is a tad annoying.

Its also expandable I plan to add live reload of assets behind the scenes. Since Asset<> controls the storage of each asset, its possible to just flop out the asset behind the scenes and anything using the Asset<> will instantly have the new resource to work with.

Downsides include:

  • Thread Unsafety: I might be able to work this out if I was super clever but as it stands the storage container for keying filenames to assets is thread unsafe. Also live reload would be tougher to add with thread safety.
  • Global state: Currently I'm not bothered by the fact it assumes there's only one OpenGL context and will put all resources there. But I eventually want to be able to use my graphics code in an editor where I might have multiple contexts.
  • No special parameters: Sometimes its nice to specify additional info for how a file should be loaded such as filtering for textures. Perhaps some variardic templates and a little SFINAE wizardry could produce usable results. (static_assert when type T of Asset doesn't supply the proper functions. Otherwise cryptic compile errors appear)

    This was my first ever journal post, and I just kinda vomited thoughts all over the page. If you have suggestions on how to handle assets leave me a comment.

1
Sign in to follow this  
Followers 0


3 Comments


Why not

Asset<Texture2D> editMe = Asset<Texture2D>::Create("ProceduralTex", 100, 100, ...);

 

then later

Asset<Texture2D> useMe = Asset<Texture2D>::Load("ProceduralTex");

1

Share this comment


Link to comment

Would it be possible to fix the thread safety issues simply by applying a lock around reads/writes to the container to associate filenames to assets?

 

I've worked with a system that seems similar to yours, and we were able to stream in several textures at the same time using an Asset wrapper as you've done. The resource loader would lock the container that associated the asset filename with the asset object, and grab a new thread to use in loading the texture data. Once loaded, the data was submitted to the GPU, and the Asset was marked with a "DataLoaded" flag to signal that the texture was ready to be bound and used.

 

This was a successful system because it also allowed us to stream things in on the fly. Your Asset wrapper could do the same thing: Game objects can hold on to a reference to a texture all the time, even if your asset isn't loaded. When the asset is bound for use, and it's not in memory, queue it to stream in and use a placeholder or transparent texture in its place until the "DataLoaded" flag has been updated on the asset.

1

Share this comment


Link to comment

achild: I like the syntactic sugar when I move away from VS2010 and have variardic templates I'll definitely put that in.

 

uint32_t: It would definately be possible to do things like you described to make it thread safe. I just haven't done that yet. I feel it would be trickier to work in thread-saftey with live reload of assets because the "DataLoaded" flag would no longer function.

0

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now