Troubleshooting

Verified failure modes and fixes — invisible NPCs, untextured terrain, Play Local errors, crashes on project open, and scripts that never compile.

16 min read

How to use this page#

Each entry below is a problem that has actually been hit in a Vastopia project, with the cause as it was diagnosed and the fix that resolved it. Entries are grouped by where you notice the symptom. When a fix says "update", it means installing the current editor or client build — several of these were engine bugs that are already fixed, and the only remaining step is to stop running the old version.

If your problem is not here, start with the logs in the next section; almost every diagnosis below began with one line in a log file.

Where the logs are#

WhatWhere to look
Editor log (Windows)%APPDATA%\Godot\app_userdata\Vastopia Editor\logs\
Game client log (Windows)%APPDATA%\Godot\app_userdata\Vastopia\logs\godot.log
Dev Test client consoleDev Test launches the client inside a console window that stays open after the client exits, and writes the same output to %TEMP%\vastopia_client_<stamp>.log
Play Local client consoleOff by default. Set the environment variable VASTOPIA_CLIENT_CONSOLE=1 before starting the editor to get the same console window and log file as Dev Test
Server script compile resultsDev Test validates your C# scripts before launching and opens the script error console when it finds errors; clicking an error opens the file at that line in the Script Editor. At runtime the server logs Compilation errors for any file it could not compile and then skips that file
Editor crash (Windows)Windows Event Viewer, Application log, Event ID 1000 — gives the faulting module and offset

Editor startup and projects#

The installed editor crashes every time a project opens#

Symptom: Editor release 1.0.16 crashes with an access violation (exit code 5 / 0xC0000005) as soon as any project opens into the Map Editor.

Cause: That release shipped a stale duplicate copy of the Terrain3D addon inside its content pack, and the map editor loaded scripts from the wrong copy.

Fix: Update to editor 1.0.17 or later. Nothing in your project is affected.

A brand-new project crashes on first open, then works on the second open#

Symptom: In editor versions before 1.0.18, a freshly created project crashed the installed editor the first time it was opened; reopening it worked. The editor log shows a storm of Cannot open file 'res://.godot/imported/...' lines.

Cause: Godot .import sidecar files next to models and textures inside the project. A game project is not a Godot project, so any .import file inside one is junk, but an old installer had left them in the bundled template and every new project copied them in. In the shipped editor those sidecars redirect every load to a folder that only exists in a development environment.

Fix: Update to 1.0.18 or later. The editor now deletes .import files when it creates a project and every time it opens one, so existing projects heal themselves on the next open. If you cannot update yet, delete every *.import file under the project folder by hand.

"Failed to create project" in the installed editor only#

Symptom: New Project fails in the installed editor but works when the editor is run from source.

Cause: An early build read its new-project template from inside its own content pack, where data files do not exist in an exported build.

Fix: Update the editor. The template now ships as loose files next to the executable.

No "Update available" card, even though a newer editor exists#

Symptom: The editor never offers an update.

Cause: The updater only shows the card when the platform's version endpoint returns an editor installer URL (a path under /editor/ ending in .exe). If the platform API is lagging a release, it can return the wrong artifact and the card stays hidden.

Fix: Download the current installer again from the dashboard and run it over your existing install. Your projects live outside the editor folder and are untouched.

Dev Test and Dev Client buttons are missing#

Symptom: The top bar shows Play Local and Play Live but no Dev Test or Dev Client.

Cause: This is by design. Dev Test and Dev Client drive source checkouts of the client and server, which a shipped editor install does not have, so the packed editor hides them. They appear only when the editor itself runs from the Godot editor.

Fix: Use Play Local to test, and Play Live once the game is launched. Developers who clone the client and server repositories run the editor from source and set their checkout paths in Settings.

The asset browser "pops out" but stays inside the editor window#

Symptom: Assets ▸ Asset Browser in New Window opens the browser as a floating panel embedded in the main window instead of a separate OS window, and the editor tells you why.

Cause: Godot can only switch to native windows while no other window — including a tooltip or an open dialog — is visible. If the switch is refused, the pop-out still opens, just embedded.

Fix: Close any open dialog, move the mouse off any control showing a tooltip, and try again. While a pop-out is open, other editor dialogs also become native OS windows; that is expected.

Maps and terrain#

The terrain shows a checker grid instead of my painted textures after saving or switching tabs#

Symptom: After a save or a map-tab switch the terrain in the viewport renders the default grid; the texture count in the log drops to 0.

Cause: The Terrain3D node can drop its in-memory textures when its node tree is disturbed. The file on disk is written before that happens, so the saved map is fine.

Fix: The editor snapshots and restores the textures around saves and tab switches, so this should be rare. If it does happen, reload the map; nothing is lost.

The map is textured in the editor but untextured, black, or showing the wrong texture in the game#

Symptom: In Dev Test or Play Local the floor has no texture, a single-texture map renders black, or the client shows texture slot 1 where the editor shows slot 0. The client log contains Terrain3D: free_editor_textures requires 'Assets' be saved to a file.

Cause: Two client bugs. Terrain3D freed embedded textures when the terrain entered the scene, and the client forced the auto-shader on, which ignores the painted control map and picks textures by slope.

Fix: Update the client (Play Local downloads the current one automatically). Then save the map once in the editor — saving externalizes any terrain textures that were still embedded in the map scene, which is the other half of the fix.

Content placed near the edge of the map is not on the terrain#

Symptom: An NPC or object placed around tile 60 or beyond sits in empty space, or the server ignores it.

Cause: Maps are centered on the origin: the default playable area is tiles -64..63 on both axes, and only active region cells exist to the server. See Coordinate system.

Fix: Lay content out around tile (0, 0) — negative tiles are normal — or activate the neighbouring region cell with the Add Region terrain tool before placing there.

An object I authored by hand appears twice as far from the origin as intended#

Symptom: An interactive object written directly into regions.json or a spawn file lands in the wrong place.

Cause: position_2d and the server spawn x/z are world units (tile times 0.5), not tile indices. Writing tile numbers doubles the distance. An early MCP build had exactly this bug; it has been fixed.

Fix: Multiply tile coordinates by 0.5 before writing them. The MCP place_object_on_map tool does this for you.

A trigger zone never fires#

Symptom: A trigger zone placed in Regions mode does nothing in the game.

Cause: Trigger zones are stored in the map's regions.json but have no server export — when a map is saved the editor writes NPC spawns, object spawns and location bounds to server/data/maps/, and nothing else.

Fix: Use a Location instead. Locations are exported, the server raises enter and leave events when a player crosses their bounds, and a location can carry a script_path.

NPCs, objects and models#

An NPC is invisible in the game but fine in the editor#

Symptom: The NPC spawns (you can see its name in the client log as a spawn) but no model appears. The client log shows Failed to parse NPC or Failed to load NPC model for that NPC id.

Cause: The client's NPC data contract is strict, and a row that fails it is skipped silently, leaving the NPC with no definition. Two things break it:

  • options in the client npcs.json must be an array of plain string labels. An object such as {label, dialogue_id} throws a parse error and the whole row is dropped. The server copy uses objects; the client copy must not.
  • model_path and extracted_mesh_path must be project-relative res://assets/... paths. A machine-absolute path (typically the cached copy behind a cloud reference asset) cannot be loaded by the client.

Fix: Open the NPC in the Data Editor and save it again. The NPC editor now sanitizes both fields on save, which repairs old rows. If you authored the NPC with the MCP tools, update the MCP server; an older update_npc wrote object-form options into the client file. Then rebuild with Play Local.

An NPC's mesh is deformed or garbled in the game but perfect in the editor#

Symptom: Limbs stretch or twist in the client while the editor preview animates correctly.

Cause: The editor plays animations on the model's own skeleton, but the client grafts the mesh onto the shared animation-base skeleton. Packed .scn models carried index-only skin binds with no bone names, and when the base skeleton's bone order differed from the mesh's, every vertex group drove the wrong bone.

Fix: Update the client, which now recovers bind names before remapping. Re-import or re-save the model in the editor as well, so the packed .scn carries named binds. One known content quirk remains: a mesh whose rest pose differs from the shared base skeleton (a head bone offset by a few centimetres, for example) renders with that offset; re-extracting a base skeleton from that character's own animation file is the fix.

An NPC will not attack#

Symptom: An NPC with combat stats stands still when players attack it.

Cause: NPCs cannot attack without a fight bound to them. Combat stats alone do nothing.

Fix: Author a fight for the NPC in the Tools tab's Combat Scripts tool (or with the MCP define_boss tool, which is used for any attacking NPC, not only bosses). If you script damage yourself, route it through the combat pipeline; setting an NPC's health directly is invisible to clients because hit-splats and health bars only come from the combat system.

A multi-tile NPC straddles half tiles#

Symptom: A large NPC sits between tiles, and collision or melee range behaves oddly around it.

Cause: Its spawn position was not a multiple of 0.5. Footprints are anchored on tile centers, so a fractional anchor breaks tile alignment.

Fix: The server now snaps NPC positions to the tile grid when it creates them, and the MCP placement tools snap too. For hand-written spawn files, use positions that are multiples of 0.5.

A deleted model is still on disk#

Symptom: After deleting a model from the asset library, its folder under assets/models/ is still there.

Cause: Older editor versions deleted only the single model file and left the assets/models/<ULID>_<Name>/ folder and its siblings behind.

Fix: Delete the folder by hand. Current versions remove the whole folder.

A model is packed twice, or a publish is much larger than expected#

Symptom: The same model appears twice in the build, or the pack is far bigger than the project folder suggests.

Cause: Importing a .glb/.gltf converts it to a self-contained .scn and deletes the source. If the source is left in place (for example copied back by hand), the exporter converts it again to the same .scn name and packs the model twice.

Fix: Remove the leftover .glb/.gltf from the model's folder, keeping the .scn.

A model's .scn is huge#

Symptom: A small .gltf became a .scn of tens of megabytes.

Cause: Texture resolution, not geometry. A 4096-pixel texture is 64 MB of raw pixels, and a .scn carries its own pixels. One real four-texture model measured 171 KB as .gltf plus shared textures and 42 MB as a .scn; at a 2048 cap that is about 11 MB, at 1024 about 2.6 MB.

Fix: Lower the editor setting assets/max_model_texture_size (default 2048; 0 turns the cap off) before importing, and run Assets ▸ Optimize Model Textures… to re-cap models already in the project.

"Sync existing" skips some models when backfilling the cloud library#

Symptom: The upload queue's Sync existing reports skipped models.

Cause: Those models were imported before the cloud library existed. Their source .glb was deleted at import and only the .scn remains, which is never uploaded.

Fix: Re-import the original file if you need it in the cloud library.

A linked model folder shows but is empty#

Symptom: A folder you linked on the Models tab is still listed but reports that it does not exist.

Cause: Linked folders are an editor setting, not part of the project, and point at a path on this machine. If the drive is unplugged or the folder moved, the link stays listed but cannot be browsed.

Fix: Reconnect the drive, or relink the folder from its new location. Models you already added to the project are unaffected; they were copied in.

Testing with Play Local#

Play Local pre-flight fails#

Play Local runs pre-flight checks and shows the reasons when it refuses to start:

MessageWhat to do
Not signed in — sign in with your account firstPlay Local deploys a test server on the platform, so it needs your account. Sign in; Continue Offline only allows local editing.
Project has no game_id — link this project to a game in the Publish tabOpen the Publish tab and link the project to one of your games.
Project is missing server/ directory or server/ directory is emptyThe project is damaged or not a Vastopia project. Expect data/, modules/, scripts/ and schemas/ inside server/.
A previous Play Local is still in progress — wait for it to finishSee the next entry.

"Play Local Busy"#

Symptom: The notice A previous Play Local is still running — hang tight. (A stuck run auto-resets after 7 minutes.)

Cause: The previous press is still building, uploading or deploying.

Fix: Wait for it. A watchdog reclaims a run that genuinely hung, but its timeout is 18 minutes, not the seven the notice claims — that number is stale text in the editor.

The client download fails#

Play Local keeps a copy of the standalone game client in the editor's user data folder (user://downloaded_client/) and refreshes it when the platform reports a newer version. If that refresh fails you see one of:

  • Couldn't reach the client download service.
  • Couldn't resolve the client download.
  • Couldn't start the client download.
  • Client download failed (HTTP <code>).
  • Couldn't extract the downloaded client.
  • Client extracted, but the executable wasn't found inside it.

Fix: Check your connection and press Play Local again. If a usable client is already in the cache, a failed update does not block you — the editor logs a warning and launches the client it has.

The client needed .NET installed#

Symptom: On a clean machine, an old client failed to start because the .NET 8 runtime was missing.

Cause: Client versions before 1.6.2 were framework-dependent.

Fix: Current clients bundle their own runtime. Let Play Local download the current version.

New or changed interfaces do not show up in the game#

Symptom: A screen you just authored in the GUI editor (or with define_interface) is missing in a client that is already running.

Cause: The running client only picks up new screens when the game content pack is rebuilt.

Fix: Launch again with Play Local (or Dev Test from source). Each launch rebuilds the pack.

Scripts and the server#

Dev Test will not launch: "script error(s) found — launch gated"#

Symptom: Pressing Dev Test opens the script error console instead of the game.

Cause: Dev Test validates every C# script first and refuses to launch while any has errors, so you do not discover a silent compile failure an hour later.

Fix: Click an entry in the error console to jump to the line in the Script Editor, fix it, and press Dev Test again.

A script or module silently does nothing#

Symptom: No error in the editor, but the command, event handler or module never runs.

Cause: At runtime the server compiles each file with Roslyn and, if compilation fails, logs the error and skips the file. The game keeps running without it. A classic example was a using Core.Game.Entities.Items; line that needed the EzRealm.Server. prefix.

Fix: Read the server boot output and search for Compilation errors or CS followed by four digits. Also remember that each script file compiles on its own: a helper declared in one script is not visible from another, so shared logic belongs in a module, and ModuleLoader.Module<T>() returns null for a module that failed to compile — null-check it. For an IDE with IntelliSense and a real build, see IDE setup.

XML escapes ended up in my script file#

Symptom: A script written through the MCP write_server_script tool contains &lt;, &gt; or &amp;.

Cause: The tool writes the body verbatim; escaped characters are not decoded.

Fix: Write raw C# to the tool, or fix the file with a text replace.

Player progress was lost when the server stopped#

Symptom: Players lost inventory or skills after a server crash or restart.

Cause: Older servers saved a player only on disconnect.

Fix: The current server autosaves every connected player every 60 seconds (staggered), saves on graceful shutdown, and attempts an emergency save on an unhandled crash. For your own persistent values use player.SetVar/GetVar (saved with the character) and ScriptWorld.GetStore("name") for shared world data, rather than in-memory dictionaries.

A dialogue opens and closes instantly#

Symptom: Talking to an NPC flashes a dialogue window that closes immediately; the server log shows an empty startNode=.

Cause: The dialogue had no start_node_id. An older MCP define_dialogue omitted it.

Fix: Update the MCP server, or open the dialogue in the Dialogue editor and re-save it with a start node. The template's dialogue module also falls back to the first node when the field is missing.

Publishing and live games#

My game does not appear on the Discover page#

Symptom: The game is launched but players cannot find it in the launcher.

Cause: Discover only lists games a player can actually join. A game is hidden as offline when its server has not sent a heartbeat for five minutes, or has never been online and is not live. A game that is live but booted less than five minutes ago shows as starting, and one mid-update is kept visible with an updating badge.

Fix: Check the game's server status in the dashboard (see Server controls and logs). If the server is stopped, start it; if it is still booting, wait a few minutes. The launcher refreshes its list every 90 seconds.

Players see "Update in Progress" or "Can't Join Game"#

Symptom: Pressing Play on the game's page shows one of these popups.

Cause: Update in Progress means a deployment is replacing the server right now. Can't Join Game surfaces the launcher's own failure message (for example, the server refused the connection).

Fix: For an update, wait for the deployment to finish. For a join failure, read the message and check the server page in the dashboard.

The game worked locally but a gameplay system is dead on the live server#

Symptom: Something such as player-to-player trading works in Dev Test and does nothing on the hosted server.

Cause: The platform ships pre-compiled fallback copies of several core modules. Older servers let the platform copy win over the game's own module of the same id, so your edited module never ran in production.

Fix: Current servers let a game module override the platform copy (the log says Game module 'X' overrides the pre-compiled platform version). If you turned a server-enforced gameplay system off, make sure it is also recorded in server/data/systems.json — that file is what stops the platform fallback from loading; deleting the game's copy of the module alone is not enough. See Templates and gameplay systems.

Client-side limitations that look like bugs#

These are not faults; they are hard walls of the current client. See Interfaces and HUD overview and Scripting overview.

  • There is no client-side scripting. Every custom behaviour is a server round-trip, so a ticking countdown label costs one packet per second per player.
  • The inventory, equipment and skills tabs are built into the client; a project's own tabs/inventory.tscn and friends are never loaded. The skills panel is still data-driven from your skills_config.json.
  • The player right-click menu, the equipment slots, the absence of nameplates and the lack of a play-sound packet are fixed in the client and cannot be changed from a project.
  • A tab bar holds at most 12 tabs.
Spotted a mistake or something missing?Tell us on Discord