Models

Supported 3D formats, how a model becomes a self-contained .scn, the texture size cap and Optimize Model Textures, thumbnails, and stale path resolution.

8 min read

What a model is in Vastopia#

A model is any 3D file you bring into a project: a character for an NPC, a sword for an item, a barrel for an interactable object, a tree you paint across a map. There is one model library per project. Every model in it has a single home on disk, assets/models/<id>_<name>/, and is referenced from items, NPCs, objects and maps by that ID or path. Changing the file changes it everywhere it is used.

Models reach the library through several doors, and they all end in the same place:

DoorWhat happens
Drop a file onto the Data Editor's create cards or an open Item, NPC or Object create pageThe Import Model pre-import screen runs, then the model is imported and attached to the new definition
Assets ▸ Import 3D Model..., or Import in the Assets tab's All Assets categoryImported directly, converted to .scn in the background
Import or drag-and-drop in the Assets tab's Models category, or the Map Editor's model LibraryAdded as a placeable prop; it becomes a permanent project file the first time it is placed or assigned
A linked external folderBrowsed in place; a model is imported the first time you use it. See Linked folders
The cloud libraryPulled as a reference shared by every project on your machine. See Cloud library

Supported formats#

FormatSupport
.glbNative. Imported as-is.
.gltf (+ .bin and texture files)Native. The referenced buffers and images are copied alongside the file.
.fbx, .obj (+ .mtl)Converted to .glb by Blender at import. Requires Blender to be installed (see below).
.scn, .tscnAlready Godot scenes; the Models category and the Map Editor place them directly.

.dae and .blend files cannot be loaded or previewed; export them as .glb first.

Blender for FBX and OBJ#

FBX and OBJ are converted by running Blender from the command line. The editor looks for Blender in this order:

  1. The VASTOPIA_BLENDER environment variable, if set, must point at the Blender executable. A path that does not exist is an error, not a fallback.
  2. Blender on your PATH.
  3. The usual install locations: C:\Program Files\Blender Foundation\Blender <version>\blender.exe on Windows, /Applications/Blender.app on macOS, /usr/bin/blender, /usr/local/bin/blender, the Snap and Flatpak paths on Linux.

If none is found, importing an .fbx or .obj fails with a message asking you to install Blender or convert to .glb yourself. The same Blender is used when the AI tools import a model.

How a model is stored#

The .scn conversion#

When a .glb or .gltf is imported through the Data Editor or the All Assets import, the editor:

  1. Copies the file (and, for .gltf, its .bin and textures) into assets/models/<id>_<name>/.
  2. Spools a copy of the original for a background upload to your cloud library (the upload happens on a worker, the import does not wait, and the job simply stays queued until you are signed in).
  3. Converts the model on a background thread into a compressed, self-contained .scn in the same folder, with every texture baked in and capped at the project's maximum texture size.
  4. Swaps the library entry to the .scn and deletes the source files from the folder.

The .scn is the shipped asset. The exporter packs it verbatim, the game client loads it directly, and nothing parses glTF at play time. The source must go: if a .gltf were left beside its .scn, the exporter would convert it to the same file name and pack the model twice.

If the conversion fails, or the editor quits before it finishes, the model simply stays as .glb/.gltf. That is the state older projects are in and everything still works: the exporter converts any remaining .glb/.gltf when it packs the game, and the editor keeps a conversion cache at .export_cache/models/ in the project so a model is only converted once. The cache key is a fingerprint of the model and every file it references, so replacing a shared texture on disk correctly invalidates it. The .export_cache/ folder is never packed or included in a template export.

Models that enter through the Models category, the Map Editor's Library or a linked folder are copied as-is rather than converted at import; they are converted at pack time like any other .glb/.gltf.

Temporary and permanent props#

A model added through the Models category or the Map Editor's Library starts as a temporary prop: its file sits in the editor's own data folder, not in the project, and it is not exported. It becomes permanent — moved to assets/models/<id>_<name>/ and registered in AssetLibrary.json — the first time you place it on a map, stamp it in a building, or assign it to an item, NPC or object. The Assets tab preview shows Status: Temporary or Status: Permanent for each prop.

Texture size cap#

Texture resolution, not geometry, decides what a model weighs. A single 4096-pixel map is 64 MB of raw pixels, and one real four-map model measured 171 KB as a .gltf with shared textures but 42 MB baked into its .scn; capped at 2048 that is about 11 MB, at 1024 about 2.6 MB. Nothing in-game is rasterized anywhere near 4K, so the editor downscales on the way in.

  • The cap is an editor setting, assets/max_model_texture_size, default 2048. It applies to every model imported from then on (the longest edge is shrunk to the cap; images are never upscaled).
  • The Import Model pre-import screen lets you pick a tighter cap for one model (512 × 512, 1024 × 1024, 2048 × 2048) and see the result before importing. Automatic means "use the editor setting".
  • When several materials share one texture it is resized once, so the .scn never carries the same pixels twice.

Change the cap and shrink existing textures#

  1. Open the project and choose Assets ▸ Optimize Model Textures... from the top bar.
  2. In Maximum texture size: pick Don't resize, 4096 px, 2048 px, 1024 px or 512 px. The report below updates: how many stored textures are larger than that size, what they use now, and roughly how much resizing frees.
  3. Click Resize Now. The editor resizes those textures, rewrites every model that referenced them, deletes texture files no model references any more, and saves the new cap for future imports. A summary dialog reports what changed.

The Resize Now button is disabled when nothing is larger than the chosen size (the cap is still applied to future imports) or when Don't resize is selected.

Thumbnails and previews#

Every model card in the Assets tab and the Map Editor's Library shows a rendered thumbnail. Thumbnails are rendered once and cached in the editor's user data folder (prop_preview_cache/ for Models cards, thumbnail_cache/ for the All Assets grid), so a project with hundreds of models opens quickly after the first time. Right-click an asset in All Assets and choose Regenerate Thumbnail if a thumbnail is stale.

Selecting a model shows an interactive 3D preview in the right panel (left-drag orbits, right-drag looks, middle-drag pans, wheel zooms) and a New: row with Item, NPC, Object and VFX buttons that open a create page with the model attached.

The Map Editor and the Data Editor render many copies of the same model; each unique model is parsed once per session and instantiated from memory after that, and is re-read automatically if its file changes on disk.

Stale paths keep resolving#

Converting a model to .scn deletes its .glb/.gltf, and a definition created earlier, an older props.bin, or a hand-edited JSON may still name the original file. Both sides cope:

  • In the editor, a model_path that points at a .glb/.gltf which no longer exists resolves to the .scn sibling of the same name (and, for cloud references, to the machine's shared store).
  • At export, model_path and icon_mesh_path in the client npcs.json, objects.json and items.json are rewritten to .scn, and map scenes get the same swap. Map props.bin is not rewritten; the client tries the .scn name itself and falls back.

You do not need to fix paths after a conversion. You do need project-relative paths: a model_path that is an absolute path on your machine cannot be resolved by players' clients, and an NPC with such a path is invisible in game. Entities created in the editor always get relative paths; this only matters if you edit the JSON by hand.

Organize the model library#

The Models category of the Assets tab (and the same Library in the Map Editor) is a folder browser over the whole library:

  • All Models / Recent chips switch between the folder tree and a flat newest-first list (40 models).
  • New Folder creates a folder at the current breadcrumb location; folders are stored in prop_library.json, not on disk, so organizing never moves files.
  • Select models with click, Ctrl-click and Shift-click, then drag onto a folder tile or a breadcrumb entry to move them. Right-click a model for Rename, Move to Root and Delete (or Move N to Root / Delete N Models for a selection).
  • Link Folder adds an external folder to browse in place; see Linked folders.
  • The search box filters by name across every folder, with folder tiles hidden while a search is active.

Deleting a model from the Models category removes its whole folder. Check the preview's Used by and Used by maps lines first; nothing stops you from deleting a model that a map still places.

With AI (MCP)#

import_asset runs the same import as the editor (type detection, model folder, dependency copy, Blender conversion for FBX/OBJ, library registration) and returns the new asset_id. list_assets with type: "MODEL_3D" is how an assistant discovers models to reference as a model_asset_id; browse_cloud_assets and pull_cloud_asset bring cloud models in; place_props scatters a model across a map. See the Tools reference.

Spotted a mistake or something missing?Tell us on Discord