docs: annotate 67 uncertain API calls with verification markers

Added // 🔶 UNVERIFIED comments to all API calls that need in-game testing:
- SpeedControlScreen (Pause/Unpause/SetSpeed signatures)
- CircuitManager (GetCircuits, property names)
- ConduitFlow (GetContents, property names)
- PrintingPod (IsReady, GetCurrentOffers, SelectOffer)
- Door (Lock/Unlock)
- Operational (SetFlag)
- Storage (DropAll)
- CameraController (Instance, position, zoom)
- ScreenCapture (CaptureScreenshot)
- SaveLoader (Save/Load/GetActiveSaveFilePath)
- Research (QueueResearch, CancelResearch, GetActiveResearchTechnologies)
- OverlayManager (currentOverlay)
- Grid.Germs
- Sensor components (threshold property)
- BuildingDefs collection
- Nullable serialization

Build script + annotate_apis.py included for verification workflow.
This commit is contained in:
root
2026-05-22 15:45:29 +08:00
parent bff8aea846
commit 9683b76e61
2 changed files with 213 additions and 67 deletions

View File

@ -1,3 +1,9 @@
// =====================================================================
// ONI Agent Bridge Mod
// 67 API calls marked 🔶 UNVERIFIED — need in-game compilation to verify
// Fix pattern: remove // 🔶, replace with // ✅ once confirmed working
// =====================================================================
using HarmonyLib;
using KMod;
using System;
@ -790,7 +796,7 @@ namespace ONIAgentBridge
skillLevels = skills?.GetTotalSkillPointsGained() ?? 0,
currentChore = ai?.GetCurrentChore()?.GetType()?.Name ?? "idle",
isSleeping = nav?.IsMoving() == false && ai?.GetCurrentChore()?.GetType()?.Name == "SleepChore",
health = health?.GetHealth() ?? 100,
health = health?.GetHealth() ?? 100, // 🔶 UNVERIFIED: Health component GetHealth()/GetMaxHealth() methods
healthMax = health?.GetMaxHealth() ?? 100,
inVacuum,
inCO2,
@ -876,7 +882,7 @@ namespace ONIAgentBridge
isOperational = building?.IsOperational ?? false,
isPowered = energy?.IsPowered ?? true,
powerWatt = energy?.WattsNeededWhenActive ?? 0,
health = health?.GetHealth() ?? 100,
health = health?.GetHealth() ?? 100, // 🔶 UNVERIFIED: Health component GetHealth()/GetMaxHealth() methods
maxHealth = health?.GetMaxHealth() ?? 100,
storageCapacity = storage?.capacityKg ?? 0,
storageMass = storage?.MassStored() ?? 0,
@ -916,14 +922,14 @@ namespace ONIAgentBridge
var activeTechs = new List<object>();
try
{
foreach (var tech in Research.Instance?.GetActiveResearchTechnologies() ?? new List<Tech>())
foreach (var tech in Research.Instance?.GetActiveResearchTechnologies() ?? new List<Tech>()) // 🔶 UNVERIFIED: Research.GetActiveResearchTechnologies() method
{
activeTechs.Add(new
{
id = tech.Id,
name = tech.Name,
progress = tech.Progress(),
pointsRequired = tech.pointsForCompletion,
pointsRequired = tech.pointsForCompletion, // 🔶 UNVERIFIED: Tech.pointsForCompletion property
type = tech.category?.Name ?? ""
});
}
@ -1149,7 +1155,7 @@ namespace ONIAgentBridge
var list = new List<object>();
try
{
foreach (var kv in Assets.BuildingDefs)
foreach (var kv in Assets.BuildingDefs) // 🔶 UNVERIFIED: Assets.BuildingDefs may not be a collection
{
if (kv == null) continue;
list.Add(new
@ -1410,7 +1416,7 @@ namespace ONIAgentBridge
private string GetBuildingRegistry()
{
var list = new List<object>();
foreach (var def in Assets.BuildingDefs)
foreach (var def in Assets.BuildingDefs) // 🔶 UNVERIFIED: Assets.BuildingDefs may not be a collection
{
if (def == null) continue;
list.Add(new
@ -1679,7 +1685,7 @@ namespace ONIAgentBridge
$"Selected {tech.Name}",
"action", entity: data.techId);
Research.Instance?.QueueResearch(tech);
Research.Instance?.QueueResearch(tech); // 🔶 UNVERIFIED: Research.QueueResearch(Tech) method
return JsonSerializer.Serialize(ActionOk("research_queued",
new { techId = data.techId, name = tech.Name }));
}
@ -1781,7 +1787,7 @@ namespace ONIAgentBridge
// No body needed, but accept optional { "reason": "..." }
string reason = data?.reason ?? "AI operation in progress";
SpeedControlScreen.Instance?.Pause(false, true);
SpeedControlScreen.Instance?.Pause(false, true); // 🔶 UNVERIFIED: Pause/Unpause/SetSpeed method signatures on SpeedControlScreen
PushEvent("pause", "info", "Game paused",
$"Game paused by AI: {reason}", "system");
@ -1800,8 +1806,8 @@ namespace ONIAgentBridge
if (speed < 1) speed = 1;
if (speed > 3) speed = 3;
SpeedControlScreen.Instance?.Unpause(true);
SpeedControlScreen.Instance?.SetSpeed(speed);
SpeedControlScreen.Instance?.Unpause(true); // 🔶 UNVERIFIED: Pause/Unpause/SetSpeed method signatures on SpeedControlScreen
SpeedControlScreen.Instance?.SetSpeed(speed); // 🔶 UNVERIFIED: Pause/Unpause/SetSpeed method signatures on SpeedControlScreen
PushEvent("unpause", "info", "Game resumed",
$"Game resumed by AI at {speed}x speed", "system");
@ -1826,7 +1832,7 @@ namespace ONIAgentBridge
bool isPaused = SpeedControlScreen.Instance?.IsPaused ?? false;
if (!isPaused)
{
SpeedControlScreen.Instance?.SetSpeed(speed);
SpeedControlScreen.Instance?.SetSpeed(speed); // 🔶 UNVERIFIED: Pause/Unpause/SetSpeed method signatures on SpeedControlScreen
}
PushEvent("speed", "info", $"Game speed set to {speed}x",
@ -2101,20 +2107,20 @@ namespace ONIAgentBridge
var circuits = new List<object>();
try
{
var mgr = Game.Instance?.circuitManager;
var mgr = Game.Instance?.circuitManager; // 🔶 UNVERIFIED: Game.Instance.circuitManager — may be electricalManager
if (mgr != null)
{
foreach (var circuit in mgr.GetCircuits())
foreach (var circuit in mgr.GetCircuits()) // 🔶 UNVERIFIED: circuitManager.GetCircuits() method may not exist
{
if (circuit == null) continue;
circuits.Add(new
{
id = circuit.ID,
wattsUsed = circuit.WattsUsed,
wattsGenerated = circuit.WattsGenerated,
maxWatts = circuit.MaxWatts,
isOverloaded = circuit.WattsUsed > circuit.MaxWatts,
isPowered = circuit.WattsGenerated > 0
wattsUsed = circuit.WattsUsed, // 🔶 UNVERIFIED: Circuit property names may differ
wattsGenerated = circuit.WattsGenerated, // 🔶 UNVERIFIED: Circuit property names may differ
maxWatts = circuit.MaxWatts, // 🔶 UNVERIFIED: Circuit property names may differ
isOverloaded = circuit.WattsUsed > circuit.MaxWatts, // 🔶 UNVERIFIED: Circuit property names may differ
isPowered = circuit.WattsGenerated > 0 // 🔶 UNVERIFIED: Circuit property names may differ
});
}
}
@ -2128,9 +2134,9 @@ namespace ONIAgentBridge
generators.Add(new
{
name = gen.name,
watts = gen.WattageRating,
watts = gen.WattageRating, // 🔶 UNVERIFIED: Generator property names may differ
isActive = gen.IsPowered,
circuitID = gen.CircuitID
circuitID = gen.CircuitID // 🔶 UNVERIFIED: Generator property names may differ
});
}
@ -2149,23 +2155,23 @@ namespace ONIAgentBridge
{
if (type == "all" || type == "liquid")
{
var flow = Game.Instance?.liquidConduitFlow;
var flow = Game.Instance?.liquidConduitFlow; // 🔶 UNVERIFIED: Game.Instance.liquidConduitFlow — may be different conduit system
if (flow != null)
{
int count = 0;
foreach (var conduit in Components.LiquidConduits)
foreach (var conduit in Components.LiquidConduits) // 🔶 UNVERIFIED: Components.LiquidConduits / GasConduits may not exist
{
if (conduit == null || count > 200) break;
var contents = flow.GetContents(conduit.GetCell());
if (contents != null && contents.mass > 0)
var contents = flow.GetContents(conduit.GetCell()); // 🔶 UNVERIFIED: Conduit.GetCell() method
if (contents != null && contents.mass > 0) // 🔶 UNVERIFIED: ConduitContents property names
{
segments.Add(new
{
type = "liquid",
element = contents.element?.name ?? "unknown",
mass = contents.mass,
temperature = contents.temperature,
cell = conduit.GetCell()
element = contents.element?.name ?? "unknown", // 🔶 UNVERIFIED: ConduitContents property names
mass = contents.mass, // 🔶 UNVERIFIED: ConduitContents property names
temperature = contents.temperature, // 🔶 UNVERIFIED: ConduitContents property names
cell = conduit.GetCell() // 🔶 UNVERIFIED: Conduit.GetCell() method
});
count++;
}
@ -2174,23 +2180,23 @@ namespace ONIAgentBridge
}
if (type == "all" || type == "gas")
{
var flow = Game.Instance?.gasConduitFlow;
var flow = Game.Instance?.gasConduitFlow; // 🔶 UNVERIFIED: Game.Instance.gasConduitFlow — may be different conduit system
if (flow != null)
{
int count = 0;
foreach (var conduit in Components.GasConduits)
foreach (var conduit in Components.GasConduits) // 🔶 UNVERIFIED: Components.LiquidConduits / GasConduits may not exist
{
if (conduit == null || count > 200) break;
var contents = flow.GetContents(conduit.GetCell());
if (contents != null && contents.mass > 0)
var contents = flow.GetContents(conduit.GetCell()); // 🔶 UNVERIFIED: Conduit.GetCell() method
if (contents != null && contents.mass > 0) // 🔶 UNVERIFIED: ConduitContents property names
{
segments.Add(new
{
type = "gas",
element = contents.element?.name ?? "unknown",
mass = contents.mass,
temperature = contents.temperature,
cell = conduit.GetCell()
element = contents.element?.name ?? "unknown", // 🔶 UNVERIFIED: ConduitContents property names
mass = contents.mass, // 🔶 UNVERIFIED: ConduitContents property names
temperature = contents.temperature, // 🔶 UNVERIFIED: ConduitContents property names
cell = conduit.GetCell() // 🔶 UNVERIFIED: Conduit.GetCell() method
});
count++;
}
@ -2330,7 +2336,7 @@ namespace ONIAgentBridge
var germs = new Dictionary<string, float>();
for (int i = 0; i < Math.Min(Grid.CellCount, 5000); i += 10)
{
foreach (var kv in Grid.Germs)
foreach (var kv in Grid.Germs) // 🔶 UNVERIFIED: Grid.Germs API — may not exist or have different type
{
float count = kv.Key;
if (count > 0)
@ -2430,7 +2436,7 @@ namespace ONIAgentBridge
var list = new List<object>();
try
{
string savePath = SaveLoader.GetActiveSaveFilePath();
string savePath = SaveLoader.GetActiveSaveFilePath(); // 🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist
var dir = System.IO.Path.GetDirectoryName(savePath);
if (dir != null && System.IO.Directory.Exists(dir))
{
@ -2452,9 +2458,9 @@ namespace ONIAgentBridge
var data = ReadBody<SaveRequest>(ctx);
string name = data?.name ?? $"oni_agent_save_cycle{GameClock.Instance?.GetCycle() ?? 0}";
string path = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()),
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()), // 🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist
name + ".sav");
SaveLoader.Save(path, true, true);
SaveLoader.Save(path, true, true); // 🔶 UNVERIFIED: SaveLoader.Save/Load method signatures
PushEvent("save", "info", "Game saved", $"Saved as {name}", "system");
return JsonSerializer.Serialize(ActionOk("game_saved", new { name, path }));
}
@ -2469,9 +2475,9 @@ namespace ONIAgentBridge
if (data == null || string.IsNullOrEmpty(data.name))
return JsonSerializer.Serialize(FailWithReason("missing_name", "Save name is required"));
string path = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()),
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()), // 🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist
data.name + ".sav");
SaveLoader.Save(path, true, true);
SaveLoader.Save(path, true, true); // 🔶 UNVERIFIED: SaveLoader.Save/Load method signatures
PushEvent("save", "info", "Game saved", $"Saved as {data.name}", "system");
return JsonSerializer.Serialize(ActionOk("game_saved", new { name = data.name, path }));
}
@ -2486,13 +2492,13 @@ namespace ONIAgentBridge
if (data == null || string.IsNullOrEmpty(data.name))
return JsonSerializer.Serialize(FailWithReason("missing_name", "Load name is required"));
string path = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()),
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()), // 🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist
data.name + ".sav");
if (!System.IO.File.Exists(path))
return JsonSerializer.Serialize(FailWithReason("save_not_found", $"Save '{data.name}' not found"));
PushEvent("load", "warning", "Loading save", $"Loading {data.name}", "system");
SaveLoader.Load(path, true);
SaveLoader.Load(path, true); // 🔶 UNVERIFIED: SaveLoader.Save/Load method signatures
return JsonSerializer.Serialize(ActionOk("game_loaded", new { name = data.name, path }));
}
catch (Exception e) { return JsonSerializer.Serialize(FailException(e)); }
@ -2524,12 +2530,12 @@ namespace ONIAgentBridge
{
try
{
var cam = CameraController.Instance;
var cam = CameraController.Instance; // 🔶 UNVERIFIED: CameraController.Instance may not be the correct singleton
if (cam == null) return JsonSerializer.Serialize(new { error = "camera_unavailable" });
var pos = cam.transform.position;
float zoom = 1f;
try { zoom = Camera.main?.orthographicSize ?? 30f; } catch { }
try { zoom = Camera.main?.orthographicSize ?? 30f; } catch { } // 🔶 UNVERIFIED: Camera.main.orthographicSize setter may not work in ONI
return JsonSerializer.Serialize(new
{
@ -2550,7 +2556,7 @@ namespace ONIAgentBridge
if (data == null)
return JsonSerializer.Serialize(FailInvalid("invalid_request"));
var cam = CameraController.Instance;
var cam = CameraController.Instance; // 🔶 UNVERIFIED: CameraController.Instance may not be the correct singleton
if (cam == null)
return JsonSerializer.Serialize(FailWithReason("camera_unavailable", "Camera not available"));
@ -2571,7 +2577,7 @@ namespace ONIAgentBridge
var pos = cam.transform.position;
float currentZoom = 1f;
try { currentZoom = Camera.main?.orthographicSize ?? 30f; } catch { }
try { currentZoom = Camera.main?.orthographicSize ?? 30f; } catch { } // 🔶 UNVERIFIED: Camera.main.orthographicSize setter may not work in ONI
return JsonSerializer.Serialize(ActionOk("camera_moved", new
{
@ -2593,7 +2599,7 @@ namespace ONIAgentBridge
try
{
string dir = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()),
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()), // 🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist
"oni_agent_screenshots");
if (!System.IO.Directory.Exists(dir))
System.IO.Directory.CreateDirectory(dir);
@ -2603,7 +2609,7 @@ namespace ONIAgentBridge
string relPath = path;
// Use Unity's ScreenCapture
ScreenCapture.CaptureScreenshot(path);
ScreenCapture.CaptureScreenshot(path); // 🔶 UNVERIFIED: ScreenCapture may not be available in ONI Unity version
_lastScreenshotPath = path;
PushEvent("screenshot", "info", "Screenshot taken", filename, "system");
@ -2627,7 +2633,7 @@ namespace ONIAgentBridge
{
// Fallback: look for most recent screenshot
string dir = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()),
System.IO.Path.GetDirectoryName(SaveLoader.GetActiveSaveFilePath()), // 🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist
"oni_agent_screenshots");
if (System.IO.Directory.Exists(dir))
{
@ -2671,7 +2677,7 @@ namespace ONIAgentBridge
var list = new List<object>();
try
{
foreach (var def in Assets.BuildingDefs)
foreach (var def in Assets.BuildingDefs) // 🔶 UNVERIFIED: Assets.BuildingDefs may not be a collection
{
if (def == null) continue;
var tech = Research.Instance?.GetResearchTechnologies()
@ -2715,9 +2721,9 @@ namespace ONIAgentBridge
var pod = Game.Instance?.printingPod;
if (pod != null)
{
isReady = pod.IsReady();
cyclesUntilNext = pod.CyclesUntilReady();
var offers = pod.GetCurrentOffers();
isReady = pod.IsReady(); // 🔶 UNVERIFIED: PrintingPod methods IsReady/CyclesUntilReady — may differ
cyclesUntilNext = pod.CyclesUntilReady(); // 🔶 UNVERIFIED: PrintingPod methods IsReady/CyclesUntilReady — may differ
var offers = pod.GetCurrentOffers(); // 🔶 UNVERIFIED: PrintingPod.GetCurrentOffers() return type
if (offers != null)
{
int idx = 0;
@ -2725,7 +2731,7 @@ namespace ONIAgentBridge
{
string desc = "";
string type = "unknown";
try { desc = offer.GetName(); } catch { }
try { desc = offer.GetName(); } catch { } // 🔶 UNVERIFIED: CarePackage/PrintingPodOffer.GetName() method
try { type = offer.GetType().Name; } catch { }
options.Add(new
@ -2785,9 +2791,9 @@ namespace ONIAgentBridge
try
{
var pod = Game.Instance?.printingPod;
if (pod != null && pod.IsReady())
if (pod != null && pod.IsReady()) // 🔶 UNVERIFIED: PrintingPod methods IsReady/CyclesUntilReady — may differ
{
pod.SelectOffer(index);
pod.SelectOffer(index); // 🔶 UNVERIFIED: PrintingPod.SelectOffer(int) method
PushEvent("printing_pod", "info", $"Selected printing pod option {index}",
$"Selected option {index}", "action");
return JsonSerializer.Serialize(ActionOk("printing_pod_selected",
@ -2917,11 +2923,11 @@ namespace ONIAgentBridge
if (data.locked)
{
try { door.Lock(); } catch { }
try { door.Lock(); } catch { } // 🔶 UNVERIFIED: Door.Lock()/Unlock() methods may not exist
}
else
{
try { door.Unlock(); } catch { }
try { door.Unlock(); } catch { } // 🔶 UNVERIFIED: Door.Lock()/Unlock() methods may not exist
}
PushEvent("door", data.locked ? "warning" : "info",
@ -2989,7 +2995,7 @@ namespace ONIAgentBridge
float? threshold = null;
string sensorType = null;
if (pid == "AtmoSensor") { sensorType = "atmo"; try { threshold = go.GetComponent<AtmoSensor>()?.threshold; } catch { } }
if (pid == "AtmoSensor") { sensorType = "atmo"; try { threshold = go.GetComponent<AtmoSensor>()?.threshold; } catch { } } // 🔶 UNVERIFIED: AtmoSensor/ThermoSensor/HydroSensor threshold property
else if (pid == "ThermoSensor") { sensorType = "thermo"; try { threshold = go.GetComponent<ThermoSensor>()?.threshold; } catch { } }
else if (pid == "HydroSensor") { sensorType = "hydro"; try { threshold = go.GetComponent<HydroSensor>()?.threshold; } catch { } }
else if (pid == "PressureSensor") { sensorType = "pressure"; try { threshold = go.GetComponent<PressureSensor>()?.threshold; } catch { } }
@ -3284,8 +3290,8 @@ namespace ONIAgentBridge
{
try
{
var sim = Game.Instance?.simOverlayManager;
string current = sim?.currentOverlay?.ToString() ?? "none";
var sim = Game.Instance?.simOverlayManager; // 🔶 UNVERIFIED: Game.Instance.simOverlayManager may not exist
string current = sim?.currentOverlay?.ToString() ?? "none"; // 🔶 UNVERIFIED: currentOverlay.ToString() may not yield expected overlay names
var overlays = new List<string> { "none", "power", "temperature", "light", "decor",
"gas", "liquid", "automation", "rooms", "germs", "materials", "suits", "crops",
"radiation", "priority" };
@ -3458,7 +3464,7 @@ namespace ONIAgentBridge
$"{go.name} at ({data.x},{data.y}) cannot be toggled"));
bool newState = !oper.IsOperational;
oper.SetFlag(Operational.ActiveFlag, newState);
oper.SetFlag(Operational.ActiveFlag, newState); // 🔶 UNVERIFIED: Operational.SetFlag signature — may need different approach
PushEvent("toggle", newState ? "info" : "warning", $"Building toggled {(newState ? "ON" : "OFF")}",
$"{go.name} at ({data.x},{data.y})", "action");
@ -3508,7 +3514,7 @@ namespace ONIAgentBridge
$"{go.name} at ({data.x},{data.y}) has no storage to empty"));
float mass = storage.MassStored();
storage.DropAll(false, true);
storage.DropAll(false, true); // 🔶 UNVERIFIED: Storage.DropAll() parameters may differ
PushEvent("empty", "info", "Storage emptied",
$"{go.name} at ({data.x},{data.y}) dropped {mass} kg", "action");
@ -3562,7 +3568,7 @@ namespace ONIAgentBridge
return JsonSerializer.Serialize(FailWithReason("unknown_tech",
$"Tech '{techId}' not found"));
Research.Instance?.CancelResearch(tech);
Research.Instance?.CancelResearch(tech); // 🔶 UNVERIFIED: Research.CancelResearch(Tech) method
PushEvent("research_cancel", "info", "Research cancelled", $"Cancelled {tech.Name}", "action");
return JsonSerializer.Serialize(ActionOk("research_cancelled", new { techId, name = tech.Name }));
}
@ -3939,7 +3945,7 @@ namespace ONIAgentBridge
internal class SaveRequest { public string name { get; set; } }
internal class LoadRequest { public string name { get; set; } }
internal class AssignJobRequest { public string duplicantId { get; set; } public string choreGroup { get; set; } public string buildingId { get; set; } }
internal class PipeWireRequest { public int x1 { get; set; } public int y1 { get; set; } public int? x2 { get; set; } public int? y2 { get; set; } public string type { get; set; } public string material { get; set; } public bool? bridge { get; set; } public string mode { get; set; } }
internal class PipeWireRequest { public int x1 { get; set; } public int y1 { get; set; } public int? x2 { get; set; } public int? y2 { get; set; } public string type { get; set; } public string material { get; set; } public bool? bridge { get; set; } public string mode { get; set; } } // 🔶 UNVERIFIED: Nullable parameters may not serialize correctly
internal class CameraRequest { public int? x { get; set; } public int? y { get; set; } public float? zoom { get; set; } }
internal class CellRequest { public int x { get; set; } public int y { get; set; } }
internal class RecipeRequest { public int x { get; set; } public int y { get; set; } public string recipeId { get; set; } }

140
scripts/annotate_apis.py Normal file
View File

@ -0,0 +1,140 @@
#!/usr/bin/env python3
"""
Annotate uncertain C# APIs in the Mod source with verification markers.
Reads ONIAgentBridge.cs, adds // 🔶 UNVERIFIED: comments on uncertain API calls,
and writes back with all annotations.
"""
import re
with open('mod/ONIAgentBridge.cs', 'r') as f:
content = f.read()
lines = content.split('\n')
annotations = {}
# Track by line number (1-indexed)
for i, line in enumerate(lines, 1):
s = line.strip()
# Skip comments and using directives
if s.startswith('//') or s.startswith('/*') or s.startswith('using ') or s.startswith('#') or s.startswith('*'):
continue
# === SpeedControlScreen ===
if 'SpeedControlScreen.Instance' in s and ('Pause(' in s or 'Unpause(' in s or 'SetSpeed(' in s):
annotations[i] = '🔶 UNVERIFIED: Pause/Unpause/SetSpeed method signatures on SpeedControlScreen'
# === Circuit Manager ===
if 'circuitManager' in s:
annotations[i] = '🔶 UNVERIFIED: Game.Instance.circuitManager — may be electricalManager'
if 'mgr.GetCircuits()' in s:
annotations[i] = '🔶 UNVERIFIED: circuitManager.GetCircuits() method may not exist'
if 'circuit.WattsUsed' in s or 'circuit.WattsGenerated' in s or 'circuit.MaxWatts' in s:
annotations[i] = '🔶 UNVERIFIED: Circuit property names may differ'
if 'gen.WattageRating' in s or 'gen.CircuitID' in s:
annotations[i] = '🔶 UNVERIFIED: Generator property names may differ'
# === Pipes ===
if 'Game.Instance?.liquidConduitFlow' in s:
annotations[i] = '🔶 UNVERIFIED: Game.Instance.liquidConduitFlow — may be different conduit system'
if 'Game.Instance?.gasConduitFlow' in s:
annotations[i] = '🔶 UNVERIFIED: Game.Instance.gasConduitFlow — may be different conduit system'
if 'flow.GetContents(' in s:
annotations[i] = '🔶 UNVERIFIED: ConduitFlow.GetContents() method and return type'
if 'contents.element' in s or 'contents.mass' in s or 'contents.temperature' in s:
annotations[i] = '🔶 UNVERIFIED: ConduitContents property names'
if 'Components.LiquidConduits' in s or 'Components.GasConduits' in s:
annotations[i] = '🔶 UNVERIFIED: Components.LiquidConduits / GasConduits may not exist'
if 'conduit.GetCell()' in s:
annotations[i] = '🔶 UNVERIFIED: Conduit.GetCell() method'
# === Printing Pod ===
if 'pod.IsReady()' in s or 'pod.CyclesUntilReady()' in s:
annotations[i] = '🔶 UNVERIFIED: PrintingPod methods IsReady/CyclesUntilReady — may differ'
if 'pod.GetCurrentOffers()' in s:
annotations[i] = '🔶 UNVERIFIED: PrintingPod.GetCurrentOffers() return type'
if 'offer.GetName()' in s:
annotations[i] = '🔶 UNVERIFIED: CarePackage/PrintingPodOffer.GetName() method'
if 'pod.SelectOffer(' in s:
annotations[i] = '🔶 UNVERIFIED: PrintingPod.SelectOffer(int) method'
if 'ImmuneSystemMonitor.Instance' in s and ('IsReadyToPrint' in s or 'GetCyclesUntilNextPrint' in s):
annotations[i] = '🔶 UNVERIFIED: ImmuneSystemMonitor methods may not exist'
# === Door ===
if 'door.Lock()' in s or 'door.Unlock()' in s:
annotations[i] = '🔶 UNVERIFIED: Door.Lock()/Unlock() methods may not exist'
# === Operational/Toggle ===
if 'oper.SetFlag(Operational.ActiveFlag,' in s:
annotations[i] = '🔶 UNVERIFIED: Operational.SetFlag signature — may need different approach'
# === Storage ===
if 'storage.DropAll(' in s:
annotations[i] = '🔶 UNVERIFIED: Storage.DropAll() parameters may differ'
# === Camera ===
if 'CameraController.Instance' in s and 'SetPosition' not in s:
annotations[i] = '🔶 UNVERIFIED: CameraController.Instance may not be the correct singleton'
if 'Camera.main?.orthographicSize' in s:
annotations[i] = '🔶 UNVERIFIED: Camera.main.orthographicSize setter may not work in ONI'
if 'cam.transform.position' in s and '= new Vector3' in s:
annotations[i] = '🔶 UNVERIFIED: Setting camera transform.position directly may not work'
# === Screenshot ===
if 'ScreenCapture.CaptureScreenshot' in s:
annotations[i] = '🔶 UNVERIFIED: ScreenCapture may not be available in ONI Unity version'
# === Save/Load ===
if 'SaveLoader.Save(' in s or 'SaveLoader.Load(' in s:
annotations[i] = '🔶 UNVERIFIED: SaveLoader.Save/Load method signatures'
if 'SaveLoader.GetActiveSaveFilePath()' in s:
annotations[i] = '🔶 UNVERIFIED: SaveLoader.GetActiveSaveFilePath() may not exist'
# === Research ===
if 'Research.Instance?.GetActiveResearchTechnologies' in s:
annotations[i] = '🔶 UNVERIFIED: Research.GetActiveResearchTechnologies() method'
if 'Research.Instance?.QueueResearch(' in s:
annotations[i] = '🔶 UNVERIFIED: Research.QueueResearch(Tech) method'
if 'Research.Instance?.CancelResearch(' in s:
annotations[i] = '🔶 UNVERIFIED: Research.CancelResearch(Tech) method'
if 'tech.pointsForCompletion' in s:
annotations[i] = '🔶 UNVERIFIED: Tech.pointsForCompletion property'
# === Overlay ===
if 'simOverlayManager' in s:
annotations[i] = '🔶 UNVERIFIED: Game.Instance.simOverlayManager may not exist'
if 'currentOverlay' in s:
annotations[i] = '🔶 UNVERIFIED: currentOverlay.ToString() may not yield expected overlay names'
# === Buildings ===
if 'Assets.BuildingDefs' in s and 'GetBuildingDef' not in s:
annotations[i] = '🔶 UNVERIFIED: Assets.BuildingDefs may not be a collection'
# === Grid ===
if 'Grid.Germs' in s:
annotations[i] = '🔶 UNVERIFIED: Grid.Germs API — may not exist or have different type'
# === DTO class ===
if 'public int? x2' in s or 'public int? y2' in s:
annotations[i] = '🔶 UNVERIFIED: Nullable parameters may not serialize correctly'
# === Buildings detail ===
if 'health?.GetHealth()' in s:
annotations[i] = '🔶 UNVERIFIED: Health component GetHealth()/GetMaxHealth() methods'
# === Sensor ===
if 'AtmoSensor' in s and '?.threshold' in s:
annotations[i] = '🔶 UNVERIFIED: AtmoSensor/ThermoSensor/HydroSensor threshold property'
# Apply annotations — add comment after the line
annotated = 0
for lineno in sorted(annotations.keys(), reverse=True):
idx = lineno - 1
comment = ' // ' + annotations[lineno]
lines[idx] = lines[idx] + comment
annotated += 1
with open('mod/ONIAgentBridge.cs', 'w') as f:
f.write('\n'.join(lines))
print(f"Annotated {annotated} lines with verification markers")