A live parameter tuning library for C++.
Edit a config file โ See changes instantly in your running program. No rebuild required.
๐ STB-style Single Header Library
Just#define LIVETUNER_IMPLEMENTATIONin one.cppfile before including.
All other files simply#include "LiveTuner.h"โ noWindows.hpollution, no linker headaches!
Tired of the edit โ compile โ run โ check โ repeat cycle just to tweak a single value?
โ Traditional workflow:
Change value โ Recompile (30 sec~) โ Restart โ Test โ Repeat...
โ
With CppLiveTuner:
Change value โ Save file โ See result instantly!
CppLiveTuner eliminates recompilation entirely for parameter tuning. Whether you're adjusting game physics, tweaking shader values, or fine-tuning UI animations, you'll see results in real-time.
| Use Case | Example |
|---|---|
| ๐ฎ Game Development | Tweak jump height, movement speed, spawn rates while playing |
| ๐จ Graphics/Shaders | Adjust exposure, bloom, color grading in real-time |
| ๐ค Robotics/Simulation | Tune PID parameters, sensor thresholds live |
| ๐ง Debug/Profiling | Toggle debug displays, adjust log levels on the fly |
| Feature | Description |
|---|---|
| โก Zero Recompilation | Change parameters while the program is running |
| ๐ Header-only | Single file, no dependencies. Just #include and go |
| ๐ก๏ธ STB-style | No Windows.h pollution in your project |
| ๐ฏ Non-blocking API | Perfect for game loops and real-time apps |
| ๐ Multiple Formats | JSON, YAML, INI, plain text |
| ๐๏ธ Event-driven Watching | Native OS APIs (inotify/FSEvents/ReadDirectoryChanges) |
| ๐งต Thread-safe | Full mutex protection |
| ๐ Cross-platform | Windows, Linux, macOS |
| ๐งช Testable Design | DI support, mock interfaces, test fixtures |
| ๐ nlohmann/json Support | Optional adapter for nlohmann/json users |
Just copy one file โ that's it!
# Option 1: Copy directly
cp LiveTuner.h /your/project/include/
# Option 2: Git submodule
git submodule add https://github.com/andogensi/CppLiveTuner.git vendor/CppLiveTuner// In main.cpp (or ONE dedicated file)
#define LIVETUNER_IMPLEMENTATION
#include "LiveTuner.h"// In all other files โ just include, no Windows.h pollution!
#include "LiveTuner.h"#define LIVETUNER_IMPLEMENTATION
#include "LiveTuner.h"
int main() {
float speed = 1.0f;
while (running) {
tune_try(speed); // โ Checks params.txt, updates if changed
player.move(speed);
}
}Edit params.txt while running:
2.5
โ speed instantly becomes 2.5! ๐
#define LIVETUNER_IMPLEMENTATION
#include "LiveTuner.h"
int main() {
livetuner::Params params("config.json");
float speed = 1.0f;
float gravity = 9.8f;
bool debug = false;
// Bind variables โ they auto-update when file changes!
params.bind("speed", speed, 1.0f);
params.bind("gravity", gravity, 9.8f);
params.bind("debug", debug, false);
while (running) {
params.update(); // โ All bound variables updated automatically!
player.move(speed);
physics.setGravity(gravity);
if (debug) showDebugInfo();
}
}Edit config.json while running:
{
"speed": 2.5,
"gravity": 15.0,
"debug": true
}โ All three values update instantly! ๐
# GCC / MinGW (C++17+)
g++ -std=c++17 your_program.cpp -I include -o program
# MSVC (C++17+)
cl /std:c++17 your_program.cpp /I include
# Linux (requires pthread)
g++ -std=c++17 your_program.cpp -I include -pthread -o program| Function | Description |
|---|---|
tune_init(path) |
Set parameter file (default: params.txt) |
tune_try(value) |
Non-blocking: Update if changed, returns true if updated |
tune(value) |
Blocking: Wait until value is available |
tune_timeout(value, dur) |
Returns false if timeout |
tune_async<T>() |
Returns std::future<T> |
tune_async<T>(callback) |
Async with callback |
tune_set_event_driven(bool) |
Enable/disable event-driven mode |
| Function | Description |
|---|---|
Params(path, format) |
Constructor (format: Auto/Json/Yaml/KeyValue/Plain) |
bind(name, var, default) |
Bind variable to parameter |
update() |
Non-blocking: Update all bindings if changed |
get<T>(name) |
Get as std::optional<T> |
get_or<T>(name, default) |
Get with default value |
on_change(callback) |
Set change callback |
start_watching() / poll() |
Background file monitoring |
| Format | Extension | Example |
|---|---|---|
| JSON | .json |
{"speed": 1.5, "debug": true} |
| YAML |
.yaml, .yml |
speed: 1.5 |
| INI | .ini, .cfg |
speed = 1.5 |
| Plain Text | .txt |
1.5 |
โ ๏ธ YAML Limitation: Only simplekey: valuepairs are supported. No nested objects, arrays, or advanced YAML features. See details below.
๐ Format Examples (click to expand)
{
"speed": 1.5,
"gravity": 9.8,
"debug": true
}[!WARNING] CppLiveTuner is NOT a full YAML parser!
Only simple
key: valuepairs are supported. Nested objects, arrays, multi-line strings, and other advanced YAML features will silently fail or produce unexpected results.For complex configurations, use JSON instead.
โ Supported:
# Comments are supported
speed: 1.5
gravity: 9.8
debug: true
name: "player1"
---
# Document markers are ignoredโ NOT Supported:
# Nested structures
player:
speed: 1.5 # โ Nested objects not supported
position:
x: 100 # โ Multi-level nesting not supported
# Arrays/Lists
items: # โ Arrays not supported
- sword
- shield
scores: [1, 2, 3] # โ Inline arrays not supported
# Multi-line strings
description: | # โ Block scalars not supported
This is a
multi-line text
# Anchors and aliases
defaults: &defaults # โ Anchors not supported
speed: 1.0๐ก Need full YAML support?
Use JSON format instead, or integrate a full YAML parser library (like yaml-cpp) and convert to JSON before passing to CppLiveTuner.
speed = 1.5
gravity = 9.8
debug = true1.5
CppLiveTuner uses native OS APIs for maximum efficiency:
| OS | API | Latency |
|---|---|---|
| Windows | ReadDirectoryChangesW |
~1ms |
| Linux | inotify |
~1ms |
| macOS | FSEvents |
~1ms |
| Polling ๐ข | Event-Driven โก | |
|---|---|---|
| CPU Usage | High (constant) | Near zero |
| Latency | 50-100ms | Real-time |
| SSD Impact | Wear over time | None |
float jump_height = 10.0f, move_speed = 5.0f;
params.bind("jump_height", jump_height);
params.bind("move_speed", move_speed);
while (game_running) {
params.update();
player.jump(jump_height); // Tweak while playing!
player.move(move_speed);
}float exposure = 1.0f, bloom = 0.8f;
params.bind("exposure", exposure);
params.bind("bloom_threshold", bloom);
while (rendering) {
params.update();
shader.setUniform("exposure", exposure);
shader.setUniform("bloom", bloom);
}bool show_fps = true, show_hitboxes = false;
params.bind("show_fps", show_fps);
params.bind("show_hitboxes", show_hitboxes);
params.on_change([]() {
std::cout << "Debug settings changed!\n";
});CppLiveTuner supports dependency injection for enterprise-grade testability.
๐ง Testing Patterns (click to expand)
TEST(MyTest, TestSomething) {
livetuner::TestFixture fixture; // Auto-reset state
tune_init("test.txt");
// Test runs in isolation
}class ConfigManager {
livetuner::IParams& params_;
public:
explicit ConfigManager(livetuner::IParams& p) : params_(p) {}
float get_speed() { return params_.get_or("speed", 1.0f); }
};
// Production
livetuner::Params real_params("config.json");
livetuner::ParamsAdapter adapter(real_params);
ConfigManager config(adapter);
// Test with mock
class MockParams : public livetuner::IParams { /* ... */ };void test_thread_1() {
livetuner::LiveTuner tuner("test1.txt");
livetuner::ScopedContext ctx(tuner, params);
game_loop(); // Uses test1.txt (thread-local)
}Preprocessor Options (click to expand)
#define LIVETUNER_USE_EXTERNAL_PICOJSON
#include "picojson.h"
#include "LiveTuner.h"#define LIVETUNER_USE_NLOHMANN_JSON
#include <nlohmann/json.hpp>
#define LIVETUNER_IMPLEMENTATION
#include "LiveTuner.h"
livetuner::NlohmannParams params("config.json");#define LIVETUNER_NO_WIN32_LEAN // Keep full Windows.h
#define LIVETUNER_NO_NOMINMAX // Keep min/max macros
#include "LiveTuner.h"// Disable default stderr logging
#define LIVETUNER_ENABLE_DEFAULT_LOGGING 0
#include "LiveTuner.h"
// Or use custom logger
livetuner::set_log_callback([](LogLevel lvl, const std::string& msg) {
MyEngine::Log(lvl, msg);
});CppLiveTuner/
โโโ include/
โ โโโ LiveTuner.h # ๐ฏ Main header (just include this!)
โโโ examples/
โ โโโ example.cpp # Usage examples
โโโ Test/ # Comprehensive test suite
โโโ cmake/ # CMake support files
โโโ README.md
| Problem | Solution |
|---|---|
| File not detected | Use absolute paths, check permissions |
| Values not updating | Verify JSON syntax, ensure update() is called |
| Build errors | Enable C++17: -std=c++17 or /std:c++17 |
Contributions welcome! Feel free to:
- ๐ Report bugs
- ๐ก Suggest features
- ๐ง Submit pull requests
MIT License โ Free for personal and commercial use.
This project includes third-party components:
- picojson (embedded in LiveTuner.h) โ BSD 2-Clause License ยฉ Kazuho Oku, Cybozu Labs, Inc.
- nlohmann/json (Json.hpp, optional) โ MIT License ยฉ Niels Lohmann
See LICENSE for full details.
โญ Star this repo if you find it useful!
Made with โค๏ธ for the C++ community
