Skip to main content
BattleManager is the entry point for every match in Beast Card Clash. It extends StateMachine and is attached to the battle scene. It is responsible for constructing the human player, spawning AI bots, wiring up signal connections, and initializing the battlefield before the state machine begins managing turn flow.
BattleManager is a scene-level node, not an autoload. It exists only while the battle scene is active. For global singletons, see Autoloads.

Class overview

battle_manager.gd
class_name BattleManager extends StateMachine

Initializes players

Creates the human player from PlayerStats and generates 1–3 AI bots with random decks.

Wires the UI

Connects BattleUI to player data and disables the 3D dice (via BattleWorld) until the state machine permits a roll.

Connects signals

Links deck_updated on the human player to BattleUI.set_hand_from_deck so the hand rerenders automatically.

Feeds the state machine

Exposes the populated players array so the StateMachine can iterate over participants during each phase.

Properties

MAX_PLAYERS
int
required
Maximum number of participants in a single battle, including the human player and all bots. Default: 4.
battle_ui
BattleUI
required
Exported reference to the BattleUI node in the battle scene. Assign this in the Godot Inspector.
battle_world
BattleWorld
required
Exported reference to the BattleWorld node, which owns the 3D dice and rocks. BattleManager calls battle_world.set_dice(false) during setup_world() to disable dice interaction at match start.
player
Player
The single human Player instance. Populated by setup_player(). Use this reference anywhere you need to read or modify the human player’s state.
players
Array[Player]
All participants — the human player plus however many bots were created. The array is shuffled by setup_bots() to randomize turn order, so position 0 is not guaranteed to be the human player. The StateMachine iterates this array to drive turns.
rocks
Array[RockScene.Rock]
All rock objects placed in the battle scene. Declared for future use by battle states that need to reference world positions.

Methods

setup_player()

Creates the human Player from the globally stored PlayerStats, builds their deck, appends them to players, and connects the deck_updated signal to keep the hand display in sync.
func setup_player() -> void:
    player = Player.new(PlayerStats.player_name, PlayerStats.team, false)
    player.create_deck()
    players.append(player)
    player.randomize()  # Temporary
    player.deck_updated.connect(battle_ui.set_hand_from_deck)
The player.randomize() call is temporary scaffolding — it assigns a random state to the player for development and testing purposes. Remove or replace it with deterministic initialization before shipping.
The signal connection on the last line means any time the player’s deck changes (cards drawn, discarded, or reordered), BattleUI.set_hand_from_deck fires automatically with the updated deck. You do not need to call set_hand_from_deck manually after this point.

setup_bots()

Spawns between 1 and MAX_PLAYERS - 1 AI bots, each with a freshly generated deck. After all bots are added, the full players array is shuffled to randomize turn order.
func setup_bots() -> void:
    var bots_count := randi_range(1, MAX_PLAYERS - 1)
    for i in range(bots_count):
        var new_bot := Player.new()
        new_bot.create_deck()
        players.append(new_bot)
        print_debug("[BattleManager] Nuevo bot creado: %s!" % new_bot.player_name)
        # ! Temporal
        new_bot.randomize()

    players.shuffle()
    print_debug(
        "[BattleManager] %s jugadores en juego: %s"
        % [bots_count, players.map(func(p): return p.player_name)]
    )
bots_count
int
Chosen randomly via randi_range(1, MAX_PLAYERS - 1). With MAX_PLAYERS = 4, this produces 1, 2, or 3 bots per battle.
Bot Player instances are constructed with no arguments (Player.new()), so they receive auto-generated names. Human players pass PlayerStats.player_name and PlayerStats.team explicitly.

setup_ui()

Prepares the battle UI for the start of a match: refreshes all player stat panels, populates the human player’s hand from their current deck, and hides the end-of-game UI.
func setup_ui() -> void:
    battle_ui.refresh_player_stats(players)
    battle_ui.set_hand_from_deck(player.deck)
    battle_ui.set_end_ui(false)
Call setup_ui() after both setup_player() and setup_bots() have completed, so players is fully populated when refresh_player_stats iterates over it.

setup_world()

Configures the 3D world elements. Disables dice interaction at match start so the player cannot roll before the state machine permits it.
func setup_world() -> void:
    battle_world.set_dice(false)
BattleWorld.set_dice(enabled: bool) sets dice.clickable on the underlying Dice node. The battle state machine re-enables dice interaction at the start of the human player’s turn.

Initialization sequence

BattleStart calls all four setup methods in this order:
1

setup_player()

Create the human player, build their deck, and connect the deck_updatedset_hand_from_deck signal.
2

setup_bots()

Randomly generate 1–3 bots, append them to players, then shuffle players to determine turn order.
3

setup_ui()

Refresh stat panels for all players, seed the hand display, and hide the end-game UI.
4

setup_world()

Disable the 3D dice until the state machine enables it on the human player’s turn.

Signal wiring

The most important signal connection established by BattleManager is:
player.deck_updated.connect(battle_ui.set_hand_from_deck)
SignalSourceTargetEffect
deck_updatedPlayerBattleUI.set_hand_from_deckRerenders the hand display whenever the player’s deck changes
This one-liner keeps the Card System visuals in sync with game state without requiring manual UI refresh calls throughout your code.

Battle state machine

How the five-phase state machine consumes players and orchestrates turn flow.

Card system

How CardScene and the inner Card data class represent cards in the hand.

Battle mechanics

Player-facing rules for how a battle round works.

Autoloads

Global singletons (SceneManager, MusicManager, FlagsManager) available to BattleManager.

Build docs developers (and LLMs) love