A comprehensive template for creating datafile plugins for Blade & Soul using my BnsDatafilePlugin SDK. This template provides a starting point for developers who want to create plugins that can intercept, modify, or extend game data table lookups.
- Table Interception: Hook into game data table lookups and modify behavior
- ImGui Integration: Built-in UI panels for plugin configuration and debugging
- Example Implementation: Complete working example with item table detour
- Comprehensive Documentation: Well-documented code with examples
- Windows 10 SDK (10.0.19041.0 or later)
- DatafilePluginSdk (included in
external/PluginSdk/) - BnsPluginTables (included in
external/BnsPluginTables/)
| Configuration | Platform | Output | Use Case |
|---|---|---|---|
| Debug | x64 | Template.dll | Development & Testing |
| Release | x64 | Template.dll | Production |
| Debug with Persistence | x64 | Template.dll | Development & Testing with Persistence |
| Release with Persistence | x64 | Template.dll | Production with Persistence |
The template demonstrates the essential components of a datafile plugin:
// 1. Define detour functions for specific tables
static PluginReturnData __fastcall DatafileItemDetour(PluginExecuteParams* params) {
// Intercept item lookups and optionally modify behavior
return {};
}
// 2. Create ImGui panels for configuration
static void TemplateUiPanel(void* userData) {
g_imgui->Text("Plugin configuration goes here");
}
// 3. Register table handlers
PluginTableHandler handlers[] = {
{ L"item", &DatafileItemDetour }
};-
Modify Plugin Metadata in CMakeLists.txt:
set(PLUGIN_NAME "Template") project ("BnsDatafilePlugin" VERSION 1.0.0)
ONLY CHANGE THE PLUGIN_NAME AND VERSION HERE!
DO NOT CHANGE THE PROJECT NAME (BnsDatafilePlugin) OR OTHER CMAKE CONFIG UNLESS YOU ARE EXPERIENCED! -
Add Table Handlers:
PluginTableHandler handlers[] = { { L"item", &YourItemDetour }, { L"skill", &YourSkillDetour }, // Add more table handlers as needed }; -
Implement Custom Logic:
- Modify the detour functions to implement your specific functionality
- Use
params->oFind()to perform original lookups - Return
PluginReturnDatawith a replacement element if needed - Use
params->displaySystemChatMessage()for ingame chat messages
-
Customize UI Panel:
- Modify
ConfigUiPanel()to add configuration options - Use ImGui API through
g_imguipointer
- Modify
The plugin can intercept lookups for all game tables (see deps/BnsPluginTables/Generated/include/EU/)
The template includes a commented example showing how to redirect one item to another:
static PluginReturnData __fastcall DatafileItemDetour(PluginExecuteParams* params) {
PLUGIN_DETOUR_GUARD(params, BnsTables::EU::TableNames::GetTableVersion);
unsigned __int64 key = params->key;
// Redirect item key 4295877296 to 4295917336
if (key == 4295877296) {
BnsTables::Shared::DrEl* result = params->oFind(params->table, 4295917336);
return { result };
}
return {}; // No modification
}auto itemRecord = GetRecord<BnsTables::EU::item_Record>(g_dataManager, L"item", 4295917336, g_oFind);ForEachRecord<BnsTables::EU::item_Record>(g_dataManager, L"item", [](BnsTables::EU::item_Record* record, size_t index) {
// Do something with each item record
std::wcout << L"Item Name: " << record->alias << std::endl;
return true; //Return true to continue the loop. Return false to break the loop.
});The template includes a logging setup into datafilePlugins/logs
Logger::Log(std::string(PLUGIN_NAME) + " (v" + std::string(PLUGIN_VERSION) + ") async setup complete.");
Logger::LogError(std::string(PLUGIN_NAME) + " (v" + std::string(PLUGIN_VERSION) + ") async setup failed.");Conditional compilation allows you to include or exclude parts of the code based on compile-time conditions. For example:
Build with ENABLE_PERSISTENCE = true
This setting determines whether the plugin stores its plugin_config in a file or not.
#ifdef PLUGIN_ENABLE_PERSISTENCE
// Code for persistence feature
#endifBuild with BNSKR = true
This setting allows you to compile the plugin specifically for the Korean version of the game.
#ifdef BNSKR
// Code specific to KR version
#else
// Code for other versions
#endifIf you use Visual Studio, you can select the desired build configuration from the toolbar.
- System Chat Messages: Use
params->displaySystemChatMessage()to output debug info ingame - ImGui Panels: Create interactive debug panels
- Visual Studio Debugging: Attach to the game process for step-through debugging
PLUGIN_DETOUR_GUARD(params, BnsTables::EU::TableNames::GetTableVersion);Use this guard macro at the beginning of detour functions for proper version check and error handling.
This makes the detour not execute if the compiled table version does not match the game version.
PluginExecuteParams: Parameters passed to detour functionsPluginInitParams: Initialization parametersPluginReturnData: Return structure for detour functionsPluginTableHandler: Maps table names to detour functions
Access ImGui functionality through the g_imgui pointer:
For example:
g_imgui->Text("Hello World");
g_imgui->Button("Click Me");
g_imgui->InputText("Input", buffer, sizeof(buffer));- Plugin API Version: Make sure to keep your submodules updated for best compatibility
- Memory Management: Be careful with memory allocation/deallocation
- Game Compatibility: Test thoroughly with target game version
- Performance: Minimize processing in detour functions to avoid game lag
This template is provided as-is for educational and development purposes.
Author: LEaN