Modding/Using Visual Studio Code

From Desynced Wiki

While it is easily possible to make Lua mods for Desynced using any text editor, Visual Studio Code is the recommended editor for some additional features it offers for Lua programming. Besides quick code navigation it has Lua syntax highlighting, auto completion and code analytics which can help finding mistakes and other bugs. It also has a full Lua debugger with breakpoints and variable inspection as well as a debug console that connects to a running game while developing a mod.

Setting up Visual Studio Code[edit | edit source]

If you don't have VS Code installed, you can download it for free at the official site. It can be installed from just a ZIP file and then there also is a way to use it in portable mode so it doesn't mess with the system or multiple installations.

Workspace Folder[edit | edit source]

After opening VS Code for the first time for Desynced modding, you should open the "mods" folder. To find it, run the game and go to OptionsSystem and then click the "Open Mods Folder". Alternatively you can browse to the game's installation directory and go into the Desynced\Content\mods\ sub-directory.

Required Extensions[edit | edit source]

Next you should switch to the Extensions tab (by clicking the icon or by pressing CTRL + SHIFT + X) and install these two extensions for Lua editing:

(Make sure to confirm the developer names before installing as there are many extensions named "Lua" or "lrdb").

Lua Language Server Setup[edit | edit source]

Alongside the Lua API documentation the developers of Desynced offer a Lua Language Server definition file for download at the following link:

https://modding.desyncedgame.com/desynced-lls-library.lua

With the Lua extension installed, the easiest way to make use of it is by downloading the above file (desynced-lls-library.lua) into the root of the Desynced mods directory (which is the workspace folder that is opened in VS Code). The API names and documentations will then show up while writing code or when hovering the mouse over function names. Alternatively you can download the file into its own directory (i.e. Desynced/Content/mods/.vscode/desynced-lls-library), then in VS Code press CTRL + SHIFT + P, write ">workspace settings json", press enter and store the following into the settings file:

{
    "Lua.runtime.version": "Lua 5.4",
    "Lua.workspace.checkThirdParty": false,
    "Lua.workspace.library": [ ".vscode/desynced-lls-library" ],
    "Lua.workspace.ignoreDir": [ ".vscode" ],
    "Lua.diagnostics.disable": [ "unbalanced-assignments", "cast-local-type", "need-check-nil", "param-type-mismatch" ],
}

Debugging Setup[edit | edit source]

With the lrdb-beamng extension installed, make sure to start the game with the command line argument -moddev and keep it running.

To attach the debugger, switch to the 'Run and Debug' tab in Visual Studio Code (menu 'View' -> 'Run' or by pressing CTRL + SHIFT + D). Click on the "create a launch.json" link and replace the content with the following:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lrdb",
            "request": "attach",
            "name": "Attach",
            "host": "localhost",
            "port": 21110,
            "sourceRoot": "${workspaceFolder}",
            "stopOnEntry": false,
        },
    ],
}

Again make sure that the workspace folder opened in VS Code matches your Desynced installation, it always needs to point to the top "mods" directory and not a specific mod directory inside of it. With the launch configuration saved, press F5 to attach the debugger to the game. If it doesn't end up connecting, open the "LUA REMOTE DEBUGGER - VMS" panel in the 'Run and Debug' tab of Visual Studio Code and try to double click the Desynced Lua VM which should be shown running on "localhost:21110".

Once connected, you'll have full access to breakpoints, code stepping, as well as accessing local and global variables and the watch window. Also it is recommended to open the Debug Console (menu 'View' -> 'Debug Console' or by pressing CTRL + SHIFT + Y) to have any logging or errors appear directly in Visual Studio Code. The debug console is interactive, too, so entering code into the input text box below the console will execute it in the game. This can be used to execute Debug.Reload() which will hot-reload the Lua code from inside the code editor (same as pressing F7 in the game).

To use breakpoints, make sure that the folder opened in Visual Studio Code is the top "mods" directory of Desynced and not a specific mod directory inside of it, as it needs to match the path defined in the "sourceRoot" field of the launch configuration.

Additional Customization[edit | edit source]

Syntax highlighting for UI layout strings[edit | edit source]

To make Visual Studio Code show syntax highlighting of Desynced UI layout strings you can install this tiny extension which will apply XML formatting for text inside multi-line Lua strings. This works because Desynced UI layout definitions are similar to XML documents. To install the extension after downloading it, switch to the Extensions tab (by clicking the icon or by pressing CTRL + SHIFT + X) and select the "Install from VSIX..." option inside the ⋯ menu in the top-right of the Extensions panel.

Download: https://github.com/StageGames/vscode-xml-in-lua/releases/download/1.0.0/stagegames.xml-in-lua-1.0.0.vsix

Highlight Status Bar While Debugging[edit | edit source]

To make it easier to know if your debugger is attached, you can make VS Code colorize the status bar in an orange tone. To do so, press CTRL + SHIFT + P, write ">workspace settings json", press enter and add the following rules to the settings file:

    "workbench.colorCustomizations": { "statusBar.background": "#007ACC", "statusBar.debuggingBackground": "#CA5100", },

Code Hot-Reload Hotkey[edit | edit source]

You can configure a custom hotkey to make the game hot-reload any code changes from within VS Code. To do so, press To do so, press CTRL + SHIFT + P, write ">keyboard shortcuts json" and select "Preferences: Open Keyboard Shortcuts (JSON)" and add the following entries to it:

[
    { "key": "ctrl+f7", "command": "workbench.debug.action.focusRepl", "when": "!inDebugRepl" },
    { "key": "ctrl+f7", "command": "workbench.action.debug.start", "when": "debuggersAvailable && debugState == 'inactive'" },
    { "key": "ctrl+f7", "command": "runCommands", "when": "inDebugRepl", "args": { "commands": [
                { "command": "workbench.action.files.saveAll" }, { "command": "cursorBottom" }, { "command": "cursorTopSelect" },
                { "command": "type", "args": { "text": "Debug.Reload()" } }, { "command": "repl.action.acceptInput" } ] } },
]

With that in place, at any time you can hold CTRL then press F7 twice to make the game reload any changes made to Lua.

Integrate with TortoiseSVN[edit | edit source]

If you use TortoiseSVN to manage software versioning of your Lua code you can add a few hotkeys to easily access common SVN functions. To do so, press CTRL + SHIFT + P, write ">keyboard shortcuts json" and select "Preferences: Open Keyboard Shortcuts (JSON)" and add the following entries to it:

[
    { "key": "ctrl+numpad1", "command": "workbench.action.terminal.sendSequence", "args": { "text": "&\"C:\\Program Files\\TortoiseSVN\\bin\\TortoiseProc.exe\" \"/command:diff\" \"/path:${file}\"\n" } },
    { "key": "ctrl+numpad2", "command": "workbench.action.terminal.sendSequence", "args": { "text": "&\"C:\\Program Files\\TortoiseSVN\\bin\\TortoiseProc.exe\" \"/command:log\" \"/path:${file}\"\n" } },
    { "key": "ctrl+numpad3", "command": "workbench.action.terminal.sendSequence", "args": { "text": "&\"C:\\Program Files\\TortoiseSVN\\bin\\TortoiseProc.exe\" \"/command:blame\" \"/path:${file}\"\n" } },
]

With these in place, the following hotkeys become available to VS Code while having a .lua file open:

  • CTRL + NUMPAD 1: Open diff of the current file against the source repository
  • CTRL + NUMPAD 2: Open the revision log of the current file
  • CTRL + NUMPAD 3: Open the blame tool for the currently edited file

For Developers At Stage Games[edit | edit source]

When working with the internal code base at Stage Games, the Lua extension can get confused about custom pre-compiler directives. To make it ignore #if/#else/#endif in Lua code, a small modification of the Lua extension is needed. In VS Code, press CTRL + SHIFT + P, write ">open extensions folder" and press enter. Then browse into sumneko.lua-VERSION-win32-x64/server/script/parser and drag the file compile.lua into VS Code. Find the function skipComment near line 532 and change the first few lines of code to the following then save and restart VS Code:

local function skipComment(isAction)
    local token = Tokens[Index + 1]
    if token == '--'
    or (
        token == '//'
        and (
            isAction
            or State.options.nonstandardSymbol['//']
        )
    ) or (
        token == '#' and (Tokens[Index + 3] == 'if' or Tokens[Index + 3] == 'else' or Tokens[Index + 3] == 'endif')
    ) then

When the extension is updated (automatically or manually) this change needs to get applied again.