Input System Configuration
Olympe Engine's input system supports keyboards, mice, and gamepads with flexible JSON-based configuration. This allows you to define custom control schemes without modifying code.
Configuration Files
Main Configuration
File: Config/olympe-config.json
Main engine configuration including input system settings:
{
"version": "2.0",
"screen_width": 1280,
"screen_height": 720,
"fullscreen": false,
"vsync": true,
"editor_enabled": false,
"input_config_path": "Config/Inputs.json",
"input_log_level": "info"
}
Key settings:
input_config_path: Path to input profile configuration fileinput_log_level: Logging verbosity (debug,info,warning,error)
Input Profiles
File: Config/Inputs.json
Defines input profiles, action mappings, and device settings.
Input Profile Structure
Profile Definition
Each profile defines bindings for a specific device type:
{
"version": "2.0",
"profiles": [
{
"name": "default_keyboard",
"device_type": "KeyboardMouse",
"description": "Default keyboard and mouse bindings",
"actions": { /* ... */ },
"settings": { /* ... */ }
},
{
"name": "default_gamepad",
"device_type": "Joystick",
"description": "Default gamepad bindings",
"actions": { /* ... */ },
"settings": { /* ... */ }
}
]
}
Device Types
KeyboardMouse: Keyboard and mouse inputJoystick: Gamepad/controller input
Keyboard Configuration
Key Bindings
{
"name": "default_keyboard",
"device_type": "KeyboardMouse",
"actions": {
"move_up": {
"type": "key",
"primary": "W",
"alternate": "UP",
"comment": "Move character forward/up"
},
"move_down": {
"type": "key",
"primary": "S",
"alternate": "DOWN"
},
"jump": {
"type": "key",
"primary": "SPACE"
},
"interact": {
"type": "key",
"primary": "E"
},
"sprint": {
"type": "key",
"primary": "LSHIFT"
},
"menu_open": {
"type": "key",
"primary": "ESCAPE"
}
}
}
Key Action Properties
type: Must be"key"primary: Main key binding (required)alternate: Alternative key binding (optional)comment: Description for documentation
Supported Key Names
Common keys:
- Letters:
A-Z - Numbers:
0-9 - Function keys:
F1-F12 - Modifiers:
LSHIFT,RSHIFT,LCTRL,RCTRL,LALT,RALT - Special:
SPACE,RETURN,ESCAPE,TAB,BACKSPACE,DELETE - Arrows:
UP,DOWN,LEFT,RIGHT
See SDL3 SDL_Scancode documentation for complete list.
Mouse Bindings
{
"shoot": {
"type": "mouse_button",
"button": 1,
"comment": "Left mouse button"
},
"aim": {
"type": "mouse_button",
"button": 3,
"comment": "Right mouse button"
}
}
Mouse Button Numbers
- 1: Left button
- 2: Middle button
- 3: Right button
- 4+: Additional mouse buttons
Keyboard Settings
{
"settings": {
"validate_overlaps": true,
"mouse_sensitivity": 1.0
}
}
validate_overlaps: Check for duplicate key bindingsmouse_sensitivity: Mouse movement multiplier
Gamepad Configuration
Button Bindings
{
"name": "default_gamepad",
"device_type": "Joystick",
"actions": {
"jump": {
"type": "button",
"button": 0,
"comment": "A button (Xbox) / Cross (PlayStation)"
},
"interact": {
"type": "button",
"button": 2,
"comment": "X button (Xbox) / Square (PlayStation)"
},
"crouch": {
"type": "button",
"button": 1,
"comment": "B button (Xbox) / Circle (PlayStation)"
}
}
}
Standard Button Layout
Xbox Controller / Generic Gamepad:
- 0: A / Cross
- 1: B / Circle
- 2: X / Square
- 3: Y / Triangle
- 4: Left Bumper (LB)
- 5: Right Bumper (RB)
- 6: Back / Select
- 7: Start
- 8: Left Stick Click (L3)
- 9: Right Stick Click (R3)
- 12-15: D-pad (Up, Down, Left, Right)
Analog Stick Bindings
{
"move": {
"type": "stick",
"stick": "left",
"deadzone": 0.15,
"sensitivity": 1.0,
"comment": "Left stick for movement"
},
"look": {
"type": "stick",
"stick": "right",
"deadzone": 0.15,
"sensitivity": 1.2,
"invert_y": false,
"comment": "Right stick for camera"
}
}
Stick Properties
stick:"left"or"right"deadzone: Ignore input below this value (0.0 - 1.0)sensitivity: Input multiplierinvert_y: Invert vertical axis (optional)
Trigger Bindings
{
"shoot": {
"type": "trigger",
"trigger": "right",
"threshold": 0.1,
"comment": "Right trigger"
},
"aim": {
"type": "trigger",
"trigger": "left",
"threshold": 0.1
}
}
Trigger Properties
trigger:"left"or"right"threshold: Minimum value to register input (0.0 - 1.0)
Gamepad Settings
{
"settings": {
"deadzone": 0.15,
"sensitivity": 1.0
}
}
deadzone: Global deadzone for all analog inputssensitivity: Global sensitivity multiplier
Action Mapping
Action maps group actions by context and priority:
{
"action_maps": [
{
"name": "gameplay",
"context": "Gameplay",
"priority": 0,
"exclusive": false,
"description": "Core gameplay actions",
"actions": [
"move_up", "move_down", "move_left", "move_right",
"jump", "shoot", "aim", "interact", "sprint"
]
},
{
"name": "ui_navigation",
"context": "UI",
"priority": 30,
"exclusive": true,
"description": "Menu navigation",
"actions": [
"ui_up", "ui_down", "ui_left", "ui_right",
"ui_confirm", "ui_cancel"
]
},
{
"name": "system",
"context": "System",
"priority": 100,
"exclusive": false,
"description": "System controls",
"actions": [
"screenshot", "toggle_fps", "toggle_debug", "menu_open"
]
}
]
}
Action Map Properties
name: Unique identifiercontext: Input context (Gameplay,UI,System)priority: Higher priority maps are checked firstexclusive: If true, blocks lower-priority maps when activeactions: List of action names in this map
Context Priority
When multiple contexts are active, priority determines processing order:
- System (priority 100): Always processed
- UI (priority 30): Active when menus are open (exclusive)
- Gameplay (priority 0): Active during normal gameplay
Exclusive maps block lower-priority maps from processing input.
Default Profile Assignment
Automatically assign profiles based on device type:
{
"default_profile_assignment": {
"Joystick": "default_gamepad",
"KeyboardMouse": "default_keyboard"
}
}
When a device connects, it's automatically assigned the appropriate profile.
System Settings
{
"settings": {
"auto_assign_devices": true,
"prefer_joysticks": true,
"enable_hot_reload": false,
"log_level": "info",
"device_reconnect_timeout_ms": 5000
}
}
auto_assign_devices: Automatically assign profiles to new devicesprefer_joysticks: Prefer gamepads over keyboard when availableenable_hot_reload: Reload config when file changes (future feature)log_level: Logging verbositydevice_reconnect_timeout_ms: Time to wait before removing disconnected device
Loading Configuration
In Code
#include "InputsManager.h"
// Initialize with default config path
InputsManager::Get().InitializeInputSystem("Config/olympe-config.json");
// Or specify custom path
InputsManager::Get().InitializeInputSystem("Config/custom_inputs.json");
Automatic Loading
The engine loads input configuration during startup:
// In GameEngine::Initialize()
InputsManager::Get().InitializeInputSystem(configPath);
Multi-Player Support
The input system supports multiple players with different devices:
- Player 1: Keyboard or first gamepad
- Player 2+: Additional gamepads
Each player gets a separate Controller_data component with their device bindings.
Player Binding
// Bind player to keyboard
InputsManager::Get().BindPlayerToDevice(0, DeviceType::Keyboard);
// Bind player to specific gamepad
InputsManager::Get().BindPlayerToDevice(1, joystickID);
Runtime Input Queries
Check Action State
// Get controller component
Controller_data* controller = World::Get().GetComponent<Controller_data>(playerEntity);
// Check if action is pressed
if (controller->actions["jump"]) {
// Jump logic
}
// Get analog input
float moveX = controller->axes["move_x"];
float moveY = controller->axes["move_y"];
Input Events
The input system publishes events to EventQueue:
// Subscribe to input events
EventQueue::Subscribe("Input", [](const Event& event) {
if (event.type == "ButtonPressed") {
std::string action = event.GetString("action");
int playerID = event.GetInt("playerID");
// Handle button press
}
});
Custom Profiles
Creating a Custom Profile
- Copy an existing profile in
Inputs.json - Modify action bindings
- Change
nameanddescription - Assign to device type
Example: Racing game profile
{
"name": "racing",
"device_type": "KeyboardMouse",
"actions": {
"accelerate": {"type": "key", "primary": "W"},
"brake": {"type": "key", "primary": "S"},
"steer_left": {"type": "key", "primary": "A"},
"steer_right": {"type": "key", "primary": "D"},
"handbrake": {"type": "key", "primary": "SPACE"},
"nitro": {"type": "key", "primary": "LSHIFT"}
}
}
Switching Profiles
// Switch to custom profile
InputDeviceManager::Get().AssignProfileToDevice(deviceID, "racing");
Troubleshooting
Keys Not Responding
- Check key names match SDL scancode names
- Verify profile is assigned to device
- Check action map context is active
Gamepad Not Detected
- Ensure gamepad is connected before starting engine
- Check
GetConnectedJoysticksCount()> 0 - Try different USB port
Actions Not Working
- Verify action name in profile matches component usage
- Check action map includes the action
- Ensure correct context is active
Input Lag
- Reduce
device_reconnect_timeout_ms - Enable
vsyncfor consistent frame timing - Check for blocking operations in input handlers
Best Practices
- Use Descriptive Names: Clear action names improve maintainability
- Document Custom Bindings: Add comments to explain non-obvious mappings
- Test All Devices: Verify keyboard, mouse, and gamepad configurations
- Provide Alternatives: Offer alternate key bindings for flexibility
- Respect Conventions: Follow standard control schemes (WASD, Xbox layout)
- Context Separation: Use action maps to separate gameplay/UI/system controls
- Deadzone Tuning: Adjust deadzones for specific gamepads if needed
Related Documentation
- Input System Architecture - Technical implementation details
- Input System User Guide - How to use input in gameplay
- ECS Overview - Controller_data component details
Example Files
Config/olympe-config.json: Main engine configurationConfig/Inputs.json: Complete input profile exampleSource/InputConfigLoader.cpp: Profile loading implementationSource/InputsManager.cpp: Input system implementation