Godot Core System

repository·main·Indexed 43 days ago

https://github.com/ligameacademy/godot_core_system

A modular and extensible framework for Godot 4.4+ designed to streamline game development. It provides a centralized CoreSystem singleton to manage essential game systems including State Machine, Audio, Input (with buffering and recording), Save (supporting Resource, JSON, and Binary formats), Scene, Config, and Logger systems, along with utilities like FrameSplitter and Async IO.

Tokens
55.5K
Snippets
158
Records
248
Agent score
50%

What's inside Godot Core System

  1. Overview of Godot Core System modules

    main

    The framework is divided into specialized systems and utilities. Use the following guide to identify which module fits your needs:

    Core Systems

    • State Machine System: Game state management and transitions.
    • Audio System: Sound and music management.
    • Input System: Input control and event handling.
    • Logger System: Logging and debugging.
    • Resource System: Resource loading and management.
    • Scene System: Scene switching and management.
    • Tag System: Object tagging and categorization.
    • Trigger System: Event-driven triggers and conditions.
    • Config System: Configuration management.
    • Save System: Game save management.

    Utilities

    • Frame Splitter: Performance optimization tool for distributing tasks.
    • Async IO Manager: Non-blocking file I/O.
    • Threading System: Simplified multi-threading management.
    • Random Picker: Weighted random selection tool.
  2. Overview of Godot Core System components

    main

    The Godot Core System is a modular framework for Godot 4.4+ consisting of several specialized systems and utility tools:

    Core Systems (via ManagerOfManagers)

    • State Machine System: Game logic state management.
    • Audio System: Audio management and transitions.
    • Input System: Input handling and event management.
    • Logger System: Multi-channel logging.
    • Resource System: Resource loading and management.
    • Scene System: Scene transitions and management.
    • Tag System: Object tagging and classification.
    • Trigger System: Event-driven triggers and conditions.
    • Save System: Game save management.
    • Config System: Configuration management.

    Utility Tools

    • Frame Splitter: Performance optimization by spreading heavy tasks across multiple frames.
    • Async IO Manager: Non-blocking file read/write with strategic processing.
    • Threading System: Simplified multi-threading management.
    • Random Picker: Weighted random selection tool.
  3. Overview of the Input System components

    main

    The Input System is composed of several specialized subsystems designed to handle different aspects of player input in Godot. Depending on your requirements, you can use specific modules for axis handling, state tracking, buffering, or recording:

    • Virtual Axis System: Handles axis-based input, such as character movement and camera control.
    • Input State System: Tracks and manages input states, supporting timestamps and input intensity.
    • Input Buffer System: Provides an input buffering mechanism to optimize game feel (e.g., making combos or timing-sensitive actions more forgiving).
    • Input Recorder: Records and replays input sequences, useful for game replays and debugging.
    • Event Processor: Handles and filters input events, managing event priorities.
  4. Overview of the Input System Subsystems

    main

    The Input System is composed of several specialized subsystems designed to handle different aspects of player input in Godot. Depending on your requirements, you can use one or more of the following components:

    • Virtual Axis System: Handles axis-based input (e.g., analog sticks, triggers).
    • Input State System: Tracks the current state of inputs (e.g., pressed, released, held).
    • Input Buffer System: Manages input buffering (e.g., queuing inputs for fighting game combos or frame-perfect actions).
    • Input Recorder: Provides functionality for recording and replaying input sequences.
    • Input Event Processor: Handles the processing of raw input events.

    Each subsystem provides its own functional introduction, API reference, usage examples, best practices, and important notes.

  5. Directory structure of the Input System Demo

    main

    The input_demo folder is organized by sub-module, with each module containing a .tscn scene and a .gd script for implementation details:

    input_demo/
    ├── basic/                # Basic functionality demo
    │   ├── basic_demo.tscn  # Basic demo scene
    │   └── basic_demo.gd    # Basic demo script
    ├── virtual_axis/         # Virtual axis system demo
    │   ├── character.tscn   # Character scene
    │   └── movement_demo.gd # Movement demo script
    ├── input_state/         # Input state system demo
    │   ├── combo_demo.tscn  # Combo demo scene
    │   └── combo_demo.gd    # Combo demo script
    ├── input_buffer/        # Input buffer system demo
    │   ├── buffer_demo.tscn # Buffer demo scene
    │   └── buffer_demo.gd    # Buffer demo script
    ├── input_recorder/      # Input recorder demo
    │   ├── recorder_demo.tscn # Recorder demo scene
    │   └── recorder_demo.gd   # Recorder demo script
    └── event_processor/     # Event processor demo
        ├── processor_demo.tscn # Processor demo scene
        └── processor_demo.gd   # Processor demo script
    input_demo/
    ├── basic/
    ├── virtual_axis/
    ├── input_state/
    ├── input_buffer/
    ├── input_recorder/
    └── event_processor/
  6. What is the Virtual Axis System

    main
    The Virtual Axis System provides a flexible way to handle axis-based input, such as character movement or camera control. It allows you to combine multiple discrete input actions (like keyboard presses or controller buttons) into a single 2D virtual axis (X and Y). The system includes built-in support for deadzones and sensitivity adjustments to refine input response.
  7. What is the FrameSplitter and when to use it

    main

    The FrameSplitter is a performance optimization utility designed to prevent game stuttering (lag) caused by heavy computations. It works by spreading time-consuming tasks across multiple frames instead of executing them all at once in a single frame.

    Key Features:

    • Automatic Frame Splitting: Distributes large tasks over multiple frames.
    • Dynamic Adjustment: Automatically adjusts the number of items processed per frame based on actual execution time.
    • Progress Feedback: Emits signals to facilitate UI progress bars.
    • Multiple Processing Modes: Supports arrays, ranges, iterators, and custom batch processing.

    Common Use Cases:

    • Resource Loading: Loading large batches of resources without freezing the game.
    • Map Generation: Generating large maps tile-by-tile.
    • Batch Data Processing: Handling large datasets.
    • AI Updates: Updating AI behaviors for many entities in chunks.
  8. What is Frame Splitter and how does it work?

    main

    Frame Splitter is a performance optimization tool designed to prevent game stuttering during heavy computations. It works by distributing time-consuming operations across multiple frames instead of executing them all at once.

    Key Mechanisms:

    • Automatic Frame Distribution: Splits large tasks across frames.
    • Dynamic Adjustment: Automatically scales the workload per frame. It reduces the workload if execution time exceeds the limit and increases it if execution time is below 80% of the limit.
    • Performance Trade-off: While it extends the total time required to finish a task, it ensures the game remains smooth and responsive.
  9. Understand the InputState core class

    main

    The InputState class is the primary manager for tracking input action states. It maintains an ActionState data structure for every registered action, allowing you to track not just whether a button is pressed, but also the timing and intensity of the input.

    Each action is represented by an ActionState containing:

    • pressed: Boolean indicating if the action is currently active.
    • just_pressed: Boolean indicating if the action was triggered in the current frame.
    • just_released: Boolean indicating if the action was released in the current frame.
    • strength: A float (0.0 to 1.0) representing input intensity (e.g., trigger pressure).
    • press_time: The timestamp of the current press.
    • last_press_time: The timestamp of the previous press.
    • last_release_time: The timestamp of the last release.
    class ActionState:
        var pressed: bool        # Current pressed state
        var just_pressed: bool   # Just pressed this frame
        var just_released: bool  # Just released this frame
        var strength: float      # Input strength (0.0 - 1.0)
        var press_time: float    # Current press timestamp
        var last_press_time: float    # Last press timestamp
        var last_release_time: float  # Last release timestamp
  10. Use the Virtual Axis System for input handling

    main

    The Virtual Axis System provides a flexible way to handle axis-based input (like character movement or camera control) by combining multiple input actions into a single 2D axis. It supports configurable deadzones and sensitivity, and provides real-time updates via signals.

    Core Features

    • 2D Axis Support: Handles both X and Y axes.
    • Configurable Parameters: Adjust _sensitivity and _deadzone to fine-tune input response.
    • Real-time Updates: Access current values via methods or listen to the axis_changed signal.
  11. Execute sequential asynchronous tasks with SingleThread

    main

    SingleThread is a lightweight wrapper for managing a single worker thread that executes tasks in the exact order they are added. It is ideal for workflows where Task B must only start after Task A has completed.

    Note: SingleThread does not support await. If you need to introduce delays within a task, use OS.delay_msec().

    func _ready() -> void:
        var thread = SingleThread.new()
        
        # Connect signals to handle results
        thread.task_completed.connect(_on_task_completed)
        thread.task_error.connect(_on_task_error)
        thread.thread_finished.connect(_on_thread_finished)
        
        # Add multiple tasks to be executed sequentially
        thread.add_task(
            func(): return load_data(),
            func(result): process_data(result)
        )
        
        thread.add_task(
            func(): return process_more_data(),
            func(result): finalize_data(result)
        )
  12. Normalize and merge input events

    main

    To handle different input types uniformly, you can transform raw InputEvent objects into a standardized Dictionary format. This process, known as normalization, allows the rest of your system to work with a consistent data structure.

    Normalization Example:

    func _normalize_event(event: InputEvent) -> Dictionary:
        return {
            "type": _get_event_type(event),
            "action": _get_event_action(event),
            "strength": event.get_action_strength(),
            "timestamp": Time.get_ticks_msec()
        }

    Event Merging: You can also implement logic to merge duplicate or conflicting events (e.g., combining two simultaneous button presses into one state) using a _merge_events function.

    func _merge_events(event1: Dictionary, event2: Dictionary) -> Dictionary:
        # Merge events based on rules
        return {
            "type": event1.type,
            "action": event1.action,
            "strength": max(event1.strength, event2.strength),
            "timestamp": event1.timestamp
        }