Plugins: server plugins know the map and hear it change

On a dedicated server reskate.level.current() was empty and level_loaded and level_unloading never
fired, so a server plugin could not tell which map ran or that it had changed. The server's
plugins are now told the map's level each tick, named as players' games name it (a destination's
level, after its "|"). When the server changes the map, they hear level_unloading for the old one
and level_loaded for the new one, as a game's plugins do; players load it after.

dingosdk_server_plugin_tests checks level.current() and both events across a map change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hs7xxJDf6SDcQUaXnzmtL5
This commit is contained in:
Robin MoellerandClaude Opus 5.5 committed 2026-10-22 20:38:22 +02:00
1 parent 45d4c64c75
commit fd5f95467f
4 files changed
+36

No files matched your search

+25
View File
@@ -206,6 +206,19 @@ int run() {
end)
)");
// One that says what the level is, and when it changes.
write(root / "Plugins" / "follower" / "reskate-plugin.json",
R"({"api": 1, "entry": "plugin/main.lua", "side": "server", "permissions": ["console"]})");
write(root / "Plugins" / "follower" / "plugin" / "main.lua", R"(
reskate.on("level_unloading", function(name) reskate.console.print("unloading " .. name) end)
reskate.on("level_loaded", function(name) reskate.console.print("loaded " .. name) end)
local ticks = 0
reskate.on("tick", function()
ticks += 1
if ticks % 20 == 0 then reskate.console.print("level " .. reskate.level.current().name) end
end)
)");
std::vector<std::string> log;
SteamTransport transport;
Host host(config, transport, [&](const std::string &line) { log.push_back(line); });
@@ -274,6 +287,18 @@ int run() {
log.clear();
run_for(1100000);
check(has(log, "skater 76561198000000001 at 10.0 2.0 -30.0 facing 1.00, stale"), "A skater's age did not grow without poses");
// The level, as players' games name it, and its change heard when the server changes it.
const auto *first = find_level(config.map);
const auto other = std::find_if(levels().begin(), levels().end(), [&](const auto &l) { return l.asset != first->asset; });
check(first && other != levels().end(), "The test needs two retail maps");
check(has(log, "level " + first->asset), "level.current() is not the server's map: " + first->asset);
host.change_map(other->name);
log.clear();
run_for(1100000);
check(has(log, "unloading " + first->asset) && has(log, "loaded " + other->asset), "The plugin did not hear the map change");
check(has(log, "level " + other->asset) && !has(log, "level " + first->asset), "level.current() did not follow the map change");
check(!has(log, "skaters 2"), "Skaters stayed on the old map's places after the map changed");
if (failures)
for (const auto &line : log) std::fprintf(stderr, "log: %s\n", line.c_str());
return failures ? 1 : 0;