From bc4455ad1b1d880d6b9063e05cb54159d639dd2e Mon Sep 17 00:00:00 2001 From: Will Stuckey Date: Thu, 23 Oct 2025 12:03:20 -0500 Subject: [PATCH] added utilities planning document, first draft --- planning/UTILITY_PLANNING.md | 692 +++++++++++++++++++++++++++++++++++ 1 file changed, 692 insertions(+) create mode 100644 planning/UTILITY_PLANNING.md diff --git a/planning/UTILITY_PLANNING.md b/planning/UTILITY_PLANNING.md new file mode 100644 index 0000000..fa7853f --- /dev/null +++ b/planning/UTILITY_PLANNING.md @@ -0,0 +1,692 @@ +# 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:** +```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 +**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:** +```csharp +// Global event system +public static class GameEvents +{ + // Player events + public static event Action PlayerMoved; + public static event Action PlayerHealthChanged; + public static event Action PlayerDied; + + // Game state events + public static event Action StateChanged; + public static event Action SceneChanged; + public static event Action GamePaused; + public static event Action GameResumed; + + // Input events + public static event Action ActionPressed; + public static event Action ActionReleased; +} + +// Type-safe event bus +public class EventBus where T : class +{ + public void Subscribe(Action handler); + public void Unsubscribe(Action handler); + public void Publish(T eventData); + public void Clear(); +} + +// Event pooling for performance +public class PooledEvent 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:** +```csharp +// Generic state machine +public class StateMachine 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 condition); + public void AddAnyTransition(T to, Func condition); + public void AddTransition(T from, T to, string triggerEvent); + + // Events + public event Action 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 : StateMachine where T : class +{ + public void AddSubState(T parentState, StateMachine subStateMachine); + public StateMachine 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:** +```csharp +// 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:** +```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 +**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:** +```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 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:** +```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 +**Priority:** 🟢 Medium-Low +**Dependencies:** EinSoftworks.StateManagement, EinSoftworks.Events +**Estimated Timeline:** 2-3 weeks + +**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 +**Priority:** 🟢 Medium-Low +**Dependencies:** EinSoftworks.StateManagement, EinSoftworks.SceneManagement +**Estimated Timeline:** 2-3 weeks + +**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 GetSaveData(); + void LoadSaveData(Dictionary data); +} +``` + +#### 4.3 EinSoftworks.UI +**Priority:** 🟢 Low +**Dependencies:** EinSoftworks.Input, EinSoftworks.StateManagement, EinSoftworks.Events +**Estimated Timeline:** 3-4 weeks + +**Core Features:** +```csharp +public class UIManager : Control +{ + public void ShowMenu(string menuName); + public void HideMenu(string menuName); + public void HideAllMenus(); + public T GetMenu(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 +```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 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