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.