How does the Controls module work?

From what I’ve seen, the Controls class can be summarized by these three functions:

void Set(unsigned buttons, bool down = true)
{
    if (down)
        buttons_ |= buttons;
    else
        buttons_ &= ~buttons;
}

/// Check if a button is held down.
bool IsDown(unsigned button) const
{
    return (buttons_ & button) != 0;
}

/// Check if a button was pressed on this frame. Requires previous frame's controls.
bool IsPressed(unsigned button, const Controls &previousControls) const
{
    return (buttons_ & button) != 0 && (previousControls.buttons_ & button) == 0;
}

How is this code able to keep track of the state of any number of buttons in a single button variable? Is this the standard way to keep track of user input?

It is supposed that user don’t need more than 32 separate controls.

It is. Note that you always can pass as much data as you need in extraData_

I guess my question is more about how buttons_, which is just an unsigned value, can keep track of multiple values.

It’s not just unsigned integer, it’s up to 32 binary controls in bitfield :wink:
But it isn’t designed to keep multiple integers like keycodes, that’s true. Only multiple bits.

What’s the advantage to using bitfields? They seem very confusing, especially for beginners.

Bitfield is small and enough for the most cases, that’s all. If you don’t like bitfields or it’s not enough for you, just push whatever you want into extraData_.

If you just want to make things work at first (without networking down the pipeline) you could just read your input directly from the Input SubSystem with:

GetSubsystem<Input>()->GetKeyDown(int key)