tsunamayo / Starship-EVO

Welcome to Starship EVO bug tracking repo !
114 stars 17 forks source link

My assessment of the logic system #493

Closed NoxyNixie closed 4 years ago

NoxyNixie commented 6 years ago

:arrow_right: Foreword

As much as I'd like to pretend that I know everything in the world ... I don't. Therefore pretty much anything below should be regarded as an opinion rather than rule and just my insight into what people have said with regards to the logic in Skywanderers.

I've added a :star2: to the topics I think are important or are the better choice.

:arrow_right: The missing pieces

The most important things that I found to be missing are ways to stop signals from flowing through, a way to compare two signals in a more friendly way and a way to store data. Below you will find my ideas around solving these issues.

Three-state buffer :star2:

This behaves kind of like a circuit breaker.

Diagram:

Truth table:

Input A Input B Output
0 0 N/A¹
1 0 N/A¹
0 0
0.5 0.5
1 1

¹ No signal is transmitted at all. ² Any value that is greater than 0.

This gate (or something very similar) has been mentioned in various places and what I've seen is that everyone agrees that something like this is needed.

Comparison gate :star2:

The comparison gate should be expanded a bit more than what the router gate offers. It should include the following comparison options: > => = <= < and != and should always output a 0 or a 1 (no fuzzy numbers).

Truth Table in Mode >:

Input A Input B Output
0 0 0
1 0 1
0 1 0
1 1 0
0.54321 0.54321 0
0.3 0.7 0
0.7 0.3 1

Truth Table Mode =>:

Input A Input B Output
0 0 1
1 0 1
0 1 0
1 1 1
0.54321 0.54321 1
0.3 0.7 0
0.7 0.3 1

Truth Table Mode =:

Input A Input B Output
0 0 0
1 0 0
0 1 0
1 1 1
0.54321 0.54321 1
0.3 0.7 0
0.7 0.3 0

The other modes are essentially the inversion of the listed truth table so might not actually need to be a separate modes since you can use a not gate.

Special care should be taken in comparisons because of floating point inaccuracies so in the actual implementation you may want to use some form of epsilon.

Even though the three-state and comparison gate both can take over the functionality of the Router gate I still think the router gate has its own uses and in some cases can simplify the logic.

The comparison gate can also be 3 separate gates; The > comparison, The => comparison and the = comparison gates. This is mostly a choice of where you would add the complexity; Either in a separate menu or in the number of choices of logic tiles.

It is technically possible to make a circuit that would behave like a comparison gate using some clever tricks with router gates, constant gates and mix gates but this is somewhat more complex and not entirely straight forward since you need to do a bit of math to calculate your mix gate values (This is demonstrated in #486 where the math is done in a spreadsheet).

Data gate :star2:

There are so many types of gates out there to store some information (D-Latch, JK-Latch, RS-Latch) but none of them really work in Skywanderers due to the unique way the logic is done (Pretty much all of these gates rely on a loop-back which can't be done in Skywanderers). For this reason I propose a logic gate that behaves as a data store.

I'm imagining this gate to have two inputs and one output. One of the inputs is the set input and any packet that is sent to this will deposit its value in the store but does not cause the output to be triggered. To read the data one needs to send a packet to the other input which then makes the gate output the stored value.

The constant gate almost already behaves like this with the exception that you currently can't set the constant gates value through logic. This was also mentioned in #335.

If the constant gate is adjusted to be able to receive a value through logic one must not forget to do the same for the mix gate as this would allow for some very interesting behaviors.

:arrow_right: Expanding Basic gates

Basics

Beyond the current basic gates some more specific gates might make some of the logic designs a little easier.

Currently we have the AND, OR and NOT gates with which we can make pretty much any other gate but to some this is not enough.

Adding the following gates may be an option: NOR, NAND, XOR, XNOR. Even though it is very easy to make this with the already existing gates these are all still considered to be basic gates.

T-Flip Flop

Yes we have the switch that can receive logic input to be toggled but it is not a true T-Flip Flop since you can't chain them and have a binary counter. I am aware that just chaining a bunch of router gates intermixed with switches will create a binary counter but this feels too complex (and too big) for something as basic as a binary counter.

:arrow_right: Mathematical gates

Due to the fuzzy (or fractional) logic people have seen the need to to do more mathematical things with the values that flow through their logic (e.g.: forum thread). The biggest problem with these mathematical gates is that it is hard to determine where you stop with implementing new gates and where you switch over to a different system (expression gate, LUT gate, programmable gate, etc.).

Addition gate

This gate simply adds the two values together and clamps them between 0 and 1 (to prevent overflows). From the perspective of pure binary logic this would behave as an or gate (therefore duplicating that functionality but only for binary logic).

Truth table:

Input A Input B Output
0 0 0
1 0 1
0 1 1
1 1 1
0.54321 0.3 0.84321
0.3 0.5 0.8
0.5 0.3 0.8

Subtraction gate

Similar to the addition gate this simply subtracts Input B from Input A and outputs the value. All other gates that currently exist do not care in which order input is given. For this gate it is important that the order of input is very clear to the user. In pure binary logic this appears to be a inverted IMPLY gate.

Truth table:

Input A Input B Output
0 0 0
1 0 1
0 1 0
1 1 0
0.54321 0.3 0.24321
0.3 0.5 0
0.5 0.3 0.2

Average gate

Somewhat of an odd gate but this popped up when we were discussing logic gates on discord. This gate translates badly to binary logic since half is not a binary number.

Truth table:

Input A Input B Output
0 0 0
1 0 0.5
0 1 0.5
1 1 1
0.54321 0.3 0.421605
0.3 0.5 0.4
0.5 0.3 0.4

Multiplication gate

After we discussed the Average gate it was brought up that this gate could also be done by adding a multiplication gate.

Note that since we can't really go above 1 the multiplication gate kinda becomes a dividing gate.

Truth table:

Input A Input B Output
0 0 0
1 0 0
0 1 0
1 1 1
0.54321 0.3 0.162963
0.3 0.5 0.15
0.5 0.3 0.15

Sinusoidal gates

Yup you guessed it when talking with fellow logic enthusiasts this craziness didn't stop at multiplication ... no instead we went as far as the sinusoidal gates! These magic puppies will give us, the nerdy bunch, a boner.

Since our range is between 0 and 1 the following formula would probably work best: sin(Input * π).

Truth table:

Input Output
0 0
1 0
0.5 1
0.54321 ~0.99080035087639830531378535569852
0.3 ~0.80901699437494742410229341718282
0.8 ~0.58778525229247312916870595463907

The Cosine variant can be easily done by just adding a not gate after this gate.

Other mathematical gates

As you can imagine there are many other gates you can think of by just looking at the C# Math library.

:arrow_right: Programmable gates

As fun as the mathematical gates can be some if not all of their functionality can be implemented using some form of programmable logic gates. Below I will touch on some of the gates that people have mentioned on the forums or on discord.

Lookup table gate

This gate mostly only makes sense in binary logic since it relies on values to be either on or off. Though technically one can make a lookup table that would work in a more fuzzy manner how this would actually be reflected in the UI can potentially be very complex. The easiest I can think of is to use min and max sliders that the user can drag around for each lookup entry and then another slider for what the output value would be but then you'd need to add so many sliders (or dynamically add sliders) and before you know it the UI is more complex than the entire problem this gate tried to solve.

This gate was mentioned in this forum thread with many examples of how the binary logic would work.

In my opinion this type of lookup table would work brilliantly if the logic was purely binary however in Skywanderers this is not the case. A gate that would work from an expression would make more sense in Skywanderers.

Expression gate :star2:

This gate alone could replace all the mathematical gates and then do so much more. The biggest choice with a gate like this is choosing how many input and outputs you are going to support. My choice would be two inputs and one output as this would allow most of the flexibility without making the gate larger than a 2 by 2 stud size tiles.

If only one output is used the entire expression will always be output so a single field to add your expression would work. With two inputs you can use variables names as A and B (as I've been using in this document).

Some examples of what I'd consider valid expressions:

Expression Notes
A + B The addition gate.
(A + B) / 2 The average gate.
sin(A * π) The sinusoidal gate.
A > 0.5 ? A : B Not sure what you'd call this but this expression uses the ternary operator.
A != 0.0 ? cos(A * π) / A : 1.0 Another expression mixing most of the previous examples.

Since a expression system like this easily allows the values to go outside of the bounds, the gate should clamp its output between 0 and 1 and warn the user both in the UI and on the tile if the expression output exceeds these bounds.

Script-able gate

This one is far more powerful than the expression gate or the lookup table gate but therefore also much more complex for the less nerdy among us. A script-able gate was mentioned in this forum thread as an option. To my delight the language Lua was mentioned and I think this is one of the better choices as a scripting language since it is both relatively simple yet powerful and has a very low overhead.

The power of scripting goes much further than simple logic and therefore also quickly grows into a very big project including designing an API for accessing various aspect of the game. Some aspects that could be made accessible through a scripting interface:

This small list is just the tip of the potentially huge and growing list of possible things that something like a scrip-able gate could have access to.

As much as I like the idea of a Lua script-able gate this is also a potentially very complex system that goes far beyond what the current logic system needs. So for the time being I would vote for a expression based gate over any of the other programmable gates mentioned above.

:arrow_right: Sensors

State Sensor

The state sensor reads the state of hinges/rotors/sliders similar to the callback gate but instead of updating the values at the end of the animation this gate reads the value when receiving a logic signal. This gate should have two inputs, one connecting to the hinge/rotor/slider and one connecting to other logic to receive the signal.

Sun Light Sensor

This sun light sensor when receiving a signal will output the level of illumination from the sun the sensor is receiving. I'm not sure how easy this is to implement but I can already think of many places where I would use something like this to enable or disable lighting.

Proximity Sensor

The proximity sensor outputs a signal based on the distance to whichever object its laser hits. This is quite similar to the Laser Sensor (without laser receiver) and because of this the Laser sensor could be updated to have this functionality instead.

Color Sensor

This is a laser like sensor with 3 outputs indicating the color the laser is touching as Red Green and Blue. This gate was mentioned on the forums. I have my reservations when it comes to the usefulness of this sensor though the future may make this more useful.

:arrow_right: The bus :star2:

Essentially the bus is a thick wire that contains for instance 8 signals in one. This is not something many people will need but in more complex logic contraptions having a bus can help a lot in keeping the circuitry clean.

The standard bus tile could be a 3 by 3 stud sized tile where the center is the "bus wire" connection and around it are 8 inputs or outputs depending on if you used a bus input or output tile. The input and output nodes need to be identifiable as it is important to know to which wire in the bus you connect to.

Some subsystems could have in inherent bus connection with potentially some additional functionality:

It might be cool to always render the bus connections similar to how the hose is rendered but with a few tweaks and possibly with a brick like wall mount so you can shape where the bus wire goes through your build.

With a bus like described above it may be useful to have a multiplexer and demultiplexer:

I'm not sure how useful a (de)multiplexer is for the average user but us nerdy folk can use this quite nicely.

:arrow_right: Miniaturisation :star2:

Miniaturization is one of those things that pops up every so often and is mostly accepted as useful. I'd love to see some form of Integrated Circuit block with support for the bus. An IC can also reduce rendering strain in comparison to just having the full circuit on your build. Below a in game mock-up of how the outside of the IC could look like:

In the image we have 4 inputs and 4 outputs and a bus input and output. The center of the IC could have a name (customization text that renders on the chip) so people can easily see which IC they are looking at before opening it.

While thinking about what size internal grid the IC should have I thought about other systems like the Galaxy map and how its size could be an indicator of how big the expanded (or opened up) IC could look. Based on that I thought a 12 by 12 grid (excluding inputs and outputs) is large enough to be useful yet small enough to keep things somewhat sane when you render it full size (while editing). I've also accounted for the ability to link one output to multiple inputs directly (thus eliminating the need for link bricks). Below a mock-up of the internal view of the IC:

In the mock-up I added a button to access the configuration screen where one can enter the IC's name but also copy and paste IC designs. When it comes to copy and pasting the designs I'm thinking of it being serialized into a base64 encoded string and actually copied into the windows copy and paste buffer. This way people can share their IC designs without having to make blueprints and it would also make it easy to have multiple IC's with the same circuit.

:arrow_right: Visual improvements

As cool as the current logic tiles are I and others feel like the logic tiles can be improved a lot by making the inputs and output nodes show their current level. The brighter the node is the higher the value. I also think the shape of the input nodes should look different from the output nodes, this will help colorblind people as well as the others to identify what is what, Perhaps the input nodes could be turned into octagons while the output nodes are turned into triangles. Maybe even something completely different like a male and female connector model.

A thing that was mentioned is adding a simple brick like tile that would be able to show the logic values. This is less useful if every tile shows its state but is an alternative if making all tiles show their state is not feasible.

:arrow_right: Additional notes

Closing thoughts

I'm a very nerdy person so tend to like these technical things even though I've tried to keep things as user friendly as I can, I am well aware that not everyone will understand the proposed systems.

I welcome any comments, suggestions and questions related to the proposed system and I encourage people to participate in an open discussion to improve the logic system here!

talrey commented 6 years ago

First, I'd just like to say that I feel this should have been on the forums instead of here, but oh well.

--- Math ---

--- Programmable ---

--- Sensors ---

--- Bus ---

No thanks. Wire is massless and free. Build a mux if you really don't want to spend time flying around wiring things, we can already build it in-game.

--- Miniturisation ---

No! I refuse to support this. Skywanderers' biggest strength right now is the amazing potential of the building system, and large circuits encourage both finding ways to build more compact logic arrangements and more compact ways of storing those logic arrays. I like being able to share circuits, but not so much that I would implement something that allows people to completely ignore the building system like this.

--- Visual ---

Blinky lights are cool, I support that. We already have a Light Indicator brick though, maybe having that actually emit light would be a better (more frame-friendly) approach to this? That way, you can wire up status lights if you want them, but you don't have to have them.

--- Additional ---

Copy/paste in general is already a requested feature, I don't see any reason why it wouldn't work for logic bricks when it arrives.

--- Closing ---

Damn, I wrote an essay too. I had to though, to tackle such a huge list of suggestions. I'm glad this is all being discussed, even if I don't agree with a lot of it.

Harlekin13 commented 6 years ago

Tri-State Buffer: I totally support it, as i can't find a way to disable circuits. We could get an additional powergrid though, what i mean is something, which transmitts energy through the ship to the more energy-needing-components (like weapons, engines, shields if implented) which transmitts a state instead of a pulse being on (signaling a value of 1, energy flows, component drains energy from the amount the ship produces) or off (no signal, no energy drain). with that and a AND-gate we'd have a tri-state-buffer, right? And it would be possible to de-/activate components.

Miniaturisation: Not necessessary, as long as blocks and bricks being able to clip through each other, but if Tsuna gets rid of that feature (which would be totally okay for me, but not for the most projects i've seen so far) we'll need it. But it would be awesome to get ICs, especially if we'd be able to save the setup and copy/paste it else where.

Visuals I'd prefer it the other way, octagons (which are more like a O) for output, triangles for input, squares for values. If we'd get a powergrid a small indicator on/off (O for on, X for off, perhaps?) on the powergrid-component and a brick similar to the light indicator to connect to it for seeing the status on the bridge.

talrey commented 6 years ago

Something I didn't notice in the Visuals category: you're suggesting different shapes to help the colorblind? I don't really see how the existing system doesn't do that. It's got [ I ] for input, [ O ] for output, [ D ] for delay, and [ A ], [ B ]. and [ V ] for constant values. That makes more sense to me than arbitrary shapes, so why fix what isn't broken?

Harlekin13 commented 6 years ago

Most of these letters are quite badly readable, and if colorblind even more so. Another way would be, just make the letters black, while keeping the glowy color behind it, should do the same job, while being way less work.

tsunamayo commented 6 years ago

Hi, thanks a lot for the clean and constructive formatting @CyaNox , and the discussion!

Additional gates So yes I agree a few things were already in the pipe like the Kill gate, or being able to push a constant into the constant block. As for the XOR and so on I also think it could be useful to some people. For the > and such I think it might be better to leave that to the Computer block.

Sensor: State sensor is very smart indeed, I have to do it. Sun I can do it also, and for proximity @talrey is right I need to take care about the performance as a raycast are taxing. Most likely I wont perform the check every frame, and will only do a the block raycast when target is close - so long range distance would be less precise.

Programmable gates So yes I agree we could offer something better and much more powerfull, and I am leaning towards the LUA solution for these reasons:

As @talrey said this is not a high priority for now and it is one of those things that might come post early access depending on how things go - but I definitely want to do that one day

Some more comments: As for miniaturization when I do the link tool update dual and quad gate would be factored out, as for call-back gate. From my experience dual and quad take up the most space. When I do the variables update I should be able to output the state of the gate for free on screen. Copy/paste will never come for bricks, as it would be shooting myself in the head. Bricks are waaay more expensive compared to blocks.

Thanks for the constructive input!

tsunamayo commented 4 years ago

Most of this is deprecated, some of the suggestions might come but are low priority. Thanks