`Roles.new_role` returned the result of `error`, which made it nullable,
and `set_permission_group` returned nil for an unknown group, which
broke the config chain with an index error rather than saying so.
Positions and bounding boxes read back from the game always use the
named members, so they are narrowed once where they enter a function.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Locals declared ahead of an assignment inside a callback were inferred
as nil at every use site.
The role event handlers are given a class so the table is not unified
with the other module handler tables.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`loadstring` was removed in Lua 5.2, `load` takes a string the same way.
Warp gui child lookups are optional, so they use the same assert the
rest of the repo does.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
emmylua takes self from the owner table, so `@param self ExpRoles.Role`
only applies with dot syntax. Call sites still use a colon.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`config.temp_warning_limit` does not exist, the warnings config defines
`script_warning_limit`, and the locale expects it as `__3__/__4__`, so
the command was printing nil.
map_tags is keyed by the force name joined to the tag number, and
custom_color is the Color union.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>