Converting a Godot Project
2dog convert turns an existing Godot project into a 2dog project – in place. Your project directory becomes the solution root, and the 2dog host projects (desktop, web, tests) are scaffolded as nested subfolders that the Godot editor ignores. Nothing is ever moved, renamed, or deleted.
The command ships as the 2dog.cli dotnet tool (a separate package from the 2dog library – see the FAQ for why). It embeds the same template content as dotnet new 2dog, so a converted project and a fresh one have identical layouts.
Usage
One-shot, no install (.NET 10+ SDK):
dnx 2dog.cli convert path/to/your/godot/projectOr install the 2dog command globally:
dotnet tool install -g 2dog.cli
2dog convert path/to/your/godot/projectThe path defaults to the current directory and must contain a project.godot. Use --dry-run first to see the planned actions without changing anything.
From stock Godot to the browser
Convert-then-publish is the fastest route to a browser (WebAssembly) release of an existing Godot project:
dnx 2dog.cli convert path/to/MyGame
cd path/to/MyGame
dotnet publish MyGame.web -c Release # static site in MyGame.web/AppBundle/One-time prerequisite: dotnet workload install wasm-tools. See Web / Browser for the full story.
Options
| Option | Effect |
|---|---|
--name <BaseName> | Override the derived project base name |
--no-web | Skip the browser (WebAssembly) host project |
--no-tests | Skip the xUnit test project |
--dry-run | Print planned actions without changing anything |
--force | Overwrite scaffolded files that already exist (never deletes/moves) |
--no-restore | Skip the final dotnet restore |
--verbose | Extra output |
Resulting layout
MyGame/ <- your existing Godot project (unchanged)
project.godot
MyGame.csproj <- created or minimally patched
MyGame.sln <- created, or your existing sln is reused
TwoDogWebBoot.cs <- added (web bootstrap, guarded by LIBGODOT_ENABLED)
export_presets.cfg <- created, or a 'Web' export preset is appended
global.json <- added (pins a wasm-capable SDK; skipped if you have one)
MyGame.2dog/ (.gdignore) <- desktop host (your Main entry point)
MyGame.web/ (.gdignore) <- browser (WebAssembly) host
MyGame.tests/ (.gdignore) <- xUnit test projectAfterwards:
dotnet run --project MyGame.2dog # desktop host
dotnet test MyGame.tests # xUnit tests (headless Godot)
dotnet publish MyGame.web -c Release # browser bundle (needs wasm-tools)The root global.json pins a .NET 10 SDK with the wasm-tools workload, which is what lets the web host publish from the project root (global.json applies at or below its own directory). If your project already has a global.json, convert leaves it untouched – make sure it pins a wasm-capable SDK, or publish from inside MyGame.web/, whose own global.json wins there.
What it does
- Creates or minimally patches the Godot csproj:
EnableDynamicLoading,AllowUnsafeBlocks, theLIBGODOT_ENABLEDdefine, andDefaultItemExcludesfor the nested host folders. An existing csproj gets a single marked<PropertyGroup>appended containing only the properties it was missing – your file is otherwise left as-is. - Adds
TwoDogWebBoot.csto the Godot project (even with--no-web: it is#if LIBGODOT_ENABLED-guarded and inert until a web host uses it, so adding web later just works). - Adds a root
global.json(unless--no-web) pinning a .NET 10 SDK with the wasm-tools workload, so the web host publishes from the project root. An existingglobal.jsonis never touched, not even with--force– it is your SDK policy, and a warning explains what it needs to pin. - Ensures a
Webexport preset exists: the web host's publish exports your project as a.pckvia that preset, and the engine refuses to export without anexport_presets.cfg. A missing file is created from the template; an existing file gets theWebpreset appended under the next free preset index – your presets are never touched. - Scaffolds the nested host projects, each with a
.gdignorefile so the Godot editor, importer, and exporter skip them. - Reuses your solution: an existing
.sln/.slnxat the project root is used as-is (projects are added to it); with none,<Name>.slnis created. The web host gets ActiveCfg-only entries (no.Build.0), so "Build Solution" works without the wasm-tools workload – the web host is built explicitly viadotnet publish. - Runs
dotnet restoreat the end (skip with--no-restore). A wasm-related restore failure is only a warning, with a pointer todotnet workload install wasm-tools.
Re-running 2dog convert on an already-converted project is a no-op ("Nothing to do"). Files that already exist are skipped and reported; pass --force to overwrite the scaffolded files with fresh template content.
What it never does
- Move, rename, or delete any file.
- Touch version control – no
.gitignoreedits, no staging, no commits. Review the diff yourself and commit when happy. - Add a second solution: if multiple solutions at the project root contain the Godot project, the tool errors instead of guessing – the same rule the Godot editor enforces.
Base name derivation
The base name names the Godot csproj, the solution, and the host folders (<Name>.2dog etc.). It is derived in priority order:
[dotnet] project/assembly_nameinproject.godot(authoritative: the Godot editor resolvesres://<assembly_name>.csprojfrom it),- the name of the sole
.csprojat the project root, application/config/name, sanitized to a valid file/assembly stem,- the project folder name.
--name overrides the derivation, but must not conflict with an existing assembly_name in project.godot – the csproj has to stay named after the assembly, or the Godot editor won't find it.
GDScript-only projects
Projects without any csproj work too: 2dog convert creates a Godot.NET.Sdk csproj and appends a [dotnet] section with project/assembly_name to project.godot, so the Godot editor picks the project up as a C# project. Your GDScript scenes and scripts keep running unchanged – the conversion just adds the .NET entry points (and the option to mix in C#) around them.
Requirements
- .NET 10 SDK (also what
dnxneeds for one-shot execution). - The wasm-tools workload only for publishing the web host (
dotnet workload install wasm-tools) – everything else builds without it.