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/generic with modified addon.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.cpp and 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_shaders and devkit_set_resource_clone for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →