Experimental is a BepInEx plugin that bootstraps itself into Gorilla Tag by creating two persistentDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ASTRA228b/Experimental/llms.txt
Use this file to discover all available pages before exploring further.
GameObject hierarchies at startup, then drives all mod logic through Unity’s standard Update, FixedUpdate, and OnGUI MonoBehaviour callbacks. Understanding this structure is essential for adding new mods or debugging existing ones.
BepInEx Entry Point — Plugin
The plugin is identified by the BepInEx attribute:
Plugin itself is a thin bootstrapper. All real work is delegated to the components it attaches to persistent GameObjects.
Startup Sequence
Awake runs before Start, so the persistent objects and their components exist before any Harmony patches are applied.
Persistent GameObjects
Experimental creates twoDontDestroyOnLoad GameObjects that survive scene transitions:
Experimental.UIS
Experimental.UIS
Created directly in
Plugin.Awake(). Hosts the two primary MonoBehaviours:| Component | Role |
|---|---|
Main | IMGUI window rendering, mod tab dispatch, Update / FixedUpdate orchestration |
ControllerSystemManager | Creates the second persistent object (see below) |
Astras.Mods.Experimental.SystemManager
Astras.Mods.Experimental.SystemManager
Created inside
ControllerSystemManager.Awake(). Hosts the two secondary MonoBehaviours:| Component | Role |
|---|---|
ATurnModController | Smooth and snap turn logic, runs in FixedUpdate |
PitGeoManager | Scene-object search (Update) and surface-multiplier application (FixedUpdate) |
Both GameObjects are marked
DontDestroyOnLoad, so they persist across every Gorilla Tag map load and Photon room transition without needing to be re-created.Update Loop Breakdown
Each Unity callback has a distinct responsibility:OnGUI (Main)
OnGUI (Main)
Runs every GUI render frame.
- On the first call, checks the
SLoadedflag and callsGlobalStyles.INIT()once to initialize all sharedGUIStyleobjects — lazy initialization is used because IMGUI styles cannot be created outside of a GUI event. - Renders the main mod window using
GUILayout.Window. - Calls each sub-mod’s UI method directly (
PullModUI.MakeUI(),ApredsUI.MakePredsUI(),PSAModUI.MakePSAModUI(), etc.) so each can draw its own controls.
Update (Main)
Update (Main)
Runs every frame (variable rate).
- Polls the E key to toggle the main menu window open/closed.
- Calls
ApredsUI.RunMod()— the Apreds locomotion mod’s per-frame logic.
FixedUpdate (Main)
FixedUpdate (Main)
Runs at a fixed physics timestep (default 50 Hz).Calls, in order:
| Call | Mod |
|---|---|
PullModUI.RunMods() | Pull / attract locomotion |
GorillaTimeUI.RunTMod() | Gorilla Time slow-motion effect |
PSAModUI.RunPSAMod() | PSA (position-set assist) mod |
VelMaxUI.RunVMod() | Velocity cap / max speed |
WallWalkUI.RunWalkerMod() | Wall-walk surface detection |
ATurnModController.FixedUpdate
ATurnModController.FixedUpdate
Handles smooth-turn (continuous rotation) and snap-turn (discrete angle steps) independently of
Main. Running in its own component on a separate GameObject means turn logic is isolated from the main mod window and cannot be accidentally disabled by UI state.PitGeoManager.Update + FixedUpdate
PitGeoManager.Update + FixedUpdate
Update: searches the scene for target geometry objects by name.FixedUpdate: applies the configured surface friction / speed multiplier to any geometry found byUpdate.
Harmony Patch System
All Harmony patches are applied in a single call duringPlugin.Start():
PatchAll() scans all types in the assembly for methods decorated with [HarmonyPatch] and applies them automatically.
Current patch file — JoinAndLeave.cs
Contains JoinManager, a MonoBehaviour whose Update method polls PhotonNetwork.InRoom each frame to detect room state transitions (join and leave events), then fires OnScreenNotify.SendIT(...) to display the appropriate on-screen message.
Shared State — GlobalVars
GlobalVars acts as the mod’s central state store: a static class holding flags, cached references, and configuration values that multiple mods and UI classes need to read or write. Because all mod logic runs on Unity’s main thread, no locking is required.