Torque3D
  • General
    • Welcome!
    • Features
    • Release Notes
      • Version 4.0.3
      • Version 4.0.2
      • Version 4.0.1
      • Version 4.0
      • Version 3.10.1
      • Version 3.10
      • Version 3.9
      • Version 3.8
      • Version 3.7
      • Version 3.6.2
      • Version 3.6.1
      • Version 3.6
  • Getting Started
    • Introduction
      • What's the Torque3D Engine?
    • Getting Familiar
      • Getting a Copy
        • Torque Project Manager
        • Downloading it Yourself
      • Getting Ready for Launch
        • Running Pre-Built Binaries
        • Building the Engine Yourself
      • Launching the Game
        • Opening the Example Level
        • Launching the Editors
      • Your First Game
        • Introduction To The Engine
        • The Module System
        • Creating an empty gamemode
        • Adding a Player
        • Adding a Coin
        • Adding a win-condition
        • Custom coin asset
        • Counting coins
        • Adding some effects
        • Supporting multiplayer
        • Adding a Scoreboard GUI
        • Keeping the scoreboard up-to-date
      • Deep Dive: BaseGame Directory Structure
    • Best Practices
    • Porting a Legacy Project
  • For Artists
    • Assets
      • What are Assets?
      • How to Create a New Asset
      • Working With Assets
      • Deep Dive: Creating a New Asset Type
    • Art
      • File Formats
      • 3D Art
        • Shape Specifications
        • Coordinates System
        • Mounting Shapes
        • Animation
        • Player Setup
        • Blender -> Torque3D Pipeline
      • 2D Art
        • Working with Adobe Substance
    • Animation
    • GUI
      • Loading and Initializing a GUI
      • Expanding a GUI via Script
      • How to Network GUIs
    • Materials
      • Material Mapping
      • Material Animation
    • Terrain
    • Shaders
    • Lighting
    • Audio
  • For Designers
    • Base Classes
      • SimObject
      • SimGroup
      • SceneObject
      • Scene
      • Datablocks
    • Game Classes
      • Creating an Object
      • Destroying an Object
      • Gameplay Scripting
        • Spawning an Object from Gameplay Code
    • Modules
      • What are Modules?
      • How to Create a New Module?
      • Making a Module do Things
      • Installing Existing Modules
        • Where to Get More Modules
    • Scenes and Levels
      • How to Create a New Level
      • How to Load a Level
        • Deep Dive: Level Loading Scripts
      • How to Edit Levels
        • Opening a Level in the Editor
        • Spawning Objects from the Asset Browser
        • Working with Scenes
        • Using SimGroups
        • Changing a Level's PostEffects
        • Deep Dive: LevelAsset Companion Files
    • Game Modes
      • Creating a New GameMode
      • Making a Level Use Your GameMode
      • Adding Gameplay Code to Your GameMode
    • AI
      • Navmesh
      • Objects
      • Scripting
    • Inputs
      • Inputs and Keybinds
        • ActionMap
        • Bind Functions
        • ActionMap Stack
    • Localization
    • Editors
      • Changing Editor Settings
      • World Editor
        • Scene Editor
        • ConvexShape Editor
        • Terrain Editor
        • Terrain Painter
        • Material Editor
        • Spline-Based Tools
          • Mesh Road Editor
          • River Editor
          • Decal Road Editor
        • Datablock Editor
        • Particle Editor
        • Decal Editor
        • Forest Editor
        • Navmesh Editor
        • Deep Dive: Creating Your Own Editor
        • Shape Editor
      • GUI Editor
        • Interface Details
  • For Programmers
    • Compiling the Engine
      • Setup Development Environment
        • SDK and Library Installation
        • Git
        • Cmake
        • Creating a Fork on Github
      • Create a Project
        • Creating a Project With CMake
        • Creating a Project With the Project Manager
      • Compiling
        • Compiling in Windows
        • Compiling in Linux
        • Compiling in MacOS
      • Building the Project Manager
    • Introduction
    • Code Style Guidelines
    • Expanding the Engine
      • Creating a New Object Class
      • Exposing Object Classes to Script
        • addProtectedField
      • Adding a New Library to the Engine
    • Major Components of the Engine
      • Core
        • Console
        • Platform
      • Audio
        • SFX
      • Rendering
        • GFX
        • Render Bins
      • Physics
        • Stock T3D Physics
        • Physics Wrapper
          • PhysX
          • Bullet
        • Classes
    • Rendering
    • Math
    • Networking
      • Client and Server Commands
    • Physics
    • Collision
    • Scripting
      • TorqueScript
        • What is TorqueScript?
        • Basic Syntax
        • Variables
        • Types
        • Operators
        • Control Structures
        • Functions
        • Objects
        • Module Interop
          • QueueExec
          • RegisterDatablock
          • CallOnModules
          • ModuleExec
        • API Reference
      • Other Languages
        • C-Interface
    • File Inputs/Outputs(I/O)
    • API Reference
Powered by GitBook
On this page
  • What are assets?
  • Loading resources the Asset way
Edit on GitHub
Export as PDF
  1. For Artists
  2. Assets

What are Assets?

PreviousAssetsNextHow to Create a New Asset

Last updated 2 years ago

What are assets?

Assets, as far as Torque3D 4.0 is concerned, is a means of tracking a game’s content via metadata. There are many types of assets: shapes, materials, images, levels, sounds and so on. Unlike a simple file path reference, the metadata an asset provides gives a litany of supporting data and utility.

Classically, engine assets such as shape files were simply the literal files themselves. A class or object that would want to use said shape file would have a filepath field that would point to it, and the class would process it. In a few special cases, like shape files, the loader logic for the shape would run some logic during load to generate secondary files. For shapes, you’d have your engine-formatted *.cached.dts data, the shape constructor script file, etc.

Loading resources the classical way An example of when the shape is loaded can be seen here. We pass in the filepath into the resource loader, and in the case of Shape resources, would generate the *.cached.dts file if it didn’t exist, and load it if/when it did, returning the shape resource.

One of the problems, however, was it relied on a direct file reference.

If for any reason - a typo, the file was moved or deleted or so on - the file was not found at the file path, it broke.

When this happened, the object would fail to load, and then would not exist in the scene. This made the level editor particularly dangerous, as if the objects failed to load their shape files, they wouldn’t be added to the scene at all, and if the mapper failed to notice missing objects and saved, they were gone for good.

Loading resources the Asset way

The asset system sidesteps this issue by instead utilizing unique id names to reference, similar to referencing an object by name. The asset itself handles the path info, and game objects themselves need only request the unique id name.

This means that if the shape’s file path was spelt incorrectly, or was moved, then as long as it’s correct in the asset metadata, any object with the assetId will get the correct path.

Another useful aspect is how assets handle fallbacks. In the event an asset isn’t found, or something is not loaded correctly preventing the asset from being used, it can safely fall back to a placeholder asset without ‘damaging’ the original data. As previously noted, the old way, this meant that the object did not load at all, causing problems with the map.

Instead, the asset system can realize it failed to find or load the requested asset, and provide a placeholder fallback. This allows the level to load as normal, and present obvious indicator content to the level editor or testers that something did not load as was expected, without harming the level file as it’s otherwise being worked on. This prevents the problem from holding up other team members’ tasks.

Other issues often faced in the legacy, path-based resources were order of operations and dependencies loading. To ensure materials were loaded before they were needed(as there was no way to associate materials to what used them), the game template would just scan all material.tscript files and bruteforce load everything ahead of time. This could lead to longer startup times, and could be an exploitable vulnerability, as well as often loading a ton of additional material into memory that wasn’t needed.

It could also suffer from similar path unreliability issues if paths the materials relied on for image maps or the like were invalid due to misspellings, or being moved.

Assets, however, allow integrated dependency tracking. When an asset, such as a shape, is loaded, it has its own list of dependencies.

Because asset loading is reference-based. Only assets that are actually called get loaded. When they go to load, it checks for any dependencies in the asset metadata, and loads them first. Those assets load in a similar way, continuing until the dependency chain is complete.

In the above example, the shapeAsset is loaded, but it relies on 2 material assets. It loads those, but those themselves have dependencies to image assets, so those are loaded. Once the entire dependency chain is loaded and valid, the shapeAsset is ready and passed back to the game object that wanted to use it. If anything goes wrong, each can provide a fallback placeholder to ensure things load correctly, while still indicating what and how it failed to provide more info for debugging.

Because assets’ loading is reference-based, when all the references are removed, such as when a level is unloaded, the asset can too be unloaded. This makes post-level cleanup easy, and goes a long way to ensure only memory and resources in use actually get consumed.