Skip to content

Game States

Yet Another Bingo has several states that it transitions through during a round. These drive most behavior changes throughout the mod. You can subscribe to state transitions as an event, tell the mod when to change state, and even create your own states throught the API.

Here is a graph of what the states currently look like:

flowchart TD
    UNINITIALIZED -->|init| PREGAME
	PREGAME -->|/bingo lobby edit| LOBBY_EDITOR
	LOBBY_EDITOR -->|/bingo lobby save| PREGAME
    PREGAME -->|GameAction.START| STARTING
    STARTING -->|GameAction.START| PRELOADING
    PRELOADING -->|GameAction.START| LOADING
    LOADING -->|GameAction.START| COUNTDOWN
    COUNTDOWN -->|GameAction.START| PLAYING
    PLAYING -->|GameAction.END| POSTGAME
    PLAYING -->|GameAction.RESET| PREGAME
    POSTGAME -->|GameAction.RESET| PREGAME

Reference the states available under GameState.Companion.

Using BingoEvents.STATE_CHANGED:

BingoEvents.STATE_CHANGED.register { (from, to) ->
println("Received: state changed from ${from} to ${to}")
}

Using BingoEvents.onStateChanged:

BingoEvents.onStateChanged(GameState.PLAYING).register {
println("Received: state changed to PLAYING")
}

With an API instance, you can write to IBingoGame.state to directly change the state.

BingoApi.INSTANCE?.game?.state = GameState.PREGAME

Alternatively, if the state change is a GameAction, you can use IBingoGame.changeState…

BingoApi.INSTANCE?.game?.changeState(GameAction.START)

To define a custom state, you’ll construct a new GameState with your own identifier.

If the state is only entered by your mod, then you can use game.state = MY_STATE directly. However, a common use case is to insert a state after a certain action, such as displaying an additional menu or sequence when starting or ending a game.

To achieve this, you can use GameAction.insertAfter to insert your state after an existing state.

val STATE_CHOOSE_EFFECTS = GameState(
identifier = "mymod:choose_effects",
status = BingoGameStatus.PREGAME,
)
object Main : DedicatedServerModInitializer {
override fun onInitializeServer() {
GameAction.START.insertAfter(GameState.PREGAME, STATE_CHOOSE_EFFECTS);
BingoEvents.onStateChanged(STATE_CHOOSE_EFFECTS).register {
mymod.beginChoosingEffects().onComplete {
BingoApi.INSTANCE!!.game.changeState(GameAction.START)
}
}
}
}
  1. Note 1, for line 1: Define your GameState with a unique identifier and status.
  2. Note 2, for line 8: Insert the state so that it's entered on START immediately after PREGAME.
  3. Note 3, for line 10: Register a listener for whenever the mod enters your GameState.
  4. Note 4, for line 12: Once your state is complete, continue GameAction.START to proceed to the next state.

With this, any method of starting the game (using the ready-up timer, running /bingo start, or punching the start button) will enter STATE_CHOOSE_EFFECTS.

Additionally, any mod that needs a similar integration can do the same thing. By calling changeState(GameAction.START), the game proceeds to the next registered state, and all states are visited in order.