1
\$\begingroup\$

I'm designing my assets, and thinking about using a UUID or a name for accessing them. I decided to use UUIDs for identifying them and for storing/accessing the cache, but what if I want to get/use an asset in my script? Do I have to know the UUID of the asset? Having a name identifier will help, but this should also be unique, so I don't know if it's a good idea having both identifiers in the asset.

This seems unintuitive; I have always accessed them by name, like this:

// before:
TextureCache *tc = ...
auto texture = tc->get("Mario");  // (more intuitive)

// now:
TextureCache *tc = ...
auto texture = tc->get(234242423424234);  // (not intuitive)

How do you retrieve assets that have been stored by UUID?

\$\endgroup\$
4
\$\begingroup\$

One way of doing this is to just have a const unsigned int TEXTURE_MARIO which stores the UUID, this can be generated either at load or at compile time.

That way you still have the advantage of not doing a comparison with a string constantly, combined with the readability of not having random numbers in your code. If you do generate the variables list at compile time a decent compiler will generate the same code as if you had the numbers inline.

\$\endgroup\$
2
\$\begingroup\$

My recommendation is to not reference specific assets so directly in your scripts.

There's a lot of reasons. One is that this breaks the ability for your tools or diagnostic helpers to see which assets are in use; they have to execute game code to see what assets get loaded, and since your scripts can generate a literally infinite number of strings/names, there's no way to be exhaustive.

A stronger approach is to use resource tables. These are basically just resources that list other resources, potentially with some other metadata. For example, a drop loot table might be a list of item ids and weights used in the random selection. The drop loot table resource would then be referenced by the monster resource that drops that loot. The script code would do something like drop_random(dead_monster.loot_table) rather than having a unique loot code or list of strings/resources of its own.

This approach can drive almost every single part of your game: spawns are resources referenced by the map, character classes are resources referenced by the player creation resource table, and so on.

The only resource that ever needs to be hard-coded is the main "boot" resource. That is the resource that contains the references to your splash screens, your main scripts, etc. Because there's just one of those it's a lot easier to special case in all your tools. In fact, loading it might even just be a single function that's compiled into all the tools from the same source code.

For your example, you'll probably want a StartupResource of some kind, maybe defined like:

struct StartupResource {
  TextureHandle mario;
  LevelHandle first_level;
};

Then your startup function would look more like this:

StartupResource* startup = load_startup_resource(); // only place you ever hardcode a resource name

TextureCache *tc = ...
auto texture = tc->get(startup->mario); // intuitive, data-driven, toolable
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.