You are viewing a potentially older version of this package. View all versions.
WUYACHIYU-WhySoLaggy-1.0.2 icon

WhySoLaggy

Find which mod causes lag and who is bombing your room. FPS tracking, plugin timing, patch profiling, full RPC monitor with feeding-chain tracing, and real-time on-screen alerts.

Date uploaded 3 months ago
Version 1.0.2
Download link WUYACHIYU-WhySoLaggy-1.0.2.zip
Downloads 194
Dependency string WUYACHIYU-WhySoLaggy-1.0.2

This mod requires the following mods to function

BepInEx-BepInExPack_PEAK-5.4.2403 icon
BepInEx-BepInExPack_PEAK

BepInEx pack for PEAK. Preconfigured and ready to use.

Preferred version: 5.4.2403

README

WhySoLaggy

Find out which mod is making your game lag, and who is bombing — or sneakily feeding — your room.

Features

Performance Profiling — Find the Lag Source

  • FPS Monitor: Tracks your frame rate in real time, flags any frame that takes too long
  • Plugin Timer: Measures how much time each installed mod takes per frame — see who's the slowest
  • Patch Analyzer: Identifies which specific modified game methods are eating up performance

Room-Bombing Detection — Find Who's Causing Trouble

  • Automatically monitors network activity in your room and detects suspicious behavior:
    • Spawning tons of objects in a short time
    • Flooding the network with RPC commands
    • Sudden explosion in the number of scene objects
  • When something suspicious is detected:
    • A red alert pops up on the top-left corner of your screen (auto-fades after 12s)
    • The log records the suspect player's name and ID number, plus the top RPC methods at that moment
  • Observation only — does NOT kick, block, or interfere with anyone. Just records evidence.

Full RPC Monitor — Know Every Network Command (new in 1.0.2)

  • Hooks the unified network entry point and tracks every single RPC going through your room
  • Every 30s report shows: top methods by call count, top senders per method, average / max / total payload bytes
  • 27 high-risk methods (feeding, healing, status/affliction, death, teleport, physics impulse, item pickup/drop/throw) get full detail records: sender, target GameObject + scene path, parsed arguments, payload size
  • Feeding-chain tracing: captures SendFeedDataRPC → RemoveFeedDataRPC → GetFedItemRPC → Consume so you can tell exactly who fed whom with which item — useful for spotting sneaky feeders in co-op
  • Per-method independent buffer: each watched method has its own 32-entry ring buffer, so a flood from one method can no longer drown out rare but critical events
  • Near-zero overhead: hot path stays under 500 ns per RPC, no allocations, no locks

Log Files

After your session, open the BepInEx folder in your game directory. You'll find two files:

File What it records
BepInEx/WhySoLaggy.log Performance data: FPS, mod timing, lag causes
BepInEx/WhySoLaggy_Abuse.log Bombing evidence + full RPC monitor reports (top methods, watched details, feeding chains)

These are recreated every time you launch the game, so they won't grow forever.


How to Analyze the Logs

Option A: Give it to any AI (Recommended)

Copy-paste the log content into any AI assistant (ChatGPT, Claude, etc.) and ask:

"This is a performance/abuse log from my game. Please tell me:

  • Which mod is causing the most lag?
  • Were there any suspicious players?
  • Did anyone feed someone else secretly?
  • What happened and when?"

The AI will give you a clear summary.

Option B: Check it yourself

  • Performance log: Look for lines with ! or !!! — the number in ms shows how slow it is
  • Abuse log:
    • Lines with ⚠ ABUSE ALERT — the suspect's player name and ID are shown right after
    • Lines with [RPC_MON] — periodic RPC statistics and watched-method details
    • Look for SendFeedDataRPC detail records: 喂食者=X#123 → 被喂者=Y#456, 物品=Z means X fed Y with item Z

Sample Logs — Real Data (names redacted)

The following snippets are real logs captured from a 6-player session. Player nicknames have been replaced with PlayerA~PlayerG (PlayerA = Master). These samples were collected on an in-development DLL whose buffer format is slightly different from the final 1.0.2 layout (single ring buffer vs. per-method buffer), but the information shown is essentially the same.

1. Plugin initialization

[21:47:25.473] [RPC_MON] Hooked PhotonNetwork.ExecuteRpc successfully
[21:47:25.473] [RPC_MON] RpcMonitor initialized (watched methods: 27)

2. Abuse alert with suspect attribution + top RPC methods at that moment

[21:47:44.510] ⚠ ABUSE ALERT: RPC flood! Rate: 85.0/s (threshold: 50/s)
[21:47:44.511] [ABUSE]   Top RPC sources (by ActorNumber):
          PlayerA#1: 42x
          PlayerB#2: 10x
          PlayerC#3: 8x
          PlayerD#6: 8x
          PlayerE#7: 8x
[21:47:44.511] [RPC_MON]   Current-window top RPC methods:
          SyncInventoryRPC: 25x
          SetItemInstanceDataRPC: 9x
          SetCharacterIdle_RPC: 6x
          SetKinematicRPC: 6x
          SyncThornsRPC_Remote: 5x

3. 30-second periodic report — top methods with payload and top senders

[21:47:55.246] [RPC_MON]   Top 10 RPC methods this period:
          SyncStatusesRPC: 82x  avg=72B max=72B total=5904B  [PlayerB#2:28, PlayerA#1:15, PlayerE#7:15]
          SyncInventoryRPC: 76x  avg=59B max=83B total=4531B  [PlayerA#1:56, PlayerE#7:5, PlayerB#2:5]
          SetItemInstanceDataRPC: 25x  avg=32B max=32B total=800B  [PlayerA#1:20, PlayerB#2:4, PlayerF#8:1]
          EquipSlotRpc: 22x  avg=24B max=24B total=528B  [PlayerB#2:10, PlayerA#1:7, PlayerE#7:3]
          ReceivePluginsFromHostRPC: 9x  avg=1392B max=1392B total=12528B  [PlayerA#1:9]
          RPC_SetThrownData: 7x  avg=24B max=24B total=168B  [PlayerA#1:7]
          DropItemRpc: 7x  avg=78B max=78B total=546B  [PlayerB#2:4, PlayerA#1:3]

4. Watched method details — sender, target GameObject + scene path, parsed arguments

[37.6s] PlayerA#1 → RPC_SetThrownData  payload=24B
   target=(PlayerA#187)  path=C_Pawn W(Clone)
   detail=投掷者=PlayerA#10002, 力度=0.00

[38.5s] PlayerA#1 → DropItemRpc  payload=78B
   target=(PlayerA#10002)  path=Character [PlayerA : 1]
   detail=丢弃物品, target=Character [PlayerA : 1]#10002

5. Feeding-chain tracing — "who fed whom with which item"

Each self-feed in the log looks like this (Consume followed immediately by RemoveFeedDataRPC on the same item view):

[668.3s] PlayerC#3 → Consume  payload=20B
   target=(PlayerC#30040)  path=Mushroom Lace(Clone)
   detail=消耗者=PlayerC#30013, 物品=Mushroom Lace(Clone)#30040
[668.3s] PlayerC#3 → RemoveFeedDataRPC  payload=20B
   target=(PlayerC#30040)  path=Mushroom Lace(Clone)
   detail=喂食结束: 喂食者=PlayerC#30013

[1238.7s] PlayerD#6 → Consume  payload=20B
   target=(PlayerD#60113)  path=Glizzy(Clone)
   detail=消耗者=PlayerD#60063, 物品=Glizzy(Clone)#60113

[1688.9s] PlayerF#8 → Consume  payload=20B
   target=(PlayerF#80071)  path=Mushroom Lace Poison(Clone)
   detail=消耗者=PlayerF#80040, 物品=Mushroom Lace Poison(Clone)#80071

In all entries above the feeder character viewID equals the consumer viewID — everyone ate their own food, no sneaky cross-player feeding. If someone ever feeds someone else, the two IDs will differ and it'll stand out immediately.


Configuration

Adjust via in-game ModConfig or BepInEx config file:

Performance Profiling

Setting Default Description
SpikeThresholdMs 50 How many ms before a frame counts as a lag spike (16–200)
ReportIntervalSeconds 10 Seconds between performance reports (5–60)
EnablePluginProfiling true Whether to measure each mod's timing
EnablePatchProfiling true Whether to measure patched method timing
TopMethodCount 10 How many slow methods to show in reports (3–30)

Room-Bombing Detection

Setting Default Description
EnableAbuseDetection true Turn bombing detection on/off
CheckIntervalSeconds 1.0 Seconds between checks (0.5–5)
ReportIntervalSeconds 30.0 Seconds between full reports (10–120)
InstantiateRateThreshold 15 Objects spawned per second to trigger alert (5–100)
DestroyRateThreshold 20 Objects destroyed per second to trigger alert (5–100)
RpcRateThreshold 50 RPC calls per second to trigger alert (10–200)
ObjectSpikeThreshold 30 Object count increase per check to trigger alert (5–100)

RPC Monitor (new in 1.0.2)

Setting Default Description
EnableRpcMonitor true Turn full RPC tracking on/off
TopMethodCount 10 How many top methods to show in each 30s report (3–30)
WatchedRecordPerMethodCapacity 32 Per-method ring buffer size — each watched method keeps its own last N records, so high-frequency methods can't drown out rare ones (8–256)
WatchedShowPerMethod 6 How many most-recent detailed records to print per watched method in each report (1–50)

Installation

  1. Install BepInExPack PEAK
  2. Place WhySoLaggy.dll into PEAK/BepInEx/plugins/

No other mods required.

Contact & Feature Requests

  • Author: wuyachiyu
  • QQ Group: 1093172647

Spotted an RPC that looks suspicious but isn't on the watched list yet? Drop a message in the QQ group with the method name and what it does — if it makes sense, I'll add it to the watched list in the next update. The full list of 27 watched methods covers feeding, healing, status/affliction, death, teleport, physics impulses, and item interactions, but the game has hundreds of RPCs and anything can be abused creatively. Your report helps.

Notes

  • The mod waits 5 seconds after launch before starting, so other mods can finish loading first
  • Extremely low overhead — the RPC monitor hot path stays under 500 ns per call
  • Bombing detection and RPC monitor are observation-only, perfect for collecting evidence after an incident

CHANGELOG

Changelog

[1.0.3] - 2026-04-26

⚠ Testing status — client-side only. Every 1.0.3 feature in this changelog was exercised from a non-host (client) install. A subset of the new diagnostics can only do real work when the install is on the Master Client — specifically:

  • OnRemoteRpcEvent Hashtable unpack (capturing real client-side RPC senders after Master relay)
  • Master-side Instantiate requester correlation (SuspectedRequesterActor/Name/Rpc)
  • PhotonView Ownership audit (EventCode 210/211/215)
  • Actor×Method hotspot detector

These Master-only paths compile cleanly and self-check, but have not yet been validated in an actual hosted session. Expect potential edge-case bugs there until a host-side capture is recorded. Client-side features (FPS / RPC monitor / Instantiate rate / FieldProbe etc.) are unaffected.

Quiet-by-default

  • EnablePluginProfiling / EnablePatchProfiling default changed to false — profilers are opt-in now
  • LogVerbosity default changed to Minimal — text logs only carry abuse alerts; CSV/JSONL still capture everything
  • Fix: abuse alerts now bypass the verbosity filter, so Minimal = "alerts only, but definitely alerts"
  • Fix: removed orphan continuation lines when a report header was filtered but its follow-up lines weren't

New features

  • Structured logging: whysolaggy_data.csv (58 cols) + whysolaggy_events.jsonl, auto-rotated at MaxLogFileSizeMB
  • Startup Harmony conflict scan: harmony_patches.csv + alerts when the same method is patched by multiple mods
  • Opt-in method stack tracer ([MethodTracer]): name methods, get filtered call stacks per hit
  • FieldProbe: JSON-driven reflective snapshots of any field / parameter / return value at any method
  • On-screen dashboard (opt-in): live FPS, frame time, GC KB/s, watched-RPC summary, last abuse alert
  • GC allocation rate + Photon ping are attached to FPS / periodic reports
  • InstantiateTrace: every PhotonNetwork.Instantiate captures a filtered caller stack (3 samples per prefab + 1 per 5s window, auto-forced on flood) — finally answers "which script / mod is spawning this?"
  • Watched-method library expanded from 27 to 65+ RPC names across feeding / healing / status / death / revive / grab-kick-carry / inventory / prefab spawn / end-game / ownership / tornado / campfire
  • Master-side Relay Diagnostics (beta, Master-only): RemoteRpcTrace unpacks EventCode=200 Hashtable to recover the real client sender; Instantiate rows gain SuspectedRequesterActor/Name/Rpc/AgeMs; OwnershipChange decodes EventCode 210/211/215; OwnershipGrab and ActorMethodHotspot alarms layer on top

Performance & robustness

  • PatchProfiler throttling via MinReportMs — ~70–90% lower self-overhead on busy scenes
  • IgnorePluginGuids / IgnorePatchMethods / ExtraWatchMethods config keys
  • RPC hot path moved fully to main-thread pump (ConcurrentQueue + PumpBatchSize)
  • Lower GC pressure across all periodic report paths; better exception reporting; null-safe patch hooks

Docs

  • README: new Real-world case section with redacted dual-client lantern lit-sync + warmth diagnostics, pulled straight from a live session ([LitSync] / [HuddleWarmth] / [FuelMath] / [WARMTH_LOG] / BugleRestore)
  • README: reworked How to analyse the logs into a tag-first workflow — grep/jq by tag now recommended, CSV pivot second, AI third (with "curate the slice first" recipe), plain-text reading fourth
  • README: added six copy-paste commands (3 PowerShell Select-String, 3 jq) covering abuse alerts, lit-sync, failed warmth ticks, top RPC senders, FieldProbe hits, frame spikes

Upgrade note: BepInEx only applies new defaults to missing keys. Delete com.wuyachiyu.WhySoLaggy.cfg or flip the three keys manually to pick up the quieter defaults.

[1.0.2] - 2026-04-23

  • Full RPC monitor hooks PhotonNetwork.ExecuteRpc; counts calls, senders and payload bytes
  • Feeding-chain tracing: SendFeedDataRPC → RemoveFeedDataRPC → GetFedItemRPC → Consume
  • 27 watched high-risk methods record sender / target / parsed args / payload size
  • Per-method 32-entry ring buffer so floods can't drown out rare events
  • Abuse alerts now include the current top RPC methods
  • Hot path <500ns per RPC, no allocs, no locks

[1.0.1] - 2026-04-20

  • Room-bombing detection now correctly identifies the remote suspect
  • Real-time on-screen alert banner (auto-fades after 12s), auto EN/中 based on system locale
  • Fixed wrong attribution to the local player; fixed a thread-safety crash

[1.0.0] - 2026-04-07

  • Initial release: FPS tracker, plugin / patch profilers, room-bombing detection, dual text logs