LuaLS Setup for CityRP Development

LuaLS (Lua Language Server) provides advanced IDE features for Lua development including syntax highlighting, error detection, auto-completion, and type checking. This guide covers setting up LuaLS for CityRP development.

Overview

LuaLS offers:

  • Syntax Highlighting: Advanced Lua syntax highlighting
  • Error Detection: Real-time error detection and warnings
  • Auto-completion: Intelligent code completion
  • Type Checking: Static type analysis with annotations
  • Function Signatures: Parameter hints and documentation
  • Go to Definition: Navigate to function/variable definitions
  • Hover Information: Documentation on hover

Installation

Step 1: Install Visual Studio Code

  1. Download Visual Studio Code from https://code.visualstudio.com/
  2. Install VS Code following the standard installation process
  3. Launch VS Code

Step 2: Install LuaLS Extension

  1. Open Extensions Panel:

  2. Press Ctrl+Shift+X (Windows/Linux) or Cmd+Shift+X (Mac)

  3. Or click the Extensions icon in the sidebar

  4. Search for LuaLS:

  5. Search for "LuaLS" or "sumneko.lua"

  6. Look for the extension by "sumneko"

  7. Install the Extension:

  8. Click "Install" on the LuaLS extension

  9. Wait for installation to complete

Step 3: Install Garry's Mod Plugin

  1. Open Command Palette:

  2. Press Ctrl+Shift+P (Windows/Linux) or Cmd+Shift+P (Mac)

  3. Open Plugin Manager:

  4. Type "LuaLS: Open Plugin Manager"

  5. Select the command from the dropdown

  6. Install Garry's Mod Plugin:

  7. Search for "Garry's Mod" in the plugin manager

  8. Click "Install" on the Garry's Mod plugin

  9. Restart VS Code when prompted

Configuration

Workspace Setup

  1. Open CityRP Workspace:

  2. Open VS Code

  3. File → Open Folder

  4. Navigate to your CityRP gamemode directory

  5. Select the folder containing cityrp.txt

  6. Create Workspace Settings: Create .vscode/settings.json in your workspace root:

{
    "Lua.runtime.version": "LuaJIT",
    "Lua.runtime.special": {
        "AddCSLuaFile": "dofile",
        "cityrp.util.Include": "dofile",
        "include": "dofile",
        "IncludeCS": "dofile"
    },
    "Lua.typeFormat.config": {
        "auto_complete_end": "true",
        "auto_complete_table_sep": "true",
        "format_line": "true"
    },
    "Lua.runtime.nonstandardSymbol": [
        "!",
        "!=",
        "&&",
        "||",
        "//",
        "/**/",
        "continue"
    ],
    "Lua.diagnostics.disable": [
        "lowercase-global",
        "inject-field",
        "duplicate-set-field"
    ],
    "Lua.completion.callSnippet": "Both",
    "Lua.completion.keywordSnippet": "Both",
    "Lua.hint.enable": true,
    "Lua.hint.paramType": true,
    "Lua.hint.setType": true,
    "Lua.hint.await": false,
    "Lua.hint.arrayIndex": "Enable",
    "Lua.hint.enable": true,
    "Lua.codeLens.enable": true,
    "Lua.hint.setType": true,
    "Lua.type.inferParamType": true,
    "Lua.type.weakNilCheck": true,
    "Lua.type.weakUnionCheck": true,
    "Lua.workspace.preloadFileSize": 500000,
    "Lua.completion.displayContext": 5,
    "Lua.diagnostics.disableScheme": [
        "git",
        "vscode",
        "github",
        ".vscode",
        ".github"
    ],
    "Lua.diagnostics.groupSeverity": {
        "type-check": "Information"
    },
    "Lua.diagnostics.libraryFiles": "Enable"
}

Advanced Configuration

See .luarc.json in your workspace root for team-wide configuration options, these settings should automatically apply to everyone using LuaLS.

Code Annotations and Documentation

LuaLS supports comprehensive type annotations that improve code intelligence and documentation. For a complete list of available annotations and detailed examples, refer to the official LuaLS Annotations Documentation.

Type Annotations

LuaLS supports type annotations that improve code intelligence:

--- @class Character
--- @field id integer
--- @field firstName string
--- @field lastName string
local character = {}

--- Get character's full name
--- @return string fullName
function character:GetFullName()
    return self.firstName .. " " .. self.lastName
end

--- Set character data
--- @param key string
--- @param value any
--- @param dataType? integer
function character:SetData(key, value, dataType)
    -- Implementation
end

Function Documentation

Document functions for better hover information:

--- Creates a new inventory
--- @param owner Player|string The owner of the inventory
--- @param size integer The size of the inventory
--- @param invType string The type of inventory
--- @param callback? function Callback when inventory is created
--- @return boolean success Whether creation was initiated
function cityrp.inventory.Create(owner, size, invType, callback)
    -- Implementation
end

Class Definitions

Define classes for better type checking:

--- @class base_item
--- @field name string
--- @field description string
--- @field cost integer
--- @field size integer
local ITEM = {}

--- @class base_equip : base_item
--- @field slot string
--- @field dropOnDeath integer
local EQUIP_ITEM = {}

Best Practices

File Organization

You should keep the standard gamemode structure within your Garry's Mod directory, for example:

 cityrp/
 ├── .vscode/
 │   └── settings.json
 ├── .luarc.json
 ├── gamemode/
 │   ├── core/
 │   │   ├── libraries/
 │   │   ├── metatables/
 │   │   └── items/
 │   └── shared.lua
 └── plugins/
     └── myplugin/
         ├── sh_plugin.lua
         └── items/

Annotation Guidelines

  1. Document Public APIs:

```lua --- @public --- @param client Player --- @return boolean success function cityrp.character.LoadAll(client) ```

  1. Mark Internal Functions:

```lua --- @private --- @param data table function cityrp.character.CreateInternal(data) ```

  1. Use Generic Types:

```lua --- @generic T --- @param base T --- @return T function ITEM:New(base) ```

Performance Tips

  1. Exclude Large Directories:

```json {

"Lua.workspace.ignoreDir": [
    ".git",
    "node_modules",
    "cache"
]

} ```

  1. Limit File Scanning:

```json {

"Lua.workspace.maxPreload": 5000,
"Lua.workspace.preloadFileSize": 500

} ```

Troubleshooting

Common Issues

LuaLS not recognizing Garry's Mod functions:

  • Ensure Garry's Mod plugin is installed and enabled
  • Check that globals are properly configured in settings
  • Restart VS Code after plugin installation

Performance issues with large codebase:

  • Increase maxPreload and preloadFileSize limits
  • Use ignoreDir to exclude unnecessary directories
  • Consider splitting large files into smaller modules

Type checking errors:

  • Add missing globals to configuration
  • Use ---@diagnostic disable-next-line for false positives
  • Check annotation syntax for typos

Debug Commands

Enable LuaLS logging for troubleshooting:

{
    "Lua.misc.parameters": [
        "--loglevel=trace",
        "--logpath=/path/to/log/directory"
    ]
}

Reset Configuration

If LuaLS stops working properly:

  1. Clear Cache:

  2. Command Palette → "LuaLS: Clear Cache"

  3. Restart Language Server:

  4. Command Palette → "LuaLS: Restart Server"

  5. Reload Window:

  6. Command Palette → "Developer: Reload Window"

Integration with CityRP Development

Code Completion

LuaLS provides intelligent completion for:

  • CityRP API functions (cityrp.character.Create)
  • Garry's Mod functions (hook.Add, timer.Simple)
  • Player methods (client:GetCharacter())
  • Item system (ITEM:New(), :AddAction())

Error Detection

Common errors detected:

  • Undefined variables and functions
  • Type mismatches
  • Missing parameters
  • Syntax errors

Refactoring Support

LuaLS helps with:

  • Renaming variables and functions
  • Finding all references
  • Go to definition/implementation
  • Symbol search across workspace

Additional Resources

Tips for Team Development

Shared Configuration

See .luarc.json within the repository, which should help make things such as the formatter consistent for us all.

Code Style

Use LuaLS formatting features:

  • Enable format on save
  • Configure indentation and spacing
  • Use consistent annotation styles

Documentation Standards

Establish team standards for:

  • Function documentation
  • Type annotations
  • Code organization
  • Naming conventions