Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ASTRA228b/BoardBiblesV1/llms.txt

Use this file to discover all available pages before exploring further.

Board Bibles V1 is loaded by BepInEx as a standard Unity plugin. The Plugin class handles the two-phase Unity startup — Awake and Start — to create a persistent game object that carries the mod’s core logic across every scene load. This page covers the BepInEx plugin declaration, the object lifecycle, and how Harmony fits into the current architecture.

BepInEx plugin declaration

BepInEx identifies plugins by a [BepInPlugin] attribute on the class that inherits BaseUnityPlugin. For Board Bibles V1 the attribute is:
[BepInPlugin(Constantss.GUID, Constantss.Name, Constantss.Version)]
public class Plugin : BaseUnityPlugin
{
    void Start() { PatchLoader.Apply(); }
    void Awake()
    {
        GameObject Plugin = new GameObject(Constantss.ObjectName);
        Plugin.AddComponent<Main>();
        DontDestroyOnLoad(Plugin);
    }
}
The three identifiers resolve to:
ConstantValue
Constantss.GUIDAstras.BoardBiblesV1
Constantss.NameBibileV1
Constantss.Version0.0.2
BepInEx uses the GUID to uniquely identify the mod in its plugin registry and in Harmony’s patch tracking.

Awake: creating the persistent game object

Awake runs before the first frame is rendered. The Plugin class uses it to create the object that hosts the Main MonoBehaviour:
void Awake()
{
    GameObject Plugin = new GameObject(Constantss.ObjectName);
    Plugin.AddComponent<Main>();
    DontDestroyOnLoad(Plugin);
}
1

Create the GameObject

new GameObject(Constantss.ObjectName) creates a plain game object named GodIsGoodReadBible in the current scene. It has no renderer or collider — it exists purely to host the script component.
2

Attach the Main MonoBehaviour

AddComponent<Main>() attaches the core script. Unity immediately begins calling Main’s lifecycle methods (Start, Update, etc.) for that object.
3

Persist across scene loads

DontDestroyOnLoad(Plugin) moves the game object to a special internal scene that Unity does not unload when the player travels between areas. This ensures the verse display and rotation timer continue running regardless of which Gorilla Tag scene is active.
Without DontDestroyOnLoad, Unity would destroy the Main game object whenever a scene transition occurred, resetting the timer and losing the cached board references.

Start: applying Harmony patches

Start runs after Awake, once all objects in the scene have been initialised. The Plugin class uses it to call PatchLoader.Apply():
void Start() { PatchLoader.Apply(); }
PatchLoader creates a Harmony instance keyed to the mod’s GUID and calls PatchAll() on the executing assembly:
using HarmonyLib;
namespace Astras_BB.Stuff;

public class PatchLoader
{
    public static void Apply()
    {
        Harmony VALLL = new Harmony(Constantss.GUID);
        VALLL.PatchAll();
    }
}
PatchAll() scans every type in the assembly for classes decorated with [HarmonyPatch] attributes and applies the corresponding prefix, postfix, or transpiler patches automatically.
Board Bibles V1 does not define any [HarmonyPatch] classes in this release. The mod achieves its effect by locating GameObjects directly via GameObject.Find() and disabling the PlayFabTitleDataTextDisplay component, rather than patching game methods. PatchAll() completes without registering any patches, but the infrastructure is in place for future versions to add method patches if needed.

The MonoBehaviour update loop

Once the Main game object exists, Unity drives everything through standard MonoBehaviour callbacks:

Start()

Sets the welcome message string and records the startup timestamp. Called once when the component is first enabled.

Update()

Called every frame. Checks whether the board GameObjects have been found yet, manages the welcome/verse/rotation state machine, and calls ApplyTexts() to write current content to the boards.

FindThem()

Invoked from Update() until all four TMP_Text references are non-null. Once cached they remain valid for the lifetime of the game object.

PickVerse() / APIPuller

PickVerse() starts the APIPuller coroutine, which runs asynchronously alongside the main game loop without blocking the frame rate.

Lifecycle summary

BepInEx loads Plugin

        ├── Awake()
        │     ├── new GameObject("GodIsGoodReadBible")
        │     ├── AddComponent<Main>()
        │     └── DontDestroyOnLoad(...)

        └── Start()
              └── PatchLoader.Apply()
                    ├── new Harmony("Astras.BoardBiblesV1")
                    └── PatchAll()  ← no patches registered in v0.0.2

Main.Start()     → records StartT, sets welcome message
Main.Update()    → frame loop: find objects → manage timers → apply text
APIPuller        → coroutine: fetch verse → parse → update CV
UseLocal()       → offline fallback: pick from hardcoded array → update CV
To add a Harmony patch in a future version, create a static class with a [HarmonyPatch(typeof(TargetClass), nameof(TargetClass.TargetMethod))] attribute. PatchLoader.Apply() will pick it up automatically on the next load without any other changes.

Build docs developers (and LLMs) love