### Install ImGuizmo with vcpkg Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/README.md Instructions for installing the ImGuizmo library using the vcpkg package manager. This method simplifies dependency management and integration into CMake projects. ```bash vcpkg install vcpkg ``` -------------------------------- ### Configure CMake with Vcpkg Toolchain Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/vcpkg-example/README.md This command configures the CMake build system, specifying the Vcpkg toolchain file. This ensures that CMake uses Vcpkg to download and manage project dependencies. It requires a 'build' directory to be created first. ```bash mkdir build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/dev/vcpkg/scripts/buildsystem/vcpkg.cmake ``` -------------------------------- ### VSCode CMake Configuration for Vcpkg Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/vcpkg-example/README.md This JSON snippet shows how to configure VSCode's CMake Tools extension to use the Vcpkg toolchain file. This is added to the `.vscode/settings.json` file to automate the Vcpkg integration for the project within VSCode. ```json { "cmake.configureArgs": [ "-DCMAKE_TOOLCHAIN_FILE=C:\\dev\\vcpkg\\scripts\\buildsystem\\vcpkg.cmake" ] } ``` -------------------------------- ### CMake: Project Setup and Language Configuration Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt Initializes the CMake project, specifying supported languages (C++, C, C#) and setting compiler flags. It also configures the MSVC runtime library and handles release build optimizations. ```cmake cmake_minimum_required(VERSION 3.15) if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build") endif() set(CMKR_ROOT_PROJECT OFF) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(CMKR_ROOT_PROJECT ON) # Bootstrap cmkr and automatically regenerate CMakeLists.txt include(cmkr.cmake OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT) if(CMKR_INCLUDE_RESULT) cmkr() endif() # Enable folder support set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Create a configure-time dependency on cmake.toml to improve IDE support configure_file(cmake.toml cmake.toml COPYONLY) endif() project(CSharpAPIProject LANGUAGES CXX C CSharp ) include(CSharpUtilities) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") set(CMAKE_CSharp_FLAGS "${CMAKE_CSHARP_FLAGS} /langversion:latest /platform:x64") # Disable exceptions # string(REGEX REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") set(ASMJIT_STATIC ON CACHE BOOL "" FORCE) set(DYNAMIC_LOADER ON CACHE BOOL "" FORCE) # OpenXR set(BUILD_TOOLS OFF CACHE BOOL "" FORCE) # DirectXTK if ("${CMAKE_BUILD_TYPE}" MATCHES "Release") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MT") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MT") # Statically compile runtime string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") string(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") message(NOTICE "Building in Release mode") endif() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") ``` -------------------------------- ### Get Selected Nodes Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Explains how to retrieve the IDs of currently selected nodes. This involves first querying the number of selected nodes and then retrieving their IDs into a vector. ```cpp // Note that since many nodes can be selected at once, we first need to query the number of // selected nodes before getting them. const int num_selected_nodes = ImNodes::NumSelectedNodes(); if (num_selected_nodes > 0) { std::vector selected_nodes; selected_nodes.resize(num_selected_nodes); ImNodes::GetSelectedNodes(selected_nodes.data()); } ``` -------------------------------- ### Get and Set Global Style Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Demonstrates how to access and modify the global style of the node editor. ImNodes::GetStyle returns a reference to the style structure, allowing direct modification of style properties. ```cpp // set the titlebar color for all nodes ImNodesStyle& style = ImNodes::GetStyle(); ``` -------------------------------- ### Check for Newly Created Links Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Provides a method to check if a new link has been created during the current frame. The function IsLinkCreated returns the IDs of the start and end attributes of the new link. ```cpp int start_attr, end_attr; if (ImNodes::IsLinkCreated(&start_attr, &end_attr)) { links.push_back(std::make_pair(start_attr, end_attr)); } ``` -------------------------------- ### Instantiate Node Editor Window Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Demonstrates how to instantiate the node editor within a Dear ImGui window. The node editor must be enclosed within ImGui::Begin and ImGui::End calls. ```cpp ImGui::Begin("node editor"); ImNodes::BeginNodeEditor(); ImNodes::EndNodeEditor(); ImGui::End(); ``` -------------------------------- ### Initialize Dear ImGui and ImNodes Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Initializes the Dear ImGui and ImNodes contexts. These contexts must be created before using any of their functions and destroyed when they are no longer needed. ```cpp ImGui::CreateContext(); ImNodes::CreateContext(); // elsewhere in the code... ImNodes::DestroyContext(); ImGui::DestroyContext(); ``` -------------------------------- ### Implement Mini-map in ImNodes Editor Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Demonstrates how to initialize a mini-map within an ImNodes editor context. The mini-map provides an interactive overlay for navigating large node graphs. ```cpp ImGui::Begin("node editor"); ImNodes::BeginNodeEditor(); // add nodes... // must be called right before EndNodeEditor ImNodes::MiniMap(); ImNodes::EndNodeEditor(); ImGui::End(); ``` -------------------------------- ### Customize ImNodes via User Configuration Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Shows how to create an imnodes_config.h file to override library defaults, such as defining custom types for callbacks to support language bindings like pybind11. ```cpp #pragma once #include namespace pybind11 { inline bool PyWrapper_Check(PyObject *o) { return true; } class wrapper : public object { public: PYBIND11_OBJECT_DEFAULT(wrapper, object, PyWrapper_Check) wrapper(void* x) { m_ptr = (PyObject*)x; } explicit operator bool() const { return m_ptr != nullptr && m_ptr != Py_None; } }; } //namespace pybind11 namespace py = pybind11; #define ImNodesMiniMapNodeHoveringCallback py::wrapper #define ImNodesMiniMapNodeHoveringCallbackUserData py::wrapper ``` -------------------------------- ### Initialize REFramework Plugin API Source: https://context7.com/praydog/reframework/llms.txt Demonstrates the mandatory plugin entry point initialization. It requires defining the plugin version and implementing the initialization function to register callbacks and access the API. ```cpp #include using namespace reframework; extern "C" __declspec(dllexport) void reframework_plugin_required_version(REFrameworkPluginVersion* version) { version->major = REFRAMEWORK_PLUGIN_VERSION_MAJOR; version->minor = REFRAMEWORK_PLUGIN_VERSION_MINOR; version->patch = REFRAMEWORK_PLUGIN_VERSION_PATCH; } extern "C" __declspec(dllexport) bool reframework_plugin_initialize(const REFrameworkPluginInitializeParam* param) { API::initialize(param); param->functions->on_lua_state_created(on_lua_state_created); param->functions->on_present(on_present); param->functions->on_pre_application_entry("BeginRendering", on_begin_rendering); param->functions->on_device_reset(on_device_reset); API::get()->log_info("Plugin initialized successfully!"); return true; } ``` -------------------------------- ### ImGui Gizmo Manipulation in C++ Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/README.md This C++ code demonstrates how to use ImGuizmo to create interactive transformation gizmos (translate, rotate, scale) within an ImGui interface. It handles user input for operation and mode selection, decomposes and recomposes matrices, and applies snapping. Dependencies include ImGui and ImGuizmo. ```C++ void EditTransform(const Camera& camera, matrix_t& matrix) { static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE); static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD); if (ImGui::IsKeyPressed(90)) mCurrentGizmoOperation = ImGuizmo::TRANSLATE; if (ImGui::IsKeyPressed(69)) mCurrentGizmoOperation = ImGuizmo::ROTATE; if (ImGui::IsKeyPressed(82)) // r Key mCurrentGizmoOperation = ImGuizmo::SCALE; if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE)) mCurrentGizmoOperation = ImGuizmo::TRANSLATE; ImGui::SameLine(); if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE)) mCurrentGizmoOperation = ImGuizmo::ROTATE; ImGui::SameLine(); if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE)) mCurrentGizmoOperation = ImGuizmo::SCALE; float matrixTranslation[3], matrixRotation[3], matrixScale[3]; ImGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale); ImGui::InputFloat3("Tr", matrixTranslation, 3); ImGui::InputFloat3("Rt", matrixRotation, 3); ImGui::InputFloat3("Sc", matrixScale, 3); ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16); if (mCurrentGizmoOperation != ImGuizmo::SCALE) { if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL)) mCurrentGizmoMode = ImGuizmo::LOCAL; ImGui::SameLine(); if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD)) mCurrentGizmoMode = ImGuizmo::WORLD; } static bool useSnap(false); if (ImGui::IsKeyPressed(83)) useSnap = !useSnap; ImGui::Checkbox("", &useSnap); ImGui::SameLine(); vec_t snap; switch (mCurrentGizmoOperation) { case ImGuizmo::TRANSLATE: snap = config.mSnapTranslation; ImGui::InputFloat3("Snap", &snap.x); break; case ImGuizmo::ROTATE: snap = config.mSnapRotation; ImGui::InputFloat("Angle Snap", &snap.x); break; case ImGuizmo::SCALE: snap = config.mSnapScale; ImGui::InputFloat("Scale Snap", &snap.x); break; } ImGuiIO& io = ImGui::GetIO(); ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y); ImGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL); } ``` -------------------------------- ### sdk.create_instance Source: https://context7.com/praydog/reframework/llms.txt Creates a new instance of a managed type, allowing for the instantiation of game objects, query structures, and temporary data containers. ```APIDOC ## sdk.create_instance ### Description Creates a new instance of a specified managed type. This is essential for initializing game-specific objects like physics queries or data structures. ### Method Lua Function ### Parameters - **type_name** (string) - Required - The full name of the managed type to instantiate (e.g., "via.physics.CastRayQuery"). ### Request Example ```lua local ray_query = sdk.create_instance("via.physics.CastRayQuery") ``` ### Response - **object** (userdata) - The newly created managed object instance. ``` -------------------------------- ### Manage VM Context and Method Calls Source: https://context7.com/praydog/reframework/llms.txt Explains how to safely execute game methods using the VM context, which is essential for proper exception handling and state management within the RE engine. ```cpp #include using namespace reframework; void safe_method_call() { auto& api = API::get(); auto vm_context = api->get_vm_context(); auto tdb = api->tdb(); auto scene_manager = api->get_native_singleton("via.SceneManager"); auto scene_manager_type = tdb->find_type("via.SceneManager"); auto get_main_view = scene_manager_type->find_method("get_MainView"); // Call with VM context for proper exception handling auto main_view = get_main_view->call( vm_context, scene_manager ); // Check for exceptions if (vm_context->has_exception()) { vm_context->unhandled_exception(); API::get()->log_error("Exception occurred during method call"); return; } if (main_view) { // Get window size using invoke (safer, handles return value properly) auto size_result = main_view->invoke("get_Size", {}); float* size = (float*)&size_result; API::get()->log_info("Window size: %.0fx%.0f", size[0], size[1]); } } ``` -------------------------------- ### Create Managed Objects with sdk.create_instance Source: https://context7.com/praydog/reframework/llms.txt Instantiates new managed objects within the game engine. This is commonly used to create query objects, such as physics raycasts, which are then configured and executed via native calls. ```lua local ray_query = sdk.create_instance("via.physics.CastRayQuery") local ray_result = sdk.create_instance("via.physics.CastRayResult") local start_pos = Vector3f.new(0, 100, 0) local end_pos = Vector3f.new(0, -100, 0) ray_query:call("setRay(via.vec3, via.vec3)", start_pos, end_pos) ray_query:call("clearOptions") ray_query:call("enableAllHits") ray_query:call("enableNearSort") local filter_info = ray_query:call("get_FilterInfo") filter_info:call("set_Layer", 3) ray_query:call("set_FilterInfo", filter_info) local physics_system = sdk.get_native_singleton("via.physics.System") local physics_type = sdk.find_type_definition("via.physics.System") sdk.call_native_func(physics_system, physics_type, "castRay(via.physics.CastRayQuery, via.physics.CastRayResult)", ray_query, ray_result) local num_hits = ray_result:call("get_NumContactPoints") if num_hits > 0 then local contact = ray_result:call("getContactPoint(System.UInt32)", 0) local hit_pos = contact:get_field("Position") local hit_normal = contact:get_field("Normal") local hit_distance = contact:get_field("Distance") end ``` -------------------------------- ### Create an Empty Node Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Shows how to create an empty node within the node editor. Each node requires a unique integer identifier. ```cpp const int hardcoded_node_id = 1; ImNodes::BeginNodeEditor(); ImNodes::BeginNode(hardcoded_node_id); ImGui::Dummy(ImVec2(80.0f, 45.0f)); ImNodes::EndNode(); ImNodes::EndNodeEditor(); ``` -------------------------------- ### Register Application Entry Point Callbacks with re.on_application_entry Source: https://context7.com/praydog/reframework/llms.txt Registers callback functions to be executed at specific points during the game's update loop. This allows for precise timing of mod actions, such as before rendering, after rendering, or during specific game phases like LockScene or UpdateBehavior. The available entry points are predefined strings. ```lua -- Called before rendering begins re.on_application_entry("BeginRendering", function() -- Update visual effects, camera modifications end) -- Called after rendering ends re.on_application_entry("EndRendering", function() -- Post-processing, cleanup end) -- Called during LockScene phase re.on_application_entry("LockScene", function() -- Scene modifications, object spawning local scene_manager = sdk.get_native_singleton("via.SceneManager") -- Perform scene operations... end) -- Called during UpdateBehavior phase re.on_application_entry("UpdateBehavior", function() -- Game logic updates end) ``` -------------------------------- ### Render Links Between Nodes Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Shows how to render links between node attributes. Links are defined by pairs of attribute IDs and require unique integer identifiers for rendering. ```cpp std::vector> links; // elsewhere in the code... for (int i = 0; i < links.size(); ++i) { const std::pair p = links[i]; // in this case, we just use the array index of the link // as the unique identifier ImNodes::Link(i, p.first, p.second); } ``` -------------------------------- ### Customize Node Color Style Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Shows how to change the color style of individual nodes using PushColorStyle and PopColorStyle. This allows for dynamic styling of UI elements mid-frame. ```cpp // set the titlebar color of an individual node ImNodes::PushColorStyle( ImNodesCol_TitleBar, IM_COL32(11, 109, 191, 255)); ImNodes::PushColorStyle( ImNodesCol_TitleBarSelected, IM_COL32(81, 148, 204, 255)); ImNodes::BeginNode(hardcoded_node_id); // node internals here... ImNodes::EndNode(); ImNodes::PopColorStyle(); ImNodes::PopColorStyle(); ``` -------------------------------- ### Initialize and Control ImGuizmo Frame Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/README.md Functions to manage the lifecycle and state of the gizmo within an ImGui frame. These functions determine if the mouse is interacting with the gizmo and allow enabling or disabling the widget. ```C++ void BeginFrame(); bool IsOver(); bool IsUsing(); void Enable(bool enable); ``` -------------------------------- ### Integrate Lua with C++ via sol2 Source: https://context7.com/praydog/reframework/llms.txt Shows how to expose C++ functions to Lua and execute Lua scripts from C++ using the sol2 library. Includes thread-safe locking mechanisms for the Lua state. ```cpp #include #include using namespace reframework; lua_State* g_lua = nullptr; void on_lua_state_created(lua_State* l) { // Lock Lua state for thread safety API::LuaLock lock{}; g_lua = l; sol::state_view lua{g_lua}; // Add custom Lua functions lua["cpp_get_player_health"] = []() -> float { auto player = API::get()->get_managed_singleton("app.Player"); if (player) { auto health = player->get_field("_Health"); return health ? *health : 0.0f; } return 0.0f; }; lua["cpp_set_player_health"] = [](float value) { auto player = API::get()->get_managed_singleton("app.Player"); if (player) { auto health = player->get_field("_Health"); if (health) *health = value; } }; // Create a table for mod data lua["my_plugin_data"] = sol::new_table{}; lua["my_plugin_data"]["version"] = "1.0.0"; } void on_lua_state_destroyed(lua_State* l) { API::LuaLock lock{}; g_lua = nullptr; } void execute_lua_code() { if (!g_lua) return; API::LuaLock lock{}; sol::state_view lua{g_lua}; // Execute Lua code from C++ auto result = lua.safe_script(R"( local health = cpp_get_player_health() print("Player health from C++: " .. health) if health < 50 then cpp_set_player_health(100) print("Healed player!") end )"); // Read Lua values sol::table data = lua["my_plugin_data"]; std::string version = data["version"]; } ``` -------------------------------- ### Access Type Database (TDB) for Types and Methods Source: https://context7.com/praydog/reframework/llms.txt Shows how to query the game's Type Database to locate classes, methods, and fields. This allows for dynamic inspection of game structures and metadata at runtime. ```cpp #include using namespace reframework; void explore_types() { auto& api = API::get(); const auto tdb = api->tdb(); const auto player_type = tdb->find_type("app.PlayerBase"); if (player_type) { auto full_name = player_type->get_full_name(); auto update_method = player_type->find_method("update"); auto health_field = player_type->find_field("_Health"); } auto method = tdb->find_method("app.Enemy", "takeDamage"); } ``` -------------------------------- ### Access Native and Managed Singletons Source: https://context7.com/praydog/reframework/llms.txt Retrieves instances of native (C++) or managed (.NET) singletons from the game engine. These singletons serve as entry points to core systems like physics, rendering, or game-specific managers. ```lua -- Get the scene manager singleton local scene_manager = sdk.get_native_singleton("via.SceneManager") local scene_manager_type = sdk.find_type_definition("via.SceneManager") -- Get the main camera view local main_view = sdk.call_native_func(scene_manager, scene_manager_type, "get_MainView") if main_view then local size = main_view:call("get_Size") local width = size:get_field("w") local height = size:get_field("h") print("Window size: " .. width .. "x" .. height) end -- Access the physics system local physics_system = sdk.get_native_singleton("via.physics.System") -- Access the application singleton local application = sdk.get_native_singleton("via.Application") local app_type = sdk.find_type_definition("via.Application") local elapsed_time = sdk.call_native_func(application, app_type, "get_UpTimeSecond") -- Get a game-specific manager (game namespace varies by title) local game_manager = sdk.get_managed_singleton("app.GameManager") if game_manager then local player = game_manager:call("get_Player") if player then local health = player:get_field("_Health") local position = player:call("get_Position") print("Player health: " .. tostring(health)) end end -- Access inventory system local inventory_manager = sdk.get_managed_singleton("app.InventoryManager") if inventory_manager then local item_count = inventory_manager:call("getItemCount", 0) end ``` -------------------------------- ### Add Output Attribute to Node Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Illustrates how to add an output attribute to a node. Attributes are UI elements within a node and require unique integer identifiers. Content within attributes can be defined using ImGui functions. ```cpp ImNodes::BeginNode(hardcoded_node_id); const int output_attr_id = 2; ImNodes::BeginOutputAttribute(output_attr_id); // in between Begin|EndAttribute calls, you can call ImGui // UI functions ImGui::Text("output pin"); ImNodes::EndOutputAttribute(); ImNodes::EndNode(); ``` -------------------------------- ### Configure Mini-map Sizing and Location Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Sets the relative size and corner placement of the mini-map overlay within the editor canvas. ```cpp // MiniMap is a square region with a side length that is 20% the largest editor canvas dimension // See ImNodesMiniMapLocation_ for other corner locations ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight); ``` -------------------------------- ### Load and Save JSON Configuration with json.load_file/json.dump_file Source: https://context7.com/praydog/reframework/llms.txt Provides functions for persisting mod settings by loading from and saving to JSON files. `json.load_file` attempts to read configuration, merging with defaults if successful, or creates a default file if none exists. `json.dump_file` writes the current configuration to the specified path. These are essential for making mod settings persistent across game sessions. ```lua local config_path = "my_mod/config.json" local default_config = { enabled = true, damage_multiplier = 1.5, hotkey = "F5", features = { god_mode = false, infinite_stamina = false } } local config = default_config local function load_config() local loaded = json.load_file(config_path) if loaded then -- Merge with defaults to handle new options for k, v in pairs(loaded) do config[k] = v end else -- Save default config json.dump_file(config_path, config) end end local function save_config() json.dump_file(config_path, config) end -- Load on script start load_config() -- Auto-save when REFramework config is saved re.on_config_save(function() save_config() end) ``` -------------------------------- ### Add Title Bar to Node Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Demonstrates adding a title bar to a node using BeginNodeTitleBar and EndNodeTitleBar. The title bar content must be added before other node UI elements. ```cpp ImNodes::BeginNode(hardcoded_node_id); ImNodes::BeginNodeTitleBar(); ImGui::TextUnformatted("output node"); ImNodes::EndNodeTitleBar(); // pins and other node UI content omitted... ImNodes::EndNode(); ``` -------------------------------- ### Manipulate Managed Objects with C++ Source: https://context7.com/praydog/reframework/llms.txt Demonstrates how to interact with .NET managed objects, including retrieving singletons, reading/modifying fields, invoking methods, and managing object references. It requires the reframework API header and proper context handling. ```cpp #include using namespace reframework; void manipulate_objects() { auto& api = API::get(); // Get a singleton auto game_manager = api->get_managed_singleton("app.GameManager"); if (game_manager) { // Call a method auto player = game_manager->call("get_Player", api->get_vm_context(), game_manager); if (player) { // Get type definition auto type = player->get_type_definition(); auto type_name = type->get_full_name(); // Read a field auto health = player->get_field("_Health"); if (health) { API::get()->log_info("Player health: %.2f", *health); *health = 100.0f; // Modify directly } // Invoke a method auto result = player->invoke("heal", {}); // Reference counting for managed objects player->add_ref(); // ... use object ... player->release(); } } // Create a managed string auto str = api->create_managed_string_normal("Hello World"); // Get native singleton auto scene_manager = api->get_native_singleton("via.SceneManager"); } ``` -------------------------------- ### Decompose and Recompose Transformation Matrices Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/README.md Helper functions to convert a 4x4 matrix into translation, rotation, and scale components, and vice versa. This is useful for manual editing via ImGui input fields. ```C++ float matrixTranslation[3], matrixRotation[3], matrixScale[3]; ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale); ImGui::InputFloat3("Tr", matrixTranslation, 3); ImGui::InputFloat3("Rt", matrixRotation, 3); ImGui::InputFloat3("Sc", matrixScale, 3); ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16); ``` -------------------------------- ### Configure C# API Test Libraries using CMake Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt This snippet demonstrates how to define a shared library target for C# API testing. It sets source files, links the csharp-api dependency, and configures target properties such as output directories and .NET SDK settings. ```cmake if(REFRAMEWORK_REF_ASSEMBLIES_EXIST_MHWILDS) set(CSharpAPITestMHWilds_SOURCES "test/Test/TestMHWilds.cs" cmake.toml ) add_library(CSharpAPITestMHWilds SHARED) target_sources(CSharpAPITestMHWilds PRIVATE ${CSharpAPITestMHWilds_SOURCES}) target_link_libraries(CSharpAPITestMHWilds PUBLIC csharp-api) set_target_properties(CSharpAPITestMHWilds PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/" DOTNET_SDK Microsoft.NET.Sdk DOTNET_TARGET_FRAMEWORK net10.0-windows VS_CONFIGURATION_TYPE ClassLibrary ) set_dotnet_references(CSharpAPITestMHWilds "mhwilds" "${MHWILDS_DLLS}") endif() ``` -------------------------------- ### Hook Native Game Methods Source: https://context7.com/praydog/reframework/llms.txt Provides a template for hooking native game methods using pre-hooks and post-hooks. This allows developers to intercept arguments and return values to modify game behavior. ```cpp #include using namespace reframework; int pre_take_damage(int argc, void** argv, REFrameworkTypeDefinitionHandle* arg_tys, unsigned long long ret_addr) { auto damage = (float*)&argv[2]; *damage *= 0.5f; return REFRAMEWORK_HOOK_CALL_ORIGINAL; } void post_take_damage(void** ret_val, REFrameworkTypeDefinitionHandle ret_ty, unsigned long long ret_addr) {} extern "C" __declspec(dllexport) bool reframework_plugin_initialize(const REFrameworkPluginInitializeParam* param) { API::initialize(param); auto tdb = API::get()->tdb(); auto method = tdb->find_method("app.PlayerBase", "takeDamage"); if (method) { unsigned int hook_id = method->add_hook(pre_take_damage, post_take_damage, false); } return true; } ``` -------------------------------- ### Configure CMake Build for C++ Application Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/vcpkg-example/CMakeLists.txt This CMake script sets up the project environment, locates required libraries such as ImGui and STB, and defines the executable target. It ensures the project is compiled with C++17 standards and links necessary dependencies. ```cmake cmake_minimum_required(VERSION 3.16) project(vcpkg-example) add_definitions(-DSTB_IMAGE_IMPLEMENTATION) find_path(STB_INCLUDE_DIRS "stb.h") find_package(imgui CONFIG REQUIRED) find_package(imguizmo CONFIG REQUIRED) add_executable(example-app) target_sources(example-app PRIVATE main.cpp) target_compile_options(example-app PRIVATE "/std:c++17") target_include_directories(example-app PRIVATE ${STB_INCLUDE_DIRS} ) target_link_libraries(example-app PRIVATE imgui::imgui imguizmo::imguizmo ) ``` -------------------------------- ### Retrieve System Types with sdk.typeof Source: https://context7.com/praydog/reframework/llms.txt Obtains a System.Type object for a given class name, enabling reflection-based operations like finding components on game objects. Caching these types is recommended for performance optimization. ```lua local component_type = sdk.typeof("app.PlayerController") local game_object = some_transform:call("get_GameObject") local player_controller = game_object:call("getComponent(System.Type)", component_type) if player_controller then local speed = player_controller:get_field("_MoveSpeed") player_controller:set_field("_MoveSpeed", speed * 2.0) end ``` -------------------------------- ### sdk.hook Source: https://context7.com/praydog/reframework/llms.txt Intercepts calls to game methods, enabling developers to modify parameters, change return values, or skip original execution. ```APIDOC ## sdk.hook ### Description Registers pre and post hooks for a specific game method to intercept and modify execution flow. ### Method Lua Function ### Parameters - **method_definition** (userdata) - Required - The method definition object obtained via `find_type_definition`. - **pre_hook** (function) - Optional - Callback executed before the original method. - **post_hook** (function) - Optional - Callback executed after the original method. ### Request Example ```lua sdk.hook(method_def, on_pre_func, on_post_func) ``` ### Response - **hook_id** (number) - An identifier for the registered hook. ``` -------------------------------- ### Define Mini-map Node Hover Callback Source: https://github.com/praydog/reframework/blob/master/dependencies/imnodes/README.md Implements a custom callback function to handle node hovering events within the mini-map, allowing for tooltips or other interactive feedback. ```cpp // User callback void mini_map_node_hovering_callback(int node_id, void* user_data) { ImGui::SetTooltip("This is node %d", node_id); } // Later on... ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight, mini_map_node_hovering_callback, custom_user_data); ``` -------------------------------- ### CMake: DLL Existence Checks for Game Targets Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt Uses the `check_dlls_exist` helper function to verify the presence of required .NET DLLs for various game targets including RE2, RE4, DMC5, DD2, and MHWILDS. The results are stored in boolean variables. ```cmake # RE2 set(RE2_DLLS "REFramework.NET._mscorlib.dll;REFramework.NET._System.dll;REFramework.NET._System.Core.dll;REFramework.NET.application.dll;REFramework.NET.viacore.dll") check_dlls_exist("re2" "${RE2_DLLS}" "REFRAMEWORK_REF_ASSEMBLIES_EXIST_RE2") # RE4 set(RE4_DLLS "REFramework.NET._mscorlib.dll;REFramework.NET._System.dll;REFramework.NET._System.Core.dll;REFramework.NET.application.dll;REFramework.NET.viacore.dll") check_dlls_exist("re4" "${RE4_DLLS}" "REFRAMEWORK_REF_ASSEMBLIES_EXIST_RE4") # DMC5 set(DMC5_DLLS "REFramework.NET._mscorlib.dll;REFramework.NET._System.dll;REFramework.NET._System.Core.dll;REFramework.NET.application.dll;REFramework.NET.viacore.dll") check_dlls_exist("dmc5" "${DMC5_DLLS}" "REFRAMEWORK_REF_ASSEMBLIES_EXIST_DMC5") # DD2 set(DD2_DLLS "REFramework.NET._System.dll;REFramework.NET.application.dll;REFramework.NET.viacore.dll") check_dlls_exist("dd2" "${DD2_DLLS}" "REFRAMEWORK_REF_ASSEMBLIES_EXIST_DD2") # MHWILDS set(MHWILDS_DLLS "REFramework.NET._System.Private.CoreLib.dll;REFramework.NET.application.dll;REFramework.NET.viacore.dll") check_dlls_exist("mhwilds" "${MHWILDS_DLLS}" "REFRAMEWORK_REF_ASSEMBLIES_EXIST_MHWILDS") ``` -------------------------------- ### Configure ObjectExplorer Library (CMake) Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt This CMake script configures the ObjectExplorer library. It conditionally builds a SHARED C# library if RE2 assemblies exist, specifying source files, linking to the csharp-api, setting .NET-specific properties like SDK and target framework, and defining .NET references. ```cmake if(REFRAMEWORK_REF_ASSEMBLIES_EXIST_RE2) # build-csharp-test-re2 set(ObjectExplorer_SOURCES "test/Test/ObjectExplorer.cs" cmake.toml ) add_library(ObjectExplorer SHARED) target_sources(ObjectExplorer PRIVATE ${ObjectExplorer_SOURCES}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${ObjectExplorer_SOURCES}) target_link_libraries(ObjectExplorer PUBLIC csharp-api ) set_target_properties(ObjectExplorer PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/" RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/bin" RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin" LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/lib" LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/lib" LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/lib" DOTNET_SDK Microsoft.NET.Sdk DOTNET_TARGET_FRAMEWORK net10.0-windows VS_CONFIGURATION_TYPE ClassLibrary ) set(CMKR_TARGET ObjectExplorer) set_dotnet_references(ObjectExplorer "re2" "${RE2_DLLS}") endif() ``` -------------------------------- ### CMake: Helper Functions for .NET References and DLL Checks Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt Defines two CMake helper functions: `set_dotnet_references` to set Visual Studio .NET target properties and package references, and `check_dlls_exist` to verify the presence of specific DLL files in a given directory. ```cmake # Helper function for setting target properties with custom DLLs function(set_dotnet_references TARGET DLL_PREFIX DLLS) foreach(dll IN ITEMS ${DLLS}) string(REPLACE "REFramework.NET." "" DLL_NAME ${dll}) string(REPLACE ".dll" "" DLL_NAME ${DLL_NAME}) set_target_properties(${TARGET} PROPERTIES VS_DOTNET_REFERENCE_${DLL_NAME} "${CMAKE_BINARY_DIR}/bin/${DLL_PREFIX}/REFramework.NET.${DLL_NAME}.dll" ) set_target_properties(${TARGET} PROPERTIES VS_PACKAGE_REFERENCES "REFramework.NET.${DLL_NAME}" ) endforeach() set_target_properties(${TARGET} PROPERTIES VS_DOTNET_REFERENCE_REFramework.NET "${REFRAMEWORK_DOT_NET_ASSEMBLY_PATH}" ) endfunction() # Helper function for checking custom DLL existence function(check_dlls_exist DLL_PREFIX DLLS VAR_NAME) message(STATUS "${VAR_NAME} Checking for DLLs in ${CMAKE_BINARY_DIR}/bin/${DLL_PREFIX}") set(${VAR_NAME} TRUE PARENT_SCOPE) foreach(dll IN ITEMS ${DLLS}) if(NOT EXISTS "${CMAKE_BINARY_DIR}/bin/${DLL_PREFIX}/${dll}") set(${VAR_NAME} FALSE) message(STATUS "DLL ${dll} does not exist in ${CMAKE_BINARY_DIR}/bin/${DLL_PREFIX}") break() endif() endforeach() if (NOT ${${VAR_NAME}}) set(${VAR_NAME} FALSE PARENT_SCOPE) message(STATUS "One or more specified DLLs do not exist (${DLL_PREFIX})") else() message(STATUS "All specified DLLs exist (${DLL_PREFIX})") endif() endfunction() ``` -------------------------------- ### re.on_frame Source: https://context7.com/praydog/reframework/llms.txt Registers a callback function to be executed every frame, ideal for continuous game state monitoring and logic updates. ```APIDOC ## re.on_frame ### Description Registers a callback that is invoked at the start of every frame update cycle. ### Method Lua Function ### Parameters - **callback** (function) - Required - The function to execute every frame. ### Request Example ```lua re.on_frame(function() -- Logic here end) ``` ``` -------------------------------- ### Set C++ Function in Lua using sol2 Source: https://github.com/praydog/reframework/blob/master/dependencies/sol2/README.md This C++ code snippet demonstrates how to expose a C++ function to Lua using the sol2 library. It sets up a Lua state, defines a C++ lambda function that increments an integer, and then calls this function from Lua. The primary dependency is the sol2 header-only library. ```cpp #include #include int main() { sol::state lua; int x = 0; lua.set_function("beep", [&x]{ ++x; }); lua.script("beep()"); assert(x == 1); } ``` -------------------------------- ### sdk.typeof Source: https://context7.com/praydog/reframework/llms.txt Retrieves a System.Type object for a given type name, facilitating reflection-based operations like component lookups. ```APIDOC ## sdk.typeof ### Description Returns a `System.Type` object corresponding to the provided type name string, used for reflection and API calls requiring type identification. ### Method Lua Function ### Parameters - **type_name** (string) - Required - The name of the type to retrieve. ### Request Example ```lua local component_type = sdk.typeof("app.PlayerController") ``` ### Response - **type_object** (userdata) - The System.Type object. ``` -------------------------------- ### Define REFCoreDeps Library with CMake Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt This CMake code defines a shared library named `REFCoreDeps`. It specifies the source files, including C# files and a `cmake.toml` configuration. It also sets various target properties such as output directories, the .NET SDK, target framework, and Visual Studio configuration type, and links the generated NuGet package references. ```cmake set(REFCoreDeps_SOURCES "REFCoreDeps/Compiler.cs" "REFCoreDeps/GarbageCollectionDisplay.cs" "REFCoreDeps/HashHelper.cs" "REFCoreDeps/PipeServer.cs" cmake.toml ) add_library(REFCoreDeps SHARED) target_sources(REFCoreDeps PRIVATE ${REFCoreDeps_SOURCES}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${REFCoreDeps_SOURCES}) set_target_properties(REFCoreDeps PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/" RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/bin" RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin" LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/lib" LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/lib" LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/lib" DOTNET_SDK Microsoft.NET.Sdk DOTNET_TARGET_FRAMEWORK net10.0-windows VS_CONFIGURATION_TYPE ClassLibrary ) set(CMKR_TARGET REFCoreDeps) set_target_properties(REFCoreDeps PROPERTIES VS_PACKAGE_REFERENCES "${REFRAMEWORK_PACKAGE_REFERENCES}") ``` -------------------------------- ### Register ImGui UI Callback with re.on_draw_ui Source: https://context7.com/praydog/reframework/llms.txt Registers a callback function to draw custom ImGui UI elements within the REFramework overlay. This function is typically used for creating in-game menus or debug interfaces. It requires the ImGui library to be available. ```lua local settings = { god_mode = false, infinite_ammo = false, speed_multiplier = 1.0, teleport_position = Vector3f.new(0, 0, 0) } re.on_draw_ui(function() local changed = false if imgui.tree_node("My Mod Settings") then changed, settings.god_mode = imgui.checkbox("God Mode", settings.god_mode) changed, settings.infinite_ammo = imgui.checkbox("Infinite Ammo", settings.infinite_ammo) changed, settings.speed_multiplier = imgui.slider_float("Speed", settings.speed_multiplier, 0.1, 10.0) imgui.separator() if imgui.button("Teleport to Origin") then local player = get_player() if player then local transform = player:call("get_Transform") transform:call("set_Position", Vector3f.new(0, 0, 0)) end end -- Display player info local player = get_player() if player then local pos = player:call("get_Position") imgui.text(string.format("Position: %.2f, %.2f, %.2f", pos.x, pos.y, pos.z)) end imgui.tree_pop() end end) ``` -------------------------------- ### Manage NuGet Packages and Versions Source: https://github.com/praydog/reframework/blob/master/csharp-api/CMakeLists.txt This CMake code defines a list of NuGet packages with their versions and target frameworks. It then iterates through this list to construct a string of package references, formatted as 'PackageName_Version;', which is stored in the `REFRAMEWORK_PACKAGE_REFERENCES` variable. ```cmake set(REFRAMEWORK_NUGET_PACKAGES "Microsoft.CodeAnalysis.Common:4.9.2:net7.0" "Microsoft.CodeAnalysis.CSharp:4.9.2:net7.0" "Hexa.NET.ImGui:2.2.9:net8.0" "HexaGen.Runtime:1.1.21:net8.0" ) set(REFRAMEWORK_PACKAGE_REFERENCES "") foreach(PACKAGE ${REFRAMEWORK_NUGET_PACKAGES}) string(REPLACE ":" ";" PACKAGE_PARTS ${PACKAGE}) list(GET PACKAGE_PARTS 0 PACKAGE_NAME) list(GET PACKAGE_PARTS 1 PACKAGE_VERSION) set(REFRAMEWORK_PACKAGE_REFERENCES "${REFRAMEWORK_PACKAGE_REFERENCES}${PACKAGE_NAME}_${PACKAGE_VERSION};") endforeach() ``` -------------------------------- ### Manipulate 4x4 Matrices Source: https://github.com/praydog/reframework/blob/master/dependencies/imguizmo/README.md The primary function to render and interact with the gizmo. It requires view and projection matrices and supports translation, rotation, and scale operations in either local or world space. ```C++ enum OPERATION { TRANSLATE, ROTATE, SCALE }; enum MODE { LOCAL, WORLD }; void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix = 0, float *snap = 0); ``` -------------------------------- ### Create and Interact with C++ User Types in Lua using sol2 Source: https://github.com/praydog/reframework/blob/master/dependencies/sol2/README.md This C++ code snippet illustrates how to define and use C++ user-defined types within Lua using the sol2 library. It creates a Lua state, registers a C++ struct 'vars' with its member 'boop', and then creates and manipulates an instance of this type from Lua. The sol2 library is the main dependency. ```cpp #include #include struct vars { int boop = 0; }; int main() { sol::state lua; lua.new_usertype("vars", "boop", &vars::boop); lua.script("beep = vars.new()\nbeep.boop = 1"); assert(lua.get("beep").boop == 1); } ``` -------------------------------- ### Hook Game Methods with sdk.hook Source: https://context7.com/praydog/reframework/llms.txt Intercepts game method calls to modify parameters or return values. Supports both pre-hooks (before execution) and post-hooks (after execution) to control game logic flow. ```lua local player_type = sdk.find_type_definition("app.PlayerBase") local take_damage_method = player_type:get_method("takeDamage") local function on_pre_take_damage(args) local player = sdk.to_managed_object(args[1]) local damage = sdk.to_int64(args[2]) print("Player taking " .. damage .. " damage!") args[2] = sdk.to_ptr(damage / 2) return sdk.PreHookResult.CALL_ORIGINAL end local function on_post_take_damage(retval) return retval end sdk.hook(take_damage_method, on_pre_take_damage, on_post_take_damage) ```