2dog.templates
4.7.2.132
dotnet new install 2dog.templates@4.7.2.132
2dog Templates
This directory contains the dotnet new templates for creating 2dog projects.
Template Overview
The twodog template creates a complete 2dog application. The output
directory is the Godot project (and the solution root); the host projects
are nested inside it, each carrying a .gdignore so the Godot editor,
importer, and exporter skip them:
- Sample Godot project - project.godot, the
Godot.NET.Sdkcsproj, and a simple scene at the root - Desktop host (
<Name>.2dog/) - Minimal working 2dog application (Program.cs with Main) - xUnit test project (
<Name>.xunit/) - xUnit (v3) tests with 2dog.xunit collection fixtures (opt-in:--xunit true) - GdUnit test project (
<Name>.gdunit/) - GDScript suites through embedded Godot and MTP (opt-in:--gdunit true) - NUnit test project (
<Name>.nunit/) - NUnit tests with 2dog.nunit (opt-in:--nunit true) - Web host project (
<Name>.web/) - Browser (WebAssembly) host that publishes the game as a static site (included by default;--web falseto omit) - WebXR host (
<Name>.webxr/) - Browser host whose page ships the WebXR Layers polyfill for VR (opt-in via--webxr true) - MAUI host (
<Name>.maui/) - Embedded Godot view for Windows and Android with MAUI overlays (opt-in via--maui true; requires MAUI workloads) - Blazor host (
<Name>.blazor/) - Blazor Web App: ASP.NET Core server plus a WebAssembly client (Client/) whose page embeds the game through2dog.blazor'sGodotView(opt-in via--blazor true) - Avalonia host (
<Name>.avalonia/) - Cross-platform GUI embedding the game (opt-in via--avalonia true) - Qt Quick host (
<Name>.qt/) - QML window on Qt Bridge for C# showing the game through2dog.qt'sGodotView(opt-in via--qt true; building needs CMake, Ninja and a C++ toolchain, and outside win-x64 a Qt 6 install inQtDir) - Android host (
<Name>.android/) - Experimental APK host (opt-in via--android true; building requires the Android workload, SDK and JDK 17) - WinForms host (
<Name>.winforms/) - Embeds the game window inside a WinForms form with a Pause button (opt-in via--winforms true; Windows-only at runtime) - WinUI 3 host (
<Name>.winui/) - Embeds the game window inside a WinUI 3 (Windows App SDK) window (opt-in via--winui true; Windows-only, builds only on Windows) - .editorconfig - Standard .NET coding conventions
- .gitignore - Ignores for .NET and Godot artifacts
Local Development
Installing the Template Locally
# From the repository root
dotnet pack twodog.templates
# Replace <TwoDogVersion> with the version printed by pack:
dotnet new install packages/2dog.templates.<TwoDogVersion>.nupkg
Packing substitutes the source template's version placeholders. Installing the
raw templates/twodog directory leaves those placeholders unresolved.
Creating Projects
# Default project (app + Godot project + web host)
dotnet new 2dog -n MyGame
# With an xUnit test project
dotnet new 2dog -n MyGame --xunit true
# GDScript tests, double precision and experimental threaded web
dotnet new 2dog -n MyGame --gdunit true --double-precision true --web-threads true
# Without the web host (all hosts require .NET 10; only browser builds need wasm-tools)
dotnet new 2dog -n MyGame --web false
# With the WebXR browser host (omitted by default)
dotnet new 2dog -n MyGame --webxr true
# With the Blazor Web App host (omitted by default)
dotnet new 2dog -n MyGame --blazor true
# With the Windows-only WinForms host (omitted by default)
dotnet new 2dog -n MyGame --winforms true
# With the Qt Quick host (omitted by default; needs CMake, Ninja and a C++ toolchain)
dotnet new 2dog -n MyGame --qt true
Uninstalling the Template
dotnet new uninstall 2dog.templates
Template Structure
templates/
└── twodog/ # Template content = the Godot project root
├── .template.config/
│ └── template.json # Template configuration
├── Company.Product1.slnx # The single solution, next to project.godot
├── Company.Product1.csproj # Godot project (Godot.NET.Sdk)
├── project.godot
├── main.tscn
├── export_presets.cfg # Web preset for the wasm host
├── global.json # Wasm-capable SDK pin (--web false to omit)
├── Company.Product1.2dog/ # Desktop host
│ ├── .gdignore
│ ├── Company.Product1.2dog.csproj
│ ├── Program.cs
│ └── app.manifest
├── Company.Product1.xunit/ # xUnit test project (opt-in: --xunit true)
│ ├── .gdignore
│ ├── Company.Product1.xunit.csproj
│ ├── BasicTests.cs
│ └── xunit.runner.json
├── Company.Product1.web/ # Browser (wasm) host (default; --web false to omit)
│ ├── .gdignore
│ ├── Company.Product1.web.csproj
│ ├── Program.cs
│ ├── global.json # Same SDK pin as the root, for runs started in here
│ └── wwwroot/index.html
├── Company.Product1.webxr/ # WebXR browser host (opt-in; --webxr true to include)
│ ├── .gdignore
│ ├── Company.Product1.webxr.csproj
│ ├── Program.cs
│ ├── global.json
│ └── wwwroot/ # index.html + vendored webxr-layers-polyfill.min.js
├── Company.Product1.blazor/ # Blazor Web App host (opt-in; --blazor true to include)
│ ├── .gdignore
│ ├── Company.Product1.blazor.csproj # ASP.NET Core server
│ ├── Program.cs
│ ├── Components/ # App.razor, Routes.razor, Error page
│ ├── wwwroot/ # app.css, favicon
│ ├── global.json
│ └── Client/ # Blazor WebAssembly client (links Godot, hosts GodotView)
│ ├── Company.Product1.blazor.Client.csproj
│ ├── Program.cs
│ └── Pages/Home.razor
├── Company.Product1.qt/ # Qt Quick host (opt-in; --qt true to include)
│ ├── .gdignore
│ ├── Company.Product1.qt.csproj
│ ├── Program.cs
│ ├── GameControls.cs # overlay state the QML binds to
│ ├── Main.qml # ApplicationWindow with the GodotView and the overlay
│ └── app.manifest
├── Company.Product1.winforms/ # WinForms host (opt-in; --winforms true to include)
│ ├── .gdignore
│ ├── Company.Product1.winforms.csproj
│ ├── Program.cs
│ ├── MainForm.cs
│ └── app.manifest
├── Company.Product1.winui/ # WinUI 3 host (opt-in; --winui true to include)
│ ├── .gdignore
│ ├── Company.Product1.winui.csproj
│ ├── Program.cs
│ ├── App.cs
│ ├── MainWindow.cs
│ └── app.manifest
├── .editorconfig
└── .gitignore
The host csprojs point <GodotProjectDir> at the parent directory (..) and
reference ../Company.Product1.csproj; the Godot csproj excludes the nested
host folders via DefaultItemExcludes. The solution gives the web host
ActiveCfg-only entries (no .Build.0) so "Build Solution" works without the
wasm-tools workload – the web host is built explicitly with dotnet publish.
Template Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
--xunit |
bool | false | Include a test project with xUnit (v3) and 2dog.xunit collection fixtures |
--nunit |
bool | false | Include an NUnit test project with 2dog.nunit |
--web |
bool | true | Include a browser (WebAssembly) host project (building it requires a .NET 10+ SDK with the wasm-tools workload) |
--webxr |
bool | false | Include a browser host preconfigured for WebXR: its page ships the WebXR Layers polyfill (same wasm-tools requirement as --web) |
--blazor |
bool | false | Include a Blazor Web App host (server + WebAssembly client embedding the game; same wasm-tools requirement as --web) |
--skipRestore |
bool | false | Skip automatic NuGet restore after creation |
Symbol Replacements
The template uses Company.Product1 as the source name, which gets replaced with your project name:
Company.Product1→ Your project name in namespace positions (namespace,using,RootNamespace) and in file names.dotnet newgives file contents itssafe_namespaceform (GWJ-97→GWJ_97) and file names the name verbatim; the2dogtool does the same.TPLRAWNAME→ Your project name verbatim: paths and folder names inside files (DefaultItemExcludes, the solution),project.godot,TrimmerRootAssembly, window titles and theEnginelabel. Anything that must match a file or assembly name uses this token, neverCompany.Product1.
Packaging
The template content in twodog/ is the single source of truth and ships two ways:
- Bundled in
2dog.templates(packed fromtwodog.templates/twodog.templates.csproj) asdotnet newtemplate content undercontent/twodog/, sodotnet new install 2dog.templatesregisters the template. - Embedded as resources into the
2dogtool assembly, which scaffolds the same content via2dog newand2dog add. The tool substitutes the rename tokens itself, including the host folder token (Company.Product1.2dogand friends), so hosts can live in freely named folders.
When packing, the version placeholders in template.json are substituted automatically.
Installing from NuGet
dotnet new install 2dog.templates
If you previously installed the template from 2dog, run dotnet new uninstall 2dog
before installing 2dog.templates. This leaves the 2dog tool installed.
Known Limitations
Test Project Requires 2dog.xunit Package
The optional xUnit test project references 2dog.xunit, which needs to be packaged and published separately.
To make it resolve:
- Package
2dog.xunitas a NuGet package (it depends on2dog.engine, which carries the fixtures) - Publish it to NuGet or a local feed
- Ensure it's available when creating projects
Alternatively, for local development:
- Omit
--xunitand--nunitwhen creating the project - Manually add a test project with project references to local 2dog projects
Web Host Requires .NET 10+ and wasm-tools
The web host project (included by default) targets net10.0 with
RuntimeIdentifier=browser-wasm. Building/publishing it requires a .NET 10+
SDK with the wasm-tools workload (dotnet workload install wasm-tools). The
rest of the solution builds fine without it; create with --web false to omit
the project entirely. The opt-in WebXR (--webxr true) and Blazor
(--blazor true) hosts have the same requirements.
Template Configuration
The template is defined in .template.config/template.json:
{
"identity": "outfox.2dog.Template",
"name": "2dog Application",
"shortName": "2dog",
"sourceName": "Company.Product1",
"symbols": {
"tests": {
"type": "parameter",
"datatype": "bool",
"description": "Include a test project",
"defaultValue": "true"
},
"web": {
"type": "parameter",
"datatype": "bool",
"description": "Include a browser (WebAssembly) host project",
"defaultValue": "true"
},
"webxr": {
"type": "parameter",
"datatype": "bool",
"description": "Include a browser host preconfigured for WebXR",
"defaultValue": "false"
}
}
}
(Abridged - see the file for the full symbol list, including winforms,
winui, avalonia, blazor, and the version placeholders.)
Testing Changes
After modifying the template:
Pack and reinstall: run
dotnet pack twodog.templates, then install the resultingpackages/2dog.templates.<TwoDogVersion>.nupkgwithdotnet new install --force.Test project creation:
mkdir test_project cd test_project dotnet new 2dog -n TestApp -o TestApp cd TestApp dotnet build dotnet run --project TestApp.2dog
The template already generates a solution with Debug/Release/Editor configurations. Browser, Android and WinUI hosts are excluded from ordinary solution builds and are built explicitly when needed.
Future Enhancements
Potential improvements for the template:
- Add
--emptyoption for projects without sample Godot content - Add
--minimaloption for absolute bare minimum - Optional CI/CD workflow files (GitHub Actions, etc.)
- Optional Docker support
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.