Televisions
Status: experimental.
What it is
A television is a set in the world that the player can switch on and off. This API lets your mod list the televisions in the scene you are in, see whether each one is switched on, switch one on or off, and get told when any television is switched on or off, by the player or by another mod.
It does not give you the power supply of a set or its screen picture.
When to use it
- Switch a television on or off from your mod, for example as part of a scene you build.
- React when the player or another mod switches a television on or off.
- Count how many televisions are on.
Quick example
This mod writes a log line every time a television is switched on or off. Once a save is loaded, it also logs every television in the scene and whether it is on.
using ObenseuerCore;
[ModInfo("example.tvwatch", "TV Watch", "0.1.0")]
[ModDependency("obenseuer.moddingframework", "0.11.0")]
public sealed class TvWatch : FrameworkMod
{
protected override void OnLoad()
{
Televisions.Changed += args => Log.Info("Television " + args.Id + " is now " + (args.On ? "on" : "off") + ".");
Events.WhenReady(() =>
{
foreach (TelevisionInfo television in Televisions.All())
Log.Info("Television " + television.Id + " is " + (television.On ? "on" : "off") + ".");
});
}
}
Changed is an event: the framework calls your code each time it happens. Events.WhenReady runs your code once a save is loaded, or at once if one already is. See Using events.
Common tasks
Switch every television in the scene off. SetOn returns true when the set is in the state you asked for afterwards, and false when it could not do it.
foreach (TelevisionInfo television in Televisions.All())
Log.Info(television.Id + " switched off: " + Televisions.SetOn(television.Id, false));
Count the televisions that are on.
int on = 0;
foreach (TelevisionInfo television in Televisions.All())
if (television.On) on++;
Log.Info(on + " televisions are on.");
Reference
This is the full list of what the API gives you. Text in brackets at the end of a note is extra detail for experienced modders, and you can skip it on a first read.
Televisions lists, reads and switches sets
Use it to find the televisions in the loaded scene and to switch one on or off with SetOn.
public static class Televisions
{
public static List<TelevisionInfo> All();
public static TelevisionInfo Get(string id);
public static bool SetOn(string id, bool on);
public static event Action<TelevisionChangedArgs> Changed;
public static bool IsAvailable { get; }
}
| Method | Returns | What it does |
|---|---|---|
All() | List<TelevisionInfo> | Every television in the scene you are in. |
Get(id) | TelevisionInfo | The television with this id. null when nobody has it. |
SetOn(id, on) | bool | Switches a television on or off. true when it ends up in the state you asked for. |
| Property | Type | What it means |
|---|---|---|
IsAvailable | bool | false when the Changed event could not be set up. |
| Event | Gives you | When it fires |
|---|---|---|
Changed | TelevisionChangedArgs: the television’s id and whether it is now on. | A television was switched on or off. |
TelevisionInfo a snapshot of one television
All() gives you one of these for each television, and Get(id) gives you one for a single id. It is a snapshot, so ask again to see a change. (It reads the game’s TelevisionNoise.)
public sealed class TelevisionInfo
{
public string Id { get; }
public bool On { get; }
}
| Property | Type | What it means |
|---|---|---|
Id | string | The television’s id. Pass it to Get and SetOn. |
On | bool | true when the set is switched on. |
TelevisionChangedArgs what Changed tells you
Changed gives you this each time a television turns on or off, and On is its new state. The framework hooks the game’s own TurnOn and TurnOff, so a switch the player makes raises it too.
public sealed class TelevisionChangedArgs
{
public string Id { get; }
public bool On { get; }
}
| Property | Type | What it means |
|---|---|---|
Id | string | The id of the television, the same as TelevisionInfo.Id. |
On | bool | true when it was switched on, false when it was switched off. |
Things to know
All()andGetonly see televisions that are switched on in the scene you are in. A television in another scene, or one the game has hidden, is not listed. (They search the active objects of the active scene forTelevisionNoise.)- A television id is a piece of text that names one set.
All()andGetgive it to you. It is stable as long as the scene does not change. A null or empty id finds nothing. (The id is the set’s save GUID when it has one, otherwise its scene path, such asScene:Root[0]/Child[2]/Television[1].) Get(id)gives you a snapshot, not a live view. The values do not change by themselves, so callGetagain for fresh values.SetOn(id, on)does what the player does when they use the set. It plays the switch sound, as the player’s use does. The set also triggers anything the map has wired to it, such as a relay. Asking for the state it is already in does nothing and also returnstrue. (It calls the game’sTurnOn(true)orTurnOff(true). Switching on or off triggers the set’sonTurnOnoronTurnOffoutputs.)- A mod that switches many sets at once plays that many switch sounds.
Changedfires when a set goes from off to on or from on to off. It fires no matter who did it: the player, your mod, or another mod or map script. A call that changes nothing does not fire. (It is raised afterTelevisionNoise.TurnOn(bool, bool)andTurnOff(bool, bool, bool, bool)whenisOndiffers from its value before the call. Every publicTurnOnandTurnOffoverload goes through one of these two. The game’s load code only setsisOnand callsRefresh(), andStartcalls them with the state the set already has.)Changedcan also fire while a save is loading or being written. If your handler should ignore those, checkSaveData.Busy, which istrueduring a load or a save.IsAvailabletells you whetherChangedworks. It isfalsewhen the framework could not set up the event. If a field it needs is missing, the reads give an empty list,nullorfalse, andSetOngivesfalse.Onis the switch, not whether the picture is showing. If a set loses power while it is on,Onstaystrue, and noChangedfires for the power cut. (The game’sPowerOffcallsTurnOffwithpowerOff: true, which leavesisOnas it was.)
Limits
SetOnreturnsfalsewhen the set is locked, has no power, or is not there. The player can’t switch a locked or unpowered set either. It also returnsfalsewhile a save is loading or being written. (It checks the private fieldslockedandpowerOnfirst, the same two checks the game’sInteractmakes.)Changeddoes not fire when a save loads, because a loaded set is already in its saved state.- An id that is a scene path changes if you move or rename the set’s object.
- You can’t cut or restore a set’s power, read its power state, or change its screen. You can switch the set with
SetOn, but the power supply and the screen picture are not part of this API yet. (PowerOff,PowerOn, the screen materials and the animation are not covered.)
Details
Target: Obenseuer 0.5.08 (buildid 25969064), Unity 6000.0.77f1 Mono, BepInEx 6 Unity.Mono (be.788, the tested build) or BepInEx 5 (5.4.23 or later). Namespace: ObenseuerCore. Files: src/Api/Televisions.cs, src/Api/TelevisionsPatches.cs.
Everything not listed in this reference is internal and may change without notice. Items marked experimental may change too.
The framework changes some of the game’s methods when it starts, so it can tell your mod when a television is switched on or off. All of those changes belong to one feature group, obenseuer.moddingframework.televisions, the name you will see in the log.
When you can call it
- Call everything from your mod’s normal code (
OnLoad, event handlers,Update), not from a background thread you started. The game and Unity only work safely on one thread, the main thread (see the glossary). This goes for every member on this page, and for the code that handlesChanged. - It is safe to call any of it at any time, even on the main menu or while a save is loading. If there is nothing to read yet, you get an empty list,
nullorfalse. - Your
Changedhandler runs inside the game’s own call, right after the state changed. If your handler throws an error, the framework logs it and still runs the other handlers.
What to check for and what comes back
- Nothing here throws an error. A null or empty id finds no set, so
GetgivesnullandSetOngivesfalse. - If the game itself fails while the framework works, you get an empty answer instead of an error. The answer is the plain default (an empty list,
nullorfalse), and the first failure of each member goes to the log as an error. Later failures of that member are not logged again.
If something fails to set up
The framework changes some of the game’s methods when it starts. If a game update breaks one of them, the framework removes all the changes of the feature group that depends on it, turns the group off, and writes error lines to the group’s log file in BepInEx\logs. The rest of the framework keeps working.
- If the television event can’t be set up, only
Changedstops. The framework needs the game’sTurnOn(bool, bool)andTurnOff(bool, bool, bool, bool)onTelevisionNoiseand the three private fieldsisOn,lockedandpowerOn. If any of them is missing, the feature groupobenseuer.moddingframework.televisionsturns off andIsAvailableisfalse. (The reads andSetOnuse reflection on those three fields, so a game update that renames one breaks them as well.)