Type tracking
The server knows how the common GLua functions transform types, and carries that through the rest of the file.Player lookup
When you callplayer.GetByID, the server knows the result is a Player entity:
Panel creation
vgui.Create with a known panel class returns that type:
Loop iteration
ipairs over a player list types each element as Player:
Typed hook sender
When you register a hook with a typed sender parameter, the callback receives the correct type:Entity methods
InsideENT methods, self is typed as Entity:
Generated accessors
Garry’s Mod creates getters and setters at runtime that appear nowhere in your source, so nothing else knows they exist. Both forms are tracked:NetworkVar in shared.lua completes in init.lua and cl_init.lua as well. Entities in other directories keep their accessors to themselves.
Your own entity and weapon classes
Garry’s Mod takes a scripted class name from where its files sit, solua/entities/my_turret/ defines the class my_turret. Spawning one gives you that class rather than a bare Entity:
lua/weapons/ and for the calls that take a class name: ents.FindByClass (as an array), ents.CreateClientside, weapons.Get, and Player:Give.
The class name itself completes inside the string, and go-to-definition on it opens the class, preferring shared.lua where there is one.
An engine class like prop_physics is left alone and stays a plain Entity — nothing in the workspace defines it, so there is nothing extra to offer.
Typing your own functions
Annotate them, or let inference read the type from the methods called on each parameter. Both work; you can mix them freely.Supported annotation tags
GLua uses the same annotation dialect as Lua Language Server.
You can also use union types, optional parameters, and array syntax:
How inference falls back
When an exact type is not available, the server picks the least wrong thing rather than guessing:- Ambiguous sets. A value that is sometimes a
Playerand sometimes anNPCnarrows to their common ancestor,Entity. The completion list is the methods both actually have. - Nothing to work with. A value the server cannot classify at all stays
any. Generic Lua completions still work; no Garry’s Mod methods are offered. - An explicit annotation always wins.
---@typeand---@paramoverride whatever inference decided.