Files
documentation/planning/UTILITY_PLANNING.md

604 lines
22 KiB
Markdown

# 3D Game Development Library Gameplan
## Overview
This document outlines a strategic plan for building a comprehensive C# library ecosystem for 3D game development in Godot. The libraries are organized by dependency hierarchy to ensure clean architecture, minimal coupling, and maximum reusability across projects.
## Core Principles
### 1. Dependency-Driven Development
- **Bottom-Up Approach**: Build foundational systems first
- **Minimal Dependencies**: Each library should depend on as few others as possible
- **Clear Interfaces**: Libraries communicate through well-defined APIs
- **Event-Driven Architecture**: Use events to decouple systems that need to communicate
### 2. Quality over Speed
- **Complete One Library Before Starting Next**: Fully implement, test, and document each library
- **Test-Driven Development**: Create example projects for each library
- **API Documentation**: Document public interfaces as you build
- **Refactor When Needed**: Don't be afraid to improve APIs based on usage experience
### 3. Real-World Validation
- **Iterative Improvement**: Refine APIs based on actual usage
- **Performance Monitoring**: Profile libraries in real game scenarios
## Development Phases
### Phase 1: Foundation Libraries (Highest Priority)
These libraries form the bedrock of your game development ecosystem. They have minimal dependencies and provide essential functionality that nearly all other systems will use.
#### 1.1 - EinSoftworks.Input
| | | |
|--------------|----|-----------------------------|
| Status | 🟢 | Complete |
| Priority | 🔴 | Critical |
| Dependencies | ⚫ | EinSoftworks.Utilities only |
**Why Build First:**
- Nearly every game system needs input handling
- Input systems rarely depend on other game systems
- Provides immediate value for any game project
- Foundation for camera controls, character movement, and UI navigation
**Core Features:**
```csharp
// Action-based input system
public class InputManager : Node
{
// Core input queries
public bool IsActionPressed(string action);
public bool IsActionJustPressed(string action);
public bool IsActionJustReleased(string action);
public float GetActionStrength(string action);
public Vector2 GetVector(string negativeX, string positiveX, string negativeY, string positiveY);
// Input mapping and customization
public void RemapAction(string action, InputEvent newEvent);
public void SaveInputMap();
public void LoadInputMap();
public void ResetToDefaultInputMap();
// Advanced features
public bool WasActionPressedInWindow(string action, float timeWindow);
public void SetDeadzone(string action, float deadzone);
public InputDevice GetLastUsedDevice();
}
// Input buffering for precise timing
public class InputBuffer
{
public void BufferInput(string action, float bufferTime);
public bool ConsumeBufferedInput(string action);
public void ClearBuffer();
}
```
**Validation Game Ideas:**
- Simple character that moves with WASD
- Menu navigation system
- Basic interaction system (press E to interact)
#### 1.2 - EinSoftworks.Events
| | | |
|--------------|----|-----------------------------|
| Status | 🟢 | Complete |
| Priority | 🔴 | Critical |
| Dependencies | ⚫ | EinSoftworks.Utilities only |
**Why Build Second:**
- Essential for decoupling systems
- Prevents circular dependencies between libraries
- Enables loose coupling between game systems
- Small scope makes it quick to implement correctly
**Core Features:**
```csharp
// Global event system
public static class GameEvents
{
// Player events
public static event Action<Vector3> PlayerMoved;
public static event Action<float> PlayerHealthChanged;
public static event Action PlayerDied;
// Game state events
public static event Action<string> StateChanged;
public static event Action<string> SceneChanged;
public static event Action GamePaused;
public static event Action GameResumed;
// Input events
public static event Action<string> ActionPressed;
public static event Action<string> ActionReleased;
}
// Type-safe event bus
public class EventBus<T> where T : class
{
public void Subscribe(Action<T> handler);
public void Unsubscribe(Action<T> handler);
public void Publish(T eventData);
public void Clear();
}
// Event pooling for performance
public class PooledEvent<T> where T : class, new()
{
public static T Get();
public static void Return(T item);
}
```
**Validation Game Ideas:**
- System where player movement triggers camera updates (without direct coupling)
- Health system that updates UI without direct references
- Scene transition system using events
#### 1.3 - EinSoftworks.StateManagement
| | | |
|--------------|----|---------------------------------------------|
| Status | 🟢 | Complete |
| Priority | 🔴 | Critical |
| Dependencies | ⚫ | EinSoftworks.Utilities, EinSoftworks.Events |
**Why Build Third:**
- State management is fundamental to game logic
- Can utilize the event system for state transition notifications
- Foundation for character AI, game flow, and UI states
- More complex than input/events but still foundational
**Core Features:**
```csharp
// Generic state machine
public class StateMachine<T> where T : class
{
public T CurrentState { get; private set; }
public T PreviousState { get; private set; }
public void ChangeState(T newState);
public void Update(float delta);
public void FixedUpdate(float fixedDelta);
// Transition system
public void AddTransition(T from, T to, Func<bool> condition);
public void AddAnyTransition(T to, Func<bool> condition);
public void AddTransition(T from, T to, string triggerEvent);
// Events
public event Action<T, T> StateChanged; // (from, to)
}
// Base state class
public abstract class State
{
public abstract void Enter();
public abstract void Update(float delta);
public abstract void FixedUpdate(float fixedDelta);
public abstract void Exit();
// Optional overrides
public virtual void HandleInput() { }
public virtual void OnDrawGizmos() { }
}
// Hierarchical state support
public class HierarchicalStateMachine<T> : StateMachine<T> where T : class
{
public void AddSubState(T parentState, StateMachine<T> subStateMachine);
public StateMachine<T> GetSubStateMachine(T parentState);
}
```
**Validation Game Ideas:**
- Character with idle/walking/running/jumping states
- Game with menu/playing/paused/game-over states
- AI enemy with patrol/chase/attack states
### Phase 2: Core 3D Systems (High Priority)
These libraries provide essential 3D game functionality and build upon the foundation libraries.
#### 2.1 - EinSoftworks.Camera
| | | |
|--------------|----|-----------------------------------------------------------------------|
| Status | 🟢 | Complete |
| Priority | 🟡 | High |
| Dependencies | ⚫ | EinSoftworks.Input, EinSoftworks.Events, EinSoftworks.StateManagement |
**Why Build Fourth:**
- Essential for any 3D game
- Benefits from input system for camera controls
- Can use state management for different camera modes
- Independent enough to develop without character systems
**Core Features:**
```csharp
// Main camera controller
public partial class CameraController : Node3D
{
public enum CameraMode { FirstPerson, ThirdPerson, Orbit, Fixed, Cinematic }
[Export] public CameraMode Mode { get; set; }
[Export] public Node3D Target { get; set; }
[Export] public float Sensitivity { get; set; } = 1.0f;
[Export] public bool InvertY { get; set; } = false;
// Camera positioning
public void SetTarget(Node3D target);
public void SetPosition(Vector3 position, float transitionTime = 0f);
public void SetLookAt(Vector3 lookAt, float transitionTime = 0f);
// Camera effects
public void Shake(float intensity, float duration);
public void Zoom(float targetFOV, float duration);
public void SetCameraMode(CameraMode mode, float transitionTime = 1f);
// Collision prevention
public void EnableCollisionAvoidance(bool enabled);
public void SetCollisionLayers(uint layers);
}
// Specialized camera types
public class FirstPersonCamera : CameraController
{
[Export] public float MouseSensitivity { get; set; } = 0.1f;
[Export] public float MinPitch { get; set; } = -90f;
[Export] public float MaxPitch { get; set; } = 90f;
}
public class ThirdPersonCamera : CameraController
{
[Export] public float Distance { get; set; } = 5f;
[Export] public float Height { get; set; } = 2f;
[Export] public Vector3 Offset { get; set; }
[Export] public bool AutoRotate { get; set; } = true;
}
public class OrbitCamera : CameraController
{
[Export] public float MinDistance { get; set; } = 2f;
[Export] public float MaxDistance { get; set; } = 10f;
[Export] public float ZoomSpeed { get; set; } = 1f;
}
```
**Validation Game Ideas:**
- First-person camera with mouse look
- Third-person camera that follows a moving object
- Orbit camera for examining 3D models
### Phase 3: Character and Interaction Systems (Medium Priority)
These systems focus on character control and world interaction, building upon the previously established libraries.
#### 3.1 - EinSoftworks.Movement
| | | |
|--------------|----|---------------------------------------------------------------------------------------------|
| Status | 🔴 | Incomplete |
| Priority | 🟡 | High |
| Dependencies | ⚫ | EinSoftworks.Input, EinSoftworks.Physics, EinSoftworks.StateManagement, EinSoftworks.Events |
**Why Build Sixth:**
- Core to most 3D games
- Benefits from all previously built systems
- Complex enough to require solid foundations
- Can be thoroughly tested with camera systems
**Core Features:**
```csharp
// Base character controller
public partial class CharacterController3D : CharacterBody3D
{
[Export] public float Speed { get; set; } = 5f;
[Export] public float JumpVelocity { get; set; } = 4.5f;
[Export] public float Acceleration { get; set; } = 10f;
[Export] public float Friction { get; set; } = 10f;
// Ground detection
public bool IsOnFloor();
public bool IsOnWall();
public bool IsOnCeiling();
public float GetFloorAngle();
public Vector3 GetFloorNormal();
// Movement
public void Move(Vector3 direction, float delta);
public void Jump();
public void ApplyGravity(float delta);
// State integration
public StateMachine<MovementState> StateMachine { get; private set; }
}
// Movement states
public class IdleState : MovementState
{
public override void Enter() { /* Set idle animation */ }
public override void Update(float delta) { /* Check for movement input */ }
}
public class WalkingState : MovementState
{
public override void Enter() { /* Set walking animation */ }
public override void Update(float delta) { /* Handle movement */ }
}
public class JumpingState : MovementState
{
public override void Enter() { /* Apply jump force, set animation */ }
public override void Update(float delta) { /* Handle air control */ }
}
// Specialized controllers
public class FirstPersonController : CharacterController3D
{
[Export] public float MouseSensitivity { get; set; } = 0.1f;
public Node3D Head { get; set; }
}
public class ThirdPersonController : CharacterController3D
{
[Export] public bool RotateToMovement { get; set; } = true;
[Export] public float RotationSpeed { get; set; } = 10f;
}
```
**Validation Game Ideas:**
- First-person character with WASD movement and mouse look
- Third-person character that rotates to movement direction
- Platformer character with precise jumping mechanics
#### 3.2 - EinSoftworks.Interaction
| | | |
|--------------|----|---------------------------------------------------------------|
| Status | 🔴 | Incomplete |
| Priority | 🟡 | Medium |
| Dependencies | ⚫ | EinSoftworks.Input, EinSoftworks.Physics, EinSoftworks.Events |
**Why Build Seventh:**
- Common need in 3D games
- Builds naturally on physics and input systems
- Can be developed independently of complex character systems
- Provides immediate gameplay value
**Core Features:**
```csharp
// Interactable base class
public partial class Interactable : Node3D
{
[Export] public string InteractionText { get; set; } = "Interact";
[Export] public float InteractionRange { get; set; } = 2f;
[Export] public bool RequiresLineOfSight { get; set; } = true;
[Export] public bool OneTimeUse { get; set; } = false;
[Signal] public delegate void InteractedEventHandler(Node3D interactor);
[Signal] public delegate void FocusedEventHandler(Node3D interactor);
[Signal] public delegate void UnfocusedEventHandler(Node3D interactor);
public virtual bool CanInteract(Node3D interactor) { return true; }
public virtual void Interact(Node3D interactor) { }
public virtual void OnFocused(Node3D interactor) { }
public virtual void OnUnfocused(Node3D interactor) { }
}
// Interaction detector
public partial class InteractionDetector : Node3D
{
[Export] public float DetectionRange { get; set; } = 3f;
[Export] public string InteractionAction { get; set; } = "interact";
public Interactable CurrentInteractable { get; private set; }
public Interactable[] GetInteractablesInRange();
public void TryInteract();
[Signal] public delegate void InteractableFoundEventHandler(Interactable interactable);
[Signal] public delegate void InteractableLostEventHandler(Interactable interactable);
}
// Specific interactable types
public class PickupItem : Interactable
{
[Export] public string ItemId { get; set; }
[Export] public int Quantity { get; set; } = 1;
[Export] public AudioStream PickupSound { get; set; }
}
public class Door : Interactable
{
[Export] public bool IsLocked { get; set; } = false;
[Export] public string RequiredKey { get; set; }
[Export] public float OpenAngle { get; set; } = 90f;
[Export] public float OpenSpeed { get; set; } = 2f;
}
```
**Validation Game Ideas:**
- Player that can pick up items and open doors
- Interaction UI that shows prompts when near interactables
- Key-door system with locked interactions
### Phase 4: Advanced Game Systems (Lower Priority)
These systems provide advanced functionality for complete games and can be built once the core systems are stable.
#### 4.1 - EinSoftworks.SceneManagement
| | | |
|--------------|----|---------------------------------------------------|
| Status | 🔴 | Incomplete |
| Priority | 🟢 | Medium-Low |
| Dependencies | ⚫ | EinSoftworks.StateManagement, EinSoftworks.Events |
**Core Features:**
```csharp
public class SceneManager : Node
{
public string CurrentScene { get; private set; }
public bool IsLoading { get; private set; }
public async Task LoadSceneAsync(string scenePath, bool additive = false);
public async Task UnloadSceneAsync(string sceneName);
public void LoadSceneWithTransition(string scenePath, SceneTransition transition);
[Signal] public delegate void SceneLoadStartedEventHandler(string scenePath);
[Signal] public delegate void SceneLoadCompletedEventHandler(string scenePath);
[Signal] public delegate void SceneUnloadedEventHandler(string sceneName);
}
```
#### 4.2 - EinSoftworks.SaveSystem
| | | |
|--------------|----|------------------------------------------------------------|
| Status | 🔴 | Incomplete |
| Priority | 🟢 | Medium-Low |
| Dependencies | ⚫ | EinSoftworks.StateManagement, EinSoftworks.SceneManagement |
**Core Features:**
```csharp
public class SaveManager : Node
{
public void SaveGame(string slotName = "default");
public bool LoadGame(string slotName = "default");
public void DeleteSave(string slotName);
public string[] GetSaveSlots();
public void RegisterSaveable(ISaveable saveable);
public void UnregisterSaveable(ISaveable saveable);
}
public interface ISaveable
{
string GetSaveId();
Dictionary<string, object> GetSaveData();
void LoadSaveData(Dictionary<string, object> data);
}
```
#### 4.3 - EinSoftworks.UI
| | | |
|--------------|----|-----------------------------------------------------------------------|
| Status | 🔴 | Incomplete |
| Priority | 🟢 | Low |
| Dependencies | ⚫ | EinSoftworks.Input, EinSoftworks.StateManagement, EinSoftworks.Events |
**Core Features:**
```csharp
public class UIManager : Control
{
public void ShowMenu(string menuName);
public void HideMenu(string menuName);
public void HideAllMenus();
public T GetMenu<T>(string menuName) where T : Control;
[Signal] public delegate void MenuShownEventHandler(string menuName);
[Signal] public delegate void MenuHiddenEventHandler(string menuName);
}
```
## Implementation Strategy
### Getting Started Checklist
Some high level checklist items to maybe follow while building these out.
**EinSoftworks.Input**
- [ ] Set up library repository structure
- [ ] Implement basic action queries (IsActionPressed, etc.)
- [ ] Add input mapping and saving/loading
- [ ] Create input buffer system
- [ ] Build validation game: Simple character movement
- [ ] Document all public APIs
- [ ] Test with multiple input devices
**EinSoftworks.Events**
- [ ] Implement global event system
- [ ] Create type-safe event bus
- [ ] Add event pooling for performance
- [ ] Build validation game: Decoupled player-camera system
- [ ] Document event naming conventions
- [ ] Test event performance under load
**EinSoftworks.StateManagement**
- [ ] Implement generic state machine
- [ ] Add transition system with conditions
- [ ] Create hierarchical state support
- [ ] Build validation game: Character with multiple states
- [ ] Document state design patterns
- [ ] Test state machine performance
**EinSoftworks.Physics**
- [ ] Implement raycast utilities
- [ ] Add shape casting methods
- [ ] Create trigger volume system
- [ ] Build validation game: Ground detection system
- [ ] Document physics best practices
- [ ] Test physics performance
**EinSoftworks.Camera**
- [ ] Implement base camera controller
- [ ] Add specialized camera types (FPS, 3rd person, orbit)
- [ ] Create camera effects (shake, zoom)
- [ ] Build validation game: Multiple camera modes
- [ ] Document camera usage patterns
- [ ] Test camera smoothness and responsiveness
### Validation Games Strategy
Perhaps create small, focused games to test each library combination:
#### Foundation Tests
- **Input Test**: Character that responds to all input types
- **Event Test**: Multiple systems communicating via events
- **State Test**: Character with idle/walk/run/jump states
#### Integration Tests
- **Physics Test**: Character with ground detection and jumping
- **Camera Test**: Switching between camera modes
- **Combined Test**: Third-person character with camera following
#### Advanced Tests
- **Movement Test**: Full 3D character controller
- **Interaction Test**: World with pickups and doors
- **Complete Game**: Small game using all built libraries
### Common Pitfalls to Avoid
#### 1. Circular Dependencies
```csharp
// ❌ BAD: Camera depends on Character, Character depends on Camera
public class Character { public Camera AttachedCamera; }
public class Camera { public Character Target; }
// ✅ GOOD: Use events or generic interfaces
public class Character { /* Publishes movement events */ }
public class Camera { public Node3D Target; } // Subscribes to events
```
#### 2. Over-Engineering Early
```csharp
// ❌ BAD: Complex inheritance hierarchy from the start
public abstract class BaseMovement<T> where T : IMovementConfig { }
// ✅ GOOD: Start simple, refactor when needed
public class CharacterController3D : CharacterBody3D { }
```
#### 3. Feature Creep
- Focus on core functionality first
- Add advanced features only after core is solid
- Each library should have a single, clear purpose
#### 4. Premature Optimization
- Build it working first
- Profile and optimize only when needed
- Don't sacrifice clarity for minor performance gains
## Long-Term Maintenance
### Versioning Strategy
- Use semantic versioning (major.minor.patch)
- Hardcore versioning adherence probably isn't necessary... should roughly keep versioning schema going just in case.
### Documentation
- Maintain comprehensive documentation