Grindstone Game Engine v0.2.0
An open source game engine and toolkit.
Loading...
Searching...
No Matches
Asset System

The Grindstone Asset System provides a unified, extensible way to load, manage, and reference game content (assets) across both the editor and runtime. It supports reference counting, type-safe asset access, and optimized loading strategies through a dual loader system.

You can learn about creating new assets with the following guides:


Purpose

The asset system abstracts asset management away from file IO, providing a consistent and efficient API for accessing resources like meshes, materials, textures, audio clips, and more.

It supports:

  • Hot-reloading in the editor.
  • Reference-counted memory management.
  • Type-safe access using AssetReference<T>.
  • Batch-packed runtime loading for performance.

Core Components

Asset

Asset is a base class for all asset types. Each Asset:

  • Has a UUID and name.
  • Tracks a referenceCount.
  • Has a AssetLoadStatus.

AssetReference

AssetReference<T> is a type-safe smart reference to an asset. Handles:

  • Automatic reference counting.
  • Access to the underlying asset (with Get() and GetUnchecked()).
  • Safe copying/moving of references.

AssetImporter

AssetImporter is an abstract interface for managing asset lifecycles. Implements:

  • Load/unload logic.
  • Reference counting.
  • Reloading support.

It can be specialized via SpecificAssetImporter<YourAssetStruct> for each asset type.

AssetManager

AssetManager is the global hub for managing all registered asset types. Responsibilities include:

  • Mapping AssetType to importer.
  • Queuing and executing asset reloads.
  • Accessing assets by UUID or address.
  • Registering new asset types.

Extensibility

You can register new asset types in plugins using these methods of a PluginInterface:

  • Runtime Assets:
    • RegisterAssetType(AssetType assetType, const char* typeName, AssetImporter*)
    • UnregisterAssetType(AssetType assetType)
  • Editor Assets:
    • RegisterAssetImporter(const char* extension, Grindstone::Editor::ImporterFactory, Grindstone::Editor::ImporterVersion)
    • DeregisterAssetImporter(const char* extension)

Loaders

Two kinds of loaders support different use cases:

FileAssetLoader

FileAssetLoader is used in the editor.

  • Loads assets directly from disk.
  • Supports live editing, hot-reloading, and development workflows.

AssetPackLoader

AssetPackLoader is used in runtime builds.

  • Loads from optimized, consolidated files (asset packs).
  • Uses a manifest for resolving UUIDs and metadata.
  • Greatly improves performance and reduces file I/O.

Supported Assets

Out of the box, %Grindstone includes support for:

Each is implemented with its own importer and load logic.


Usage Patterns

Load an asset reference:

Access by AssetReference:

Grindstone::AssetReference<CustomAsset>& customAssetReference = myComponent.customAsset;
CustomAsset* myAssetAsset = customAssetReference.Get();
if (myAssetAsset == nullptr) {
return;
}
// Use the asset...
Definition AssetReference.hpp:45

Access by UUID:

Grindstone::Uuid uuid = /* Retrieved from the scene components. */;
Grindstone::EngineCore& engineCore = Grindstone::EngineCore::GetInstance();
Grindstone::Assets::AssetManager* assetManager = engineCore.assetManager;
CustomAsset* customAssetReference = assetManager->GetAssetByUuid<CustomAsset>(uuid);
if (customAssetReference == nullptr) {
return;
}
CustomAsset* customAsset = customAssetReference.Get();
// Use the asset...
Definition AssetManager.hpp:15
Definition EngineCore.hpp:60
Definition Uuid.hpp:7

Access by Address (Hashed String):

Grindstone::EngineCore& engineCore = Grindstone::EngineCore::GetInstance();
Grindstone::Assets::AssetManager* assetManager = engineCore.assetManager;
CustomAsset* customAssetReference = assetManager->GetAssetReferenceByAddress<CustomAsset>("@Assets/test");
if (customAssetReference == nullptr) {
return;
}
CustomAsset* customAsset = customAssetReference.Get();
// Use the asset...

Notes

  • UUIDs identify assets internally across the engine, which ensure unique identities for each asset.
  • Address HashedStrings are human-friendly identifiers.
  • Reference counts prevent premature unloading.
  • Asset reloads are queued and applied during an update.