### Example: Replacing Main Menu Start Game Action Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Demonstrates how to register a wrapper type, instantiate it, set a command handler, and replace an existing DataContext. ```APIDOC ## Example: Main Menu Start Game Action ### Description This example illustrates a practical use case: replacing the main menu's start game action by registering a wrapper ViewModel, instantiating it, assigning a custom handler to its command, and updating the widget's DataContext. ### Method N/A (Illustrative Script) ### Endpoint N/A (Client-side Script) ### Code Example ```lua -- Register a wrapper type for the main menu DataContext Ext.UI.RegisterType("SAMPLE_MainMenuCtx", { StartGameCommand = {Type = "Command"} -- builtin command to start game }, "gui::DCMainMenu") -- gui::DCMainMenu is the name of the ingame main menu DataContext -- Jank sample code for getting a widget, DON'T DO IT LIKE THIS! local mainMenu = Ext.UI.GetRoot():Find("ContentRoot"):VisualChild(1) -- Create a wrapper around the original main menu DataContext local ctx = Ext.UI.Instantiate("se::SAMPLE_MainMenuCtx", mainMenu.DataContext) ctx.StartGameCommand:SetHandler(function () print("do stuff") end) -- Overwrite datacontext with our wrapper mainMenu.DataContext = ctx ``` ``` -------------------------------- ### Complete TileSet Configuration Example Source: https://github.com/norbyte/bg3se/blob/main/Docs/VirtualTextures.md A full example of a tile set configuration XML including paths, textures, layers, and build settings. ```xml Public\YOUR_MOD_NAME\Assets\Textures Public\YOUR_MOD_NAME\Assets\VirtualTextures Best false true true ``` -------------------------------- ### Get and Modify Skill Data Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md This example demonstrates how to retrieve all skill data entries, iterate through them, and modify a specific attribute (`DamageType`). It uses `Ext.Stats.GetStats` to get a list of stat names and `Ext.Stats.Get` to access individual stat objects. ```lua -- Swap DamageType from Poison to Air on all skills for i,name in pairs(Ext.Stats.GetStats("SkillData")) do local stat = Ext.Stats.Get(name) if stat.DamageType == "Poison" then stat.DamageType = "Air" end end ``` -------------------------------- ### Create NetChannel Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Example of creating a new NetChannel with a unique module identifier and channel name. This should be done in shared files. ```lua -- Shared: create channels for both server and client Channels = {} Channels.TemplateAddTo = Ext.Net.CreateChannel(ModuleUUID, "TemplateAddTo") return Channels ``` -------------------------------- ### Client-side Send Message to Server Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Example of a client sending a message to the server using `SendToServer`. This is a fire-and-forget operation. ```lua -- Client side: send message to server Channels.TemplateAddTo:SendToServer({ Items = { {"item-template-guid-1", 1}, {"item-template-guid-2", 2} }, Target = someEntityId }) ``` -------------------------------- ### Create Mod Directory Symlinks Source: https://github.com/norbyte/bg3se/blob/main/Docs/Debugger.md Commands to link your VS Code project mod folder to the game's installation directory for testing. ```shell mklink /D "\Data\Mods\" "\Mods\" ``` ```shell ln -s /Mods// /Data/Mods/ ``` -------------------------------- ### Accessing Static Game Resources Source: https://context7.com/norbyte/bg3se/llms.txt Use these methods to retrieve resource GUIDs or full resource objects from the game's static data tables. ```lua -- Get all resources of a type local raceGuids = Ext.StaticData.GetAll("Race") local classGuids = Ext.StaticData.GetAll("ClassDescription") local backgroundGuids = Ext.StaticData.GetAll("Background") -- Get specific resource local race = Ext.StaticData.Get("race-uuid", "Race") print(race.Name) -- Get resources by mod local modRaces = Ext.StaticData.GetByModId("Race", ModuleUUID) ``` -------------------------------- ### Check Mod Load Status Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Verify if a specific module is loaded using its GUID. ```lua if (Ext.Mod.IsModLoaded("5cc23efe-f451-c414-117d-b68fbc53d32d")) _P("Mod loaded") end ``` -------------------------------- ### Get mod load order and details Source: https://context7.com/norbyte/bg3se/llms.txt Retrieves the load order of all mods and detailed information for a specific mod using its UUID. Includes name, author, version, and directory. ```lua local loadOrder = Ext.Mod.GetLoadOrder() for i, uuid in ipairs(loadOrder) do local mod = Ext.Mod.GetMod(uuid) print(i .. ": " .. mod.Info.Name .. " (" .. uuid .. ")") end local mod = Ext.Mod.GetMod("your-mod-uuid") print("Name: " .. mod.Info.Name) print("Author: " .. mod.Info.Author) print("Version: " .. mod.Info.ModVersion) print("Directory: " .. mod.Info.Directory) ``` -------------------------------- ### Server-side Handler for Template Addition Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Example of a server-side handler that processes incoming messages to add items. It uses `SetHandler` and does not expect a reply. ```lua -- Server side: handle requests -- Using SetHandler: note there's no reply callback Channels.TemplateAddTo:SetHandler(function(data, user) for _, v in pairs(data.Items) do local template, amount = table.unpack(v) _P("Adding " .. template .. " to " .. data.Target .. " with amount " .. amount) Osi.TemplateAddTo(template, data.Target, amount or 1) end end) ``` -------------------------------- ### Read Osiris Databases Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Retrieve rows from databases using the Get method with optional column filters. ```lua -- Fetch all rows from DB_GiveTemplateFromNpcToPlayerDialogEvent local rows = Osi.DB_GiveTemplateFromNpcToPlayerDialogEvent:Get(nil, nil, nil) -- Fetch rows where the first column is CON_Drink_Cup_A_Tea_080d0e93-12e0-481f-9a71-f0e84ac4d5a9 local rows = Osi.DB_GiveTemplateFromNpcToPlayerDialogEvent:Get("CON_Drink_Cup_A_Tea_080d0e93-12e0-481f-9a71-f0e84ac4d5a9", nil, nil) ``` -------------------------------- ### Get current game state Source: https://context7.com/norbyte/bg3se/llms.txt Retrieves the current state of the game, such as whether it's in the main menu, in-game, or loading. ```lua local state = Ext.Utils.GetGameState() print("Game State: " .. tostring(state)) ``` -------------------------------- ### Get game version Source: https://context7.com/norbyte/bg3se/llms.txt Retrieves the version string of the running Baldur's Gate 3 game. Essential for ensuring mod compatibility with the game version. ```lua local gameVersion = Ext.Utils.GameVersion() print("Game Version: " .. gameVersion) ``` -------------------------------- ### Get and Update Localized Strings Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use Ext.Loca.GetTranslatedString to retrieve localized text and Ext.Loca.UpdateTranslatedString to override it at runtime. Ensure you have the correct localization handle. ```lua local text = Ext.Loca.GetTranslatedString("h1234567890abcdef1234567890abcdefg") Ext.Loca.UpdateTranslatedString("h1234567890abcdef1234567890abcdefg", text .. " (modified)") ``` -------------------------------- ### Multiline Console Input Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Enter multiline code into the console by starting input with '--[[' and closing with ']]--'. This is useful for longer scripts or loops. ```lua --[[ someTable={1,2,3,4,5} for key,value in pairs(someTable) do print(value) end ]]-- ``` -------------------------------- ### Get All Components Attached to an Entity Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Fetches all components known to the Script Extender that are attached to a given entity. Note that components with unknown structures are omitted. ```lua local entity = Ext.Entity.Get(GetHostCharacter()) _D(entity:GetAllComponents()) -- Prints: -- { -- "ActionResources" : -- { -- "Entity" : "Entity (02c0000100000180)", -- "GetReplicationFlags" : "function: 00007FFDE482D5E0", -- ... -- } -- } ``` -------------------------------- ### Get Script Extender version Source: https://context7.com/norbyte/bg3se/llms.txt Retrieves the version string of the installed Script Extender. Useful for compatibility checks. ```lua local version = Ext.Utils.Version() print("SE Version: " .. version) ``` -------------------------------- ### Ext.Entity.OnCreate Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Subscription for component creation events. ```lua OnCreate(componentName, callback, [entity], [opt1], [opt2]) ``` -------------------------------- ### Ext.Entity.OnCreateOnce Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md One-shot create subscription that auto-unsubscribes after the first match. ```lua OnCreateOnce(componentName, callback, [entity]) ``` -------------------------------- ### Define Bootstrap Scripts Source: https://context7.com/norbyte/bg3se/llms.txt Entry points for server-side and client-side Lua logic. Use Ext.Require to load additional modular scripts. ```lua -- Mods/YourMod/ScriptExtender/Lua/BootstrapServer.lua Ext.Require("Server/Main.lua") Ext.Require("Server/Combat.lua") -- Mods/YourMod/ScriptExtender/Lua/BootstrapClient.lua Ext.Require("Client/UI.lua") Ext.Require("Client/Effects.lua") ``` -------------------------------- ### Utilities - Ext.Utils Source: https://context7.com/norbyte/bg3se/llms.txt General utility functions for version checking, game state management, and handle conversions. ```APIDOC ## Ext.Utils ### Description General purpose helper functions for debugging and system information. ### Methods - **Ext.Utils.Version()**: Returns the Script Extender version. - **Ext.Utils.GameVersion()**: Returns the game version. - **Ext.Utils.GetGameState()**: Returns the current game state. - **Ext.Utils.Print/PrintWarning/PrintError**: Logging utilities. - **Ext.Utils.HandleToInteger/IntegerToHandle**: Handle conversion utilities. ``` -------------------------------- ### Ext.Entity.OnCreateDeferredOnce Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Deferred and one-shot variant of OnCreate. ```lua OnCreateDeferredOnce(componentName, callback, [entity]) ``` -------------------------------- ### Verify Debugger Server Startup Source: https://github.com/norbyte/bg3se/blob/main/Docs/Debugger.md Expected output in the extender console log when the debugger server initializes successfully. ```text Starting Lua debugger server Debugger::Debugger(): Starting Lua debugger Lua debugger listening on 127.0.0.1:9998; DBG protocol version 3 ``` -------------------------------- ### I/O - Ext.IO Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Provides server and client filesystem helper functions for loading, saving, and redirecting file access. ```APIDOC ## I/O - `Ext.IO` Server and client filesystem helpers. ### Methods - `Ext.IO.LoadFile(path, [context]): string?` Reads file contents. Returns `nil` if the file cannot be read. - `Ext.IO.SaveFile(path, content): boolean` Writes content to a file. Creates missing parent directories. - `Ext.IO.AddPathOverride(originalPath, newPath)` Redirects game file access from `originalPath` to `newPath`. - `Ext.IO.GetPathOverride(path): string?` Returns active override target for `path`, if any. `AddPathOverride` should be called as early as possible (typically `ModuleLoadStarted`), before the original resource is loaded. Example: ```lua Ext.IO.AddPathOverride("Public/Game/GUI/enemyHealthBar.swf", "Public/YourMod/GUI/enemyHealthBar.swf") ``` ``` -------------------------------- ### Configure Launch Task Integration Source: https://github.com/norbyte/bg3se/blob/main/Docs/Debugger.md Fields to add to your launch.json configuration to link the game process lifecycle with the debugger. ```json ... "configurations": [ { "preLaunchTask": "bg3Continue", "postDebugTask": "bg3Kill", "internalConsoleOptions": "openOnSessionStart", ... ``` -------------------------------- ### Subscribe to SessionLoaded Event Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Fires after a game session has been successfully set up. ```lua Ext.Events.SessionLoaded:Subscribe(function() -- Code to run after a session is loaded end) ``` -------------------------------- ### Get All Component Names for an Entity Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Retrieves a list of all component type names attached to an entity. Useful for inspecting an entity's capabilities. ```lua local char = Ext.Entity.Get(GetHostCharacter()) _D(char:GetAllComponentNames()) -- Prints: -- { -- "eoc::ActionResourcesComponent" : "eoc::ActionResourcesComponent Object (1c4000010000039e)", -- "eoc::BackgroundComponent" : "eoc::BackgroundComponent Object (1e000001000003ff)", -- "eoc::BackgroundPassivesComponent" : "eoc::BackgroundPassivesComponent Object (66c00001000003ff)", -- ... -- } ``` -------------------------------- ### File I/O - Ext.IO Source: https://context7.com/norbyte/bg3se/llms.txt Enables reading and writing files within the Script Extender directory and managing game file path overrides. ```APIDOC ## Ext.IO ### Description Provides file system access for reading/writing configuration files and overriding game asset paths. ### Methods - **Ext.IO.SaveFile(path, content)**: Saves a string to a file in the Script Extender directory. - **Ext.IO.LoadFile(path)**: Loads the content of a file from the Script Extender directory. - **Ext.IO.AddPathOverride(originalPath, overridePath)**: Redirects game file requests to a custom path. - **Ext.IO.GetPathOverride(path)**: Retrieves the current override path for a given file. ``` -------------------------------- ### Subscribe to ModuleLoadStarted Event Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use this to add filesystem-level hooks before mod data is loaded. Most mod editing functionality is unavailable at this stage. ```lua Ext.Events.ModuleLoadStarted:Subscribe(function() -- Code to run when module loading starts end) ``` -------------------------------- ### Get a Specific Component from an Entity Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Retrieves a specific component by its name from an entity. Returns nil if the component is not found or its structure is unknown to the Script Extender. ```lua local entity = Ext.Entity.Get(GetHostCharacter()) _D(entity:GetComponent("DisplayName")) -- Prints: -- { -- "Entity" : "Entity (02c0000100000180)", -- "Name" : "Tav", -- "NameKey" : "ResStr_669727657", -- ... -- } ``` -------------------------------- ### Load Scripts with Ext.Require Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use Ext.Require to load additional Lua files during module startup. Paths are relative to the mod's Lua folder. ```lua Ext.Require("Server/SkillMechanics.lua") ``` -------------------------------- ### Ext.Entity.OnSystemPostUpdate Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Subscribes to ECS system post-update hooks. ```lua OnSystemPostUpdate(systemType, callback, [once]) ``` -------------------------------- ### Get translated string by handle Source: https://context7.com/norbyte/bg3se/llms.txt Retrieves a translated string from the game's localization data using its unique handle. Fallback text can be provided. ```lua local text = Ext.Loca.GetTranslatedString("h1234567890abcdef1234567890abcdefg") print(text) local textWithFallback = Ext.Loca.GetTranslatedString("h123...", "Default Text") ``` -------------------------------- ### Configure Event Subscription Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use an options table to set priority or execution frequency for event handlers. ```lua Ext.Events.GameStateChanged:Subscribe(handler, { Priority = 50, Once = true }) ``` -------------------------------- ### Console Commands - Ext.RegisterConsoleCommand Source: https://context7.com/norbyte/bg3se/llms.txt Allows registration of custom console commands that can be triggered via the game console. ```APIDOC ## Ext.RegisterConsoleCommand ### Description Registers a custom command handler that can be invoked using the '!' prefix in the console. ### Parameters - **commandName** (string) - Required - The name of the command. - **callback** (function) - Required - The function to execute when the command is called. ``` -------------------------------- ### Iterate and Modify Spell Autocast Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Loop through all spells and disable autocast if it's currently enabled. This example demonstrates reading and writing stat properties in a loop. ```lua for i,name in pairs(Ext.Stats.GetStats("SpellData")) do local spell = Ext.Stats.Get(name) if spell.Autocast == "Yes" then spell.Autocast = "No" end end ``` -------------------------------- ### Replace Main Menu DataContext Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Demonstrates wrapping an existing DataContext to intercept and handle UI commands. ```lua -- Register a wrapper type for the main menu DataContext Ext.UI.RegisterType("SAMPLE_MainMenuCtx", { StartGameCommand = {Type = "Command"} -- builtin command to start game }, "gui::DCMainMenu") -- gui::DCMainMenu is the name of the ingame main menu DataContext -- Jank sample code for getting a widget, DON'T DO IT LIKE THIS! local mainMenu = Ext.UI.GetRoot():Find("ContentRoot"):VisualChild(1) -- Create a wrapper around the original main menu DataContext local ctx = Ext.UI.Instantiate("se::SAMPLE_MainMenuCtx", mainMenu.DataContext) ctx.StartGameCommand:SetHandler(function () print("do stuff") end) -- Overwrite datacontext with our wrapper mainMenu.DataContext = ctx ``` -------------------------------- ### Handle Networking with Ext.Net Source: https://context7.com/norbyte/bg3se/llms.txt Facilitate communication between client and server using channels for messages, requests, and broadcasts. ```lua -- Create channels (do in shared code loaded by both client and server) local Channels = {} Channels.MyAction = Ext.Net.CreateChannel(ModuleUUID, "MyAction") Channels.SyncData = Ext.Net.CreateChannel(ModuleUUID, "SyncData") -- Server: Handle incoming messages Channels.MyAction:SetHandler(function(data, user) print("Received from client: " .. data.action) Osi.TemplateAddTo(data.template, data.target, data.amount) end) -- Client: Send message to server Channels.MyAction:SendToServer({ action = "addItem", template = "item-template-guid", target = characterUuid, amount = 5 }) -- Server: Handle request with reply Channels.SyncData:SetRequestHandler(function(data, user) local entity = Ext.Entity.Get(data.target) return { health = entity.Health.Hp, maxHealth = entity.Health.MaxHp } end) -- Client: Request with callback Channels.SyncData:RequestToServer({ target = characterUuid }, function(response) print("Health: " .. response.health .. "/" .. response.maxHealth) end) -- Server: Broadcast to all clients Channels.SyncData:Broadcast({ globalState = "updated" }) -- Server: Send to specific client Channels.SyncData:SendToClient({ message = "hello" }, clientUserId) -- Check if host if Ext.Net.IsHost() then print("This client is the host") end ``` -------------------------------- ### Get game object template by ID Source: https://context7.com/norbyte/bg3se/llms.txt Retrieves a specific game object template (e.g., character, item definition) using its unique identifier. Also provides access to root templates and all root templates. ```lua local template = Ext.Template.GetTemplate("template-uuid") local rootTemplate = Ext.Template.GetRootTemplate("template-uuid") local allTemplates = Ext.Template.GetAllRootTemplates() for id, template in pairs(allTemplates) do print(id, template.Name) end -- Server-only: local and cache templates local localTemplate = Ext.Template.GetLocalTemplate("template-uuid") local cacheTemplate = Ext.Template.GetCacheTemplate("template-uuid") ``` -------------------------------- ### Measure Execution Time with Ext.Timer Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use monotonic time to profile code execution duration in milliseconds. ```lua local startTime = Ext.Timer.MonotonicTime() DoLongTask() local endTime = Ext.Timer.MonotonicTime() _P("Took: " .. tostring(endTime - startTime) .. " ms") ``` -------------------------------- ### Static Data - Ext.StaticData Source: https://context7.com/norbyte/bg3se/llms.txt Access static game resources such as races, classes, and backgrounds. ```APIDOC ## Static Data - Ext.StaticData ### Description Access static game resources like races, classes, and backgrounds. ### Method Various (Lua functions) ### Endpoint N/A (Lua API) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua -- Get all resources of a type local raceGuids = Ext.StaticData.GetAll("Race") local classGuids = Ext.StaticData.GetAll("ClassDescription") local backgroundGuids = Ext.StaticData.GetAll("Background") -- Get specific resource local race = Ext.StaticData.Get("race-uuid", "Race") print(race.Name) -- Get resources by mod local modRaces = Ext.StaticData.GetByModId("Race", ModuleUUID) ``` ### Response #### Success Response (200) Returns Lua tables containing static data. #### Response Example ```json { "example": "race.Name (string)" } ``` ``` -------------------------------- ### Instantiating a ViewModel Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Constructs a new instance of a registered ViewModel type. Can optionally wrap an existing DataContext. ```APIDOC ## POST /api/viewmodels/instantiate ### Description Constructs and returns a new instance of a specified ViewModel type. If wrapping an existing DataContext, it should be provided as the second argument. ### Method POST ### Endpoint /api/viewmodels/instantiate ### Parameters #### Query Parameters - **type** (String) - Required - The registered name of the ViewModel type to instantiate. - **wrappedViewModel** (Object) - Optional - The existing DataContext object to wrap. #### Request Body *Note: The request body is not explicitly defined for this operation in the provided text, but conceptually it would contain the parameters passed to the function.* ### Request Example (No Wrapper) ```lua local vm = Ext.UI.Instantiate("PREFIX_YourTypeName") vm.MyStringProperty = "whatever" ``` ### Request Example (With Wrapper) ```lua local vm = Ext.UI.Instantiate("se::PREFIX_YourTypeName", mainMenu.DataContext) mainMenu.DataContext = vm ``` ### Response #### Success Response (200) - **instance** (Object) - The newly created ViewModel instance. #### Response Example ```json { "instance": "" } ``` ``` -------------------------------- ### Ext.Entity.OnDestroyOnce Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md One-shot destroy subscription that auto-unsubscribes after the first match. ```lua OnDestroyOnce(componentName, callback, [entity]) ``` -------------------------------- ### Ext.Entity.OnDestroyDeferredOnce Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Deferred and one-shot variant of OnDestroy. ```lua OnDestroyDeferredOnce(componentName, callback, [entity]) ``` -------------------------------- ### Subscribe to SessionLoading Event Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md This event is triggered when the engine begins setting up a game session, including new games, loading saves, or joining multiplayer. ```lua Ext.Events.SessionLoading:Subscribe(function() -- Code to run when a session starts loading end) ``` -------------------------------- ### Execute User Queries Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Invoke user-defined queries (QRY) which return a success boolean. ```lua local succeeded = Osi.Qry_IsHealingStatus("DAMAGE") ``` -------------------------------- ### Ext.Entity.OnSystemUpdate Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Subscribes to ECS system update hooks. ```lua OnSystemUpdate(systemType, callback, [once]) ``` -------------------------------- ### Manage Mod Variables with Ext.Vars Source: https://context7.com/norbyte/bg3se/llms.txt Register and access persistent mod-wide data that syncs between client and server. ```lua -- Register mod variable (in bootstrap) Ext.Vars.RegisterModVariable(ModuleUUID, "GlobalSettings", { Server = true, Client = true, SyncToClient = true, Persistent = true }) -- Access mod variables local vars = Ext.Vars.GetModVariables(ModuleUUID) -- Write data vars.GlobalSettings = { difficulty = "hard", enableFeatureX = true, playerScores = {} } -- Read data local settings = vars.GlobalSettings if settings.enableFeatureX then print("Feature X is enabled") end -- Force sync Ext.Vars.SyncModVariables(ModuleUUID) ``` -------------------------------- ### Configure JSON Serialization Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use an options table to customize JSON output, such as enabling beautification or setting recursion limits. ```lua Ext.Json.Stringify(val, { Beautify = true, MaxDepth = 4 }) ``` -------------------------------- ### Entity Component Access Shorthand Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Illustrates the shorthand syntax for accessing a component using dot notation, which is equivalent to calling GetComponent. ```lua local entity = Ext.Entity.Get(GetHostCharacter()) -- The two below are equivalent local displayName = entity:GetComponent("DisplayName") local displayName = entity.DisplayName ``` -------------------------------- ### Utilities Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md General utility functions for script extender and game version checks, state retrieval, and command line arguments. ```APIDOC ## Utils - `Ext.Utils` ### Description General utility helpers. ### Common Methods - `Ext.Utils.Version(): int32` - Returns the Script Extender API version. - `Ext.Utils.GameVersion(): string?` - Returns the game version string. - `Ext.Utils.GetGameState()` - Returns the current game state enum. - `Ext.Utils.GetGlobalSwitches(): GlobalSwitches` - Returns a settings object including fields like `AiEnableSwarm`, `CanAutoSave`, `NrOfAutoSaves`, etc. - `Ext.Utils.GetCommandLineParams(): string[]` - Returns the command line arguments used to launch the game. - `Ext.Utils.HandleToInteger(handle): int64` - Converts a handle to an integer. - `Ext.Utils.IntegerToHandle(value): EntityHandle` - Converts an integer to an entity handle. - `Ext.Utils.IsValidHandle(handle): boolean` - Checks if a handle is valid. - `Ext.Utils.ProfileBegin(name)` - Starts a profiling block. - `Ext.Utils.ProfileEnd()` - Ends a profiling block. ### Example Usage (Command Line Params) ```lua local params = Ext.Utils.GetCommandLineParams() for _, param in ipairs(params) do _P(param) end ``` ``` -------------------------------- ### Subscribe to Engine Events Source: https://context7.com/norbyte/bg3se/llms.txt Register handlers for game state changes using Ext.Events. Supports priority levels and one-shot execution. ```lua -- Subscribe to game state changes Ext.Events.GameStateChanged:Subscribe(function(e) print("State changed from " .. tostring(e.FromState) .. " to " .. tostring(e.ToState)) end) -- Subscribe with priority (lower = called first) and one-shot flag Ext.Events.SessionLoaded:Subscribe(function(e) print("Session loaded - initializing mod...") -- Initialize your mod here end, { Priority = 50, Once = false }) -- Unsubscribe later using the returned handler ID local handlerId = Ext.Events.StatsLoaded:Subscribe(function(e) print("Stats loaded - applying modifications...") end) -- Later: Ext.Events.StatsLoaded:Unsubscribe(handlerId) -- Common events: -- ModuleLoadStarted - Before mod data loads (use for Ext.IO.AddPathOverride) -- StatsLoaded - After stats entries loaded (apply stat modifications here) -- SessionLoading - Game session starting -- SessionLoaded - Game session ready -- Tick - Every game tick (~30hz on server) -- ResetCompleted - After Lua state reset ``` -------------------------------- ### Instantiate a ViewModel Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Constructs a new instance of a registered ViewModel type. Supports both standalone instances and those wrapping existing DataContext objects. ```lua local vm = Ext.UI.Instantiate("PREFIX_YourTypeName") vm.MyStringProperty = "whatever" ``` ```lua local vm = Ext.UI.Instantiate("se::PREFIX_YourTypeName", mainMenu.DataContext) mainMenu.DataContext = vm ``` -------------------------------- ### Listen for NetMessages on Client Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Subscribe to Ext.Events.NetMessage to receive messages. Parse the payload if it was stringified. Ext.RegisterNetListener provides a convenient wrapper. ```lua --Client context local channel = "MyModChannel_SomethingSpecific" Ext.Events.NetMessage:Subscribe(function(data) if data.Channel == channel then --Parse the string back into a table if it was stringified local data = Ext.Json.Parse(data.Payload) --Do whatever you want with the data in the client context someFunction(data) end end) ``` ```lua --wrapper for Ext.Events.NetMessage:Subscribe(function(data) ...end) --which removes the need to check for the channel Ext.RegisterNetListener(channel, function(channel, payload, userID) --Parse the string back into a table local data = Ext.Json.Parse(payload) --Do whatever you want with the data in the client context someFunction(data) end) ``` -------------------------------- ### Iterate Loaded Mods Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Retrieve the current load order and inspect details for each loaded module. ```lua local loadOrder = Ext.Mod.GetLoadOrder() for k,uuid in pairs(loadOrder) do local mod = Ext.Mod.GetMod(uuid) _D(mod) end ``` -------------------------------- ### Ext.Math Library Functions Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md A collection of mathematical utility functions for vector and matrix operations. ```APIDOC ## Ext.Math Library ### Description The Ext.Math library provides various functions for arithmetic, vector, and matrix calculations. ### Functions - **Add** (a: any, b: any) -> any: Adds two operands. - **Sub** (a: any, b: any) -> any: Subtracts two operands. - **Mul** (a: any, b: any) -> any: Multiplies two operands. - **Div** (a: any, b: any) -> any: Divides two operands. - **Reflect** (I: vec3|vec4, N: vec3|vec4) -> vec3|vec4: Returns reflection direction. - **Angle** (a: vec3|vec4, b: vec3|vec4) -> float: Returns absolute angle between two normalized vectors. - **Cross** (x: vec3, y: vec3) -> vec3: Returns the cross product. - **Distance** (p0: vec3, p1: vec3) -> float: Returns distance between p0 and p1. - **Dot** (x: vec3, y: vec3) -> float: Returns the dot product. - **Length** (x: vec3|vec4) -> float: Returns the length of x. - **Normalize** (x: vec3|vec4) -> vec3|vec4: Returns a normalized vector. - **Determinant** (x: mat3|mat4) -> float: Returns the determinant of a matrix. - **Inverse** (x: mat3|mat4) -> mat3|mat4: Returns the inverse of a matrix. - **Transpose** (x: mat3|mat4) -> mat3|mat4: Returns the transposed matrix. - **OuterProduct** (c: vec3|vec4, r: vec3|vec4) -> mat: Returns outer product. - **Rotate** (m: mat3|mat4, angle: float, axis: vec4) -> void: Builds a rotation matrix. - **Translate** (m: mat4, translation: vec3) -> void: Transforms a matrix with translation. - **Scale** (m: mat4, translation: vec3) -> void: Transforms a matrix with scale. - **BuildRotation4** (v: vec3, angle: float) -> mat4: Builds a 4x4 rotation matrix. - **BuildRotation3** (v: vec3, angle: float) -> mat3: Builds a 3x3 rotation matrix. - **BuildTranslation** (v: vec3) -> mat4: Builds a 4x4 translation matrix. - **BuildScale** (v: vec3) -> mat4: Builds a 4x4 scale matrix. - **ExtractEulerAngles** (m: mat3|mat4) -> vec3: Extracts Euler angles. - **BuildFromEulerAngles4** (angles: vec3) -> mat4: Creates a 4x4 rotation matrix from Euler angles. - **BuildFromEulerAngles3** (angles: vec3) -> mat3: Creates a 3x3 rotation matrix from Euler angles. - **Decompose** (m: mat4, scale: vec3, yawPitchRoll: vec3, translation: vec3) -> void: Decomposes a model matrix. - **ExtractAxisAngle** (m: mat3|mat4, axis: vec3) -> float: Extracts axis-angle representation. - **BuildFromAxisAngle3** (axis: vec3, angle: float) -> mat3: Builds a 3x3 rotation matrix from axis-angle. - **BuildFromAxisAngle4** (axis: vec3, angle: float) -> mat4: Builds a 4x4 rotation matrix from axis-angle. - **Perpendicular** (x: vec3|vec4, normal: vec3|vec4) -> vec3|vec4: Projects x on a perpendicular axis. - **Project** (x: vec3|vec4, normal: vec3|vec4) -> vec3|vec4: Projects x on normal. - **Fract** (x: float) -> float: Returns x - floor(x). - **Trunc** (x: float) -> float: Returns nearest integer. - **Sign** (x: float) -> float: Returns sign of x. - **Clamp** (val: float, minVal: float, maxVal: float) -> float: Clamps value. - **Lerp** (x: float, y: float, a: float) -> float: Linear blend. - **Acos** (x: float) -> float: Arc cosine. - **Asin** (x: float) -> float: Arc sine. - **Atan** (y_over_x: float) -> float: Arc tangent. - **Atan2** (x: float, y: float) -> float: Arc tangent of y/x. ``` -------------------------------- ### Ext.Entity.OnDestroy Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Subscription for component destruction events. ```lua OnDestroy(componentName, callback, [entity], [opt1], [opt2]) ``` -------------------------------- ### Send Request to Client with Reply Callback Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Sends a request to a specific client. Optionally specify a user and a reply callback for the response. ```lua --- Send a request to a client; optionally specify a user and reply callback ---@param data table ---@param user integer|Guid ---@param replyCallback fun(data:table) function NetChannel:RequestToClient(data, user, replyCallback) end ``` -------------------------------- ### Ext.Events Subscription Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Documentation for subscribing to engine and SE events using Ext.Events.:Subscribe(fun). ```APIDOC ## Ext.Events Subscription ### Description Subscribe to engine and SE events to execute custom logic during specific game lifecycle stages. ### Method Ext.Events.:Subscribe(fun) ### Events - **ModuleLoadStarted**: Thrown when the engine has started loading mods. Useful for filesystem-level hooks via Ext.IO.AddPathOverride. - **StatsLoaded**: Thrown after stats entries are cleared and reloaded. Use for persistent stat modifications. - **SessionLoading**: Thrown when the engine starts setting up a game session. - **SessionLoaded**: Thrown when the game session setup is complete. - **ResetCompleted**: Thrown when Ext.Debug.Reset() or the reset console command completes. - **GameStateChanged**: Indicates a change in server/client game state. - **Tick**: Thrown after each game engine tick (~30hz on server). Use Ext.OnNextTick(fun) for one-time execution. ``` -------------------------------- ### Templates - Ext.Template Source: https://context7.com/norbyte/bg3se/llms.txt Provides access to game object templates, including characters and items. ```APIDOC ## Ext.Template ### Description Methods to access and retrieve game object definitions. ### Methods - **Ext.Template.GetTemplate(uuid)**: Retrieves a template by ID. - **Ext.Template.GetRootTemplate(uuid)**: Retrieves a root template by ID. - **Ext.Template.GetAllRootTemplates()**: Returns all available root templates. ``` -------------------------------- ### Configure Script Extender Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Create a Config.json file in the mod's ScriptExtender directory to enable features like Lua scripting. ```json { "RequiredVersion": 29, "ModTable": "YOUR_MOD_NAME_HERE", "FeatureFlags": ["Lua"] } ``` -------------------------------- ### Level and Physics API Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Methods for pathfinding, raycasting, and physics overlap tests. ```APIDOC ## Ext.Level Methods ### Description Handles spatial queries, pathfinding, and physics interactions. ### Methods - `Ext.Level.BeginPathfinding(entity, targetPos, opts): AiPath` - `Ext.Level.RaycastAny(from, to, physicsType, collidesWith, ignoredGroups, maxHits): boolean` - `Ext.Level.GetEntitiesOnTile(position): EntityHandle[]` - `Ext.Level.GetHeightsAt(x, z): number[]` ``` -------------------------------- ### Send Request to Server with Reply Callback Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Sends a request to the server. The reply is handled asynchronously via the provided callback. ```lua --- Send a request to the server; reply arrives via `replyCallback` ---@param data table ---@param replyCallback fun(data:table) function NetChannel:RequestToServer(data, replyCallback) end ``` -------------------------------- ### Send NetMessage from Server to Client(s) Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Use BroadcastMessage to send to all clients, PostMessageToUser for a specific user ID, or PostMessageToClient for a specific character UUID. Payloads must be stringified if they are tables. ```lua --Server context local channel = "MyModChannel_SomethingSpecific" local payload = {["somedata"] = somevalue, ["supertable"]={1,2,3,4,5}} --We need to stringify our payload in this case since it is a table and not a string payload=Ext.Json.Stringify(payload) --If we want to send the message to ALL the clients Ext.ServerNet.BroadcastMessage(channel, payload) --If we wanted to send the message to a specific userId local somePeer = 9999 Ext.ServerNet.PostMessageToUser(somePeer, channel, payload) --If we wanted to send the message to the client controlling a specific character local someUUID = "c774d764-4a17-48dc-b470-32ace9ce447d" -- Wyll's uuid Ext.ServerNet.PostMessageToClient(characterUUID, channel, payload) ``` -------------------------------- ### Modify Game Stats with Ext.Stats Source: https://context7.com/norbyte/bg3se/llms.txt Read, modify, or create game stat entries. Runtime modifications require a sync call. ```lua -- Get all stats of a type local spells = Ext.Stats.GetStats("SpellData") local weapons = Ext.Stats.GetStats("Weapon") local statuses = Ext.Stats.GetStats("StatusData") -- Get a specific stat entry local spell = Ext.Stats.Get("Shout_FlameBlade") print("Cost: " .. spell.UseCosts) print("Damage: " .. spell.SpellType) -- Modify stats (during StatsLoaded or with Sync) Ext.Events.StatsLoaded:Subscribe(function() -- Modify existing spell local fireball = Ext.Stats.Get("Projectile_Fireball") fireball.SpellProperties = "IF(not SavingThrow(Ability.Dexterity, 15)):ApplyStatus(BURNING,100,3)" -- Disable autocast on all spells for _, name in pairs(Ext.Stats.GetStats("SpellData")) do local stat = Ext.Stats.Get(name) if stat.Autocast == "Yes" then stat.Autocast = "No" end end end) -- Create new stat entry local newSpell = Ext.Stats.Create("MyMod_CustomSpell", "SpellData", "Projectile_Fireball") newSpell.DisplayName = "Custom Fireball" newSpell.Description = "A custom fireball spell" newSpell.SpellSchool = "Evocation" newSpell:Sync() -- Required for runtime changes -- Modify stats at runtime (requires sync) local weapon = Ext.Stats.Get("WPN_Longsword") weapon.Damage = "2d8" weapon:Sync() ``` -------------------------------- ### Registering User Variables Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md This section explains how to register custom variables for entities, enabling automatic network synchronization and savegame persistence. ```APIDOC ## Ext.Vars.RegisterUserVariable ### Description Registers a user variable for entities, allowing for custom properties with network synchronization and savegame persistence. ### Method `Ext.Vars.RegisterUserVariable(variableName, settings)` ### Parameters #### Path Parameters - **variableName** (string) - Required - The name of the user variable to register. It's recommended to prefix with your mod name. - **settings** (table) - Optional - A table of settings to configure the variable's behavior. - **Server** (boolean) - Default: `true` - Whether the variable is present on server entities. - **Client** (boolean) - Default: `false` - Whether the variable is present on client entities. - **WriteableOnServer** (boolean) - Default: `true` - Whether the variable can be modified on the server. - **WriteableOnClient** (boolean) - Default: `false` - Whether the variable can be modified on the client. - **Persistent** (boolean) - Default: `true` - Whether the variable is written to/restored from savegames. - **SyncToClient** (boolean) - Default: `false` - Whether server-side changes are synced to all clients. - **SyncToServer** (boolean) - Default: `false` - Whether client-side changes are synced to the server. - **SyncOnTick** (boolean) - Default: `true` - Whether client-server sync is performed once per game loop tick. - **SyncOnWrite** (boolean) - Default: `false` - Whether client-server sync is performed immediately when the variable is written. - **DontCache** (boolean) - Default: `false` - Disables Lua caching of variable values. ### Usage Notes - Variables must be registered before savegame load and Lua context reset, ideally in `BootstrapServer.lua` or `BootstrapClient.lua`. - Register variables with the same settings on both client and server to avoid synchronization issues. - Client-only variables cannot be persistent. ### Request Example ```lua Ext.Vars.RegisterUserVariable("NRD_Whatever", { Server = true, Client = true, SyncToClient = true }) ``` ### Usage Example ```lua _C().Vars.NRD_Whatever = 123 Ext.Print(_C().Vars.NRD_Whatever) ``` ``` -------------------------------- ### Ext.Entity Source: https://context7.com/norbyte/bg3se/llms.txt Provides methods to retrieve and manipulate game entities and their components. ```APIDOC ## Ext.Entity.Get ### Description Retrieves a game entity by its UUID or handle. ### Parameters - **id** (string) - Required - The UUID or handle of the entity. ### Response - **entity** (object) - The entity object containing components and helper methods. ``` -------------------------------- ### Server-side Broadcast Global Settings Source: https://github.com/norbyte/bg3se/blob/main/Docs/API.md Server pushes current settings to all connected clients using `Broadcast`. This is a one-way message. ```lua -- Server side: push current data to all connected clients Channels.SyncSettings:Broadcast({ Settings = MCM.GetCurrentSettings() }) ``` -------------------------------- ### Localization - Ext.Loca Source: https://context7.com/norbyte/bg3se/llms.txt Provides access to game localization strings and allows runtime updates to translated text. ```APIDOC ## Ext.Loca ### Description Methods to retrieve and modify translated strings using their handles. ### Methods - **Ext.Loca.GetTranslatedString(handle, [fallback])**: Retrieves a translated string by its handle. - **Ext.Loca.UpdateTranslatedString(handle, text)**: Updates a translated string at runtime. ``` -------------------------------- ### Mod Info - Ext.Mod Source: https://context7.com/norbyte/bg3se/llms.txt Provides functionality to query information about loaded mods and the current mod load order. ```APIDOC ## Ext.Mod ### Description Utilities for checking mod status and retrieving metadata for loaded mods. ### Methods - **Ext.Mod.IsModLoaded(uuid)**: Returns true if the specified mod is loaded. - **Ext.Mod.GetLoadOrder()**: Returns an array of mod UUIDs in the current load order. - **Ext.Mod.GetMod(uuid)**: Retrieves detailed information about a specific mod. ``` -------------------------------- ### Schedule Tasks with Ext.Timer Source: https://context7.com/norbyte/bg3se/llms.txt Execute code after delays or on the next tick, with support for persistent timers that survive save/load cycles. ```lua -- Wait using game time (pauses when game pauses) Ext.Timer.WaitFor(3000, function() print("3 seconds (game time) have passed") end) -- Wait using real time Ext.Timer.WaitForRealtime(5000, function() print("5 seconds (real time) have passed") end) -- Persistent timer (survives save/load) Ext.Timer.RegisterPersistentHandler("MyMod_DelayedAction", function(timerName) print("Persistent timer fired: " .. timerName) end) local handle = Ext.Timer.WaitForPersistent(60000, "MyMod_DelayedAction", function() print("One minute passed (persistent)") end) -- Timer control Ext.Timer.Pause(handle) Ext.Timer.Resume(handle) local isPaused = Ext.Timer.IsPaused(handle) Ext.Timer.Cancel(handle) -- Execute on next tick Ext.OnNextTick(function() print("Runs on the next game tick") end) -- Performance measurement local start = Ext.Timer.MonotonicTime() -- ... do work ... local elapsed = Ext.Timer.MonotonicTime() - start print("Took " .. elapsed .. "ms") ```