Skip to content

feat(game): ask minimap mods to switch themselves off - #315

Merged
theEvilReaper merged 2 commits into
mainfrom
feat/disable-client-minimaps
Oct 5, 2026
Merged

theEvilReaper merged 2 commits into
mainfrom
feat/disable-client-minimaps

Conversation

@TheMeinerLP

@TheMeinerLP TheMeinerLP commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes

Cygnus now asks cooperating client minimap mods to switch themselves off, so nobody finds the slender or the pages on a radar. This is opt-in on the mods' side and cannot be enforced: modified clients and mods that do not know the convention ignore it.

Change.

  • New MinimapPolicy (net.onelitefeather.cygnus.minimap, a GameFeature) sends one system chat message per code on every PlayerSpawnEvent, so on join and again whenever a player spawns into another instance (lobby to map). The codes are sent as a literal text component, so the § characters reach the client raw and the line renders as an empty message.
  • New MinimapConfig with key minimap.mode: disabled (default; Xaero minimap off plus radar and cave mode off), fair (map allowed, radar and cave mode off), off (nothing sent, the feature is not registered). An unknown value is logged and replaced by the default. Documented in config.properties.example.

Codes.

Mode Lines sent (one message each)
disabled §n§o§m§i§n§i§m§a§p, §f§a§i§r§x§a§e§r§o, §3 §6 §3 §6 §3 §6 §e, §3 §6 §3 §6 §3 §6 §d
fair §f§a§i§r§x§a§e§r§o, §3 §6 §3 §6 §3 §6 §e, §3 §6 §3 §6 §3 §6 §d
off none
  • Xaero's Minimap / World Map: §f§a§i§r§x§a§e§r§o = fair play (no entity radar, no cave mode), §n§o§m§i§n§i§m§a§p = no minimap. VoxelMap and compatible mods: §3 §6 §3 §6 §3 §6 §e = no radar, §3 §6 §3 §6 §3 §6 §d = no cave mode. There is no full-disable code for VoxelMap.
  • JourneyMap (current versions) is not covered: it is controlled by its own server mod, there is no lightweight server-side signal without it.
  • Open question, not verified against a real client: whether Xaero keeps its flags across a Minestom instance change. Resending is cheap and harmless, so it is done on every spawn.

Sources.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING.md
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Further comments

Test plan.

  • MinimapPolicyTest: join sends the expected strings per mode, off sends nothing and is disabled, spawning into a second instance resends, and the captured SystemChatPacket carries a literal text component with intact § signs, no children and nothing visible.
  • GameConfigReaderTest / GameConfigTest: default disabled, case-insensitive parsing, unknown value falls back, null mode rejected.
  • ./gradlew :game:test :common:test is green.

Entity radar check (report only). A radar shows what the client knows as entities. The hidden slender and spectators are not sent as entities to survivors: VisibilityRules.slenderRule / spectatorRule are installed via updateViewableRule (TeamHelper.java:84, SpectatorService.java:89), and the slender is only a viewer-visible entity while revealed by design. The Creaking body is limited to an explicit viewer set (CreakingBody.java:53). Dead survivors' mannequins are visible by design (PlayerDeathListener.java:70).

LabyMod

Second commit, feat(game): ask labymod to switch off unfair features. LabyModPolicy follows the same minimap.mode (off sends nothing and is not registered).

  • Protocol. LabyMod 4 uses the plugin channel labymod:neo; a packet is a VarInt id plus its fields. The client opens with VersionLoginPacket (id 0), which the official Minestom integration also waits for, so the policy answers only that hello. The PermissionPacket (id 10) is a VarInt count, then per permission a VarInt-prefixed UTF-8 identifier and one boolean byte. This is hand-encoded (about 15 lines) instead of depending on the Server API; the tests pin the exact bytes (0A 01 0D "entity_marker" 00).
  • What is denied: only entity_marker. The client's DefaultPermissionRegistry registers improved_lava, crosshair_sync, refill_fix, range, slowdown, entity_marker, gui_*, chat_autotext, blockbuild, sneaking*, tags, chat, animations, saturation_bar. None of them is a minimap, radar or waypoint permission: LabyMod 4 has no such built-in feature. entity_marker (lets a player mark an entity) is the only one that could point at other players, and it is off by default, so denying it only makes that explicit. The other permissions are cosmetic or gameplay tweaks and carry no map information, so they are left alone. Third-party minimap addons would have to be disabled through AddonDisablePacket (id 24) by addon namespace; no namespace could be verified, so that is not done.
  • Legacy. LabyMod 4 also translates the LabyMod 3 labymod3:main message PERMISSIONS (a JSON object of name: boolean) into the same packet, so no separate legacy path is sent.
  • Same caveat as above: opt-in, a modified client ignores it.

Sources:

Sends invisible colour-code system messages that Xaero's Minimap and VoxelMap obey, on every spawn. Configurable through minimap.mode (disabled, fair, off).
@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Test results

  588 files    588 suites   3m 42s ⏱️
1 294 tests 1 286 ✅  8 💤 0 ❌
3 885 runs  3 861 ✅ 24 💤 0 ❌

Results for commit 934f313.

♻️ This comment has been updated with latest results.

Answers the LabyMod 4 hello on labymod:neo with a hand-encoded permission packet denying entity_marker, following minimap.mode.
@theEvilReaper
theEvilReaper merged commit e320baa into main Oct 5, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants