604 lines
22 KiB
Markdown
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
|