# Lua Support in Maguyva: Code Graphs for Games, Plugins, and OpenResty

Canonical source: https://maguyva.ai/languages/lua

License: text under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); code samples under [MIT-0](https://opensource.org/license/mit-0); the Maguyva name, logos, brand assets and other code are not covered. Details: [maguyva.ai/license](https://maguyva.ai/license).

Maguyva parses Lua with AST, symbol, and graph support, so AI agents can follow modules, colon methods, metatable classes, and require chains in Lua code.

## Support snapshot

- Tier: AST and symbol support
- Programming
- Extensions: .lua
- Real AST parsing for syntax-aware search and structural context.
- Named symbols feed semantic lookup and cross-reference. Graph navigation is available when relationship extraction is enabled.
- This language contributes symbols and relationships to graph-aware search; supported edge types vary with its native constructs.
- AST parsing and symbol extraction are both available.

## Best fit

- Game code and engine scripts where modules, table-based classes, and event handlers call each other.
- Neovim plugins and editor configuration split across many required modules.
- OpenResty and other embedded Lua, where request handlers sit beside shared helper modules.

## Agent workflows

- Find every caller of a module function before changing its arguments.
- Trace which modules require a shared helper before moving it.
- Map which tables inherit from a base class through `setmetatable`.

## Where Lua trips up shallow AI tools

Lua has no class keyword. Objects are tables, methods are functions stored in them, and inheritance is a `setmetatable` call. A module is whatever `require` returns. The structure is real, but it lives in conventions that text search does not understand.

Maguyva reads those conventions as structure, so an agent can ask who calls a method or which tables extend a base and get a direct answer.

## What Maguyva extracts in Lua

Maguyva covers `.lua` files. Function declarations, `local function` definitions, and function expressions are extracted, and colon methods such as `function Account:deposit()` are attributed to their owning table, `Account`. Method chains are followed call by call, and calls on `self` stay tied to the enclosing object.

Lua's conventions map onto relationships:

- `require`, `dofile`, and `loadfile` record imports.
- A module-level `setmetatable` call records inheritance.
- `ClassName:new()`, `ClassName.new()`, and `setmetatable({...}, ClassName)` count as instantiation.
- `error()` records a throw, and `pcall` and `xpcall` record a catch.

The graph also records reads and writes and control flow.

## Example agent prompts

- "Who calls `Inventory:addItem`, and from which scripts?" (`find_symbol`, then `dependency_search` incoming)
- "Which modules require `util.http`?" (`dependency_search`)
- "Trace what happens when the player takes damage." (`get_task_context`)

## Known limits

- About 150 names are filtered from relationships: the Lua standard library (`string`, `table`, `math`, `io`, `os`, `coroutine`, `debug`, and `utf8`) plus the Neovim `vim.*` and OpenResty `ngx.*` APIs. Calls into those APIs are not graph edges, so use `text_pattern_search` to find them.
- Because modules and classes are built from ordinary calls and tables, the `classes` and `imports` presets in `structural_search` select nothing for Lua. Use `find_symbol` or `text_pattern_search` instead.
- Lua has no interfaces or type annotations, so interface-implementation and type-reference relationships are marked not applicable.

## Next steps

Connect a repository with the [quickstart](/docs/quickstart), then check the support matrix on the [compatibility page](/docs/compatibility). For engines that embed Lua in native code, read the [C guide](/languages/c) too.

## Engine details

- Lua support covers `.lua`. Colon methods such as `function Account:deposit()` are attributed to their owning table.
- `require`, `dofile`, and `loadfile` record imports, module-level `setmetatable` records inheritance, and `ClassName:new()` counts as instantiation.
- `error()` records a throw and `pcall` records a catch, while about 150 standard-library, `vim.*`, and `ngx.*` names are filtered.

## Useful MCP entry points

- `find_symbol`: Use it for a module function or colon method when you need the definition and callers.
- `dependency_search`: Use incoming traversal on a shared module to see which files require it before moving it.
- `text_pattern_search`: Use it for calls into `vim.*`, `ngx.*`, or the standard library, which are filtered from the graph.
