Files
documentation/docs/LIBRARY_MANAGEMENT.md

7.7 KiB

Godot C# Library Management with Git Submodules

Overview

Manage reusable C# libraries across multiple Godot projects using Git submodules. Each library is a separate repository that game projects include as submodules.

Directory Structure

~/GameDev/
├── Godot/                     # Engine installation
├── libraries/                 # Local library development
│   ├── utilities/
│   ├── audio-manager/
│   └── ui-framework/
└── projects/                  # Game projects
    ├── test-game/
    │   └── Libraries/         # Git submodules
    │       ├── utilities/
    │       └── audio-manager/
    └── puzzle-game/
        └── Libraries/
            └── utilities/

Git Organization:

  • library/ org - Reusable libraries
  • project/ org - Game projects

Prerequisites

  • Godot v4.5.1+ (C# support)
  • .NET 8.0+
  • Git with Gitea access
  • Gitea organizations: library and project

Create a Library

1. Initialize Repository

cd ~/GameDev/libraries
git init utilities
cd utilities
mkdir -p Scripts

2. Configure Library

project.godot:

[application]
config/name="Utilities Library"
config/features=PackedStringArray("4.3", "C#", "Forward Plus")

[dotnet]
project/assembly_name="EinSoftworks.Utilities"

Utilities.csproj:

<Project Sdk="Godot.NET.Sdk/4.3.0">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <EnableDynamicLoading>true</EnableDynamicLoading>
    <RootNamespace>EinSoftworks.Utilities</RootNamespace>
    <AssemblyName>EinSoftworks.Utilities</AssemblyName>
  </PropertyGroup>
</Project>

3. Add Code

Scripts/MathUtils.cs:

using Godot;

namespace EinSoftworks.Utilities
{
    public static class MathUtils
    {
        public static float Clamp01(float value) => Mathf.Clamp(value, 0f, 1f);
        
        public static bool Approximately(float a, float b, float threshold = 0.001f) 
            => Mathf.Abs(a - b) < threshold;
        
        public static float DegreesToRadians(float degrees) => degrees * Mathf.Pi / 180f;
        
        public static float RadiansToDegrees(float radians) => radians * 180f / Mathf.Pi;
    }
}

4. Create .gitignore

.godot/
.import/
.mono/
bin/
obj/
*.tmp
export_presets.cfg

5. Commit and Push

git add .
git commit -m "Initial utilities library"
git remote add origin https://git.ein-softworks.com/library/utilities.git
git branch -M main
git push -u origin main

Create a Game Project

1. Initialize Project

cd ~/GameDev/projects
git init test-game
cd test-game
mkdir -p Scripts Scenes Libraries

2. Configure Project

project.godot:

[application]
config/name="Test Game"
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
run/main_scene="res://Scenes/Main.tscn"

[dotnet]
project/assembly_name="TestGame"

TestGame.csproj:

<Project Sdk="Godot.NET.Sdk/4.3.0">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <EnableDynamicLoading>true</EnableDynamicLoading>
    <RootNamespace>TestGame</RootNamespace>
  </PropertyGroup>
  
  <ItemGroup>
    <ProjectReference Include="Libraries/utilities/Utilities.csproj" />
  </ItemGroup>
</Project>

3. Add Library as Submodule

git submodule add https://git.ein-softworks.com/library/utilities.git Libraries/utilities
git submodule update --init --recursive

4. Use Library in Code

Scripts/Main.cs:

using Godot;
using EinSoftworks.Utilities;

namespace TestGame
{
    public partial class Main : Node2D
    {
        public override void _Ready()
        {
            float radians = MathUtils.DegreesToRadians(90f);
            GD.Print($"90° = {radians} rad");
        }
    }
}

5. Create Scene and Commit

Create Scenes/Main.tscn in Godot, then:

cp ../utilities/.gitignore .
git add .
git commit -m "Initial test game with utilities library"
git remote add origin https://git.ein-softworks.com/project/test-game.git
git branch -M main
git push -u origin main

Common Operations

Update Library to Latest

cd ~/GameDev/projects/test-game
git submodule update --remote Libraries/utilities
git add .
git commit -m "Update utilities library"
git push

In Godot: Project → Reload Current Project, then rebuild.

Update to Specific Version

cd ~/GameDev/projects/test-game/Libraries/utilities
git checkout v1.2.0
cd ../..
git add Libraries/utilities
git commit -m "Update utilities to v1.2.0"
git push

Add Another Library

cd ~/GameDev/projects/test-game
git submodule add https://git.ein-softworks.com/library/audio-manager.git Libraries/audio-manager

Update TestGame.csproj:

<ItemGroup>
  <ProjectReference Include="Libraries/utilities/Utilities.csproj" />
  <ProjectReference Include="Libraries/audio-manager/AudioManager.csproj" />
</ItemGroup>
git add .
git commit -m "Add audio-manager library"
git push

Create New Project with Existing Libraries

cd ~/GameDev/projects
git init puzzle-game
cd puzzle-game
mkdir -p Scripts Scenes Libraries

# Add libraries
git submodule add https://git.ein-softworks.com/library/utilities.git Libraries/utilities
git submodule add https://git.ein-softworks.com/library/audio-manager.git Libraries/audio-manager
git submodule update --init --recursive

# Create project.godot and .csproj with references
# (see example structure above)

git add .
git commit -m "Initial puzzle game setup"
git remote add origin https://git.ein-softworks.com/project/puzzle-game.git
git push -u origin main

Clone Project on New Machine

git clone --recursive https://git.ein-softworks.com/project/test-game.git

# Or if already cloned
cd test-game
git submodule update --init --recursive

Library Dependencies

If one library depends on another, reference it in the .csproj:

Libraries/ui-framework/UIFramework.csproj:

<ItemGroup>
  <ProjectReference Include="../utilities/Utilities.csproj" />
</ItemGroup>

Version Control

Create Library Release

cd ~/GameDev/libraries/utilities
git tag -a v1.0.0 -m "Release v1.0.0 - Initial stable release"
git push origin v1.0.0

Development Workflow

# Library development
cd ~/GameDev/libraries/utilities
git checkout -b feature/new-utils
# Make changes
git add .
git commit -m "Add new utility functions"
git push origin feature/new-utils
# Merge in Gitea, then pull main
git checkout main
git pull origin main

# Update in project
cd ~/GameDev/projects/test-game
git submodule update --remote Libraries/utilities
git add .
git commit -m "Update utilities to latest"
git push

Best Practices

Library Design:

  • Keep libraries focused and single-purpose
  • Use namespace pattern: CompanyName.LibraryName
  • Document public APIs with XML comments
  • Use semantic versioning (major.minor.patch)

Project Organization:

  • Use kebab-case for repos, PascalCase for namespaces
  • Only include needed libraries
  • Test after library updates

Git Workflow:

  • Use feature branches for development
  • Write clear commit messages
  • Push changes regularly
  • Tag important releases

Troubleshooting

Submodule empty:

git submodule update --init --recursive

Build errors:

  • Godot → Project → Reload Current Project
  • Project → Tools → C# → Create C# solution
  • Rebuild

Missing references: Check .csproj has all <ProjectReference> entries.

Submodule update conflicts:

cd Libraries/utilities
git stash
git pull origin main
git stash pop

IntelliSense not working:

  • Reload Godot project
  • Rebuild solution
  • Restart VS Code with project folder open