Files
oniagent/mod/API_REFERENCE.md
2026-05-30 11:00:36 +08:00

5.8 KiB

ONI Mod API Reference (Confirmed via DLL Decompile)

Assembly: Assembly-CSharp.dll (D:\steam...\Managed)

BuildingDef (extends Def -> ScriptableObject)

FIELD string PrefabID          # FROM BASE CLASS Def
FIELD int WidthInCells
FIELD int HeightInCells
FIELD float EnergyConsumptionWhenActive
FIELD float ExhaustKilowattsWhenActive
FIELD string[] MaterialCategory
FIELD float[] Mass
FIELD string Name              # PROPERTY (Name getter)
PROPERTY string Desc, Flavor, Effect

Usage: def.PrefabID (NOT def?.PrefabID — fields cannot use null-conditional)

Building (base of BuildingComplete)

FIELD BuildingDef Def
PROPERTY Orientation Orientation
METHOD int GetCell()
METHOD int GetBottomLeftCell()

Usage: ((BuildingComplete)item).Def.PrefabID / building.Def.WidthInCells IsOperational is NOT on BuildingComplete — use go.GetComponent<Operational>()?.IsOperational IsOperational is a PROPERTY (bool), NOT a method: no () after it

Operational

PROPERTY bool IsOperational   # getter
PROPERTY bool IsFunctional
PROPERTY bool IsActive
METHOD void SetFlag(Flag flag, bool value)
METHOD bool GetFlag(Flag flag)
METHOD void SetActive(bool value, bool force_ignore)

Generator

PROPERTY float WattageRating
PROPERTY ushort CircuitID
PROPERTY float JoulesAvailable
PROPERTY float Capacity
PROPERTY bool IsEmpty

NO IsPowered property. Check JoulesAvailable > 0 instead.

ConduitFlow.ConduitContents (STRUCT — value type!)

STRUCT ConduitContents {
  SimHashes element    # FIELD
  float mass           # FIELD
  float temperature    # FIELD
  int diseaseHash
  int diseaseCount
}

flow.GetContents(int cell) returns ConduitContents (always valid since it's a struct) Never null-check with != null — use contents.mass > 0 instead

CircuitManager

METHOD ushort GetCircuitID(int cell)
METHOD float GetWattsUsedByCircuit(ushort circuitID)
METHOD float GetWattsGeneratedByCircuit(ushort circuitID)
METHOD float GetMaxSafeWattageForCircuit(ushort circuitID)
METHOD List<Generator> GetGeneratorsOnCircuit(ushort circuitID)
METHOD List<IEnergyConsumer> GetConsumersOnCircuit(ushort circuitID)
METHOD List<Battery> GetBatteriesOnCircuit(ushort circuitID)

NO GetCircuits() method. Discover circuit IDs via GetCircuitID(cell) for each building.

SaveLoader

PROPERTY static SaveLoader Instance   # getter
METHOD string Save(string filename, bool isAutoSave, bool updateSavePointer)
METHOD bool Load(string filename)
METHOD string GetActiveSaveFilePath()

All are INSTANCE methods. Usage: SaveLoader.Instance.Save(...)

Techs (ResourceSet)

METHOD Tech TryGetTechForTechItem(string itemId)

To enumerate: use the base class ResourceSet<T> which has resources / implements IEnumerable Db.Get().Techs returns the Techs collection. Iterate via foreach (var tech in Db.Get().Techs.resources) or check if Techs implements IEnumerable directly

World

PROPERTY static World Instance

NO worldName property. Fallback: Use a hardcoded string like "ONI World"

Components quirks

  • Cmps<T> implements IEnumerable (non-generic) → foreach gives object, cast explicitly
  • CmpsByWorld<T> does NOT implement IEnumerable → CANNOT foreach. Access items through its internal API
    • Workaround: skip Components.Geysers or use reflection to access items
  • Components.CreatureIdentities NOT FOUND → use Components.Brains instead
  • Components.Crops gives Crop objects → access .gameObject not cast to GameObject

Missing types in this ONI version

  • ImmuneSystemMonitor → NOT FOUND, wrap in try-catch
  • GlobalNotificationManager → NOT FOUND, use Notifier if available
  • AlertManager → NOT FOUND
  • PriorityScreen.Instance → NOT FOUND
  • AttributeLevels → NOT FOUND
  • GameTags.RawPoultry / PreciousStone → NOT FOUND
  • MoraleProvider / QualityOfLife / HappyMonitor → NOT FOUND

Grid (Stable — confirmed working)

STATIC Element[] Element         # grid[cell]
STATIC float[] Mass
STATIC float[] Temperature
STATIC bool[] Solid
STATIC bool[] IsVisible
STATIC GameObject[,] Objects      # [cell, ObjectLayer enum]
STATIC int XYToCell(int x, int y)
STATIC void CellToXY(int cell, out int x, out int y)
STATIC int CellCount (field)
STATIC int WidthInCells
STATIC int HeightInCells

ObjectLayer (enum values include)

  • Building, Pickupables, Minion, Plants, Creatures, etc.
  • NO Creature value → check the actual enum

Health

PROPERTY float hitPoints    # NOT a method
PROPERTY float maxHitPoints
METHOD bool IsIncapacitated()
METHOD void Damage(float amount)

Verified correct patterns

// Buildings
foreach (var item in Components.BuildingCompletes) {
    var b = (BuildingComplete)item;
    var go = b.gameObject;
    var def = b.Def;  // FIELD on Building base
    string id = def.PrefabID;  // FIELD on Def base
    int w = def.WidthInCells;
    bool op = go.GetComponent<Operational>()?.IsOperational ?? false;
}

// Pipes (ConduitContents is struct!)
var contents = flow.GetContents(cell);
if (contents.mass > 0) { ... }

// Power
ushort cid = mgr.GetCircuitID(cell);
float used = mgr.GetWattsUsedByCircuit(cid);

// Save/Load
SaveLoader.Instance.Save("name", true, false);
SaveLoader.Instance.Load("path");

// Pause
SpeedControlScreen.Instance.Pause(false, true);
SpeedControlScreen.Instance.Unpause(true);
bool paused = SpeedControlScreen.Instance.IsPaused;
int speed = SpeedControlScreen.Instance.GetSpeed();
SpeedControlScreen.Instance.SetSpeed(3);

// Camera
CameraController.Instance.SnapTo(new Vector3(x, y, z));

// Duplicants
foreach (var item in Components.MinionIdentities) {
    var m = (MinionIdentity)item;
    string name = m.GetProperName();
    var go = m.gameObject;
}