Framework:
- Intervals are gone. Update periods are hardcoded on_nth_tick values
again, since nobody has needed to change them.
- apply is a single loop over the declared fields and logs a warning
when an override is invalid. receive_update also warns about
unknown keys.
- Nested tables are addressed as "section.key". Lists of strings can be
overridden. Features.optional declares a value with no default.
- Features.on_apply rebuilds values derived from the config, such as
lookup sets. It also runs during on_load.
exp_roles is assumed to be present:
- AFK Kick picks a role (active_role_id) instead of a custom check
function.
- Chat Auto Reply, Protection, and Nuke Protection no longer take a
permission as a setting.
New features, each chosen for an edge case:
- Discord Alerts: conditional handlers, and a command map that becomes
a list.
- Entity Protection: lists turned into sets at load, and bookkeeping
that must keep running while disabled.
- Nuke Protection: config keyed by defines, flattened to a banned items
list.
- Popups: one config shared by two control files.
- Spawn Area: nested sections, and settings that only apply when the
map is created.
Page: now laid out like the role page. It has a search across every
setting, one long list with a sticky sidebar to jump between sections,
and the enabled switch separated at the front of each header with
Reset to defaults on the right. Changed rows are highlighted, and a
bottom bar offers Revert and Apply. Role settings use a role picker and
lists use a tag select.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The entity protection module moves to exp_scenario/module/control/protection.lua
in the event_handler shape the other control modules use, and the copy in
exp_legacy is removed. The config lookups are built as local sets instead of
rewriting the config tables in place, the two mined handlers become one, and
the entity and area key helpers are exposed so the protection command no
longer keeps its own copies. Event ids are exposed as
Protection.on_player_mined_protected and Protection.on_repeat_violation.