---
name: Assets Pipeline
slug: assets-pipeline
category: DevOps
description: Assets Pipeline explains how Godot imports images, 3D scenes, audio, and other resources, and when to adjust compression, mipmaps, and import settings. Use it when preparing assets for clean versioned imports and efficient runtime use.
github: "https://github.com/jame581/GodotPrompter/tree/master/skills/assets-pipeline"
language: JavaScript
stars: 614
forks: 30
install: "npx degit https://github.com/jame581/GodotPrompter/tree/master/skills/assets-pipeline ~/.claude/skills/assets-pipeline"
installs_to: ~/.claude/skills/assets-pipeline
source_path: skills/assets-pipeline/SKILL.md
collection_size: 25
category_size: 798
collection_url: "https://dirskills.com/collections/jame581/GodotPrompter"
added: 2026-08-24T05:18:46.573Z
last_synced: 2026-08-24T05:18:46.573Z
canonical_url: "https://dirskills.com/skills/assets-pipeline"
---

# Assets Pipeline

Assets Pipeline explains how Godot imports images, 3D scenes, audio, and other resources, and when to adjust compression, mipmaps, and import settings. Use it when preparing assets for clean versioned imports and efficient runtime use.

**Install:**

```bash
npx degit https://github.com/jame581/GodotPrompter/tree/master/skills/assets-pipeline ~/.claude/skills/assets-pipeline
```

## README

# Assets Pipeline in Godot 4.3+

All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.

> **Related skills:** **audio-system** for audio playback and bus architecture, **3d-essentials** for 3D materials and lighting, **2d-essentials** for 2D rendering and sprites, **animation-system** for imported animations, **godot-optimization** for asset-related performance, **multithreading** for threaded resource loading.

---

## 1. How Importing Works

### The Import System

When you add a file to `res://`, Godot auto-imports it based on its type. Import settings are stored in `.import` sidecar files alongside the original.

```
project/
├── textures/
│   ├── player.png           ← original file (committed to VCS)
│   └── player.png.import    ← import settings (committed to VCS)
└── .godot/
    └── imported/            ← compiled cache (NOT committed — .gitignore it)
```

### Key Rules

- **Never modify files in `.godot/imported/`** — they are regenerated from originals
- **Commit `.import` files** to version control — they store your settings
- **Reimport** after changing settings: select file → Import dock → click **Reimport**
- `.godot/` should be in your `.gitignore`

### Changing Import Settings

1. Select the file in the **FileSystem** dock
2. Open the **Import** dock (next to Scene dock by default)
3. Change settings
4. Click **Reimport** (or **Reimport All** for batch changes)

> Import settings can also be set via **Advanced Import Settings** for 3D scenes (double-click the `.glb`/`.gltf` file).

---

## 2. Image Import

### Compression Modes

| Mode | Quality | VRAM | File Size | Use For |
|----------------|-----------|----------|-----------|----------------------------------|
| **Lossless** | Perfect | High | Large | Pixel art, UI elements |
| **Lossy** | Good | High | Small | Large photos, backgrounds |
| **VRAM Compressed** | Reduced | Low | Small | 3D textures, large 2D sprites |
| **VRAM Uncompressed** | Perfect | High | Large | When VRAM compression artifacts are unacceptable |
| **Basis Universal** | Reduced | Low | Very small | Cross-platform, multiple GPU formats |

### When to Use Each

```
Pixel art / UI icons       → Lossless (no artifacts, crisp pixels)
2D game sprites            → Lossless (small sprites) or VRAM Compressed (large sprites)
3D textures (albedo, normal) → VRAM Compressed (saves GPU memory)
Large backgrounds          → Lossy or VRAM Compressed
Mobile targets             → VRAM Compressed (essential for memory)
```

### Key Import Settings

| Setting | Description | Default |
|--------------------|-----------------------------------------------|-------------|
| **Compress > Mode** | Compression algorithm (see table above) | VRAM Compressed |
| **Mipmaps > Generate** | Generate mipmaps for distance rendering | Off |
| **Process > Fix Alpha Border** | Prevents dark outlines on transparent sprites | On |
| **Process > Premult Alpha** | Pre-multiply alpha (avoids dark halos) | Off |
| **Flags > Filter** | Bilinear filtering (smooth) vs nearest (crisp) | Linear |
| **Flags > Repeat** | Enable texture tiling | Disabled |

### Pixel Art Setup

For crisp pixel art, set these project-wide:

**Project Settings > Rendering > Textures > Canvas Textures > Default Texture Filter** → `Nearest`

Or per-image in Import dock: **Filter** → `Nearest`

### Enabling Mipmaps

Mipmaps prevent shimmering on textures viewed at an angle or from a distance. Required for 3D textures; optional for 2D.

- **3D textures:** Always enable mipmaps (Import dock → Mipmaps → Generate → On)
- **2D sprites:** Usually off (unless you use Camera2D zoom)
- **UI textures:** Off (rendered at fixed scale)

> **Godot 4.7+:** DDS import supports the R8 and R8G8 texture formats. ([GH-116307](https://github.com/godotengine/godot/pull/116307))

---

## 3. 3D Scene Import

### Supported Formats

| Format | Extension | Recommendation |
|-----------|-------------|----------------------------------------------|
| **glTF** | `.gltf`, `.glb` | **Recommended** — open standard, best support |
| **Blend** | `.blend` | Direct Blender import (requires Blender installed) |
| **FBX** | `.fbx` | Good for legacy pipelines |
| **Collada** | `.dae` | Older format, use glTF if possible |
| **OBJ** | `.obj` | Static meshes only — no animations/rigs |

> **glTF is the recommended format.** It has the best Godot support, is an open standard, and preserves materials, animations, and rigs accurately.

### Node Naming Conventions

Godot auto-creates appropriate node types based on **suffixes** in your 3D model's object names:

| Suffix | Generated Node | Example Name |
|-----------------------|---------------------------|----------------------------|
| `-col` | StaticBody3D + collision | `Wall-col` |
| `-convcol` | ConvexPolygonShape3D | `Rock-convcol` |
| `-rigid` | RigidBody3D | `Barrel-rigid` |
| `-navmesh` | NavigationRegion3D | `Floor-navmesh` |
| `-occluder` | OccluderInstance3D | `BigWall-occluder` |

```
In Blender:                  In Godot (after import):
Wall-col                  →  StaticBody3D
├── Wall (mesh)           →    ├── MeshInstance3D
                          →    └── CollisionShape3D (auto-generated)
```

### Import Dock Settings

Select the imported `.glb`/`.gltf` in FileSystem, then in the Import dock:

| Setting | Description |
|----------------------------|--------------------------------------------------|
| **Root Type** | Override root node type (Node3D, RigidBody3D, etc.) |
| **Root Name** | Custom name for the root node |
| **Meshes > Generate LOD** | Auto-generate LOD levels (on by default) |
| **Meshes > Light Baking** | Static or Dynamic for lightmap baking |
| **Animation > Import** | Enable/disable animation import |
| **Animation > FPS** | Bake animation at this framerate |

> **Godot 4.7+:** The Import dock's import-type option can also import a 3D scene file as a single `Mesh` resource or as a `MeshLibrary` (for GridMap), instead of a full scene — no separate export step in the 3D authoring tool needed. ([GH-107856](https://github.com/godotengine/godot/pull/107856))

> ⚠️ **Changed in Godot 4.7:** `EditorSceneFormatImporter`'s `IMPORT_SCENE`, `IMPORT_ANIMATION`, `IMPORT_FAIL_ON_MISSING_DEPENDENCIES`, `IMPORT_GENERATE_TANGENT_ARRAYS`, `IMPORT_USE_NAMED_SKIN_BINDS`, `IMPORT_DISCARD_MESHES_AND_MATERIALS`, and `IMPORT_FORCE_DISABLE_MESH_COMPRESSION` constants moved into a new `ImportFlags` enum (bitfield). GDScript-compatible; C# importer plugins referencing the old class-level constants must switch to the enum members. See the [4.7 migration guide](https://docs.godotengine.org/en/latest/tutorials/migrating/upgrading_to_godot_4.7.html).

### Runtime Scene Loading

Use `preload()` for paths known at compile time and `load()` for data-driven paths. GDScript + C# snippets: [references/runtime-resource-loading.md](references/runtime-resource-loading.md).

### Runtime glTF Import Flags (Godot 4.7+)

`GLTFDocument` exposes an `ImportFlags` bitfield — `IMPORT_FLAG_GENERATE_TANGENT_ARRAYS` (8), `IMPORT_FLAG_USE_NAMED_SKIN_BINDS` (16), `IMPORT_FLAG_DISCARD_MESHES_AND_MATERIALS` (32), `IMPORT_FLAG_FORCE_DISABLE_MESH_COMPRESSION` (64) — accepted by the `flags: int = 0` parameter of `append_from_file()`, `append_from_buffer()`, and `append_from_scene()`:

```gdscript
var doc := GLTFDocument.new()
var state := GLTFState.new()
doc.append_from_file("user://mods/enemy.glb", state,
        GLTFDocument.IMPORT_FLAG_GENERATE_TANGENT_ARRAYS | GLTFDocument.IMPORT_FLAG_USE_NAMED_SKIN_BINDS)
add_child(doc.generate_scene(state))
```

```csharp
var doc = new GltfDocument();
var state = new GltfState();
doc.AppendFromFile("user://mods/enemy.glb", state,
    (uint)(GltfDocument.ImportFlags.GenerateTangentArrays | GltfDocument.ImportFlags.UseNamedSkinBinds));
AddChild(doc.GenerateScene(state));
```

---

## 4. Animation Import

### Splitting Animations

If a 3D file contains a single timeline with multiple animations, split them in the **Advanced Import Settings**:

1. Double-click the `.glb` file to open Advanced Import Settings
2. Go to **Animations** tab
3. Add animation clips with **start frame** and **end frame**
4. Set **loop mode** per clip (None, Linear, Ping-Pong)

### Retargeting Animations

Share animations between characters with different skeletons:

1. Import both the source (animation) and target (character) models
2. Open **Advanced Import Settings** on the target model
3. Go to **Skeleton3D > Retarget** settings
4. Map source bones to target bones
5. Use `SkeletonProfile` resources for standard humanoid mappings

### Animation Import Settings

| Setting | Description |
|-----------------------|------------------------------------------|
| **Import** | Enable/disable animation import |
| **FPS** | Bake framerate (30 is standard) |
| **Trimming** | Remove empty frames at start/end |
| **Remove Immutable Tracks** | Remove tracks that don't change |

---

## 5. Audio Import

> For in-depth audio playback, bus setup, and music management, see the **audio-system** skill.

### Format Recommendations

| Format | Import As | Use For | Key Settings |
|--------|-----------------|---------------------------|-------------------------|
| WAV | AudioStreamWAV | Short SFX | Loop Mode, Mix Rate |
| OGG | AudioStreamOggVorbis | Music, long SFX | Loop, Loop Offset |
| MP3 | AudioStreamMP3 | Music (fallback) | Loop, BPM |

### Key Import Settings

| Setting | Description | When to Use |
|---------------|------------------------------------------------|-------------------------|
| **Loop** | Enable looping playback | Music, ambient loops |
| **Loop Offset** | Start position for loop restart | Avoid intro on loop |
| **Force Mono** | Convert stereo to mono | 3D positional audio |
| **BPM** | Beats per minute | Rhythm games |
| **Beat Count** | Total beats in the track | Rhythm sync |

> **Import tip:** Use WAV for short SFX (zero decode latency). Use OGG for music (small file, good quality). Enable **Force Mono** for any audio used with AudioStreamPlayer3D — stereo doesn't spatialize properly.

---

## 6. Resource Formats

### .tres vs .res

| Format | Type | Readable | Use For |
|--------|------------|----------|--------------------------------------|
| `.tres` | Text | Yes | Resources you edit by hand or diff |
| `.res` | Binary | No | Large resources, faster loading |

```gdscript
# Save as text resource
ResourceSaver.save(my_resource, "res://data/item.tres")

# Save as binary resource
ResourceSaver.save(my_resource, "res://data/item.res")

# Load (either format)
var resource: Resource = load("res://data/item.tres")
```

```csharp
ResourceSaver.Save(myResource, "res://data/item.tres");
ResourceSaver.Save(myResource, "res://data/item.res");
var resource = GD.Load<Resource>("res://data/item.tres");
```

### When to Use Each

- **`.tres`** — Custom resources you create and edit (item data, config, skill definitions). Version control friendly.
- **`.res`** — Generated or large binary data (baked lightmaps, navigation meshes, large meshes). Faster to load.
- **`.tscn`** — Text scene files (always use text for scenes — diffable in VCS)
- **`.scn`** — Binary scene files (rare — only for very large scenes where load time matters)

### Threaded Resource Loading

Load large resources without freezing the game with the `ResourceLoader.load_threaded_request()` / `load_threaded_get_status()` / `load_threaded_get()` pattern. Full loading-screen recipe (GDScript + C#): [references/runtime-resource-loading.md](references/runtime-resource-loading.md).

---

## 7. Common Pitfalls

| Symptom | Cause | Fix |
|---------------------------------------|----------------------------------------------|--------------------------------------------------------------------|
| Texture looks blurry | Filter is set to Linear for pixel art | Set Default Texture Filter to Nearest in Project Settings |
| Dark outlines on transparent sprites | Alpha border not fixed on import | Enable "Fix Alpha Border" in Import dock |
| 3D model has no collisions | No naming suffix in source model | Add `-col` suffix to mesh names in Blender, or add manually |
| Imported animations missing | "Import Animation" disabled in Import dock | Enable Animation > Import and reimport |
| Texture VRAM too high on mobile | Using Lossless compression for large textures | Switch to VRAM Compressed for textures > 256px |
| 3D textures shimmer at distance | Mipmaps not generated | Enable Mipmaps > Generate in Import dock |
| Audio has pop/click at loop point | Loop offset not set correctly | Adjust Loop Offset in Import dock; add fade in audio editor |
| Scene file is enormous | Using binary `.scn` instead of `.tscn` | Save scenes as `.tscn` (text) for VCS; use `.scn` only if needed |
| Import settings lost after reclone | `.import` files not committed to VCS | Always commit `.import` files; only `.godot/` goes in .gitignore |
| Threaded load freezes game | Checking status every frame with `load()` | Use `ResourceLoader.load_threaded_request/get_status` pattern |

> ⚠️ **Changed in Godot 4.7:** The font import `hinting` default changed from `1` (Light) to `3` (Light (Except Pixel Fonts)) — pixel-style fonts now auto-disable hinting on import, so their rendering can change after upgrading. Set `hinting` back to `1` (Light) in the Import dock per font to keep the 4.6 look. See the [4.7 migration guide](https://docs.godotengine.org/en/latest/tutorials/migrating/upgrading_to_godot_4.7.html).

---

## 8. Implementation Checklist

- [ ] `.gitignore` excludes `.godot/` but NOT `.import` files
- [ ] Pixel art projects set Default Texture Filter to `Nearest` in Project Settings
- [ ] 3D textures have mipmaps enabled (Import dock → Mipmaps → Generate)
- [ ] Large textures use VRAM Compressed (especially on mobile targets)
- [ ] 3D models use glTF format (`.glb` or `.gltf`) as the primary import format
- [ ] Collision shapes use naming suffixes (`-col`, `-convcol`) in the 3D authoring tool
- [ ] Animations are split into individual clips in Advanced Import Settings
- [ ] Audio SFX uses WAV; music uses OGG Vorbis
- [ ] 3D positional audio files are imported as mono (Force Mono enabled)
- [ ] Custom data resources use `.tres` (text) for version control diffability
- [ ] Large or runtime-loaded resources use `ResourceLoader.load_threaded_request()`
- [ ] Scene files use `.tscn` (text format) for version control
