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
Subscribing to state transitions
Section titled “Subscribing to state transitions”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")}Changing the state
Section titled “Changing the state”With an API instance, you can write to IBingoGame.state to directly change the state.
BingoApi.INSTANCE?.game?.state = GameState.PREGAMEAlternatively, if the state change is a GameAction, you can use IBingoGame.changeState…
BingoApi.INSTANCE?.game?.changeState(GameAction.START)Creating a custom state
Section titled “Creating a custom state”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) } } }}- Note 1, for line 1: Define your
GameStatewith a unique identifier and status. - Note 2, for line 8: Insert the state so that it's entered on
STARTimmediately afterPREGAME. - Note 3, for line 10: Register a listener for whenever the mod enters your
GameState. - Note 4, for line 12: Once your state is complete, continue
GameAction.STARTto 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.