GBALATRO/balatro-gba

Enforce matching substate enums to functions

Open

#583 opened on Jul 6, 2026

 (0 comments) (1 reaction) (0 assignees)C (95 forks)auto 404
Refactorgood first issue

Repository metrics

Stars
 (2,281 stars)
PR merge metrics
 (Avg merge 4d 5h) (21 merged PRs in 30d)

Description

In the main state machine, the matching of the functions to the states is enforced in def_state_info_table.h, e.g.

DEF_STATE_INFO(GAME_STATE_MAIN_MENU,     game_main_menu_on_init,    game_main_menu_on_update,    game_main_menu_on_exit   )

However, for the substates of the various states the definitions of the states and the functions are separate, e.g.

enum GameShopStates
{
    GAME_SHOP_INTRO,
    GAME_SHOP_ACTIVE,
    GAME_SHOP_SHOW_CARD_DESC,
    GAME_SHOP_HIDE_CARD_DESC,
    GAME_SHOP_EXIT,
    GAME_SHOP_MAX
};

static void game_shop_intro(void);
static void game_shop_process_user_input(void);
static void game_shop_show_card_desc(void);
static void game_shop_hide_card_desc(void);
static void game_shop_outro(void);

static StateInfo shop_state_actions[GAME_SHOP_MAX] = {
    STATE_INFO_UPDATE_FN_ONLY(game_shop_intro),
    STATE_INFO_UPDATE_FN_ONLY(game_shop_process_user_input),
    STATE_INFO_UPDATE_FN_ONLY(game_shop_show_card_desc),
    STATE_INFO_UPDATE_FN_ONLY(game_shop_hide_card_desc),
    STATE_INFO_UPDATE_FN_ONLY(game_shop_outro),
};

so it relies on the definitions being at the same order, which can easily go out of sync. This can be mitigated by using the format

static StateInfo shop_state_actions[GAME_SHOP_MAX] = {
    [GAME_SHOP_INTRO] = STATE_INFO_UPDATE_FN_ONLY(game_shop_intro),
...
};

So the connection between state and function is explicit and enforced in the code.

Contributor guide