Template
A template used for quickly setting up new Godot 4 C# games that features ENet multiplayer, visual in-game debugging and more.
Install / Use
/learn @CSharpGodotTools/TemplateREADME
Overview
- Setup
- Templates
- Minimal 2D scene
- Minimal 3D scene
- FPS scene
- Performance
- In-Game debugging
- Utilities
- Multiplayer
- Thank You
Setup
Prerequisites
Install
Download the latest release and open project.godot. Click Run Setup to restart Godot with your template ready to go.
Update
Updates can be done from Dev Tools > Update.
Templates
FPS Scene
<image src="https://github.com/user-attachments/assets/02bd2f01-e5f7-4856-93d8-d12471589c22" />Performance
Centralized Component Scripts
There is a very noticeable gap in performance when we have 10,000 nodes all with their own _Process functions. If we use a centralized component manager that handles all processes we notice a 3.5x increase in performance (This only applies to C# users)
public partial class Player : Node
{
private EntityMovementComponent _movement;
public override void _Ready()
{
_movement = new EntityMovementComponent(this);
}
public override void _Process(double delta)
{
_movement.Process(delta);
}
public override void _ExitTree()
{
_movement.Dispose();
}
}
</details>
But we can do better! Let's extend from Component.
public class EntityMovementComponent(Player player) : Component(player)
{
// Notice these methods do not start with an underscore
protected override void Ready()
{
// Process is disabled by default and we must enable it ourselves
SetProcess(true);
}
protected override void Process(double delta)
{
// Handle process...
}
protected override void ExitTree()
{
// Handle exit tree...
}
}
Now the Player script looks much cleaner.
public partial class Player : Node
{
// Optionally add components to a ComponentList to hide unused warnings
private EntityMovementComponent _movement;
public override void _Ready()
{
_movement = new EntityMovementComponent(this);
}
}
In Game Debugging
Visual Debugging
https://github.com/user-attachments/assets/1fe282b9-f044-42cd-b9be-0e26f20b1aa6
https://github.com/user-attachments/assets/2f44ae8e-0c99-4bd2-b15f-a72a70ffaa74
Example Usage 1
// Works in both 2D and 3D scenes
public partial class Player : CharacterBody3D
{
[Visualize]
private int _x;
public override void _Ready()
{
Visualize.Register(this);
}
[Visualize]
public void IncrementX(int amount)
{
_x += amount;
Visualize.Log(amount);
}
}
Example Usage 2
// Scripts do not have to extend from Node for Visualize to work
public class PlayerMovementComponent
{
[Visualize]
private float _y;
public PlayerMovementComponent(Player player)
{
Visualize.Register(this, player);
}
}
Supported Members
| Member Type | Supported | Example Types |
|-------------------|------------|-----------------------------------------------|
| Numericals | ✅ | int, float, double |
| Enums | ✅ | Direction, Colors |
| Booleans | ✅ | bool |
| Strings | ✅ | string |
| Color | ✅ | Color |
| Vectors | ✅ | Vector2, Vector2I |
| Quaternion | ✅ | Quaternion |
| NodePath | ✅ | NodePath |
| StringName | ✅ | StringName |
| Methods | ✅ | |
| Static Members| ✅ | |
| Arrays | ✅ | int[], string[], Vector2[] |
| Lists | ✅ | List<string[]>, List<Vector2> |
| Dictionaries | ✅ | Dictionary<List<Color[]>, Vector2> |
| Structs | ✅ | struct |
| Classes | ✅ | class |
| Resources | ✅ | Resource |
| Godot Array | ✅ | Godot.Collections.Array<int> |
| Godot Dictionary | ✅ | Godot.Collections.Dictionary<int, bool> |
[!NOTE] No mouse interactions have been implemented in 3D, so you will only be able to use it for read only.
Metrics Overlay
The metrics overlay can be toggled in-game with F1. All monitored variables or profiled code will appear under the 'Variables' section.
Monitor Variables
Track variables in your code.
Game.Metrics.StartMonitoring("My Variable", () => _someVariable);
// Specifiying a name is optional
Game.Metrics.StartMonitoring(() => _someVariable);
Profile Code
Log the running time of your code.
// _Ready
Game.Profiler.Start("Player Init");
PlayerSetup();
Game.Profiler.Stop("Player Init"); // The running time will be printed to the console
// _Process
Game.Profiler.StartProcess("Player Firing Logic");
PlayerFire();
Game.Profiler.StopProcess("Player Firing Logic"); // The running time will be displayed in the Metrics Overlay (F1)
Console Commands
[!NOTE] The in-game console can be brought up with
F12
Registering new commands is easy.
public override void _Ready()
{
Game.Console.RegisterCommand("help", CommandHelp);
Game.Console.RegisterCommand("quit", CommandQuit).WithAliases("exit");
Game.Console.RegisterCommand("debug", CommandDebug);
}
private void CommandHelp(string[] args)
{
IEnumerable<string> cmds = Game.Console.GetCommands().Select(x => x.Name);
Logger.Log(cmds.ToFormattedString());
}
private async void CommandQuit(string[] args)
{
await Global.Instance.ExitGame();
}
private void CommandDebug(string[] args)
{
if (args.Length <= 0)
{
Logger.Log("Specify at least one argument");
return;
}
Logger.Log(args[0]);
}
Utilities
Improved Debugger Dock
This is just like the built-in Godot debugger dock except with more features.
- Fully customizable
- Double click to open any entry in VSCode
- Hide methods from stack trace with
[StackTraceHidden]attribute
Dev Tools Dock
Contains useful utilities to clean stale uids, empty f
