From 5b1be32e060767fbe8d7786a515319f3b88f6f58 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 29 Sep 2026 02:03:10 -0500 Subject: [PATCH] feat(ghosting): scene ghosting on by default ghosting_scenes defaults to 1 in the worldconfig.ini template, the settings catalog and when the key is missing. Zones without a terrain scene map keep distance ghosting; ghosting_scenes=0 turns it off everywhere. Check in game: with a fresh worldconfig.ini the world server log says "Scene ghosting is on" in Avant Gardens; objects appear by scene (the whole scene you are in and its neighbours) instead of within 100-150 units. In a zone without a scene map (e.g. a property) the log says it is off and ghosting is by distance. Co-Authored-By: Claude Opus 5.5 --- README.md | 4 ++-- dDashboardServer/routes/SettingsCatalog.cpp | 2 +- dGame/EntityManager.cpp | 4 ++-- resources/worldconfig.ini | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 62d779db0..72b1926dc 100644 --- a/README.md +++ b/README.md @@ -74,8 +74,8 @@ icons without building them locally. See [docs/UgcServer.md](docs/UgcServer.md). property. * **Brick-by-Brick:** server-side autosave storage, model metadata answers, and saved builds split into models with every bone and rigid system moved together. See [docs/BuildWorkflow.md](docs/BuildWorkflow.md). -* **Scene ghosting** (optional): players get the objects of the scenes the client has loaded, as the client streams - them. +* **Scene ghosting** (on by default, `ghosting_scenes`): players get the objects of the scenes the client streams; + zones without a terrain scene map keep distance ghosting. * Server-side knockback for AI-moved objects, switchable trigger volumes, missing force field, jetpack NPC and Skullkin volume scripts, deletion restrictions enforced, cross-world new-mail notices, pet LOTs stored with names, stale character saves refused. diff --git a/dDashboardServer/routes/SettingsCatalog.cpp b/dDashboardServer/routes/SettingsCatalog.cpp index eca83644a..b121068a3 100644 --- a/dDashboardServer/routes/SettingsCatalog.cpp +++ b/dDashboardServer/routes/SettingsCatalog.cpp @@ -161,7 +161,7 @@ namespace { c.Add(Format(Text(SHARED, "dump_folder", "Crash dump folder", "Where crash logs go. Empty turns them off.", "", true), eFormat::PATH)); c.Add(Bool(WORLD, "generate_dump", "Crash dumps from world servers", "Write a dump when a world server crashes (needs the crash dump folder).", false, true)); c.Add(Bool(WORLD, "save_lxfmls", "Save model files", "Save players' models (LXFML) to disk before they are split, for debugging.", false)); - c.Add(Bool(WORLD, "ghosting_scenes", "Scene ghosting", "Players get the objects of the scenes their game keeps loaded (the scene under them, the scenes connected to it and the global scene), as the client streams scenes, instead of the ones within 100 to 150 units. Needs the zone's terrain scene map; zones without one keep distance ghosting.", false, true)); + c.Add(Bool(WORLD, "ghosting_scenes", "Scene ghosting", "Players get the objects of the scenes their game keeps loaded (the scene under them, the scenes connected to it and the global scene), as the client streams scenes, instead of the ones within 100 to 150 units. Needs the zone's terrain scene map; zones without one keep distance ghosting.", true, true)); c.Add(Bool(WORLD, "save_property_location", "Log back in on properties", "Logging out on a property and back in returns to that property. Off (as live): to the last world before it.", false)); c.Add(Bool(WORLD, "bbb_consume_bricks", "Brick building uses bricks", "Saving a brick by brick model uses up the bricks in it, as live did. Off: the bricks go back to the backpack.", false)); c.Add(Bool(SHARED, "dont_generate_dcf", "Don't build the chat filter file", "Skip compiling the chat word list to a file.", false, true)); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 8b057e635..501937546 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -100,8 +100,8 @@ void EntityManager::Initialize() { Game::zoneManager->GetZoneID().GetMapID() ) == m_GhostingExcludedZones.end(); - // Scene ghosting needs the terrain's scene map; without one it stays off - if (m_GhostingEnabled && GeneralUtils::TryParse(Game::config->GetValue("ghosting_scenes")).value_or(false)) { + // Scene ghosting (on unless ghosting_scenes=0) needs the terrain's scene map; without one it stays off + if (m_GhostingEnabled && GeneralUtils::TryParse(Game::config->GetValue("ghosting_scenes")).value_or(true)) { auto* zone = Game::zoneManager->GetZoneMut(); m_SceneGhosting = zone && zone->LoadSceneMap(); LOG("Scene ghosting is %s", m_SceneGhosting ? "on" : "off: the zone has no scene map"); diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index f03271b55..429f01960 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -117,10 +117,10 @@ bbb_consume_bricks=0 # 1: logging out on a property and back in returns to that property. 0 (as live): to the last world before it. save_property_location=0 -# 1: players get the objects of the scenes their game keeps loaded (the scene under them, the scenes connected to it -# by the zone's scene transitions, and the global scene) instead of the objects within the ghosting distances. -# Needs the zone's terrain scene map; zones without one keep distance ghosting. -ghosting_scenes=0 +# 1 (default): players get the objects of the scenes their game streams (the scene under them, the scenes connected to +# it by the zone's scene transitions, and the global scene) instead of the objects within the ghosting distances. +# Needs the zone's terrain scene map; zones without one keep distance ghosting. 0: distance ghosting everywhere. +ghosting_scenes=1 # ---- Logging and crashes ---- # Crash dumps from world servers: Write a dump when a world server crashes (needs the crash dump folder). Read when the