Web Overlay

Adding Configs

How to define a config struct and register it with the config system.

Adding a new config requires changes in two places — the C++ backend to define and register the struct, and the React frontend to create the page that interacts with it.


1. Define the Config Struct

Create a header file for your config, for example src-cheat/src/misc/config.h:

#pragma once
#include <nlohmann/json.hpp>

namespace misc
{

struct MiscConfig
{
    bool walkspeed_enabled = false;
    float walkspeed = 16.0f;

    bool noclip_enabled = false;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(
        MiscConfig,
        walkspeed_enabled,
        walkspeed,
        noclip_enabled)
};

inline MiscConfig g_config;

} // namespace misc

NLOHMANN_DEFINE_TYPE_INTRUSIVE generates the to_json and from_json functions automatically — every field listed in the macro is included in serialization and the names must match exactly what the UI expects.


2. Register in main.cpp

Include your config header and register it after set_directory and before setup_ipc:

#include "misc/config.h"

config::g_config.register_config("misc", misc::g_config);

Callbacks

register_config accepts two optional callbacks as the third and fourth arguments. Pass nullptr if you don't need them.

on_set fires after the config struct has already been updated with the new values pushed from the UI. This is where you react to changes — for example, applying the new walkspeed to the player immediately when the UI slider changes:

config::g_config.register_config(
    "misc",
    misc::g_config,
    nullptr,
    [](const nlohmann::json &)
    {
        // g_config is already updated at this point so you can
        // read the new values directly from the struct

        if (misc::g_config.walkspeed_enabled)
        {
            misc::set_walkspeed(misc::g_config.walkspeed);
        }
        else
        {
            misc::reset_walkspeed();
        }

        if (misc::g_config.noclip_enabled)
        {
            misc::enable_noclip();
        }
        else
        {
            misc::disable_noclip();
        }
    });

Without an on_set callback the config struct is still updated correctly — the callback is only needed if something needs to immediately react to the change. In this case without it, toggling walkspeed in the UI would update the config value but never actually apply it to the player until the next time your feature loop reads from g_config.

on_get fires just before the config is sent to the UI. It's less commonly needed but useful if you want to inject a live value into the config before it's read — for example overwriting walkspeed with the player's actual current speed so the UI always shows the real value rather than whatever was last set:

config::g_config.register_config(
    "misc",
    misc::g_config,
    [](const nlohmann::json &)
    {
        // sync the stored value with the real in-game value
        // before it gets sent to the UI
        misc::g_config.walkspeed = misc::get_current_walkspeed();
    },
    nullptr);

Note that on_get fires before serialization so any changes you make to g_config inside it will be reflected in what the UI receives.

On this page