RED4ext Documentation

repository·master·Indexed 19 days ago

https://github.com/wopss/red4ext

A script extender for REDengine 4 (Cyberpunk 2077) that allows modders to extend game functionality through plugins. The project consists of the RED4ext loader and the RED4ext.SDK, which provides reversed types and helpers. Key features include the Hook class for intercepting engine functions, the Paths class for filesystem resolution, a ScriptCompiler system, and a LoggerSystem for plugin diagnostics.

Tokens
2.6K
Snippets
5
Records
13
Agent score
66%

What's inside RED4ext

  1. Understand the RED4ext architecture and components

    master

    RED4ext is a script extender for REDengine 4 (used in Cyberpunk 2077) that allows modders to add new features, modify game behavior, and add or call scripting functions via plugins.

    The project is split into two distinct parts:

    1. RED4ext: The loader component that manages plugins.
    2. RED4ext.SDK: A separate project containing reversed types and helpers used to extend the engine.

    Important for developers: When developing a new plugin, you should only add RED4ext.SDK to your project structure. The SDK can be used independently of the RED4ext loader.

  2. Configure RED4ext logging settings

    master

    The LoggingConfig structure controls the verbosity and rotation of the RED4ext log files. It uses spdlog levels for configuration.

    Key settings include:

    • level: The minimum logging level to record (e.g., info, debug, warn, error).
    • flushOn: The logging level at which the log buffer is automatically flushed to disk.
    • maxFiles: The maximum number of log files to retain.
    • maxFileSize: The maximum size of each log file (in MB).
  3. Configure RED4ext developer settings

    master

    The DevConfig structure provides options for debugging the RED4ext loader itself.

    Key settings include:

    • hasConsole: Enables or disables the developer console.
    • waitForDebugger: If enabled, the loader will wait for a debugger to attach before proceeding.
  4. Configure RED4ext plugin behavior

    master

    The PluginsConfig structure allows you to manage how RED4ext handles plugins.

    Key settings include:

    • isEnabled: A boolean flag to globally enable or disable the plugin loading system.
    • ignored: A list of plugin identifiers (as wide strings) that RED4ext should skip during the loading process.
  5. Configure and run the Script Compiler with ScriptCompilerSettings

    master

    The ScriptCompilerSettings class provides a fluent interface for configuring the script compilation process. You initialize it with an SccApi instance and the path to the R6 directory.

    Key configuration capabilities include:

    • Adding script paths via AddScriptPath.
    • Managing cache files using SetCustomCacheFile or SetOutputCacheFile (the latter is only available if SupportsOutputCacheFileParameter() returns true).
    • Registering specific types for reference handling using RegisterNeverRefType or RegisterMixedRefType.

    After configuration, call Compile() to execute the process. The result is a std::variant containing either a ScriptCompilerFailure or a ScriptCompilerOutput.

    // Example usage of ScriptCompilerSettings
    ScriptCompilerSettings settings(sccApi, r6Path);
    
    settings.AddScriptPath("/path/to/scripts")
            ->SetOutputCacheFile("/path/to/cache.bin")
            ->RegisterNeverRefType("MyCustomType");
    
    auto result = settings.Compile();
    
    if (std::holds_alternative<ScriptCompilerOutput>(result)) {
        auto& output = std::get<ScriptCompilerOutput>(result);
        // Handle successful output
    } else {
        auto& failure = std::get<ScriptCompilerFailure>(result);
        // Handle failure
    }
  6. ScriptCompilerSettings API Reference

    master

    The ScriptCompilerSettings class manages the state and execution of the script compiler.

    Methods

    MethodReturn TypeDescription
    ScriptCompilerSettings(SccApi& aApi, std::filesystem::path aR6Path)ConstructorInitializes settings with the SCC API and the R6 path.
    SupportsOutputCacheFileParameter()boolReturns true if the compiler supports the output cache file parameter.
    AddScriptPath(std::filesystem::path aPath)ScriptCompilerSettings*Adds a directory to the list of script paths. Returns this for chaining.
    SetCustomCacheFile(std::filesystem::path aPath)ScriptCompilerSettings*Sets a custom cache file path. Returns this for chaining.
    SetOutputCacheFile(std::filesystem::path aPath)ScriptCompilerSettings*Sets the output cache file path. Returns this for chaining.
    RegisterNeverRefType(std::string aType)ScriptCompilerSettings*Registers a type that should never be treated as a reference. Returns this for chaining.
    RegisterMixedRefType(std::string aType)ScriptCompilerSettings*Registers a type that can be treated as a mixed reference. Returns this for chaining.
    Compile()ResultExecutes the compilation. Returns a std::variant<ScriptCompilerFailure, ScriptCompilerOutput>.
  7. Resolve engine and plugin file system paths with the Paths class

    master

    The Paths class provides a centralized way to resolve filesystem paths for the game engine, RED4ext, and various script directories. This is essential for plugins that need to locate their own assets, configuration files, or engine-specific script folders.

    Key path resolution methods include:

    • Core Directories:

      • GetRootDir(): The root directory of the game installation.
      • GetX64Dir(): The directory containing the x64 binaries.
      • GetExe(): The path to the game executable.
      • GetRED4extDir(): The installation directory for RED4ext.
      • GetLogsDir(): The directory where logs are stored.
      • GetPluginsDir(): The directory containing installed plugins.
    • Scripting and Redscript Paths:

      • GetRedscriptPathsFile(): Path to the redscript paths configuration file.
      • GetR6Scripts(): The directory containing R6 scripts.
      • GetDefaultScriptsBlob(): Path to the default scripts blob.
      • GetR6CacheModded(): Path to the modded R6 cache.
      • GetR6Dir(): The R6 directory.
    • Configuration:

      • GetConfigFile(): Returns the path to the RED4ext configuration file.
    // Example usage of the Paths class to locate the plugins directory
    Paths paths;
    std::filesystem::path pluginsDir = paths.GetPluginsDir();
  8. Use the Hook class to intercept engine functions

    master

    The Hook<T> template class is used to intercept (detour) engine functions. You can initialize a hook using either a direct memory address or a function hash. If a hash is provided, the class will automatically resolve the address using the Addresses singleton when GetAddress() or Attach() is called.

    Key Methods:

    • Attach(): Attempts to apply the detour. Returns 0 if already attached or if successful, and returns an error code otherwise. It resolves the address via hash if the address is currently 0.
    • Detach(): Removes the detour. Returns 0 if not attached or if successful.
    • GetAddress(): Returns the memory address of the target function as a uintptr_t. If the address is 0 and a hash was provided during construction, it resolves the address using Addresses::Instance()->Resolve(m_hash).
    • operator T(): Allows the hook object to be used directly as the address type (e.g., a function pointer).
    // Example: Hooking a function using its hash
    typedef void (*TargetFunc)(int);
    typedef void (*DetourFunc)(int);
    
    TargetFunc originalFunc = nullptr;
    DetourFunc myDetour = [](int val) {
        // Custom logic here
    };
    
    // Initialize with hash and detour function
    Hook<TargetFunc> myHook(0x12345678, myDetour);
    
    // Apply the hook
    int32_t result = myHook.Attach();
    if (result == 0) {
        // Success
    }
  9. Log messages from a plugin using LoggerSystem

    master

    The LoggerSystem provides several logging levels to record diagnostics from a plugin. When calling these methods, you must pass a std::shared_ptr<PluginBase> representing your plugin. This allows the system to associate the log entry with the specific plugin and route it to the correct log file.

    Supported log levels are:

    • Trace: Fine-grained informational events.
    • Debug: Fine-grained informational events useful for debugging.
    • Info: Informational messages that highlight progress.
    • Warn: Potentially harmful situations.
    • Error: Error events that might still allow the plugin to continue.
    • Critical: Severe error events that might lead the plugin to abort.

    Each method accepts both std::string_view and std::wstring_view for the message text.

    // Example usage within a plugin context
    void MyPlugin::DoSomething(std::shared_ptr<PluginBase> myPlugin, std::shared_ptr<LoggerSystem> logger)
    {
        logger->Info(myPlugin, "Starting operation...");
        
        if (error_occurred) {
            logger->Error(myPlugin, L"An error occurred during the operation! (Wide string support)");
        }
    }