feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: respect world config WorldMap settings & BetterMap compatibility - #102

Merged
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat
Mar 15, 2026
Merged

feat: respect world config WorldMap settings & BetterMap compatibility#102
derrickmehaffy merged 22 commits into
releases/0.12.0from
feat/worldmap-settings-bettermap-compat

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Respect world config WorldMap settings ([Feat] Respect world config WorldMap settings instead of overriding them #96): HyperFactions now reads the world's native WorldMapSettings before replacing the generator. Disabled worlds ("WorldMap": { "Type": "Disabled" }) are skipped entirely. All settings (scale, allow* flags, imageScale, viewRadius, biomeData) are inherited from the world config instead of being hardcoded.
  • BetterMap compatibility ([Feat] BetterMap compatibility — avoid conflicts with map tracker hooks and settings #97): Detects BetterMap via reflection at startup (Class.forName). When active, defers imageScale to BetterMap's quality system and inherits world settings that BetterMap can then modify via its reflection hooks. No compile-time dependency on BetterMap.
  • Config overrides: New settingsOverrides section in worldmap.json allows admins to override specific inherited values (scale, teleport flags, marker creation). null or absent = inherit from world. Exposed in admin GUI with 0 = inherit for scale values and inherit/enabled/disabled dropdowns for flags.
  • Admin GUI: Added "Respect World Config" toggle, "BetterMap Compat" dropdown (auto/always/never), and full "Map Settings" override section (scale values, teleport/marker flags) to the worldmap config tab.
  • Consolidated registration: Removed 3 duplicate world map registration paths in WorldSetup; all registration now routes through WorldMapService.registerProviderIfNeeded().
  • HiddenPlayersManager integration: Faction-based player visibility now uses BOTH setPlayerMapFilter() (vanilla icons, deprecated API) AND HiddenPlayersManager.hidePlayer()/showPlayer() (BetterMap radar + future-proof). Tracks ownership of hidden pairs to avoid conflicts with other mods.
  • Live settings reapply: Changing worldmap settings in the admin GUI and saving immediately re-creates generators and sends UpdateWorldMapSettings packets to all connected players — no restart needed.
  • Sentry integration: All worldmap catch blocks now report to Sentry via ErrorHandler.report().
  • Test fixes: Updated PlayerPowerTest and MockStorage for PlayerPower record and PlayerStorage interface changes.

Key Changes

FileChange
worldmap/HyperFactionsWorldMap.javaRemoved singleton, per-world instances with settings merge, reflection for private fields
worldmap/WorldMapService.javaCaptures original settings, skips disabled worlds, stores generators, reapplySettings() for live config updates
worldmap/BetterMapCompat.javaNew — reflection-based BetterMap detection with config-driven mode
worldmap/HyperFactionsWorldMapProvider.javaCreates per-world instances in getGenerator()
worldmap/MapPlayerFilterService.javaDual-layer visibility: setPlayerMapFilter + HiddenPlayersManager with ownership tracking
config/modules/WorldMapConfig.javaAdded respectWorldConfig, betterMapCompat, settingsOverrides with validation
config/ModuleConfig.javaAdded getOptionalFloat()/getOptionalBool() nullable helpers
platform/WorldSetup.javaConsolidated + delayed registration (60 ticks) to capture vanilla settings
gui/admin/page/AdminConfigPage.javaFull map settings override section in worldmap tab
gui/admin/ConfigSnapshot.javaNew setting keys + int step values
gui/admin/ConfigValidator.javaValidation ranges for scale overrides
HyperFactions.javaBetterMapCompat init + compat mode logging + reapplySettings() on config save
manifest.jsonAdded dev.ninesliced:BetterMap >= 1.3.3 as OptionalDependency

Config Example

{
"respectWorldConfig": true,
"betterMapCompat": "auto",
"settingsOverrides": {
"_description": "Override inherited world settings. Remove a key or set to null to inherit.",
"defaultScale": null,
"minScale": null,
"maxScale": null,
"imageScale": null,
"allowTeleportToCoordinates": null,
"allowTeleportToMarkers": null,
"allowCreatingMapMarkers": null
}
}

Known Limitations

Test Plan

  • World with "WorldMap": { "Type": "Disabled" } → HyperFactions skips registration, no claim overlay
  • World with "WorldMap": { "Type": "WorldGen" } → inherits scale/flag values from world
  • respectWorldConfig: false → legacy behavior (hardcoded values)
  • Admin GUI toggles work and save correctly
  • /f admin map refresh works after changes
  • Without BetterMap: all existing worldmap functionality unchanged
  • Player visibility filtering still works
  • Settings overrides in admin GUI save and reapply to clients
  • With BetterMap: claim overlays render alongside exploration tracking
  • With BetterMap: zoom range preserved, not locked
  • With BetterMap: HiddenPlayersManager hides faction-filtered players from radar

Closes#96, Closes#97

WorldMapService now captures each world's original WorldMapSettings before
replacing the generator, creates per-world HyperFactionsWorldMap instances
with those settings, and skips registration for worlds with map disabled
in their world config (Issue #96). Generator re-registration on refresh
reuses stored instances to preserve original settings.
viewRadiusMultiplier, viewRadiusMin, viewRadiusMax are private fields
with no public getters in WorldMapSettings. Use reflection with safe
fallback defaults to read them during settings inheritance.
…ig value
- Add getSettingsPacket() null check in getWorldMapSettings() to prevent
NPE if a world has non-null WorldMapSettings with a null packet
- Validate and normalize betterMapCompat config value (auto/always/never)
with warning on invalid input
- Log effective BetterMap compat mode at startup for debuggability
UpdateWorldMapSettings.enabled defaults to false (Java boolean default),
so even normal WorldGen worlds appear disabled when checking packet.enabled.
Only use identity equality with the DISABLED singleton to detect truly
disabled worlds.
WorldMapManager generators are initialized AFTER plugin enable during
'Getting Hytale Universe ready'. Schedule delayed registration (60 ticks)
so we can capture original settings from the fully-initialized manager.
Set WorldConfig provider early so the server uses it during init.
Vanilla UpdateWorldMapSettings has 0.0f for defaultScale/minScale/maxScale
(Java float default) — the server never sets these because the client
handles zoom independently. Inheriting zeros causes a tiny low-quality
map view. Fall back to 128/64/128 when inherited values are zero.
…t first
Setting our provider before the server initializes WorldMapManager caused
the server to use HyperFactionsWorldMap during init, so the delayed
registration captured our own hardcoded settings instead of the vanilla
GeneratorChunkWorldMap values (imageScale, viewRadius, scale bounds).
Now we only register via the delayed task, which runs AFTER the server
initializes with the vanilla generator, allowing us to capture the
original high-quality settings before replacing.
Expose scale overrides (defaultScale, minScale, maxScale, imageScale)
and allow* flag overrides in the admin config GUI. Scale values use
0 = inherit from world. Boolean flags use inherit/enabled/disabled
dropdowns.
Add WorldMapService.reapplySettings() that re-creates per-world
generators with current config overrides, installs them on the
WorldMapManager, and sends UpdateWorldMapSettings packets to all
connected players. Called from reloadRuntimeSystems() after admin
GUI config save so changes take effect without server restart.
…ibility
MapPlayerFilterService now uses BOTH mechanisms for player visibility:
1. setPlayerMapFilter() — for vanilla OtherPlayersMarkerProvider (deprecated)
2. HiddenPlayersManager.hidePlayer/showPlayer — for BetterMap's PlayerRadarProvider
Tracks which viewer→target pairs we hid to avoid accidentally unhiding
players hidden by other systems (admin /hide command, other mods).
Faction visibility rules (own/ally/enemy/neutral/factionless) are applied
through both layers for complete coverage.
Sign up for freeto 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.

1 participant

@derrickmehaffy