[WIP] Signals, you can't stop them!

Started by justarandomgeek, March 07, 2015, 08:40:14 PM

Previous topic - Next topic

justarandomgeek

I'm working on a mod that adds Signals to RimWorld, so that you can automatically detect and react to various events

Currently functional parts:
Signal Conduit - Works like Power Conduit, but it carries a signal (true/false). It links under similar rules to Power Conduit. Currently conduit connects on all sides, but a future release will add the option to block connecting on some sides, to allow running multiple signals side-by-side.

Power Sensor - Produces a signal based on the amount of power available in the connected PowerNet. Currently hardcoded to output the result of [Stored Power > 100WD], but this will be configurable soon with an interface similar to the temperature buttons on heaters/coolers. (This also eventually needs a new graphic - it currently looks like a Power Switch.)

Power Relay - A modified Power Switch that switches on/off by a signal.

Pressure Plate - A floor tile which emits a signal when items are placed on top of it.

AND/XOR gates - These take up to 3 input signals, and AND/XOR them, to produce one output. Gate can be rotated in any direction. Also has an option to invert output. I'm terrible at drawing :(

Logic Buffer - Passes a signal in one direction. Has an option to invert output, to be used as a NOT gate.

Crossover Node - Allows one signal to run across another. Useful for designing large circuits with many signals.

De/Mux and dense conduit - 3-into-1 De/Mux, and 3-signal conduit. Further upgrade to take three bundles of three and combine into a 9-signal conduit.


Planned Components (in no particular order):
Switch - An input switch for colonists to flip.
Radios - for sending signals long distances. Multiple levels for range/channels.
Solenoid-locking Doors - Doors that lock/unlock based on a signal.
Light Sensor - Either a 1-signal output of above/below threshold, or a multi-signal output for light levels.
Temperature Sensor - Either a 1-signal output of above/below threshold, or a multi-signal output of temperature value.
Simple functional blocks (maybe) - A Flip-Flop, 3/9 bit adders/comparators/logical operations. (Yep, definitely building a computer...)

Eventually I'm also hoping to tie in the mechanical walls from MD2 (to make a "lockdown" button, that activates turrets and re-arranges external walls to route all traffic through the killbox(es)), and make some components that link with the A2B belts to allow smarter thing-routing.

[attachment deleted due to age]

Famous Shoes

Sounds great! Shrinks who specialize in OCD are going to love you. ;)

Latta

I was so waiting for this. For that graphic problem, I made a quick changes. Please check my attachment.



Also, Power sensor is throwing error whenever I place one.

[attachment deleted due to age]

justarandomgeek

Thanks! I don't think that's a permanent fix for the linking, since that will fail once I have multiple different nets side by side, but for now it'll do! I'm not sure what's up with your Power Sensor, I'll have to play with that a bit to replicate it. I've updated OP with a new zip that has Pressure Plates (which may still be buggy occasionally - i had one stick 'on' a few minutes ago, but it seems to be behaving now) in it. I've also removed some of my long debugging inspect strings (the ones that listed every component on the current net), which will make it complain a lot less in general.

Latta

A threat sensor would come in handy, combined with power relay.
Also, would you mind if I decompile it? I'm...desperately curious...about how net system...works...

justarandomgeek

#5
For the Power Sensor issue - it appears that sometimes the CompPower.PowerNet is null when the first tick happens, and that's what causes the error! It looks like it sorts itself out before the second tick, but I'll be adding a check to suppress that in my next upload!

Dive on in with the decompiler, I'll be adding source eventually anyway!

The short version is there's a CompSignal in each device (Except sources, which get the subclass CompSignalSource), including conduit (some future devices will have more than one, i haven't worked all the details of that out yet). Each CompSignal identifies the list of sides it can connect on, currently everything on all sides. The CompSignals assemble themselves into SignalNets, which each have a list of CompSignals, and of CompSignalSources. When a device wants to read the value from the net, it gets SignalNet.CurrentSignal, which ORs the signals from all the CompSignalSources on that net. There's some black magic in the net-splitting code that handles removal of nodes, but everything else is actually pretty simple. Nets are assigned numeric IDs to aid in mapping out what's connected to what, but the IDs aren't used for anything beyond that. SignalGrid has some housekeeping and helpers for finding what's in a particular cell, and on particular sides.

justarandomgeek

Updated OP: Added AND/XOR gates, which take up to three input signals, and produce one output. Sorry for my hideous sprites! (anybody want to draw some better ones?)

The XOR gate treats unconnected inputs as false, the AND treats them as true, to allow use as 2-way gates also.

Latta

Oooh yess! Finally I made a working prototype of heat pipe! I'm in debt of yours!
Also, thank you for those kind and detailed description. It really helped me.

But one question: How can SignalNet's signal gets updated? I can't see any updating method within any Tick(). I know that each building sets its CompSignalSource's OutputSignal, but why? Does every Comps get updated automatically by game?

justarandomgeek

SignalNets are lazy-evaulated: when something reads SignalNet.CurrentSignal(), it goes out and reads each CompSourceSignal that's attached and OR's them. If nothing is reading that net, it never bothers to update. The buildings have Tick()s that do most of the work (updating their own output, or reading the net and taking an action).

How much did you have to change to make heat pipes?

Latta

#9
Quote from: justarandomgeek on March 08, 2015, 09:41:33 AM
How much did you have to change to make heat pipes?

Not much, just changed classes/variables to respectful names, with HeatNet.CurrentTemperature() (Was it SignalNet.CurrentSignal()?) being float from bool.
CompHeatSource will set its float value to its room's temperature while HeatNet.CurrentTemerature() SUMs all HeatSources and returns average value. (Instead of OR of bool values, it is.) It's a prototype, so I never bothered to make it more realistic. (Planned)
Also, HeatSource will push its connectedNet's returned CurrentTemperature(), So all connected rooms will equalize their temperature.

EDIT: Maybe I'll rename HeatSource to HeatTrader.

Latta

#10
What I've done so far. I tried to draw overlay just like PowerNet, but can't figure it out correctly.

It DOES draw it, but doesn't update graphic automatically so you need to build a power conduit nearby. Also, It displays when you choose CompPower, not custom Comp made here.

EDIT: Now it can refresh itself, but need to select CompPower to show itself.

justarandomgeek

#11
Updated OP: added a Logic Buffer component, and added inversion to it and the existing gates. Also added a Crossover component.

I tried to make my own subclass of Graphic_Linked to draw conduit linked by nets, but it looks like it's a bit more complicated than that. Anyone know of an existing mod I can look at for how to manage graphic linking myself? Notably, I'm planning to make the conduit configurable to only link on certain sides, to allow multiple signals to run side by side, which will require the graphics to react on the net a conduit is on.

Specifically, I need linking to use logic something like this:

public override bool ShouldLinkWith(IntVec3 c, Thing parent)
{
return SignalGrid.SignalListAt(parent.Position)
.FindAll(cs=>cs.parent==parent)
.FindAll(cs=>cs.AdjacentNode(
IntRot.FromIntVec3(c-parent.Position)
)!=null)
.Count!=0;
}


I'm shelving that for now to build out other components. Also, I've posted my source so far on github. Feel free to send pullreqs, especially for fixes to graphical issues - that's not exactly my strong suit, as evidenced by the logic device sprites!

justarandomgeek

#12
Updated OP: Updated to A10(c), and added wide (3x and 9x) conduit and Mux/Demux components. I'm not super happy with the inconsistent ordering of bits when a wide signal turns corners before being split back apart, but I haven't come up with a good way to handle that yet.

I also made some major architectural changes to how signals are implemented to do this, including adding a custom properties class to give options to CompSignal in the XML, and collapsing all (except for Source) back into CompSignal directly.

I think my next changeset will be some more useful sensors, especially now that Tynan has taken away the last of our manual power controls...

EDIT: Don't lay signals of different widths directly against each other in this release, they'll try to connect and throw errors.

noone

Quote from: justarandomgeek on March 07, 2015, 08:40:14 PM
[...] Eventually I'm also hoping to [...] make some components that link with the A2B belts to allow smarter thing-routing.

That sounds like a great idea. Let's get in touch when you get to that stage to make it happen one way or another. By then, the A2B mod should have reached a new stable level with underground belt instead of teleporters. And (hopefully) food degradation.

justarandomgeek

Quote from: noone on April 27, 2015, 12:23:59 AM
Quote from: justarandomgeek on March 07, 2015, 08:40:14 PM
[...] Eventually I'm also hoping to [...] make some components that link with the A2B belts to allow smarter thing-routing.

That sounds like a great idea. Let's get in touch when you get to that stage to make it happen one way or another. By then, the A2B mod should have reached a new stable level with underground belt instead of teleporters. And (hopefully) food degradation.

I'm in the middle of some upgrades to the Pressure Plate (so it reports the stack count in it's square as a 9-bit signal), and adding in some higher-order logic components (specifically, 3/9 bit comparators and constants), but once I finish those I'll probably be work on this next, and you'll definitely hear from me if I run into trouble making the belts do what I want!

The biggest problem I see so far is that the building class(es) for the belt components I want will have to reference both the A2B assembly, and the Signals assembly, which means it can't be included in either without then requiring the other be present. I'll probably end up doing it as a separate "integration" mod that must be loaded after the two "base" mods.