Table of Contents

Class PrestigeSystem

Namespace
GrindFest
Assembly
GrindFest.dll

Single source of truth for the Grimoire (prestige tree). Holds the static bonus fields the rest of the game reads (LevelCap, HeroSlot, etc.), AND the JS bridge that the OneJS / Preact UI calls into to query state, register the node registry, and inscribe nodes.

History: this used to be split across PrestigeSystem (fields + dormant legacy shop stubs) and PrestigeTreeBridge (registry + purchases + bot API projection). The split was an artifact of the migration off the old gold shop \u2014 they're now a single class so callers don't have to remember which side owns what.

JS callers reach this class via Puerts as CS.GrindFest.PrestigeSystem.{GetState, TryInscribe, RegisterNodes}.

public class PrestigeSystem : Singleton<PrestigeSystem>
Inheritance
object
PrestigeSystem
Inherited Members

Fields

ArmorBonus
AttackRatingBonus
CarryingCapacity
DamageBonus
ElementalResistance
ExperienceBonus
GoldBonus
GoldCap
HealthBonus
HeroSlot
LevelCap
MagicFindBonus
MovementSpeed
NameHero
PATRON_MONTHLY_NODE_ID
PremiumShop
SexHero
SkillPoints
StatPoints
VillageStash
_shopItems

Properties

AllKnownNodeIds

Methods

ApplyNodeEffects(string, int)

Adds a single node's effects onto the static bonus fields. Unknown kinds are silently ignored (Pact unlocks, Umbra trade-offs, etc. don't have a backing field yet).

CalculatePrestigePoints(int)
EnumerateRegistry()

In-process accessor for pure-C# consumers (bot API, save migration). Returns the live registry entries directly — do NOT mutate. Empty when the registry hasn't been populated yet.

GetAllNodes()

Returns the full registry as a JSON array. Empty array if the Grimoire hasn't been registered yet (i.e. UI never mounted / startup not complete). Bot API consumers should treat empty as "registry not ready".

GetPrestigeBonusLevel(PrestigeShopItem)
GetPrestigeNode(string)

Returns a single node's projection, or null if unknown.

GetPrestigeNodes()

Returns every registered Grimoire node as a PrestigeNode (id, name, kind, parents, IsInscribed, per-currency costs). This is the canonical view used by the bot API (AutomaticParty.GetPrestigeNodes); the bridge owns the projection so the BotApi layer stays a thin facade that doesn't know about PrestigeSystem.NodeRegistryEntry.

Empty list if the registry hasn't been populated yet (App.tsx bootstrap hasn't run).

GetRegistryEntry(string)

In-process registry lookup. Returns null if the id is unknown.

GetState()
InscribeFromSteamCallback(string)

Inscribes a node that was paid for externally (Steam IAP). Skips the in-game cost validation entirely. Idempotent — safe to call when the node is already inscribed.

IsInscribed(string)

Returns true if the given node id is currently inscribed on the local party. Cheaper than building a full PrestigeNode.

PurchasePrestigeBonus(PrestigeShopItem, int)
PurchasePrestigeBonus(string, int, int, int)
RecomputeAllBonuses()

Zeros every backing static field and re-applies every inscribed node's effects from scratch. Call after refund or after the registry is (re)populated.

RefreshPrestige()
RegisterNodeEffects(string)

Called from JS (PrestigeTreeView mount) with a JSON array [{"id":"...","effects":[{"kind":"GoldBonus","value":10}]}]. Replaces the previously-registered map and re-applies bonuses for everything currently inscribed.

RegisterNodeIds(string)

Called from JS (PrestigeTreeView mount) with a JSON array of node IDs, e.g. ["gateway","awakening","ember_apex",...]. Replaces the previously-registered list.

RegisterNodes(string)

Called once from App startup with a JSON array of every node in the Grimoire (id, name, kind, parents, costs, effects). Replaces any previously-registered set, repopulates the id list and the per-node effects map, and recomputes bonuses to reflect the current InscribedPrestigeNodes against the new registry.

Sacrifice(HeroController)
TryInscribe(string, string)

Attempts to inscribe a node. Returns true on success (currency deducted and node added to Party.InscribedPrestigeNodes). Returns false if already owned or insufficient currency.

costsJson is [{"currency":"Gold","amount":5000}, ...].

TryInscribeById(string)

Looks up a node's costs in the registry and attempts to inscribe it. Caller doesn't need to know costs — they're whatever the Grimoire authored. Returns false if the node id is unknown, the registry is empty, the node is already inscribed, or the player can't afford it.

ZeroAllBonuses()