Skip to content
Type a keyword to search.
This page was translated with machine assistance. The Simplified Chinese version is the authoritative reference.

Calling and Debugging Lua Scripts In Game

Developers can use any suitable tool to write Lua scripts. VSCode plus the EmmyLua plugin is recommended for editing Lua scripts, with support for breakpoints, variable watches, and related debugging features.

EmmyLua plugin

  • xLua Lua files use the .lua.txt extension, so VSCode does not recognize them as Lua files by default. Add a settings entry to complete the mapping.

VSCode file association settings

  • Open the custom settings JSON file and add:
{
"files.associations": {
"*.lua.txt":"lua"
},
"luaide.apiType": "xlua",
}

When choosing the settings file, select workspace settings rather than user settings. After selection, a .vscode folder is created under the project root with a settings.json file inside. If .lua.txt files show Lua syntax highlighting, the configuration is working.

Workspace settings JSON

Lua syntax highlighting

Lua script code in game must ultimately be mapped to the resource directory Asset\BuildSource\LuaScripts\. At runtime, use RUN_SCRIPT or RUN_SCRIPT_FUNC to call a script or a function inside a script.

Example:

RUN_SCRIPT_FUNC*test_script#TestFunc1
  • To make debugging work correctly, VSCode must open the project as a workspace.

From the top VSCode menu, choose File -> Add Folder to Workspace, or right-click an empty area in the project directory and open it with VSCode. Open the whole project folder or the directory containing LuaScripts in VSCode.

After opening, save the workspace. From the top VSCode menu, choose File -> Save Workspace As and save the workspace to a file. VSCode should then show:

Workspace title bar

  • Start breakpoints.
  1. Press F5, or click Run -> Start Debugging from the top VSCode menu.
  2. Select EmmyLua Attach Debug in the following window.

Select EmmyLua Attach Debug

  1. Attach to the Sands of Salzaar game process DesertLegend.exe.

Attach to game process

After attachment succeeds, the left side of VSCode switches to the debug panel and the bottom bar turns orange, indicating Debug mode.

Debug mode

Mount Lua Logic with the Plugin Settings Table

Section titled “Mount Lua Logic with the Plugin Settings Table”

When custom Lua logic needs to be mounted into the game, use the plugin settings table. After specifying the logic to mount and binding the target function, the game automatically runs the mounted logic when the corresponding logic point executes.

This is the recommended way to add Lua logic and reduce Lua script conflicts.

Available Lua mount points in the plugin settings table:

TypeTarget FieldTarget ValueFunction ExampleDescription
ADDon_game_startScriptName#FunctionNamefunction onGameStart()
— operations when entering the game
end
Runs after entering the game or loading a game.
ADDget_lua_intADScriptName#FunctionNamefunction GetLuaIntVal(valKey, contextArgVal)
if string.find(valKey,‘test=’) ~= nil then
local key = string.sub(valKey, 6)
return tonumber(key)
elseif valKey == “rand100” then
return math.random(1, 100)
end
return 0
end
Implements custom integer variable queries through Lua, corresponding to query directive [$lua_int:KEY$].
valKey: string, the KEY passed by the directive.
contextArgVal: RuntimeArgVals, the current script environment parameters.
Returning 0 means no result, so other Lua query mount functions continue to be called until a valid result is obtained.
Returning a non-zero value ends the query immediately and returns that value as the query result.
ADDget_lua_strScriptName#FunctionNamefunction GetLuaStringVal(valKey, contextArgVal)
if valKey == “test” then
return “ok”
end
return ""
end
Implements custom string variable queries through Lua, corresponding to query directive [$lua_str:KEY$].
valKey: string, the KEY passed by the directive.
contextArgVal: RuntimeArgVals, the current script environment parameters.
Returning nil or an empty string means no result, so other Lua query mount functions continue to be called until a valid result is obtained.
Returning a non-empty string ends the query immediately and returns that value as the query result.
ADDgame_hour_logicsScriptName#FunctionNamefunction OnGameHourLogic(curDay, curH)
if curH == 7 then
— check party member favor at a fixed time each day
PlayerPartyMemberLeaveCheck(curDay);
elseif curH == 9 then
— iterate custom faction logic
CampDailyUpdateLogic();
end
end
Logic executed each time one unit of in-game time passes. One day contains 12 units.
curDay: int, current in-game day.
curHour: int, current unit of the in-game day, with 12 units per day.
Avoid concentrating too much logic in this interface; distribute logic where possible to reduce stutter.
ADDcamp_daily_logicsScriptName#FunctionNamefunction OnCampDailyLogic(tagCamp, curDay)
— run faction logic checks
end
Daily in-game faction logic.
tagCamp: HanFramework.GameCampRtData, the faction currently being checked.
curDay: int, current in-game day.
Only active factions participating in the game struggle execute faction logic.

Some core game logic is implemented in Lua scripts. MOD creators can override the corresponding scripts to adjust diplomacy, internal affairs, favor, and similar logic.

The main built-in game logic interface code is in the Lua script mapped to Asset\BuildSource\LuaScripts\GameLogics.lua.txt. This file can be found under ModSamples\LuaScripts in the game root directory. Use the MOD override function to map that path and replace the specified Lua script.

Main code interfaces in GameLogics.lua.txt:

Interface MethodPurposeParameters
OnGameStart()Called every time the game is entered, including after loading a game.No parameters.
GetLuaStringVal(valKey, contextArgVal)Interface for the [$lua_str:KEY$] query directive.valKey: query field KEY.
contextArgVal: environment variable parameters when the query directive is called.
Return value: query result string.
GetLuaIntVal(valKey, contextArgVal)Interface for the [$lua_int:KEY$] query directive.valKey: query field KEY.
contextArgVal: environment variable parameters when the query directive is called.
Return value: query result integer.
SetRoleRep(opRole, targetType, tagID, opVal, isAdd, isNotify, isChainedMode)Interface for changing a role’s reputation in game.opRole: role object performing the operation.
targetType: target type, 0 faction, 1 role, 2 place.
tagID: target object ID.
opVal: operation value.
isAdd: operation mode. When true, add/subtract from the original value; otherwise set directly to the target value.
isNotify: whether to show a message when the main character is involved.
isChainedMode: whether to use chained operations, changing related favor objects.
Return value: integer query result.
GivePresentLogic(contextArgVal)Logic interface for increasing NPC favor by giving gifts.contextArgVal: environment variable parameters when this logic is called.
Return value: none.
OnCampDailyLogic(tagCamp, curDay)Daily faction logic. The game calls this logic interface for all factions each day.No parameters or return value.
OnAIDecideDipEvent(execCamp, dipInfo)AI faction decision logic for diplomacy behavior. Player-side diplomacy behavior is decided by handling dip_event trigger events.execCamp: faction object executing the diplomacy event.
dipInfo: detailed info for the diplomacy event, type DiplomaticEventInfo, with structure:
- public GameCampRtData fromCamp;
- public GameCampRtData execCamp;
- public int dipType;
- public string tagRoleID;
- public string argsVal;
- public float resultRatio;
- public bool isDecided;
Return value: none.
OnDipEventCallback(dipResult, dipInfo)Interface for handling the result of diplomacy events executed by all factions.dipResult: diplomacy event result, true means agree, false means refuse.
dipInfo: same as above.
Return value: none.
SetCampRl(campID1, campID2, rlState, fvOpMode, fvOpVal, isNotify)Interface executed when changing diplomacy relations between factions in game.campID1: diplomacy relation object A.
campID2: diplomacy relation object B.
rlState: target diplomatic state, -1 no change, 0 neutral, 1 hostile, 2 allied.
fvOpMode: diplomacy favor operation mode, 0 no change, 1 add, 2 set to target value.
fvOpVal: diplomacy favor operation value.
isNotify: whether to show a message when the player is involved.
Return value: integer query result.