Files
documentation/planning/UTILITY_PLANNING.md
2025-10-23 12:03:20 -05:00

23 KiB

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

  • Build Small Games: Create tiny games to test each library combination
  • 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

Priority: 🔴 Critical - Build First Dependencies: EinSoftworks.Utilities only Estimated Timeline: 1-2 weeks

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:

// 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

Priority: 🔴 Critical - Build Second Dependencies: EinSoftworks.Utilities only Estimated Timeline: 1 week

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:

// 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

Priority: 🔴 Critical - Build Third Dependencies: EinSoftworks.Utilities, EinSoftworks.Events Estimated Timeline: 1-2 weeks

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:

// 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.Physics

Priority: 🟡 High Dependencies: EinSoftworks.Utilities, EinSoftworks.Events Estimated Timeline: 1-2 weeks

Why Build Fourth:

  • Nearly all 3D games need physics utilities
  • Independent of complex game systems
  • Provides foundation for character controllers and interaction systems
  • Can be validated independently

Core Features:

// Raycast utilities
public static class PhysicsUtils
{
    public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance,
                              uint collisionMask = uint.MaxValue);
    public static RaycastHit RaycastWithInfo(Vector3 origin, Vector3 direction, float maxDistance);
    public static RaycastHit[] RaycastAll(Vector3 origin, Vector3 direction, float maxDistance);

    // Shape casting
    public static bool SphereCast(Vector3 origin, float radius, Vector3 direction, float maxDistance);
    public static bool BoxCast(Vector3 origin, Vector3 size, Vector3 direction, float maxDistance);

    // Overlap detection
    public static Node3D[] OverlapSphere(Vector3 center, float radius, uint collisionMask);
    public static Node3D[] OverlapBox(Vector3 center, Vector3 size, uint collisionMask);
}

// Physics materials management
public class PhysicsMaterialManager : Node
{
    public void RegisterMaterial(string name, PhysicsMaterial material);
    public PhysicsMaterial GetMaterial(string name);
    public void ApplyMaterial(RigidBody3D body, string materialName);
}

// Trigger volume system
public partial class TriggerVolume : Area3D
{
    [Signal] public delegate void BodyEnteredEventHandler(Node3D body);
    [Signal] public delegate void BodyExitedEventHandler(Node3D body);

    public bool IsBodyInside(Node3D body);
    public Node3D[] GetBodiesInside();
}

Validation Game Ideas:

  • Character that detects ground beneath them
  • Interaction system using raycasts
  • Trigger volumes that activate when player enters

2.2 EinSoftworks.Camera

Priority: 🟡 High Dependencies: EinSoftworks.Input, EinSoftworks.Events, EinSoftworks.StateManagement Estimated Timeline: 2-3 weeks

Why Build Fifth:

  • 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:

// 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

Priority: 🟡 Medium-High Dependencies: EinSoftworks.Input, EinSoftworks.Physics, EinSoftworks.StateManagement, EinSoftworks.Events Estimated Timeline: 2-4 weeks

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:

// 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

Priority: 🟡 Medium Dependencies: EinSoftworks.Input, EinSoftworks.Physics, EinSoftworks.Events Estimated Timeline: 1-2 weeks

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:

// 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

Priority: 🟢 Medium-Low Dependencies: EinSoftworks.StateManagement, EinSoftworks.Events Estimated Timeline: 2-3 weeks

Core Features:

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

Priority: 🟢 Medium-Low Dependencies: EinSoftworks.StateManagement, EinSoftworks.SceneManagement Estimated Timeline: 2-3 weeks

Core Features:

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

Priority: 🟢 Low Dependencies: EinSoftworks.Input, EinSoftworks.StateManagement, EinSoftworks.Events Estimated Timeline: 3-4 weeks

Core Features:

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

Week 1-2: 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

Week 3: 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

Week 4-5: 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

Week 6-7: 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

Week 8-10: 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

Quality Assurance Process

For Each Library:

  1. API Design Review

    • Is the API intuitive and consistent?
    • Are there any obvious missing features?
    • Does it follow C# naming conventions?
  2. Dependency Check

    • Does it only depend on earlier libraries in the plan?
    • Are there any circular dependencies?
    • Can dependencies be reduced without losing functionality?
  3. Performance Testing

    • Profile the library in a realistic game scenario
    • Identify and optimize any performance bottlenecks
    • Ensure memory allocation is minimal during gameplay
  4. Integration Testing

    • Build a small game that uses multiple libraries together
    • Verify that libraries work well in combination
    • Test edge cases and error conditions
  5. Documentation Review

    • Are all public APIs documented?
    • Are there usage examples for complex features?
    • Is the library architecture clearly explained?

Validation Games Strategy

Create small, focused games to test each library combination:

Foundation Tests (Weeks 1-5)

  • 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 (Weeks 6-10)

  • Physics Test: Character with ground detection and jumping
  • Camera Test: Switching between camera modes
  • Combined Test: Third-person character with camera following

Advanced Tests (Weeks 11+)

  • 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

// ❌ 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

// ❌ 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

Success Metrics

Per Library:

  • API is intuitive and well-documented
  • Zero dependencies on later libraries
  • Validation game demonstrates all major features
  • Performance is acceptable for real games
  • Code coverage > 80% through validation games

Overall Ecosystem:

  • Can build a complete 3D game using only these libraries
  • Libraries work well together without conflicts
  • Development time significantly reduced for new projects
  • Other developers can understand and use the libraries

Long-Term Maintenance

Versioning Strategy

  • Use semantic versioning (major.minor.patch)
  • Major version changes for breaking API changes
  • Minor version changes for new features
  • Patch version changes for bug fixes

Backward Compatibility

  • Maintain backward compatibility within major versions
  • Provide migration guides for major version upgrades
  • Deprecate features before removing them

Community and Documentation

  • Maintain comprehensive documentation
  • Create tutorial projects demonstrating library usage
  • Establish contribution guidelines if open-sourcing
  • Regular review and updates based on real-world usage