Overview
Garry’s Mod Lua runs in two realms: client (CLIENT) and server (SERVER). Code that runs in both is called shared.
Many GMod API functions only exist in one realm (for example, LocalPlayer() is client-only). Calling them in the wrong realm is a common bug.
GLuaLS detects which realm each file runs in and reports diagnostics when you call realm-restricted functions from the wrong realm.
Realm detection
GLuaLS detects realm using multiple signals. Most projects need no extra setup.
GLuaLS infers realm with this 5-level priority system (highest to lowest):
1. @realm annotation (highest priority)
Do not add file-level realm overrides if inference is already correct. It can hide real cross-realm mistakes. Prefer function-level overrides.
Put ---@realm at the top of a file or on a function:
---@realm client
-- Everything in this file is clientside
See the @realm annotation reference for full syntax. @realm overrides all other detection methods, and function-level annotations override file-level ones.
2. Filename prefix detection
GLuaLS assigns realms to files that begin with cl_, sv_, or sh_:
| Prefix | Realm |
|---|
cl_ | Client |
sv_ | Server |
sh_ | Shared |
3. Directory-based detection
GLuaLS assigns realms to files in common GMod directories:
| Path pattern | Realm |
|---|
lua/autorun/client/ | Client |
lua/autorun/server/ | Server |
lua/autorun/ | Shared |
lua/client/, lua/vgui/, lua/postprocess/, lua/matproxy/, lua/skins/ | Client |
lua/effects/, lua/includes/, */stools/ | Shared |
This works for both common workspace layouts:
- Garry’s Mod root:
addons/<name>/lua/... and gamemodes/<name>/...
- Addon or gamemode root:
lua/..., gamemode/..., and entities/...
4. Block-level narrowing
Within shared files, GLuaLS narrows realm within if CLIENT / if SERVER blocks:
if CLIENT then
-- GLuaLS treats this block as client-only
surface.DrawRect(0, 0, 100, 100) -- OK here
end
if SERVER then
-- This block is server-only
ply:SetHealth(100) -- OK here
end
5. Heuristic inference (lowest priority)
When no other rule applies, GLuaLS infers realm from code usage. Calling a server-only API suggests server realm. This heuristic is less reliable than explicit detection.
Call-based inference
When call-based detection is on, GLuaLS also looks at file-loading calls:
AddCSLuaFile("file.lua") marks that file as Client
AddCSLuaFile() (no args) adds a Shared hint to the current file (stronger filename/path hints can still resolve as Client or Server)
IncludeCS("file.lua") is treated like AddCSLuaFile("file.lua") + include("file.lua")
IncludeCS() with no filename is ignored
require("mod") marks the required module as Shared
include("file.lua") passes realm hints to the included file
AddCSLuaFile does not mark the caller as server. It only affects the target file.
Loading defaults
Default path-based realm rules follow Garry’s Mod’s usual loading conventions and similar addon patterns. See Lua Loading Order for reference.
Realm diagnostics
| Code | Description |
|---|
gmod-realm-mismatch | Confident realm mismatch based on annotations |
gmod-realm-mismatch-heuristic | Probable realm mismatch based on inference |
gmod-unknown-realm | Realm could not be determined |
Disabling realm checks
Disable realm checks only when necessary. Other features depend on realm detection. In most cases, disable only specific diagnostics from settings.
Disable realm diagnostics workspace-wide:
Use the settings menu instead of editing the JSON file directly. This helps you avoid config mistakes.
{
"diagnostics": {
"disable": ["gmod-realm-mismatch", "gmod-realm-mismatch-heuristic", "gmod-unknown-realm"]
}
}
Or suppress for a specific file:
---@realm shared
-- This file intentionally has mixed realm code
Per-function realm overrides
Override or set realm detection for an individual function:
---@realm server
function MyAddon.ServerAction()
-- This function is always treated as server-side,
-- even if the surrounding file is shared
end
Use function-level overrides when possible. They help the language server skip expensive inference when annotations are present.
Realm in hover and autocomplete
Every hover tooltip for a GMod API function includes a realm badge showing where it runs:
- Client badge: function is clientside only
- Server badge: function is serverside only
- Shared badge: function is available on both realms
The badge appears in completions as well, so you can check a function’s realm before inserting it.
Realm also filters autocomplete. In client files, server-only functions are hidden (and vice versa). If a function seems missing, check inferred realm first.