Assets

An asset is any file under your project's Assets/ folder. Turian watches the folder, imports each source file into an engine-ready artifact under .Cache/, and records it in the project's asset catalog.

Ids and .meta files

Every asset gets a .meta file beside it, holding a stable id. Scenes, materials and your components refer to assets by that id, never by path, so you can move and rename files freely — in Studio's Assets panel or in your file manager. Commit .meta files to version control; never commit .Cache/.

Supported files

Kind Extensions Opens in
Scene / prefab .prefab a Studio tab
Material .material the Inspector
Data asset .dataasset, .asset the Inspector
Model .gltf, .glb, .fbx, .obj your default program
Texture .png, .jpg, .jpeg, .tga, .bmp, .gif, .webp, .dds your default program
Font .ttf, .otf —
UI document / style sheet .ui, .uss your default program
String table .strings your default program
Script .cs your code editor

Models

  • glTF 2.0 (.gltf, .glb) — geometry, every mesh and primitive, and materials. Each glTF material becomes a child material asset, and each embedded image a child texture asset, with ids derived from the model's, so they stay stable across reimports. Textures stored as separate files are imported as assets of their own.
  • FBX — geometry and materials, through Assimp.
  • OBJ — geometry.

Put a model in a scene with a ModelComponent: drop the model on its Model field. Materials overrides the material of each submesh, like Unity's material slots.

Textures

Textures upload with mipmaps. The import settings in the Inspector cap the resolution (the longest edge) overall or per build target; the project-wide default is Texture Max Resolution in Graphics Settings.

Materials

Create one from the Assets panel: right-click → New → Material. Materials use the PBR metallic-roughness model of glTF 2.0:

Property Meaning
BaseColorFactor, BaseColorTexture Albedo colour (RGBA) and texture.
MetallicFactor, RoughnessFactor, MetallicRoughnessTexture Metalness and roughness.
NormalTexture Tangent-space normal map.
OcclusionTexture Ambient occlusion.
EmissiveFactor, EmissiveTexture Light the surface emits.

Drop textures from the Assets panel onto the texture slots in the Inspector.

Data assets

Data assets are your own C# classes saved as asset files and edited in the Inspector — like Unity's ScriptableObjects. Use them for items, enemy stats, dialogue, level lists: anything a designer should tune without touching code.

namespace Usercode;

[CreateAssetMenu(path: "Game/Weapon", fileName: "NewWeapon")]
public class WeaponData : DataAsset
{
    public string DisplayName = "Sword";
    [Range(1, 100)] public int Damage = 10;
    public float Cooldown = 0.5f;
}

After the script compiles, New → Game → Weapon appears in the Assets panel's context menu.

Each data asset is one shared object: every component and data asset referencing it gets the same instance, so a change made through one is seen by all — the basis for shared variables and event channels. Changes made while playing never reach the asset file; they last until Play Mode stops. When one user of the data needs its own copy (one enemy's stats taken from a template), make it with DataAsset.Instantiate(template).

Data assets can reference each other by declaring a field of the other type, cycles included. They cannot reference nodes or components — a data asset outlives any scene — and the compiler warns (TUR0001) if one tries; use NodeRef<T> or ComponentRef<T> there.

To react when a value changes, make the class partial and mark partial properties [Observable]; Turian generates the property and raises the asset's Changed event only when the value actually changes:

public partial class PlayerHealth : DataAsset
{
    [Observable] public partial int Current { get; set; }
}

health.Changed += (asset, member) => healthBar.Refresh();

Turian also generates each data asset's serializer at compile time, so loading data assets needs no reflection.

Loading assets at runtime

Expose references as fields and let the Inspector fill them; load through IAssetLoader:

public class Armory : Component
{
    public AssetReference<MaterialAsset>? GoldMaterial;

    public override async void OnStart()
    {
        var loader = RuntimeServices.TryGet<IAssetLoader>();
        if (loader is null || GoldMaterial is null) return;

        var material = await GoldMaterial.LoadAsync(loader);
    }
}

Loading a scene loads the data assets it references in parallel before the scene starts. To load a group of assets ahead of time — a level's data, say — list a label in each asset's .meta file ("Labels": ["level-2"]) and preload it:

await loader.PreloadLabelAsync("level-2");

loader.PreloadAsync(ids) does the same for any list of assets.

Shipping assets

When you export, Turian packs every imported asset into an Open Asset Package (.oap) in the game's Content/ folder: a single compressed file with CRC-checked entries, read directly by the runtime. The CLI can also pack (optionally with ChaCha20 encryption), list, inspect, validate and unpack .oap files.

Reimporting

Imports run automatically when files change. Project → Reimport Assets rewrites every .meta and imports the whole project again, and turian-cli compile <project> does the same headlessly.


← All docs Edit this page