Static Analysis, Formatting and Type Annotations

For real static typing, use Teal or Luau (--!strict). LDoc generates documentation from comments.

luarocks install luacheck
luacheck src/                # unused variables, accidental globals, shadowing, unreachable code
stylua src/                  # format (configured via stylua.toml)
selene src/                  # Rust-based linter (Roblox-friendly)
-- .luacheckrc
std = "lua54"
globals = { "love", "vim" }
max_line_length = 120
ignore = { "212/self" }      -- unused argument 'self'
-- LuaLS (Lua Language Server) annotations (LuaCATS / EmmyLua style)
---@class Player
---@field name string
---@field hp integer
local Player = {}
Player.__index = Player

---Creates a new player.
---@param name string
---@param hp? integer Optional starting HP (default 100)
---@return Player
function Player.new(name, hp)
    return setmetatable({ name = name, hp = hp or 100 }, Player)
end

---@param amount integer
---@return boolean ok, string? err
function Player:damage(amount)
    if amount < 0 then return false, "negative damage" end
    self.hp = self.hp - amount
    return true
end

---@alias Direction "up"|"down"|"left"|"right"
---@type table<string, Player>
local players = {}