added a directory
This commit is contained in:
806
docs/LIBRARY_MANAGEMENT_SYSTEM.md
Normal file
806
docs/LIBRARY_MANAGEMENT_SYSTEM.md
Normal file
@@ -0,0 +1,806 @@
|
||||
# Godot C# Library Management System
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes a comprehensive system for managing reusable C# libraries across multiple Godot game projects using Git submodules. This approach enables clean separation of concerns, version control for individual libraries, and easy code reuse across multiple game projects.
|
||||
|
||||
## System Architecture
|
||||
|
||||
### Core Principles
|
||||
|
||||
1. **Separation of Concerns**: Libraries and game projects exist in separate Git repositories
|
||||
2. **Modular Design**: Each library serves a specific purpose and can be developed independently
|
||||
3. **Version Control**: Libraries can be versioned and updated independently of game projects
|
||||
4. **Code Reuse**: Multiple projects can share the same libraries without code duplication
|
||||
5. **Clean Dependencies**: C# project references ensure proper compilation and IntelliSense support
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
~/GameDev/
|
||||
├── Godot/ # Godot engine installation
|
||||
├── libraries/ # Local development copies of libraries
|
||||
│ ├── utilities/ # Example: utilities library repository
|
||||
│ ├── audio-manager/ # Example: audio management library
|
||||
│ └── ui-framework/ # Example: UI framework library
|
||||
└── projects/ # Game project repositories
|
||||
├── test-game/ # Example: test game project
|
||||
│ └── Libraries/ # Git submodules directory
|
||||
│ ├── utilities/ # Submodule → library/utilities
|
||||
│ └── audio-manager/# Submodule → library/audio-manager
|
||||
└── puzzle-game/ # Example: another game project
|
||||
└── Libraries/ # Git submodules directory
|
||||
└── utilities/ # Submodule → library/utilities
|
||||
```
|
||||
|
||||
### Git Repository Organization
|
||||
|
||||
**Gitea Organizations:**
|
||||
- `library/` - Contains all reusable library repositories
|
||||
- `project/` - Contains all game project repositories
|
||||
|
||||
**Repository Examples:**
|
||||
- `https://git.ein-softworks.com/library/utilities.git`
|
||||
- `https://git.ein-softworks.com/library/audio-manager.git`
|
||||
- `https://git.ein-softworks.com/project/test-game.git`
|
||||
- `https://git.ein-softworks.com/project/puzzle-game.git`
|
||||
|
||||
## How Git Submodules Work
|
||||
|
||||
Git submodules allow you to include one Git repository inside another as a subdirectory. In our case:
|
||||
|
||||
1. **Library repositories** contain reusable C# code and Godot scenes
|
||||
2. **Game project repositories** include libraries as submodules in their `Libraries/` directory
|
||||
3. **Submodules point to specific commits** in the library repositories, ensuring reproducible builds
|
||||
4. **Updates are explicit** - you control when to pull in library changes
|
||||
|
||||
### Benefits of This Approach
|
||||
|
||||
- **Independent Development**: Work on libraries without affecting game projects
|
||||
- **Version Stability**: Games use specific library versions until explicitly updated
|
||||
- **Selective Updates**: Choose which libraries to update in each project
|
||||
- **Clean History**: Each repository maintains its own commit history
|
||||
- **Collaborative Friendly**: Multiple developers can work on different libraries simultaneously
|
||||
|
||||
## Initial Setup Process
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- macOS with Godot v4.5.1 stable installed at `~/GameDev/Godot/`
|
||||
- .NET 8.0.121 installed
|
||||
- Git configured with access to your Gitea instance
|
||||
- Gitea instance with `library` and `project` organizations created
|
||||
|
||||
### Step 1: Create Directory Structure
|
||||
|
||||
```bash
|
||||
cd ~/GameDev
|
||||
mkdir -p libraries projects
|
||||
```
|
||||
|
||||
### Step 2: Create Your First Library
|
||||
|
||||
#### Initialize the Library Repository
|
||||
|
||||
```bash
|
||||
cd ~/GameDev/libraries
|
||||
git init utilities
|
||||
cd utilities
|
||||
mkdir -p Scripts
|
||||
```
|
||||
|
||||
#### Create Library Project Configuration
|
||||
|
||||
Create `project.godot`:
|
||||
```ini
|
||||
; Engine configuration file.
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Utilities Library"
|
||||
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="EinSoftworks.Utilities"
|
||||
```
|
||||
|
||||
Create `Utilities.csproj`:
|
||||
```xml
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>EinSoftworks.Utilities</RootNamespace>
|
||||
<AssemblyName>EinSoftworks.Utilities</AssemblyName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
#### Create Example Library Code
|
||||
|
||||
Create `Scripts/MathUtils.cs`:
|
||||
```csharp
|
||||
using Godot;
|
||||
|
||||
namespace EinSoftworks.Utilities
|
||||
{
|
||||
public static class MathUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Clamps a value between 0 and 1.
|
||||
/// </summary>
|
||||
public static float Clamp01(float value)
|
||||
{
|
||||
return Mathf.Clamp(value, 0f, 1f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a number is approximately equal to another number.
|
||||
/// </summary>
|
||||
public static bool Approximately(float a, float b, float threshold = 0.001f)
|
||||
{
|
||||
return Mathf.Abs(a - b) < threshold;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts degrees to radians.
|
||||
/// </summary>
|
||||
public static float DegreesToRadians(float degrees)
|
||||
{
|
||||
return degrees * Mathf.Pi / 180f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts radians to degrees.
|
||||
/// </summary>
|
||||
public static float RadiansToDegrees(float radians)
|
||||
{
|
||||
return radians * 180f / Mathf.Pi;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Create .gitignore
|
||||
|
||||
```gitignore
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
|
||||
# Godot-specific ignores
|
||||
.import/
|
||||
export.cfg
|
||||
export_presets.cfg
|
||||
|
||||
# Imported translations (automatically generated from CSV files)
|
||||
*.translation
|
||||
|
||||
# Mono-specific ignores
|
||||
.mono/
|
||||
data_*/
|
||||
mono_crash.*.json
|
||||
|
||||
# .NET specific ignores
|
||||
bin/
|
||||
obj/
|
||||
*.tmp
|
||||
```
|
||||
|
||||
#### Commit and Push Library
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Initial utilities library setup with MathUtils"
|
||||
git remote add origin https://git.ein-softworks.com/library/utilities.git
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### Step 3: Create Your First Game Project
|
||||
|
||||
#### Initialize the Game Repository
|
||||
|
||||
```bash
|
||||
cd ~/GameDev/projects
|
||||
git init test-game
|
||||
cd test-game
|
||||
mkdir -p Scripts Scenes Libraries
|
||||
```
|
||||
|
||||
#### Create Game Project Configuration
|
||||
|
||||
Create `project.godot`:
|
||||
```ini
|
||||
; Engine configuration file.
|
||||
|
||||
[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"
|
||||
```
|
||||
|
||||
Create `TestGame.csproj`:
|
||||
```xml
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>TestGame</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Libraries/utilities/Utilities.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
#### Add Library as Submodule
|
||||
|
||||
```bash
|
||||
git submodule add https://git.ein-softworks.com/library/utilities.git Libraries/utilities
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
#### Create Game Code
|
||||
|
||||
Create `Scripts/Main.cs`:
|
||||
```csharp
|
||||
using Godot;
|
||||
using EinSoftworks.Utilities;
|
||||
|
||||
namespace TestGame
|
||||
{
|
||||
public partial class Main : Node2D
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
GD.Print("Test Game Started!");
|
||||
|
||||
// Test the utilities library
|
||||
TestMathUtils();
|
||||
}
|
||||
|
||||
private void TestMathUtils()
|
||||
{
|
||||
// Test degree/radian conversion
|
||||
float testAngle = 90f;
|
||||
float radians = MathUtils.DegreesToRadians(testAngle);
|
||||
float backToDegrees = MathUtils.RadiansToDegrees(radians);
|
||||
GD.Print($"90° → {radians} rad → {backToDegrees}°");
|
||||
|
||||
// Test clamping
|
||||
float clampedValue = MathUtils.Clamp01(1.5f);
|
||||
GD.Print($"Clamped 1.5 to 0-1 range: {clampedValue}");
|
||||
|
||||
// Test approximation
|
||||
bool isApprox = MathUtils.Approximately(0.1f, 0.100001f);
|
||||
GD.Print($"0.1 ≈ 0.100001: {isApprox}");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Create `Scenes/Main.tscn`:
|
||||
```
|
||||
[gd_scene load_steps=2 format=3 uid="uid://b8y1qxqxqxqxq"]
|
||||
|
||||
[ext_resource type="Script" path="res://Scripts/Main.cs" id="1"]
|
||||
|
||||
[node name="Main" type="Node2D"]
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
offset_right = 400.0
|
||||
offset_bottom = 100.0
|
||||
text = "Test Game - Check console for utilities library output"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
```
|
||||
|
||||
#### Create .gitignore
|
||||
|
||||
```gitignore
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
|
||||
# Godot-specific ignores
|
||||
.import/
|
||||
export.cfg
|
||||
export_presets.cfg
|
||||
|
||||
# Imported translations (automatically generated from CSV files)
|
||||
*.translation
|
||||
|
||||
# Mono-specific ignores
|
||||
.mono/
|
||||
data_*/
|
||||
mono_crash.*.json
|
||||
|
||||
# .NET specific ignores
|
||||
bin/
|
||||
obj/
|
||||
*.tmp
|
||||
```
|
||||
|
||||
#### Commit and Push Game Project
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Initial test game setup with utilities library submodule"
|
||||
git remote add origin https://git.ein-softworks.com/project/test-game.git
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### Step 4: Open and Build in Godot
|
||||
|
||||
1. Launch Godot: `~/GameDev/Godot/Godot.app/Contents/MacOS/Godot`
|
||||
2. In Project Manager, click **"Import"**
|
||||
3. Navigate to `~/GameDev/projects/test-game/` and select `project.godot`
|
||||
4. Click **"Import & Edit"**
|
||||
5. In the Godot editor, go to **Project → Tools → C# → Create C# solution**
|
||||
6. Click the **"Build"** button in the toolbar (or **Project → Tools → C# → Build Solution**)
|
||||
7. Run the game with the **Play** button
|
||||
|
||||
Expected console output:
|
||||
```
|
||||
Test Game Started!
|
||||
90° → 1.5708 rad → 90°
|
||||
Clamped 1.5 to 0-1 range: 1
|
||||
0.1 ≈ 0.100001: True
|
||||
```
|
||||
|
||||
## Usage Workflows
|
||||
|
||||
### Working on Libraries
|
||||
|
||||
#### Developing New Features
|
||||
|
||||
When you want to add functionality to an existing library:
|
||||
|
||||
```bash
|
||||
# Navigate to library
|
||||
cd ~/GameDev/libraries/utilities
|
||||
|
||||
# Create a new branch for your feature
|
||||
git checkout -b feature/string-utilities
|
||||
|
||||
# Add your new code (example)
|
||||
cat >> Scripts/StringUtils.cs << 'EOF'
|
||||
using Godot;
|
||||
|
||||
namespace EinSoftworks.Utilities
|
||||
{
|
||||
public static class StringUtils
|
||||
{
|
||||
public static string ToPascalCase(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
return char.ToUpper(input[0]) + input.Substring(1).ToLower();
|
||||
}
|
||||
|
||||
public static bool IsValidEmail(string email)
|
||||
{
|
||||
return email.Contains("@") && email.Contains(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Test your changes in Godot
|
||||
# Open ~/GameDev/libraries/utilities in Godot
|
||||
# Build and test the library
|
||||
|
||||
# Commit your changes
|
||||
git add .
|
||||
git commit -m "Add StringUtils with PascalCase and email validation"
|
||||
|
||||
# Push the feature branch
|
||||
git push origin feature/string-utilities
|
||||
|
||||
# Create a pull request in Gitea
|
||||
# After review and merge, switch back to main
|
||||
git checkout main
|
||||
git pull origin main
|
||||
|
||||
# Clean up feature branch
|
||||
git branch -d feature/string-utilities
|
||||
```
|
||||
|
||||
#### Creating a New Library
|
||||
|
||||
```bash
|
||||
# Create new library repository
|
||||
cd ~/GameDev/libraries
|
||||
git init audio-manager
|
||||
cd audio-manager
|
||||
|
||||
# Set up library structure
|
||||
mkdir -p Scripts Resources
|
||||
cat > project.godot << 'EOF'
|
||||
; Engine configuration file.
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Audio Manager Library"
|
||||
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="EinSoftworks.AudioManager"
|
||||
EOF
|
||||
|
||||
cat > AudioManager.csproj << 'EOF'
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>EinSoftworks.AudioManager</RootNamespace>
|
||||
<AssemblyName>EinSoftworks.AudioManager</AssemblyName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
EOF
|
||||
|
||||
# Create basic audio manager
|
||||
cat > Scripts/AudioManager.cs << 'EOF'
|
||||
using Godot;
|
||||
|
||||
namespace EinSoftworks.AudioManager
|
||||
{
|
||||
public partial class AudioManager : Node
|
||||
{
|
||||
private AudioStreamPlayer _musicPlayer;
|
||||
private AudioStreamPlayer _sfxPlayer;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_musicPlayer = new AudioStreamPlayer();
|
||||
_sfxPlayer = new AudioStreamPlayer();
|
||||
|
||||
AddChild(_musicPlayer);
|
||||
AddChild(_sfxPlayer);
|
||||
}
|
||||
|
||||
public void PlayMusic(AudioStream music, float volume = 1.0f)
|
||||
{
|
||||
_musicPlayer.Stream = music;
|
||||
_musicPlayer.VolumeDb = Mathf.LinearToDb(volume);
|
||||
_musicPlayer.Play();
|
||||
}
|
||||
|
||||
public void PlaySFX(AudioStream sfx, float volume = 1.0f)
|
||||
{
|
||||
_sfxPlayer.Stream = sfx;
|
||||
_sfxPlayer.VolumeDb = Mathf.LinearToDb(volume);
|
||||
_sfxPlayer.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Copy standard .gitignore
|
||||
cp ../utilities/.gitignore .
|
||||
|
||||
# Commit and push
|
||||
git add .
|
||||
git commit -m "Initial audio manager library"
|
||||
git remote add origin https://git.ein-softworks.com/library/audio-manager.git
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### Working with Game Projects
|
||||
|
||||
#### Adding Libraries to Existing Projects
|
||||
|
||||
To add a new library to an existing game project:
|
||||
|
||||
```bash
|
||||
# Navigate to your game project
|
||||
cd ~/GameDev/projects/test-game
|
||||
|
||||
# Add the new library as a submodule
|
||||
git submodule add https://git.ein-softworks.com/library/audio-manager.git Libraries/audio-manager
|
||||
|
||||
# Update the .csproj file to reference the new library
|
||||
# Edit TestGame.csproj and add to ItemGroup:
|
||||
# <ProjectReference Include="Libraries/audio-manager/AudioManager.csproj" />
|
||||
|
||||
# Example of the updated .csproj:
|
||||
cat > TestGame.csproj << 'EOF'
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>TestGame</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Libraries/utilities/Utilities.csproj" />
|
||||
<ProjectReference Include="Libraries/audio-manager/AudioManager.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
EOF
|
||||
|
||||
# Commit the changes
|
||||
git add .
|
||||
git commit -m "Add audio-manager library dependency"
|
||||
git push origin main
|
||||
|
||||
# In Godot: Project → Reload Current Project
|
||||
# Then build the solution
|
||||
```
|
||||
|
||||
#### Updating Libraries in Projects
|
||||
|
||||
To update a library to the latest version:
|
||||
|
||||
```bash
|
||||
# Navigate to your game project
|
||||
cd ~/GameDev/projects/test-game
|
||||
|
||||
# Update specific library to latest
|
||||
git submodule update --remote Libraries/utilities
|
||||
|
||||
# Or update all submodules
|
||||
git submodule update --remote
|
||||
|
||||
# Commit the library updates
|
||||
git add .
|
||||
git commit -m "Update utilities library to latest version"
|
||||
git push origin main
|
||||
|
||||
# In Godot: Project → Reload Current Project
|
||||
# Then rebuild the solution
|
||||
```
|
||||
|
||||
To update to a specific version/commit:
|
||||
|
||||
```bash
|
||||
# Navigate to the submodule
|
||||
cd ~/GameDev/projects/test-game/Libraries/utilities
|
||||
|
||||
# Check available tags/versions
|
||||
git tag -l
|
||||
|
||||
# Checkout specific version
|
||||
git checkout v1.2.0
|
||||
|
||||
# Go back to project root
|
||||
cd ~/GameDev/projects/test-game
|
||||
|
||||
# Commit the specific version
|
||||
git add Libraries/utilities
|
||||
git commit -m "Update utilities library to v1.2.0"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
#### Creating New Game Projects
|
||||
|
||||
To create a new game project with existing libraries:
|
||||
|
||||
```bash
|
||||
# Create new project
|
||||
cd ~/GameDev/projects
|
||||
git init puzzle-game
|
||||
cd puzzle-game
|
||||
|
||||
# Set up basic structure
|
||||
mkdir -p Scripts Scenes Libraries
|
||||
|
||||
# Create project.godot
|
||||
cat > project.godot << 'EOF'
|
||||
; Engine configuration file.
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Puzzle Game"
|
||||
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
|
||||
run/main_scene="res://Scenes/Main.tscn"
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="PuzzleGame"
|
||||
EOF
|
||||
|
||||
# Add required 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
|
||||
|
||||
# Create .csproj with all dependencies
|
||||
cat > PuzzleGame.csproj << 'EOF'
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>PuzzleGame</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Libraries/utilities/Utilities.csproj" />
|
||||
<ProjectReference Include="Libraries/audio-manager/AudioManager.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
EOF
|
||||
|
||||
# Copy .gitignore from another project
|
||||
cp ../test-game/.gitignore .
|
||||
|
||||
# Initialize submodules
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Create basic game code
|
||||
cat > Scripts/Main.cs << 'EOF'
|
||||
using Godot;
|
||||
using EinSoftworks.Utilities;
|
||||
using EinSoftworks.AudioManager;
|
||||
|
||||
namespace PuzzleGame
|
||||
{
|
||||
public partial class Main : Node2D
|
||||
{
|
||||
private AudioManager _audioManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
GD.Print("Puzzle Game Started!");
|
||||
|
||||
// Set up audio manager
|
||||
_audioManager = new AudioManager();
|
||||
AddChild(_audioManager);
|
||||
|
||||
// Test utilities
|
||||
float angle = MathUtils.DegreesToRadians(45f);
|
||||
GD.Print($"45 degrees = {angle} radians");
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Commit and push
|
||||
git add .
|
||||
git commit -m "Initial puzzle game setup with utilities and audio-manager libraries"
|
||||
git remote add origin https://git.ein-softworks.com/project/puzzle-game.git
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### Advanced Workflows
|
||||
|
||||
#### Working with Library Dependencies
|
||||
|
||||
If one library depends on another:
|
||||
|
||||
```csharp
|
||||
// In Libraries/ui-framework/UIFramework.csproj
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>EinSoftworks.UIFramework</RootNamespace>
|
||||
<AssemblyName>EinSoftworks.UIFramework</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../utilities/Utilities.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
#### Creating Library Releases
|
||||
|
||||
For important library milestones:
|
||||
|
||||
```bash
|
||||
# In your library repository
|
||||
cd ~/GameDev/libraries/utilities
|
||||
|
||||
# Create and push a tag
|
||||
git tag -a v1.0.0 -m "Release version 1.0.0 - Initial stable release"
|
||||
git push origin v1.0.0
|
||||
|
||||
# Create release notes in Gitea
|
||||
# Navigate to your Gitea repository → Releases → New Release
|
||||
```
|
||||
|
||||
#### Cloning Projects on New Machines
|
||||
|
||||
When setting up on a new development machine:
|
||||
|
||||
```bash
|
||||
# Clone project with submodules
|
||||
git clone --recursive https://git.ein-softworks.com/project/test-game.git
|
||||
|
||||
# Or if already cloned without --recursive
|
||||
cd test-game
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Library Design
|
||||
|
||||
1. **Keep libraries focused**: Each library should have a single, well-defined purpose
|
||||
2. **Use proper namespacing**: Follow the pattern `CompanyName.LibraryName`
|
||||
3. **Document your code**: Use XML documentation comments for public APIs
|
||||
4. **Version your releases**: Use semantic versioning (major.minor.patch)
|
||||
5. **Test thoroughly**: Create test projects for each library
|
||||
|
||||
### Project Organization
|
||||
|
||||
1. **Consistent naming**: Use kebab-case for repository names, PascalCase for namespaces
|
||||
2. **Clear dependencies**: Only include libraries you actually use
|
||||
3. **Regular updates**: Keep libraries updated, but test thoroughly after updates
|
||||
4. **Backup strategy**: Ensure all repositories are backed up on your Gitea instance
|
||||
|
||||
### Git Workflow
|
||||
|
||||
1. **Feature branches**: Use feature branches for library development
|
||||
2. **Descriptive commits**: Write clear commit messages
|
||||
3. **Regular pushes**: Push changes regularly to avoid data loss
|
||||
4. **Clean history**: Squash commits when merging features
|
||||
|
||||
### Development Environment
|
||||
|
||||
1. **Consistent paths**: Always use the `~/GameDev/` structure
|
||||
2. **IDE setup**: Configure your IDE to recognize the library references
|
||||
3. **Build automation**: Consider setting up CI/CD for library testing
|
||||
4. **Documentation**: Keep this document updated as your system evolves
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Submodule Not Found
|
||||
```bash
|
||||
# If Libraries/utilities is empty
|
||||
cd ~/GameDev/projects/test-game
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
#### Build Errors
|
||||
```bash
|
||||
# In Godot editor
|
||||
# Project → Reload Current Project
|
||||
# Project → Tools → C# → Create C# solution
|
||||
# Build
|
||||
```
|
||||
|
||||
#### Missing References
|
||||
Check that your `.csproj` file includes all required `<ProjectReference>` entries for your submodules.
|
||||
|
||||
#### Submodule Update Conflicts
|
||||
```bash
|
||||
# If you have uncommitted changes in a submodule
|
||||
cd Libraries/utilities
|
||||
git stash
|
||||
git pull origin main
|
||||
git stash pop
|
||||
```
|
||||
|
||||
### Getting Help
|
||||
|
||||
1. Check Godot's C# documentation
|
||||
2. Review Git submodule documentation
|
||||
3. Examine this document for reference patterns
|
||||
4. Test changes in isolation before applying to important projects
|
||||
|
||||
---
|
||||
|
||||
*This documentation should be updated as your library system evolves and new patterns emerge.*
|
||||
768
docs/VSCODE_INTEGRATION.md
Normal file
768
docs/VSCODE_INTEGRATION.md
Normal file
@@ -0,0 +1,768 @@
|
||||
# VS Code Integration Guide for Godot Development
|
||||
|
||||
## Overview
|
||||
|
||||
This guide provides comprehensive instructions for setting up Visual Studio Code as your primary editor for Godot game development. VS Code offers superior C# support, excellent Git integration, and powerful extensions that significantly enhance the Godot development experience compared to the built-in editor.
|
||||
|
||||
## Why Use VS Code with Godot?
|
||||
|
||||
### Advantages of VS Code
|
||||
|
||||
- **Superior IntelliSense**: Advanced code completion, error detection, and refactoring tools
|
||||
- **Powerful Extensions**: Rich ecosystem of extensions for C#, Git, and game development
|
||||
- **Better Git Integration**: Built-in Git support with visual diff tools and GitLens integration
|
||||
- **Multi-Project Support**: Work with multiple libraries and projects simultaneously
|
||||
- **Debugging Support**: Integrated debugging capabilities for C# code
|
||||
- **Customizable Interface**: Themes, layouts, and keyboard shortcuts
|
||||
- **Fast Performance**: Lightweight and responsive compared to full IDEs
|
||||
|
||||
### What You'll Get
|
||||
|
||||
- Full project context when opening files from Godot
|
||||
- IntelliSense for your custom libraries and Godot APIs
|
||||
- Seamless navigation between files and projects
|
||||
- Integrated terminal for Git operations
|
||||
- Side-by-side editing of multiple files
|
||||
- Advanced search and replace across entire projects
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Godot v4.5.1+ with C# support enabled
|
||||
- .NET 8.0+ installed
|
||||
- Visual Studio Code installed
|
||||
- Basic familiarity with VS Code interface
|
||||
|
||||
## Initial Setup and Configuration
|
||||
|
||||
### Step 1: Install VS Code Extensions
|
||||
|
||||
Install these essential extensions for optimal Godot development:
|
||||
|
||||
#### Required Extensions
|
||||
|
||||
```bash
|
||||
# Core C# support
|
||||
code --install-extension ms-dotnettools.csdevkit
|
||||
code --install-extension ms-dotnettools.csharp
|
||||
|
||||
# Godot integration
|
||||
code --install-extension geequlim.godot-tools
|
||||
```
|
||||
|
||||
#### Highly Recommended Extensions
|
||||
|
||||
```bash
|
||||
# Enhanced development experience
|
||||
code --install-extension visualstudioexptteam.vscodeintellicode
|
||||
code --install-extension eamodio.gitlens
|
||||
code --install-extension ms-vscode.vscode-json
|
||||
|
||||
# Code quality and formatting
|
||||
code --install-extension ms-dotnettools.vscode-dotnet-runtime
|
||||
code --install-extension streetsidesoftware.code-spell-checker
|
||||
|
||||
# Productivity enhancements
|
||||
code --install-extension ms-vscode.powershell
|
||||
code --install-extension ms-vscode-remote.remote-repositories
|
||||
```
|
||||
|
||||
#### Optional but Useful Extensions
|
||||
|
||||
```bash
|
||||
# Visual enhancements
|
||||
code --install-extension pkief.material-icon-theme
|
||||
code --install-extension zhuangtongfa.material-theme
|
||||
|
||||
# Additional tools
|
||||
code --install-extension formulahendry.auto-rename-tag
|
||||
code --install-extension ms-vscode.hexeditor
|
||||
code --install-extension redhat.vscode-yaml
|
||||
```
|
||||
|
||||
### Step 2: Configure Godot to Use VS Code
|
||||
|
||||
#### Basic External Editor Setup
|
||||
|
||||
1. **Open Godot Editor Settings**
|
||||
- Go to **Editor → Editor Settings**
|
||||
- Navigate to **Network → Language Server**
|
||||
- Set **Use Language Server** to **On**
|
||||
|
||||
2. **Configure External Editor**
|
||||
- Navigate to **Text Editor → External**
|
||||
- Check **Use External Editor**
|
||||
- Set **Exec Path** to VS Code installation:
|
||||
- **macOS**: `/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code`
|
||||
- **Windows**: `C:\Users\[Username]\AppData\Local\Programs\Microsoft VS Code\Code.exe`
|
||||
- **Linux**: `/usr/bin/code` or `/snap/bin/code`
|
||||
- **Alternative**: Just `code` if you have the command in your PATH
|
||||
|
||||
### Step 3: Fix Project Context Issue
|
||||
|
||||
The default setup opens individual files without project context. Here are several solutions:
|
||||
|
||||
#### Solution A: Create Smart Wrapper Script (Recommended)
|
||||
|
||||
Create a script that ensures VS Code always opens with full project context:
|
||||
|
||||
**For macOS/Linux:**
|
||||
```bash
|
||||
# Create the wrapper script
|
||||
cat > ~/GameDev/vscode-godot.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Get the file path passed by Godot
|
||||
FILE_PATH="$1"
|
||||
LINE_NUMBER="$2"
|
||||
COLUMN_NUMBER="$3"
|
||||
|
||||
# Find the project directory by looking for project.godot
|
||||
PROJECT_DIR=$(dirname "$FILE_PATH")
|
||||
while [[ "$PROJECT_DIR" != "/" && ! -f "$PROJECT_DIR/project.godot" ]]; do
|
||||
PROJECT_DIR=$(dirname "$PROJECT_DIR")
|
||||
done
|
||||
|
||||
# If we found a project.godot, open that directory with the file
|
||||
if [[ -f "$PROJECT_DIR/project.godot" ]]; then
|
||||
echo "Opening project: $PROJECT_DIR"
|
||||
code "$PROJECT_DIR" --goto "$FILE_PATH:$LINE_NUMBER:$COLUMN_NUMBER"
|
||||
else
|
||||
echo "No project.godot found, opening file directory"
|
||||
code "$(dirname "$FILE_PATH")" --goto "$FILE_PATH:$LINE_NUMBER:$COLUMN_NUMBER"
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Make it executable
|
||||
chmod +x ~/GameDev/vscode-godot.sh
|
||||
```
|
||||
|
||||
**For Windows (PowerShell):**
|
||||
```powershell
|
||||
# Create vscode-godot.ps1 in your GameDev directory
|
||||
@'
|
||||
param(
|
||||
[string]$FilePath,
|
||||
[string]$LineNumber = "1",
|
||||
[string]$ColumnNumber = "1"
|
||||
)
|
||||
|
||||
# Find project directory
|
||||
$ProjectDir = Split-Path $FilePath -Parent
|
||||
while (($ProjectDir -ne [System.IO.Path]::GetPathRoot($ProjectDir)) -and
|
||||
(-not (Test-Path (Join-Path $ProjectDir "project.godot")))) {
|
||||
$ProjectDir = Split-Path $ProjectDir -Parent
|
||||
}
|
||||
|
||||
# Open VS Code with project context
|
||||
if (Test-Path (Join-Path $ProjectDir "project.godot")) {
|
||||
Write-Host "Opening project: $ProjectDir"
|
||||
& code $ProjectDir --goto "$FilePath`:$LineNumber`:$ColumnNumber"
|
||||
} else {
|
||||
Write-Host "No project.godot found, opening file directory"
|
||||
& code (Split-Path $FilePath -Parent) --goto "$FilePath`:$LineNumber`:$ColumnNumber"
|
||||
}
|
||||
'@ | Out-File -FilePath "~/GameDev/vscode-godot.ps1" -Encoding UTF8
|
||||
```
|
||||
|
||||
#### Configure Godot to Use the Wrapper Script
|
||||
|
||||
In Godot's **Editor Settings → Text Editor → External**:
|
||||
- **Exec Path**: `/Users/[your-username]/GameDev/vscode-godot.sh` (or path to .ps1 on Windows)
|
||||
- **Exec Flags**: `{file} {line} {col}`
|
||||
|
||||
#### Solution B: Simple Project Opening
|
||||
|
||||
Alternative simpler approach in **Exec Flags**:
|
||||
```
|
||||
{project} --goto {file}:{line}:{col}
|
||||
```
|
||||
|
||||
This opens the project directory and navigates to the specific file.
|
||||
|
||||
## Project-Specific VS Code Configuration
|
||||
|
||||
### Step 1: Create Workspace Settings
|
||||
|
||||
For each Godot project, create `.vscode/settings.json`:
|
||||
|
||||
```bash
|
||||
# Navigate to your project
|
||||
cd ~/GameDev/projects/test-game
|
||||
|
||||
# Create .vscode directory
|
||||
mkdir -p .vscode
|
||||
|
||||
# Create comprehensive settings
|
||||
cat > .vscode/settings.json << 'EOF'
|
||||
{
|
||||
// .NET and C# Configuration
|
||||
"dotnet.defaultSolution": "TestGame.sln",
|
||||
"omnisharp.enableEditorConfigSupport": true,
|
||||
"omnisharp.enableImportCompletion": true,
|
||||
"omnisharp.enableRoslynAnalyzers": true,
|
||||
"omnisharp.useModernNet": true,
|
||||
|
||||
// Godot Integration
|
||||
"godot_tools.editor_path": "~/GameDev/Godot/Godot.app/Contents/MacOS/Godot",
|
||||
"godot_tools.gdscript_lsp_server_port": 6005,
|
||||
|
||||
// File Management
|
||||
"files.exclude": {
|
||||
"**/.godot": true,
|
||||
"**/.import": true,
|
||||
"**/bin": true,
|
||||
"**/obj": true,
|
||||
"**/*.tmp": true
|
||||
},
|
||||
|
||||
// Window Behavior
|
||||
"window.openFilesInNewWindow": "off",
|
||||
"window.openFoldersInNewWindow": "off",
|
||||
"workbench.editor.revealIfOpen": true,
|
||||
|
||||
// Search Configuration
|
||||
"search.exclude": {
|
||||
"**/.godot": true,
|
||||
"**/bin": true,
|
||||
"**/obj": true
|
||||
},
|
||||
|
||||
// File Associations
|
||||
"files.associations": {
|
||||
"*.cs": "csharp",
|
||||
"*.tscn": "godot-scene",
|
||||
"*.tres": "godot-resource",
|
||||
"*.gd": "gdscript"
|
||||
},
|
||||
|
||||
// Code Formatting
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnType": true,
|
||||
"csharp.format.enable": true,
|
||||
|
||||
// Git Integration
|
||||
"git.autoRepositoryDetection": "subFolders",
|
||||
"git.detectSubmodules": true,
|
||||
|
||||
// Terminal Configuration
|
||||
"terminal.integrated.cwd": "${workspaceFolder}"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Step 2: Create Launch Configuration
|
||||
|
||||
Set up debugging and task running with `.vscode/launch.json`:
|
||||
|
||||
```bash
|
||||
cat > .vscode/launch.json << 'EOF'
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Play in Editor",
|
||||
"type": "godot",
|
||||
"request": "launch",
|
||||
"project": "${workspaceFolder}",
|
||||
"port": 6007,
|
||||
"debugServer": 6008,
|
||||
"preLaunchTask": "build"
|
||||
},
|
||||
{
|
||||
"name": "Launch Game",
|
||||
"type": "godot",
|
||||
"request": "launch",
|
||||
"project": "${workspaceFolder}",
|
||||
"port": 6007,
|
||||
"debugServer": 6008,
|
||||
"executable": "~/GameDev/Godot/Godot.app/Contents/MacOS/Godot",
|
||||
"executableArguments": [
|
||||
"--path",
|
||||
"${workspaceFolder}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Launch Main Scene",
|
||||
"type": "godot",
|
||||
"request": "launch",
|
||||
"project": "${workspaceFolder}",
|
||||
"port": 6007,
|
||||
"debugServer": 6008,
|
||||
"executable": "~/GameDev/Godot/Godot.app/Contents/MacOS/Godot",
|
||||
"executableArguments": [
|
||||
"--path",
|
||||
"${workspaceFolder}",
|
||||
"Scenes/Main.tscn"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Step 3: Configure Build Tasks
|
||||
|
||||
Create `.vscode/tasks.json` for build automation:
|
||||
|
||||
```bash
|
||||
cat > .vscode/tasks.json << 'EOF'
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"type": "dotnet",
|
||||
"task": "build",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "clean",
|
||||
"type": "dotnet",
|
||||
"task": "clean",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "restore",
|
||||
"type": "dotnet",
|
||||
"task": "restore",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
## Multi-Project Workspace Setup
|
||||
|
||||
### Creating a Master Workspace
|
||||
|
||||
For working with multiple projects and libraries simultaneously:
|
||||
|
||||
```bash
|
||||
# Create a master workspace file
|
||||
cat > ~/GameDev/godot-development.code-workspace << 'EOF'
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "🎮 Test Game",
|
||||
"path": "./projects/test-game"
|
||||
},
|
||||
{
|
||||
"name": "🎮 Puzzle Game",
|
||||
"path": "./projects/puzzle-game"
|
||||
},
|
||||
{
|
||||
"name": "📚 Utilities Library",
|
||||
"path": "./libraries/utilities"
|
||||
},
|
||||
{
|
||||
"name": "📚 Audio Manager Library",
|
||||
"path": "./libraries/audio-manager"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
// Global workspace settings
|
||||
"files.exclude": {
|
||||
"**/.godot": true,
|
||||
"**/.import": true,
|
||||
"**/bin": true,
|
||||
"**/obj": true
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/.godot": true,
|
||||
"**/bin": true,
|
||||
"**/obj": true
|
||||
},
|
||||
"git.detectSubmodules": true,
|
||||
"git.autoRepositoryDetection": "subFolders",
|
||||
|
||||
// Default to first project's solution
|
||||
"dotnet.defaultSolution": "./projects/test-game/TestGame.sln"
|
||||
},
|
||||
"extensions": {
|
||||
"recommendations": [
|
||||
"ms-dotnettools.csdevkit",
|
||||
"ms-dotnettools.csharp",
|
||||
"geequlim.godot-tools",
|
||||
"eamodio.gitlens",
|
||||
"visualstudioexptteam.vscodeintellicode"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Opening the Workspace
|
||||
|
||||
```bash
|
||||
# Open the master workspace
|
||||
code ~/GameDev/godot-development.code-workspace
|
||||
|
||||
# Or open individual projects
|
||||
cd ~/GameDev/projects/test-game
|
||||
code .
|
||||
```
|
||||
|
||||
## Development Workflows
|
||||
|
||||
### Daily Development Routine
|
||||
|
||||
1. **Start Your Day**
|
||||
```bash
|
||||
# Open your workspace
|
||||
code ~/GameDev/godot-development.code-workspace
|
||||
|
||||
# Or open specific project
|
||||
cd ~/GameDev/projects/test-game
|
||||
code .
|
||||
```
|
||||
|
||||
2. **Working with Files**
|
||||
- **From Godot**: Double-click scripts → Opens in VS Code with full project context
|
||||
- **From VS Code**: Use `Cmd/Ctrl + P` to quickly open files
|
||||
- **Navigation**: Use `Cmd/Ctrl + Click` on symbols to jump to definitions
|
||||
|
||||
3. **Building and Testing**
|
||||
- **Quick Build**: `Cmd/Ctrl + Shift + P` → "Tasks: Run Build Task"
|
||||
- **From Godot**: Use Godot's Build button (recommended for final builds)
|
||||
- **Debug**: Use F5 in VS Code (if debugging is set up)
|
||||
|
||||
### Working with Libraries
|
||||
|
||||
#### Editing Library Code
|
||||
|
||||
1. **Navigate to library**:
|
||||
```bash
|
||||
cd ~/GameDev/libraries/utilities
|
||||
code .
|
||||
```
|
||||
|
||||
2. **Make changes** with full IntelliSense support
|
||||
|
||||
3. **Test changes**:
|
||||
- Open the library project in Godot
|
||||
- Or test within a game project that uses the library
|
||||
|
||||
4. **Commit and push changes**:
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Add new utility function"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
#### Updating Libraries in Projects
|
||||
|
||||
1. **Update from VS Code terminal**:
|
||||
```bash
|
||||
# In your game project
|
||||
git submodule update --remote Libraries/utilities
|
||||
git add Libraries/utilities
|
||||
git commit -m "Update utilities library"
|
||||
```
|
||||
|
||||
2. **Reload project in Godot** to pick up changes
|
||||
|
||||
### Git Integration Workflows
|
||||
|
||||
#### Using VS Code's Built-in Git
|
||||
|
||||
1. **Source Control Panel** (`Cmd/Ctrl + Shift + G`):
|
||||
- View changes across all repositories
|
||||
- Stage and commit changes
|
||||
- See submodule status
|
||||
|
||||
2. **Git Commands**:
|
||||
- `Cmd/Ctrl + Shift + P` → "Git: " for all Git commands
|
||||
- Built-in diff viewer for file changes
|
||||
- Integrated merge conflict resolution
|
||||
|
||||
#### Advanced Git with GitLens
|
||||
|
||||
1. **Blame Information**: See who changed each line of code
|
||||
2. **File History**: View complete file change history
|
||||
3. **Repository Insights**: Visualize branch structure and commits
|
||||
4. **Interactive Rebase**: Advanced Git operations through UI
|
||||
|
||||
## Advanced Features and Tips
|
||||
|
||||
### IntelliSense and Code Navigation
|
||||
|
||||
#### Maximizing IntelliSense Performance
|
||||
|
||||
1. **Ensure proper project references** in `.csproj` files
|
||||
2. **Build solution regularly** to update IntelliSense cache
|
||||
3. **Use "Reload Window"** if IntelliSense stops working:
|
||||
- `Cmd/Ctrl + Shift + P` → "Developer: Reload Window"
|
||||
|
||||
#### Navigation Shortcuts
|
||||
|
||||
- **Go to Definition**: `F12` or `Cmd/Ctrl + Click`
|
||||
- **Go to References**: `Shift + F12`
|
||||
- **Go to Symbol**: `Cmd/Ctrl + Shift + O`
|
||||
- **Go to File**: `Cmd/Ctrl + P`
|
||||
- **Command Palette**: `Cmd/Ctrl + Shift + P`
|
||||
|
||||
### Code Formatting and Quality
|
||||
|
||||
#### Auto-Formatting Setup
|
||||
|
||||
1. **Install C# extension** with formatting support
|
||||
2. **Configure format on save** in settings.json
|
||||
3. **Use EditorConfig** for consistent formatting across team
|
||||
|
||||
Create `.editorconfig` in project root:
|
||||
```ini
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.cs]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{csproj,props,targets}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
```
|
||||
|
||||
#### Code Quality Tools
|
||||
|
||||
1. **Enable Roslyn Analyzers** in settings.json
|
||||
2. **Use SonarLint extension** for additional code quality checks
|
||||
3. **Configure spell checking** for comments and strings
|
||||
|
||||
### Debugging Setup
|
||||
|
||||
#### Enable Debugging in Godot
|
||||
|
||||
1. **In Godot Project Settings**:
|
||||
- Go to **Debug → Settings**
|
||||
- Enable **Remote Port** (usually 6007)
|
||||
- Enable **Remote Host** (usually 127.0.0.1)
|
||||
|
||||
2. **In VS Code**:
|
||||
- Set breakpoints in your C# code
|
||||
- Press `F5` to start debugging
|
||||
- Godot will connect to VS Code debugger
|
||||
|
||||
#### Debugging Workflow
|
||||
|
||||
1. **Set breakpoints** in VS Code
|
||||
2. **Start debugging** with F5
|
||||
3. **Play scene in Godot**
|
||||
4. **Debug in VS Code** when breakpoints hit
|
||||
|
||||
### Customization and Themes
|
||||
|
||||
#### Recommended Themes for Game Development
|
||||
|
||||
```bash
|
||||
# Dark themes optimized for long coding sessions
|
||||
code --install-extension zhuangtongfa.material-theme
|
||||
code --install-extension github.github-vscode-theme
|
||||
code --install-extension dracula-theme.theme-dracula
|
||||
|
||||
# Icon themes for better file recognition
|
||||
code --install-extension pkief.material-icon-theme
|
||||
code --install-extension vscode-icons-team.vscode-icons
|
||||
```
|
||||
|
||||
#### Custom Keybindings
|
||||
|
||||
Create custom keybindings for Godot workflows in `keybindings.json`:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"key": "cmd+shift+g",
|
||||
"command": "godot.runProject",
|
||||
"when": "resourceExtname == '.cs'"
|
||||
},
|
||||
{
|
||||
"key": "cmd+shift+b",
|
||||
"command": "workbench.action.tasks.build"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues and Solutions
|
||||
|
||||
#### VS Code Opens Individual Files Instead of Project
|
||||
|
||||
**Problem**: Clicking scripts in Godot opens single files without project context.
|
||||
|
||||
**Solutions**:
|
||||
1. **Use the wrapper script** (recommended approach above)
|
||||
2. **Keep project always open** in VS Code
|
||||
3. **Modify Exec Flags** to `{project} --goto {file}:{line}:{col}`
|
||||
|
||||
#### IntelliSense Not Working
|
||||
|
||||
**Problem**: No code completion or error detection.
|
||||
|
||||
**Solutions**:
|
||||
1. **Check C# extension is installed** and enabled
|
||||
2. **Verify .csproj references** are correct
|
||||
3. **Reload VS Code window**: `Cmd/Ctrl + Shift + P` → "Developer: Reload Window"
|
||||
4. **Rebuild solution**: `Cmd/Ctrl + Shift + P` → "Tasks: Run Build Task"
|
||||
5. **Check OmniSharp output** in Output panel
|
||||
|
||||
#### Submodule Libraries Not Recognized
|
||||
|
||||
**Problem**: Libraries in submodules don't have IntelliSense.
|
||||
|
||||
**Solutions**:
|
||||
1. **Verify submodules are initialized**:
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
2. **Check project references** in `.csproj`
|
||||
3. **Rebuild solution** after submodule updates
|
||||
|
||||
#### Git Integration Issues
|
||||
|
||||
**Problem**: Git operations not working correctly with submodules.
|
||||
|
||||
**Solutions**:
|
||||
1. **Enable submodule detection** in settings:
|
||||
```json
|
||||
"git.detectSubmodules": true
|
||||
```
|
||||
2. **Use terminal** for complex Git operations
|
||||
3. **Check repository status** in each submodule directory
|
||||
|
||||
#### Build Errors in VS Code
|
||||
|
||||
**Problem**: Build fails in VS Code but works in Godot.
|
||||
|
||||
**Solutions**:
|
||||
1. **Check .NET SDK version** matches Godot requirements
|
||||
2. **Use Godot's build system** as authoritative
|
||||
3. **Clean and rebuild**:
|
||||
```bash
|
||||
dotnet clean
|
||||
dotnet restore
|
||||
dotnet build
|
||||
```
|
||||
|
||||
#### Performance Issues
|
||||
|
||||
**Problem**: VS Code becomes slow with large projects.
|
||||
|
||||
**Solutions**:
|
||||
1. **Exclude build directories** in settings.json
|
||||
2. **Disable unnecessary extensions**
|
||||
3. **Increase VS Code memory limit**:
|
||||
```bash
|
||||
code --max-memory=8192
|
||||
```
|
||||
|
||||
### Diagnostic Commands
|
||||
|
||||
#### Check Extension Status
|
||||
```bash
|
||||
# List installed extensions
|
||||
code --list-extensions
|
||||
|
||||
# Check if specific extensions are installed
|
||||
code --list-extensions | grep -E "(csdevkit|godot-tools|csharp)"
|
||||
```
|
||||
|
||||
#### Verify Project Setup
|
||||
```bash
|
||||
# Check submodule status
|
||||
git submodule status
|
||||
|
||||
# Verify project can build
|
||||
dotnet build
|
||||
|
||||
# Check Godot project configuration
|
||||
grep -A 5 "\[dotnet\]" project.godot
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Project Organization
|
||||
|
||||
1. **Consistent Structure**: Use the same folder layout across all projects
|
||||
2. **Clear Naming**: Use descriptive names for files and folders
|
||||
3. **Separate Concerns**: Keep game logic, UI, and utilities in separate folders
|
||||
4. **Document Code**: Use XML documentation comments for public APIs
|
||||
|
||||
### Code Quality
|
||||
|
||||
1. **Follow C# Conventions**: Use PascalCase for classes, camelCase for methods
|
||||
2. **Use Meaningful Names**: Avoid abbreviations and unclear variable names
|
||||
3. **Keep Methods Small**: Single responsibility principle
|
||||
4. **Comment Complex Logic**: Explain why, not what
|
||||
|
||||
### Git Workflow
|
||||
|
||||
1. **Commit Often**: Small, focused commits are easier to review
|
||||
2. **Descriptive Messages**: Use clear commit messages
|
||||
3. **Branch Strategy**: Use feature branches for new development
|
||||
4. **Test Before Pushing**: Ensure code builds and runs before pushing
|
||||
|
||||
### Performance
|
||||
|
||||
1. **Exclude Build Folders**: Keep VS Code fast by excluding unnecessary directories
|
||||
2. **Regular Cleanup**: Clean build artifacts regularly
|
||||
3. **Monitor Extensions**: Disable unused extensions
|
||||
4. **Use Workspace Settings**: Project-specific settings improve performance
|
||||
|
||||
## Conclusion
|
||||
|
||||
This setup provides a powerful, integrated development environment for Godot game development with C#. The combination of VS Code's advanced editing capabilities with Godot's excellent game engine creates an optimal workflow for both solo developers and teams.
|
||||
|
||||
### Key Benefits Achieved
|
||||
|
||||
- **Full Project Context**: No more single-file editing
|
||||
- **Superior IntelliSense**: Complete code completion and error detection
|
||||
- **Seamless Git Integration**: Visual diff tools and submodule support
|
||||
- **Multi-Project Support**: Work with libraries and games simultaneously
|
||||
- **Professional Debugging**: Set breakpoints and inspect variables
|
||||
- **Extensible Environment**: Customize with thousands of available extensions
|
||||
|
||||
### Next Steps
|
||||
|
||||
1. **Implement the wrapper script** for proper project opening
|
||||
2. **Configure your first project** with the provided settings
|
||||
3. **Install recommended extensions**
|
||||
4. **Create a multi-project workspace** for library development
|
||||
5. **Customize themes and keybindings** to your preferences
|
||||
|
||||
Remember to update this documentation as your workflow evolves and new VS Code features become available!
|
||||
|
||||
---
|
||||
|
||||
*Keep this documentation updated as VS Code and Godot continue to evolve.*
|
||||
Reference in New Issue
Block a user