README.md 5.2 KB

GhostBuddy

This is a DLL to disable brick searching (scope query, for finding bricks to ghost) and to replace it with a script-facing interface to read from pre-populated SimSets containing bricks.

An add-on making use of this DLL can be found here: https://blocklandglass.com/addons/addon.php?id=760

There are also two functions relating to making the brick scope query instantly trigger for a client. You can have nearby players instantly ghost new bricks when they open a new room in some hypothetical dungeon explorer game.

You can get a visualization of how the game handles brick ghosting by falling down a previously unghosted shaft in one of the mining mods You will only ghost batches of bricks in distinct intervals of 5 seconds.

Background

Every 5 seconds, each ShapeBase-derived object attached to a NetConnection (Player and Camera objects) triggers a scope query specifically to search for bricks that need to be ghosted. With all bricks being stored in the octtree, while much more efficient than the Torque-native system of SceneGraphs still used by non-brick objects, there is still a non-negligible processing time correlated with brick counts and player counts. Because the octtree method for bricks is efficient, a server with 1 million bricks out of the ghosting range of 100 players will not have a problem. However, a server with 100 players and 1 million bricks in ghosting range will have a hard time. While I have no concrete data on typical values from an actual Blockland server on a VPS, a quick test was setup with the following conditions or assumptions:

- The New Year's 2024 build has 126,000 bricks almost entirely near the map origin
- I spawn my player in the middle of the map (in range of almost all 126K bricks)
- The brick scope query is every 5 seconds per player
- The brick scope query consumes 11-15 ms for a single player on this specific computer

Therefore, with those circumstances, the server would spend a total of around 1300ms on scope queries every 5 seconds for 100 players, thus resulting in about 25% CPU.

This DLL exposes several several methods to disable the brick scope query and to assist with manually ghosting a list of bricks instead. A script can collect all bricks on the server into a SimSet and tell the DLL-backed functions that a client needs to start ghosting all bricks in that SimSet. Any bricks created after the DLL-backed ghosting has finished should be ghosted through script methods to all players as normal ghosting is completely disabled.

The API (for developers)

Variables

$GhostBuddy::brickScopeBlocking
	Inhibit scope queries for bricks
	Internally, this makes octTree::findObjects return zero objects when called during the execution of Player/ShapeBase::onCameraScopeQuery()
	There must be an addon to handle this and manually ghost bricks after this is enabled
$GhostBuddy::totalRadiusSearchTime
	Total time in milliseconds spent on radius searches by every client
	Can be reset to zero as desired
$GhostBuddy::totalRadiusSearchCounter
	Total amount of radius searches done by every client (whether brick scoping was blocked or not)
	Can be reset to zero as desired

Variables set on client (GameConnection) objects

ghostBuddy_total_radius_search_time
	Total time in milliseconds spent on radius searches by this client
	Can be reset to zero as desired
ghostBuddy_total_radius_search_counter
	Total amount of radius searches done by this client  (whether brick scoping was blocked or not)
	Can be reset to zero as desired

Functions

GameConnection::ghostBuddy_newClient(group)
	setup the client for ghosting and copy list of objects from the given SimSet

GameConnection::ghostBuddy_clearClient()
	clear data for this client

GameConnection::ghostBuddy_ghostNext(int num)
	ghost next num bricks

GameConnection::ghostBuddy_getIndex()
	get total amount of bricks to be ghosted

GameConnection::ghostBuddy_getCount()
	get number of bricks ghosted so far

Functions (for triggering scope queries; not an essential part of this project)

GameConnection::ghostBuddy_rescope()
	Immediately make the client query for nearby bricks (brick scope blocking must not be enabled)

GameConnection::ghostBuddy_getSimtimeLastScopeQuery()
	get the simtime of when the last brick scoping query occurred

Installing

Install RedBlocklandLoader (Eagle517) here: https://gitlab.com/Eagle517/redblocklandloader

Create a "modules" folder in your Blockland folder if you don't have one yet.

Copy "GhostBuddy.dll" (located in the release folder of this project) to the "modules" folder.

Libraries used (for developers)

All dependencies except MinHook are included. This project is setup (USE_OWN_MINHOOK) for the MinHook-export version of RedBlocklandLoader which would cause this project to no longer need MinHook for compilation, however the MinHook-export version of RBL doesn't yet exist at the time of writing.

MinHook - https://notabug.org/Queuenard/blockland-DLL-MinHook (https://github.com/TsudaKageyu/minhook @ 49d03ad118)

TSfuncs - https://notabug.org/Queuenard/blockland-DLL-libTSfuncs (derived from https://gitlab.com/Eagle517/tsfuncs)

libBLstructs - https://notabug.org/Queuenard/blockland-DLL-libBLstructs