Best Practices for Developing with RenoDX: A Complete Guide to Building Reshade Mods
RenoDX development best practices center on using the three-layer architecture of add-on modules, utility libraries, and the Devkit+MCP bridge for live iteration, with proper HDR handling and shader verification as critical requirements.
RenoDX is a Reshade-based modding framework that enables shader replacement, buffer injection, and swapchain upgrades for PC games. Developing effectively with this framework requires understanding its layered architecture, following the established Devkit workflow for rapid iteration, and avoiding common pitfalls around shader hashing and HDR pipeline handling.
Understanding the RenoDX Architecture
RenoDX organizes code into three distinct layers. Each layer has a specific purpose and designated file locations in the clshortfuse/renodx repository.
| Layer | Purpose | Key Implementation |
|---|---|---|
| Add-on modules | Game-specific logic including shader replacements and resource upgrades. Each compiles to *.addon64 or *.addon32 and loads via Reshade. |
src/games/<game>/addon.cpp – the entry point for any game mod. |
| Utility library | Shared helpers for swapchain operations, resource cloning, HDR detection, and settings management. | src/utils/swapchain.hpp, src/utils/resource.hpp, src/utils/settings.hpp. |
| Devkit + MCP bridge | Live-inspection tooling for shader dumping, resource cloning, and iteration without rebuilds. | src/addons/devkit/addon.cpp, src/apps/mcp_bridge/main.cpp, documented in DEVKIT_MCP.md. |
All add-ons register callbacks through Reshade's add-on API using reshade::register_addon and reshade::register_event. The utility layer stores state through a generic data container pattern: renodx::utils::data::Create<T> and Get<T>.
Core Data Structures
According to swapchain.hpp, two primary structs track runtime state:
- DeviceData – holds back-buffer description and effect runtimes
- CommandListData – tracks the current render-target list
These structures enable safe state management across the Reshade event lifecycle without global variables.
Setting Up Your Development Environment
Before writing code, configure your toolchain correctly to avoid version conflicts and missing dependencies.
Run the bootstrap script to fetch required tools:
# From repository root
scripts/setup-dev-env.ps1 -Install
This installs DXC, glslang, 3Dmigoto, and other dependencies into the .\bin directory. The setup script is documented in docs/CONTRIBUTING.md alongside CMake preset configurations.
Verify your build environment with:
cmake --preset clang-x64
cmake --build --preset clang-x64-release
Available presets are defined in CMakePresets.json and include configurations for clang, Ninja, and Visual Studio 2022.
Creating a New RenoDX Mod
Follow this structured workflow to create, test, and package a game modification.
Step 1: Initialize the Mod Structure
Copy the generic template to your new game folder:
cp -r src/games/generic src/games/<mygame>
Edit src/games/<mygame>/addon.cpp to register resource upgrades and shader replacements. This file serves as your add-on entry point.
Step 2: Add Shader Replacements
Place HLSL files following the naming convention:
{CRC32}.{TYPE}_{MAJOR}_{MINOR}.hlsl
For example: 0xA1B2C3D4.VS_5_0.hlsl for a vertex shader. The build system automatically embeds these into the final .addon64 binary.
Step 3: Build the Add-on
cmake --build --preset clang-x64-release
Output location: build/Release/renodx-<mygame>.addon64
Leveraging the Devkit for Rapid Iteration
The Devkit + MCP bridge eliminates rebuild cycles. This workflow is documented in docs/DEVKIT_MCP.md and implemented across src/addons/devkit/addon.cpp and src/apps/mcp_bridge/main.cpp.
Building and Running the Devkit
cmake --build --preset clang-x64-debug --target devkit
Then launch the bridge:
renodx-mcp-bridge.exe
Connect an MCP client (Codex, Claude Desktop, or custom) to the exposed JSON-RPC pipe.
Live Shader Development Workflow
// MCP JSON-RPC sequence
devkit_set_tools_path("C:\\Path\\to\\renodx\\bin");
devkit_set_live_shader_path("C:\\Mods\\renodx\\src\\games\\mygame");
devkit_load_live_shaders();
Verify your changes:
devkit_get_shader(shader_hash);
// Confirm source field shows "File" indicating live load success
HDR Verification with Resource Cloning
Enable cloning before analysis:
// MCP JSON-RPC
{
"jsonrpc":"2.0","id":1,
"method":"devkit_set_resource_clone",
"params":{"resourceHash":"0xABCDEF01","enabled":true}
}
Then inspect with devkit_analyze_resource to output EXR files for HDR range verification.
Working with Swapchain and Settings APIs
RenoDX provides utility headers that wrap DXGI operations in platform-agnostic interfaces.
FPS Limiting Implementation
The reference implementation in src/addons/fpslimiter/addon.cpp demonstrates settings registration:
// src/addons/fpslimiter/addon.cpp (excerpt)
renodx::utils::settings::Setting fps_setting{
.key = "FPSLimit",
.binding = &renodx::utils::swapchain::fps_limit,
.default_value = 0.f,
.label = "FPS Limit",
.min = 0.f,
.max = 480.f,
};
renodx::utils::settings::Settings settings{ &fps_setting };
The limiter reads renodx::utils::swapchain::fps_limit and throttles the present callback automatically.
Runtime Color Space Changes
#include "utils/swapchain.hpp"
void EnableHDR(reshade::api::swapchain* sc) {
renodx::utils::swapchain::ChangeColorSpace(
sc,
reshade::api::color_space::hdr10_hlg
);
}
Available operations in swapchain.hpp include ResizeBuffer, ChangeColorSpace, and SetHDREnabled.
Event Registration Requirements
Ensure callbacks are properly registered through the shared utility:
internal::shared.RegisterEvent<reshade::addon_event::init_swapchain>(
my_callback_function
);
Missing event registration causes silent failures for FPS limiting, HDR toggles, and other swapchain-dependent features.
Common Pitfalls in RenoDX Development
| Issue | Symptom | Resolution |
|---|---|---|
| Incorrect shader hash | Replacement fails, original shader renders | Verify CRC32 with devkit_list_shaders before naming HLSL files |
| HDR clipped in final output | Colors clamped despite HDR-aware shaders | Inspect late draws, clone back-buffer, verify with devkit_analyze_resource EXR output |
| DXC DLL conflicts | Live shader reload crashes | Point devkit_set_tools_path to repository .\bin directory |
| Resource cloning disabled | HDR values clamped on readback | Call devkit_set_resource_clone with enabled:true before analysis |
| Missing swapchain events | FPS limiter or HDR settings inactive | Register callbacks via internal::shared.RegisterEvent<> pattern from swapchain.hpp |
Verification Checklist for Production
Before releasing a RenoDX mod:
- Bootstrap environment with
setup-dev-env.ps1 -Install - Template copied from
src/games/genericwith modifiedaddon.cpp - Settings registered via
renodx::utils::settings - Swapchain helpers used for HDR, color-space, or FPS modifications
- Add-on builds successfully with CMake preset
- Devkit iteration completed with
renodx-mcp-bridge.exe - HDR pipeline verified through resource cloning and EXR analysis
- Logic finalized in
addon.cppand packaged as.addon64
Summary
- RenoDX architecture separates concerns into add-on modules, utility libraries, and Devkit tooling—respect these boundaries for maintainable code
- Live iteration via Devkit+MCP eliminates rebuild cycles; use
devkit_load_live_shadersanddevkit_set_resource_clonefor rapid testing - Shader verification requires correct CRC32 hashes obtained through
devkit_list_shaders - HDR integrity demands careful pipeline inspection with resource cloning enabled before
devkit_analyze_resource - Settings and swapchain operations should use the utility layer (
settings.hpp,swapchain.hpp) rather than direct DXGI calls
Frequently Asked Questions
What build tools does RenoDX require?
RenoDX requires DXC, glslang, and 3Dmigoto for shader compilation and injection. The setup-dev-env.ps1 script automates installation into the .\bin directory. CMake presets in CMakePresets.json provide configurations for clang, Ninja, and Visual Studio 2022.
How do I find the correct shader hash for replacement?
Use the Devkit's devkit_list_shaders method to enumerate runtime shaders and their CRC32 hashes. Name your HLSL file using this exact hash in the format {CRC32}.{TYPE}_{MAJOR}_{MINOR}.hlsl. Mismatched hashes cause silent fallback to original shaders.
Why does my HDR output appear clipped despite HDR settings?
The final blit to swapchain may strip HDR metadata. Enable resource cloning with devkit_set_resource_clone, capture the back-buffer with devkit_analyze_resource, and examine the exported EXR for preserved luminance values. The inspection workflow in DEVKIT_MCP.md provides step-by-step guidance.
Can I modify shaders without rebuilding the add-on?
Yes. The Devkit+MCP bridge supports live shader reloading. Set your tools path with devkit_set_tools_path, point to your shader directory with devkit_set_live_shader_path, and call devkit_load_live_shaders. Changes reflect immediately without CMake rebuild.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →