mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-29 03:46:50 +01:00
Trim per-frame multiplayer client work; size mesh pool to the GPU
Mesh streaming pool (fixes loading crashes on older GPUs) - 1.0.0 forced MeshStreaming.PoolSize to 3.5 GiB on every card. An RX 580 crashed while loading with DXGI_ERROR_DEVICE_RESET, and the oversized pool is the likely cause. The pool is now a quarter of the largest hardware adapter's dedicated video memory, capped at 3.5 GiB; cards of 6 GB or less keep the game's own 520 MB. The card, its memory and the chosen size are logged once at startup. Remote players (busy servers) - Transform interpolate is inline plain arithmetic: 22 -> 5.8 ns per joint. It was 4% of a busy server's client frame, since every player within 200 m has the whole skeleton interpolated every frame. - Players out of the camera's view and more than 8 m away are sampled at 20 Hz, like far players. Their position still updates every frame for collision, sound and nametags, and a player coming into view is sampled that frame. Expression hooks (run for every expression the game executes) - No profiler zones in the expression hooks: taking a sample switched them on, inflating the very samples that measured the hooks. - The throwdown lab pump does one sorted lookup of the running graph and skips everything else for graphs it doesn't watch (graph_throttle gets throttled_graph for this). Settings and memory reads - Script gameplay-setting and native-setting gets are served from small per-thread caches, keyed on the asset/key address, its first 8 name bytes and a new profile::Store::changes() counter, instead of a store lookup each call. - Per-frame reads in the client tick, native settings and population controls use memory::peek instead of ReadProcessMemory. - Script error logging probes each argument pointer once.
This commit is contained in:
1 parent
f7fc909ca7
commit
b763631b77
24 files changed
+320
-151
No files matched your search
@@ -14,7 +14,7 @@ void script_error(std::uintptr_t, std::uintptr_t*, std::uintptr_t* arguments) {
|
||||
PreserveError preserve;
|
||||
// Authored graphs raise the same error every frame, from the same constant text: a text
|
||||
// pointer already looked at is not read again (each character was a system call).
|
||||
static std::mutex mutex; static std::set<std::string> seen; static std::set<std::uintptr_t> looked_at;
|
||||
static std::mutex mutex; static std::set<std::string> seen; static std::set<std::uintptr_t> looked_at, arguments_seen;
|
||||
std::lock_guard lock(mutex);
|
||||
try {
|
||||
// The message position is not known from the binding alone; take the
|
||||
@@ -35,6 +35,10 @@ void script_error(std::uintptr_t, std::uintptr_t*, std::uintptr_t* arguments) {
|
||||
for (std::size_t index = 0; arguments && index < 4 && message.empty(); ++index) {
|
||||
std::uintptr_t argument{}, inner{};
|
||||
if (!memory::peek(reinterpret_cast<std::uintptr_t>(arguments) + index * 8, argument) || argument < 0x10000) break;
|
||||
// The same arguments come back every frame: each is probed once (read, not peeked:
|
||||
// it is often not a pointer, and a failed peek costs an exception).
|
||||
if (arguments_seen.contains(argument)) continue;
|
||||
if (arguments_seen.size() < 4096) arguments_seen.insert(argument);
|
||||
if (read(argument, inner) && inner >= 0x10000) message = printable(inner);
|
||||
if (message.empty()) message = printable(argument);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user