Skip to main content

Overview

Garry’s Mod uses a “scripted class” pattern. You define a global table, such as ENT or SWEP, in a specific file location, and GMod registers it as a class. GLuaLS detects these classes and provides:
  • Class registration including inheritance
  • Synthesis of NetworkVar getter/setter pairs
  • Synthesis of AccessorFunc getter/setter pairs
  • Better completions and type checking for scripted class code

Automatic detection

GLuaLS detects scripted classes by file path. It treats any file under a recognized directory as defining the matching table. For example:
Directory patternClass tableBase class
lua/entities/**/ENTEntity
lua/weapons/**/SWEPWeapon
lua/effects/**/EFFECT(none)
GLuaLS types the detected class table with the base class’s methods and fields, so you get completions and type checking without annotations. You can adjust this table in settings.

AccessorFunc synthesis

AccessorFunc(table, member, name, ...) generates getter and setter methods. GLuaLS detects these calls and synthesizes the methods:
AccessorFunc(ENT, "m_bOrient", "Orient", FORCE_BOOL)

-- GLuaLS synthesizes:
-- ENT:GetOrient() -> boolean
-- ENT:SetOrient(value: boolean) -> nil
Use the ---@accessorfunc annotation for custom getters and setters. See @accessorfunc for details.

NetworkVar synthesis

ENT:NetworkVar(type, slot, name, ...) generates entity accessors. GLuaLS detects these calls and synthesizes matching methods:
function ENT:SetupDataTables()
    self:NetworkVar("Int", 0, "Health")
    self:NetworkVar("Bool", 1, "Active")
    self:NetworkVar("String", 2, "Name")
end

-- GLuaLS synthesizes:
-- ENT:GetHealth() -> number
-- ENT:SetHealth(value: number) -> nil
-- ENT:GetActive() -> boolean
-- ENT:SetActive(value: boolean) -> nil
-- ENT:GetName() -> string
-- ENT:SetName(value: string) -> nil
You get completions and type checking for generated accessors without manual annotations.

Supported NetworkVar types

NetworkVar typeGetter/setter type
"Int"integer
"UInt"integer
"Float"number
"Double"number
"Bool"boolean
"String"string
"Entity"Entity
"Vector"Vector
"Angle"Angle
"Color"Color

Base class inheritance

Scripted classes in GMod inherit from base classes. GLuaLS understands this chain and suggests inherited methods. The scripted class table also gets the standard base type for that scope, such as Entity, Weapon, or Tool. DEFINE_BASECLASS(...) and values like ENT.Base can refine that type further.
function ENT:Use(ply)
    self:EmitSound("...")    -- inherited from Entity / base class chain ✅
    ply:ChatPrint("Hello")   -- Player method ✅
end
For gamemodes that derive from another gamemode, such as DarkRP deriving from Sandbox, GLuaLS adds the parent’s folder as a library. See Gamemode inheritance to configure or disable this.

Hook overrides in scripted classes

GLuaLS treats functions defined in a scripted class table as engine hook overrides for that class:
function ENT:Think()    -- override of ENTITY:Think hook
function ENT:Draw()     -- override of ENTITY:Draw hook
function ENT:OnRemove() -- override of ENTITY:OnRemove hook
Completions suggest the correct signature for each override.

Class Explorer integration

The VS Code Class Explorer lists detected scripted classes. You can browse groups, such as entities, weapons, effects, and custom scopes, and jump to class definitions. Class grouping and labels come from gmod.scriptedClassScopes.include.

Scaffolding integration

Scripted class scopes also control class scaffolding. Each scope can define scaffold output files with scaffold.files and a rootDir in gmod.scriptedClassScopes.include. You can create new classes with your own template layout while GLuaLS keeps class analysis, explorer grouping, and generated files in sync. See GMod settings for all supported fields.

Creating a new class

  1. Open the Class Explorer in the sidebar.
  2. Find the group you want, such as Entities.
  3. Click the + button next to that group.
  4. Enter the class name.
  5. The VS Code extension creates the files and opens the main file.

Built-in templates

The VS Code extension includes built-in templates for the standard scripted class types:
Class typeGenerated files
Entityshared.lua, init.lua, cl_init.lua
Weapon (SWEP)shared.lua
Effectyour_effect_name.lua
Scripted Tool (STOOL)your_tool_name.lua

Custom class scopes

If you use a non-standard directory structure or custom class types, configure GLuaLS to recognize them:
Use the settings menu instead of editing the JSON file directly. This helps you avoid config mistakes.
.gluarc.json
{
  "gmod": {
    "scriptedClassScopes": {
      "include": [
        {
          "id": "my_panels",
          "label": "Panels",
          "classGlobal": "PANEL",
          "path": ["panels"],
          "include": ["lua/panels/**"],
          "rootDir": "lua/panels"
        }
      ]
    }
  }
}

Fields

FieldDescription
idUnique identifier for this class scope
labelDisplay name in the Class Explorer sidebar
classGlobalThe global table name used in scripts (e.g., ENT, SWEP, PANEL)
pathPath segments used for display grouping in the Class Explorer
includeGlob patterns matching files that belong to this class type
rootDirRoot directory for scaffolded files
iconVS Code icon ID shown in the Class Explorer (e.g., symbol-class)

Disabling scripted class inference

To disable a built-in scripted class scope, add an override with the same id and set "disabled": true.
.gluarc.json
{
  "gmod": {
    "scriptedClassScopes": {
      "include": [
        {
          "id": "effects",
          "disabled": true
        }
      ]
    }
  }
}