This page documents the resource import system, which converts external source assets (PNG images, OGG audio, GLTF scenes, etc.) into Godot-optimized internal formats. It covers the ResourceFormatImporter and ResourceImporter classes, the .import metadata file format, how the editor triggers imports, and how the runtime load path resolves imported files.
For the generic resource loading pipeline (cache, threading, ResourceFormatLoader), see page 5.1. For resource saving, see 5.5.
Godot separates source assets (the files users place in the project) from imported resources (the engine-optimized files actually loaded at runtime). When a source file like texture.png is added to the project, the editor runs an importer that:
.ctex for textures)..godot/imported/..import metadata file alongside the source file that records the import configuration and the path to the result.At runtime, ResourceLoader::load("res://texture.png") is intercepted by ResourceFormatImporter, which reads texture.png.import and transparently redirects the load to the optimized file in .godot/imported/.
This design lets source assets remain human-readable and VCS-friendly while runtime loading always uses optimized data.
| Class | File | Role |
|---|---|---|
ResourceFormatImporter | core/io/resource_importer.h | Singleton ResourceFormatLoader that bridges source paths to imported paths via .import files |
ResourceImporter | core/io/resource_importer.h | Abstract base for all per-type importers |
ResourceFormatLoader | core/io/resource_loader.h | Base for all format loaders; ResourceFormatImporter extends this |
Class hierarchy diagram:
Sources: core/io/resource_importer.h1-50 core/io/resource_loader.h47-95
ResourceFormatImporter is a singleton registered as a ResourceFormatLoader with ResourceLoader. It is the single point of contact between the generic loading pipeline and the import system.
Internally, ResourceFormatImporter uses a PathAndType struct to hold what it reads from a .import file:
| Field | Purpose |
|---|---|
path | Path to the imported output file (e.g., .godot/imported/...) |
type | Godot resource type string (e.g., "CompressedTexture2D") |
importer | Name of the importer that produced the file |
group_file | Optional group file for grouped imports |
metadata | Arbitrary importer metadata |
uid | Resource UID |
The central method _get_path_and_type opens p_path + ".import" and reads it as a config-format file using VariantParser. It populates the PathAndType struct. If the .import file does not exist, the method returns an error and sets *r_valid = false.
Sources: core/io/resource_importer.cpp44-55
In ResourceLoader::_load, after all registered loaders fail to find a handler, there is an editor-mode check:
// core/io/resource_loader.cpp:302-313
if (ResourceFormatImporter::get_singleton()->get_importer_by_file(p_path).is_valid()) {
// The format is known to the editor, but the file hasn't been imported yet.
found = true;
*r_error = ERR_FILE_NOT_FOUND;
}
This provides a meaningful error message when a source file is present but not yet imported. At runtime (non-editor), ResourceFormatImporter itself is a registered loader and handles loading directly.
Sources: core/io/resource_loader.cpp302-313
ResourceImporter is the abstract base class that specific importers implement. It is a RefCounted (not a ResourceFormatLoader itself).
| Method | Return | Description |
|---|---|---|
get_importer_name() | String | Unique stable identifier (e.g., "texture") |
get_visible_name() | String | Display name in editor UI |
get_recognized_extensions() | List<String> | Source file extensions handled |
get_save_extension() | String | Extension for imported output (e.g., "ctex") |
get_resource_type() | String | Godot type produced (e.g., "CompressedTexture2D") |
get_import_options() | via parameter | Options list with names, types, defaults |
get_preset_count() | int | Number of built-in presets |
get_preset_name() | String | Name of a preset at a given index |
import() | Error | Performs the actual import |
import(
p_source_file, // source asset path
p_save_path, // base path for output (without extension)
p_options, // HashMap of option name → value
r_platform_variants, // out: platform-specific variant suffixes
r_gen_files, // out: additional generated files
r_metadata // out: optional metadata stored in .import
)
Sources: core/io/resource_importer.h41-50
ResourceImporter defines an ImportOrder enum. Standard importers use IMPORT_ORDER_DEFAULT = 0. Scene importers use IMPORT_ORDER_SCENE = 100, ensuring scene files are processed after their dependency assets.
Each imported source file has a companion .import file placed at the same path. For example, res://assets/icon.png has res://assets/icon.png.import.
The file uses Godot's config file format (INI-like with [sections]). Key sections:
The path field may be a single path, or for platform-specific imports, a dictionary of platform → path.
Records source and output files for dependency tracking.
The full set of importer options used when the import was last run. The editor uses this section to detect whether settings have changed and a reimport is needed.
The following diagram shows the editor-side import pipeline triggered when a file is added or changed.
Editor Import Pipeline:
Sources: core/io/resource_importer.cpp40-55 core/io/resource_importer.h41-50
Runtime Load Flow (source asset path → imported resource):
Sources: core/io/resource_importer.cpp44-55 core/io/resource_loader.cpp273-330
Godot ships with importers for common asset types. These are implemented in editor-specific code and registered during editor initialization.
| Importer Name | Extensions | Output Type | Output Extension |
|---|---|---|---|
texture | .png, .jpg, .bmp, .webp, etc. | CompressedTexture2D | .ctex |
texture_3d | same | CompressedTexture3D | .ctex3d |
texture_array | same | CompressedTextureLayered | .ctexarray |
ogg_vorbis | .ogg | AudioStreamOggVorbis | .oggvorbisstr |
mp3 | .mp3 | AudioStreamMP3 | .mp3str |
wav | .wav | AudioStreamWAV | .sample |
scene | .gltf, .glb, .fbx, .dae, .obj | PackedScene | .scn |
font_data_dynamic | .ttf, .otf, .woff, etc. | FontFile | .fontdata |
bitmap_font | .fnt | FontFile | .fontdata |
csv_translation | .csv | Translation | .translation |
Scene imports use EditorSceneFormatImporter as an additional plugin layer, allowing third parties to support additional 3D formats via EditorPlugin::add_scene_format_importer_plugin.
Sources: doc/classes/EditorSceneFormatImporter.xml1-10
ResourceFormatImporter selects an importer for a file by calling get_importer_by_file(path), which iterates all registered ResourceImporter instances and calls get_recognized_extensions() on each. When multiple importers recognize the same extension, the one with the highest priority (lower ImportOrder wins for DEFAULT; explicit priority fields may exist per importer) is chosen.
Importers are sorted by name (SortImporterByName) for deterministic iteration:
core/io/resource_importer.cpp40-42
ResourceFormatLoader has two import-specific virtual methods that ResourceFormatImporter uses:
is_import_valid(path) — Returns whether the .import file's recorded settings and dest files still match what's on disk. Used by EditorFileSystem to decide whether a reimport is needed.get_import_group_file(path) — Returns a "group file" path if the importer batches multiple source files into a single import (e.g., sprite sheet atlases). All files sharing a group file are imported together.core/io/resource_loader.h89-92
A function pointer typedef ResourceFormatImporterLoadOnStartup in resource_importer.h provides a hook for loading resources at engine startup before the full import pipeline is available. This is used internally for bootstrapping resources that must be available very early.
To implement a custom importer (editor-only), extend ResourceImporter and override the required virtual methods. Key steps:
get_importer_name() with a unique string.get_recognized_extensions() to list handled source extensions.get_save_extension() and get_resource_type().get_import_options() to describe configurable parameters.import() to read the source file, process it, and save the output using ResourceSaver::save() to p_save_path + "." + get_save_extension().ResourceFormatImporter::get_singleton()->add_importer(importer) during editor plugin initialization, and unregister it on cleanup.The EditorPlugin base class provides add_import_plugin / remove_import_plugin as the standard registration entry point.
ResourceFormatImporter is registered with ResourceLoader as a standard ResourceFormatLoader, giving it the same integration as any other loader (caching, threaded loading, etc.). The cache key used is the source file path (e.g., res://icon.png), not the imported path in .godot/imported/. This means ResourceLoader::load("res://icon.png") will return a cached CompressedTexture2D on subsequent calls without re-reading the .import file.
For more detail on the cache behavior, see page 5.3. For the broader ResourceLoader pipeline, see 5.1.
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.