// Logic system refactor

Here I ask your opinion and feedback on specific aspect of the game, or feature I am working on.
User avatar
tsunamayo
Game developer
Posts: 201
Been thanked: 27 times

Mon May 28, 2018 11:19 pm

Thanks for answering!
Noxy wrote:
Mon May 28, 2018 6:45 pm
What we are lacking is sensors that output in a fuzzy manner.
Some potential examples:
- distance sensor (useful for audio/visual docking/landing aids)
- radar sensor (for measuring the closest ship/enemy)
- solar sensor (detecting distance to (selected) objects in the system)
- Luminance sensor (automaticly dim/brighten internal lights based on incoming light)
- color detector
- system status readout (shield, hull, heat)

I will make a LUA scripting system for these use. Current system is not made to handle continous signal like these, it is pulse based.

Noxy wrote:
Mon May 28, 2018 6:45 pm
The second reason provided was that the current system is pulse based. To me this is fine as pretty much any logic system that I've worked with in games is either pulse based or very close to that.
Minecrafts system can be considered pulse based internally since every logic change is done via a "block update".
The problem is that some of the current interactions make it very clear that it is a pulse based system. Fixing these might be easier than to change the whole thing to an actual state simulation.
Also this problem persists even in a binary system so this actually isn't a good reason.
I agree, new system will still be pulse base on status change, but with the ON/OFF lingo and the tight coupling it seems like a continuous current to the player (and is strictly equivalent to - so no cheat)
Noxy wrote:
Mon May 28, 2018 6:45 pm
To me the proposed controller block is just a bridge between a binary and fuzzy logic system which makes it two systems to maintain :P
Actually to me it feels like the opposite, using fuzzy logic inside the gate code make it harder to do. I was redoing the code for the multi gate fuzzy XOR, it dont make any sense, I dont see how somebody is gonna genuinely use the gate like that in its own system.
I iterate doing this:
result = Mathf.Max(Mathf.Min(result, 1 - predecessors.Command.State), Mathf.Min(1 - result, predecessors.Command.State));

Some system use binary, some other needs a controller to be controlled, it make more sense to me. What would a newcomer use to control a rotor: a mix/constant gate, or a controller?

If you have some example of fuzzy logic actually being used, I am looking forward to see them. By fuzzy logic I mean doing operation AND/OR (so actually min and max) on a fuzzy signal. That would be the only cases the new system would not be able to replicate in my understanding.

User avatar
Zarra
Newbie
Posts: 13
Has thanked: 1 time
Been thanked: 4 times

Tue May 29, 2018 12:47 am

I see one huge potential problem with changing the current 'fuzzy' logic to something as strict as binary logic; currently the Fussy 0.0 to 1.0 pulses allow us to set positions on rotors and sliders, multiples even with the constant gate. if you do away with that, how would we set those rotor/slider positions with a signal?

Personally I feel that setting those positions is better doing it through a logic system as what we have now allows for a near infinite number of positions that can be switched between given enough logic circuits. doing away with the current, you'd have to have someone if retaining the current functionality, as quite a few designs rely on being able to custom set the exact position of the rotors and sliders by way of constant gates on the fly.


I'd suggest to keep the current logic signals as is but for blocks that only require binary logic, they could just consider anything above 0.0 to be a binary 1;

User avatar
Talrey
Entrepreneur
Posts: 91
Location: Garden of the Sun
Has thanked: 8 times
Been thanked: 55 times

Tue May 29, 2018 7:58 am

I was busy all day IRL so I've had some time to stew on the answers - and questions - you've given us in this thread, Tsuna. It's exciting!

Re: Current-Based System
tsunamayo wrote:
Mon May 28, 2018 10:44 pm
It will still be pulse based in code, but you broadcast state change basically. It is more a cosmetic wrapup for the player + an change in the button behaviour more than anything really. Button would toggle the switch.
Ah, I see. This makes sense, thank you! I've made a couple of circuits that rely on detecting a pulse to work, I was worried I'd have to find a different way to make them update :D

Re: Callback gate
tsunamayo wrote:
Mon May 28, 2018 10:44 pm
To me it seems more related to the pulse/state debate: in the new system it does not make sense to "ping" a gate to read its system, because of tight coupling your ouput is always read an in sync with the rest of the circuit.
Tight coupling or not, as long as the Callback only sends value updates when the linked entity finishes moving then it will be useless for continuous Rotors. I was suggesting a method by which we could make it useful for those Rotors, as well as (maybe!) other ship systems like Shields or Reactors. Being able to see my shield and heat levels on a display is cool, but I want my ship to react to those numbers. I want orange lights to shine when the heat rises, I want to build decorative heat vents that open and close. I want my ship to feel alive, not because it was programmed to but because I built it to.

Re: Fuzzy Logic
tsunamayo wrote:
Mon May 28, 2018 11:19 pm
If you have some example of fuzzy logic actually being used, I am looking forward to see them. By fuzzy logic I mean doing operation AND/OR (so actually min and max) on a fuzzy signal. That would be the only cases the new system would not be able to replicate in my understanding.
I'm giving this a shot, I've dubbed it "Tsuna's Challenge" :D

It is quite difficult to really make use of fuzzy logic signals without at least an Equals gate. I mean, I've built one shown here (with hinges and screens to see the outputs, because we lost the signal value preview on mouse-over when you changed to the new build tool :? )...

That's a large circuit to use for such a critical function, especially when it can only compare to a constant value that requires calculating four Mix gate values whenever I want to change it!

I'm still going to attempt to make good use of the Min / Max behavior of AND / OR, but it's already almost 1 AM here and my first shot at it feels like an artificial example. My standards are too high?? I'm going to try dreaming up something better. :lol:

Edit: I forgot to mention that my "equals" circuit actually performs "epsilon comparison" instead; it's a form of "about equals" that permits a small amount of difference between what it considers "identical" numbers. It's critical when dealing with small floating-point numbers!
Last edited by Talrey on Tue May 29, 2018 6:42 pm, edited 1 time in total.

VIPMTHE2ND
Newbie
Posts: 41
Has thanked: 6 times
Been thanked: 13 times

Tue May 29, 2018 6:14 pm

tsunamayo wrote:
Mon May 28, 2018 10:23 pm
For the input based on sensors and more, I feel it is not the best way to solve this - a scripting language like LUA would be. You tap into each variables of the ship and do some complex behaviour based on that.
LUA would be nice, but I don't think it'd be the end-all to be-all solution for reacting to sensor input.

I mean, I program as a hobby, so I'd be fine with using it? And it's technically an end-all to be-all solution to all computational problems, since LUA is Turing complete? But not everyone programs, and it might not be immediately obvious as a solution to a problem that reacts to sensor inputs. (Plus there's a gameplay flow problem with having to bring up a screen just to view the LUA script.)

Like, say you wanted to throttle a reactor based on your heat level. You want something like:

Set reactor throttle to a value proportional to percentage of heat capacity remaining

OR

Set reactor throttle to a value inversely proportional to percentage of ratio of heat to total heat capacity

In a binary system with LUA scripting, you'd do something like this:

Code: Select all

Reactor:throttle <- LUA block <- Ship:Heat
Where the LUA block has a script like (PSEUDO CODE DO NOT USE)

Code: Select all

function TickUpdate (){
	Reactor.throttle = 100((Ship.heat_cap-Ship.heat)/Ship.heat_cap)
}
Which is...comparatively simple, I guess? But not particularly obvious at first glance. Especially as all of the logic is hidden inside the LUA block and can't be seen from the outside.

...Whereas in a fuzzy logic system you'd do something like this:

Code: Select all

Reactor:Throttle input <- NOT gate <- Sensor:Heat
And...that's it. (Assuming you don't add a MIX gate somewhere after the NOT gate, but that's a very simple addition.) This is a very simple control problem, and the fuzzy logic system presents a very simple solution.

Now, suppose you want to modify the above systems to accept throttle commands from a slider, so long as it stays within the 'safe' range. We want something like:

Set total available reactor throttle to a value inversely proportional to percentage of ratio of heat to total heat capacity, and actual reactor throttle to a value either proportional to the output of the throttle slider or equal to the total available reactor throttle, whichever is smaller.

For the LUA system:

Code: Select all

                    
                       Slider
                          |
                         \/
Reactor:throttle <- LUA block <- Ship:Heat

Code: Select all

function TickUpdate (){
	total = 100((Ship.heat_cap-Ship.heat)/Ship.heat_cap)
	if ( (Slider*100) < total ) {
		Reactor.throttle = (Slider*100)
	}
	else Reactor.throttle = total
}
For the fuzzy logic system:

Code: Select all

                          Slider
                             |
                            \/
Reactor:Throttle input <- AND gate <- NOT gate <- Sensor:Heat
Again, that's it. The LUA block works, for sure--and it's probably more compact for complex systems like missile guidance algorithms--but for simple control problems like these the fuzzy logic system is, conceptually, a lot simpler.

There are other benefits as well. There are no hidden components, every piece of the logic is 'physically' present as a logic component. Debugging these circuits consists of inputting test values and watching each component react in real time--no diving into a LUA block, making changes, compiling, and then trying again with no idea if what you just did actually solved the problem. There are no extra threads executing LUA scripts in the background to complicate networking. And so on.

And what would a binary logic solution look like? Something like this for the first problem:

Code: Select all

                                       
Reactor:Throttle input <- NOT gate <- Controller <- Sensor:Heat
The Controller would output a 1 signal if the heat readout exceeds some value, and 0 otherwise.

Simple? Perhaps, but it loses the granularity of either the LUA solution or the fuzzy logic solution--it's an ON/OFF switch, as it were--AND is more complicated, in terms of logic components placed, than either. ( I'll leave a binary logic solution for the second problem as an exercise for the reader).

In short, for simple control problems, the current fuzzy logic system beats out LUA scripting in terms of simplicity, intuitiveness, and accessibility. It can handle the same kinds of problems a binary logic system can handle as well, courtesy of kill switches and constant gates--whereas the binary logic system would be hard-pressed to do more than simple ON/OFF operations like opening a door or operating an elevator. Switching to a binary logic system would be a step down from the fuzzy logic system in terms of what can be done with it, the Controller system is only a band-aid solution to that, and the LUA system, while an adequate replacement for both fuzzy and binary logic systems in terms of what can be done with it, is difficult to use for the average player and boring besides.

I submit to you that the fuzzy logic system is thus irreplaceable, and that if it feels like there is not enough being done with it that is because there are at present too few systems that actually use it. The solution should not be to toss out the fuzzy logic system, but rather to expand it by introducing additional sensors with fuzzy logic outputs and systems that take and react properly to a fuzzy logic input.

EDIT 0: Punctuation.
EDIT 1: More punctuation.

User avatar
Talrey
Entrepreneur
Posts: 91
Location: Garden of the Sun
Has thanked: 8 times
Been thanked: 55 times

Tue May 29, 2018 7:38 pm

Finally, I've come up with a simple design for a system that uses the Min / Max ability of fuzzy logic AND / OR gates as a demonstration. I present to you, a concept for a ship hangar with two exit doors. Two slides form a "docking crane" to attach to a ship to assist with docking, and the crane's range of motion is limited by the state of the vertical doors - no matter what value the player puts into the crane control sliders, the crane will never try to leave the docking bay when the doors are closed.

Image

Image

Image

A Callback on each bay door feeds into a Mix gate, which each store one bound on the crane's position. When the player puts a position into the system input, here a slider control with a blue link line, the following happens:
  1. The value from the input is compared to the left door's bounds using an OR / Maximum gate
  2. The result from the Maximum calculation is compared to the right door's bound using an AND / Minimum gate
  3. The final result is sent to the crane's slide, linked in red.
When the doors are open, the Mix gates at the top output 1 on the left door and 0 on the right door. When the doors are shut, the Mix gates contain decimal values that brings the crane close to the door without clipping into it.

This is a simple implementation to focus on the role of the Minimum and Maximum functions. The design could be modified to include automatic centering of the crane when the doors are signaled to close, as well as a second axis (or more) on the crane itself.

User avatar
tsunamayo
Game developer
Posts: 201
Been thanked: 27 times

Tue May 29, 2018 9:59 pm

Talrey wrote:
Tue May 29, 2018 7:38 pm
Finally, I've come up with a simple design for a system that uses the Min / Max ability of fuzzy logic AND / OR gates as a demonstration. I present to you, a concept for a ship hangar with two exit doors. Two slides form a "docking crane" to attach to a ship to assist with docking, and the crane's range of motion is limited by the state of the vertical doors - no matter what value the player puts into the crane control sliders, the crane will never try to leave the docking bay when the doors are closed.
Amazing, thanks for the demo!

User avatar
tsunamayo
Game developer
Posts: 201
Been thanked: 27 times

Tue May 29, 2018 11:12 pm

VIPMTHE2ND wrote:
Tue May 29, 2018 6:14 pm
tsunamayo wrote:
Mon May 28, 2018 10:23 pm
For the input based on sensors and more, I feel it is not the best way to solve this - a scripting language like LUA would be. You tap into each variables of the ship and do some complex behaviour based on that.
LUA would be nice, but I don't think it'd be the end-all to be-all solution for reacting to sensor input.

I mean, I program as a hobby, so I'd be fine with using it? And it's technically an end-all to be-all solution to all computational problems, since LUA is Turing complete? But not everyone programs, and it might not be immediately obvious as a solution to a problem that reacts to sensor inputs. (Plus there's a gameplay flow problem with having to bring up a screen just to view the LUA script.)

Like, say you wanted to throttle a reactor based on your heat level. You want something like:

Set reactor throttle to a value proportional to percentage of heat capacity remaining

OR

Set reactor throttle to a value inversely proportional to percentage of ratio of heat to total heat capacity
Okay, the only problem is that the logic system was not made to do that. It was made to broadcast player inputed value to rotor and slider and is pulse based. Here what you want (and everybody else actually) is sensor that output continuous float signal and manipulate it, the system just cant do that.
That is one more reason to get rid of it actually, as people expect to see that naturally, and they will think "why the dev arent adding that, devs must be stupids" :twisted: .
A LUA could be optimized to do that, but I could also add a quantitized sensor to the binary circuit: it would only check its value once in a while, and only trigger circuit execution when a condition is met (user definable).

Also as a side note (not really important) but the code equivalent to:
Slider
|
\/
Reactor:Throttle input <- AND gate <- NOT gate <- Sensor:Heat

Should be just Throttle = Min(slider, 1 - sensor). When you will want to make some more evolved stuff (True IF, keeping variables), I can tell you that LUA should be much easier that gate!

Anyway in its current state I dont think that getting rid of true fuzzy will impact anybody. For the elevator stops at each stage case, I think I will do specific controller equivalent to a stack of constant gate. It would create an input on each new constant added, and the input would only show when the link tool is equiped. That will make the specific behaviour of constant override looks more legit as contained to this controller (but is the same really), so I could add a rule of only one controller is linked to a rotor.

User avatar
Talrey
Entrepreneur
Posts: 91
Location: Garden of the Sun
Has thanked: 8 times
Been thanked: 55 times

Wed May 30, 2018 12:37 am

tsunamayo wrote:
Tue May 29, 2018 11:12 pm
A LUA could be optimized to do that, but I could also add a quantitized sensor to the binary circuit: it would only check its value once in a while, and only trigger circuit execution when a condition is met (user definable).
Wouldn't this be easier to do with a fuzzy logic system, since it could simply output the value of the linked system whenever that user condition is met rather than emitting a binary signal? That would allow for simple systems for gradual reaction, rather than totally on or totally off.

In fact, this could be a rebuild of the Callback gate, with "system stopped moving" as one of those user-selectable conditions.

User avatar
schlid
Entrepreneur
Posts: 36
Location: Great Britain
Has thanked: 30 times
Been thanked: 51 times

Wed May 30, 2018 1:10 am

Talrey wrote:
Wed May 30, 2018 12:37 am
tsunamayo wrote:
Tue May 29, 2018 11:12 pm
A LUA could be optimized to do that, but I could also add a quantitized sensor to the binary circuit: it would only check its value once in a while, and only trigger circuit execution when a condition is met (user definable).
Wouldn't this be easier to do with a fuzzy logic system, since it could simply output the value of the linked system whenever that user condition is met rather than emitting a binary signal? That would allow for simple systems for gradual reaction, rather than totally on or totally off.

In fact, this could be a rebuild of the Callback gate, with "system stopped moving" as one of those user-selectable conditions.
THIS.

As someone who loves to make overcomplicated trash with logic, I think this should really be the approach. Why should LUA coding be introduced into the system? I don't know how to code, nor does a large portion of the community. To achieve reactive movements like this, I shouldn't have to do something as daunting as learning a programming language (I'm aware that LUA is a basic entry level language, however I believe adding programming like this to a point where it is somewhat necessary in circuits seems to steepen the learning curve a lot.)

I've already mentioned & explained it earlier in the thread, but current based fuzzy logic alongside some more blocks to make full use of the fuzzy system is all I believe we need.

The current based behaviour would be more familiar with those who've used logic in other games. They expect this and not pulse based signals.

Extra blocks/interactions like being able to data input into constants & mix gates, and addition subtraction gates would give far more incentive to utilise the range of values in fuzzy logic within the circuit unlike at the moment. You've seen Talrey's addition "gate", and it is absolutely massive; if this was condensed into a more regularly useable format - a new logic block, then this utility of non-binary values within circuits would increase tenfold.

(To make a final point I'm not against programming being in the game, it however should have its own place, for example sensing momentum, acceleration, and so on to add reactivity to the ships and stations you build, as opposed to being so necessary as to receive feedback from a rails position.)
fantastique

VIPMTHE2ND
Newbie
Posts: 41
Has thanked: 6 times
Been thanked: 13 times

Wed May 30, 2018 2:15 am

tsunamayo wrote:
Tue May 29, 2018 11:12 pm

Okay, the only problem is that the logic system was not made to do that. It was made to broadcast player inputed value to rotor and slider and is pulse based. Here what you want (and everybody else actually) is sensor that output continuous float signal and manipulate it, the system just cant do that.
That is one more reason to get rid of it actually, as people expect to see that naturally, and they will think "why the dev arent adding that, devs must be stupids" :twisted: .
A LUA could be optimized to do that, but I could also add a quantitized sensor to the binary circuit: it would only check its value once in a while, and only trigger circuit execution when a condition is met (user definable).

Also as a side note (not really important) but the code equivalent to:
Slider
|
\/
Reactor:Throttle input <- AND gate <- NOT gate <- Sensor:Heat

Should be just Throttle = Min(slider, 1 - sensor). When you will want to make some more evolved stuff (True IF, keeping variables), I can tell you that LUA should be much easier that gate!

Anyway in its current state I dont think that getting rid of true fuzzy will impact anybody. For the elevator stops at each stage case, I think I will do specific controller equivalent to a stack of constant gate. It would create an input on each new constant added, and the input would only show when the link tool is equiped. That will make the specific behaviour of constant override looks more legit as contained to this controller (but is the same really), so I could add a rule of only one controller is linked to a rotor.
Tsun, just so you know I'm about to get very insulting, and I don't mean to denigrate your skill in programming in any way.

Problem number 1. The binary system as proposed is utterly inadequate for the task.
The fact that you need to add controller variants and sensor conditions and such just to cover each edge case we come up with is a sign that the binary system does not have the flexibility to match the fuzzy logic system currently implemented, much less the final form such a system could take. Each component in the binary system is more specialized

Is it more 'intuitive'? Maybe to other people. Not to me. By my rule of thumb, if I need to place more components or to interact with more GUIs to set up a system, then that system is less intuitive, not more.

Can it handle everything it needs to? Maybe. I'm thinking, however, that you'd end up needing to add more and more components to address more and more edge cases. You would definitely need more components than a fuzzy logic system would have required.

Problem number 2:The LUA system as proposed is a bandaid solution for the binary system.
I'm not gonna lie. An option to LUA script ingame will be a powerful tool, and I will be using it.

The problem is that such a system is inevitably going to be a little clunky. I'm willing to live with that--for complex tasks.

I don't want to be so frustrated juggling controllers for an elevator that I just default to using the LUA block. I don't want to have to dive into a scripting window to debug that elevator.

You are treating the LUA block as an end-all to be all-solution for what I consider to be very simple control problems. You are using it as a cover for the fact that the binary system couldn't find it's own ass with both hands and a map--that may not necessarily be true, but the fact that was the first comparison to come to mind for me is, by my reckoning, not a good sign.

This all leads to problem number 3.You're treating the current state of the game as the environment the logic system will always be operating in. This will not be the case.

Remember: This is a game you have said is in a closed alpha. Not all the systems are in yet. Not all the systems are even properly conceptualized yet.

You know what I'm willing to bet though? All of these systems will interact with the logic system, in deep and meaningful ways.

You don't just need a logic system that's quick and 'intuitive'. You need a logic system that is capable of handling ALL OF THESE systems, because if you don't add hooks in these systems other people will. And they will not work nearly as well as if you'd planned for this from the beginning.

In short, you are fixating on what you think is quick and intuitive to understand, and in the process you are making a logic system that is less quick and less intuitive to use, and less powerful besides. I believe that the reports of the playtesters will bear this out once such a system is implemented (because it'd be good practices to try it out once at least--that's what alphas are for), and I believe you will lose a small but very important section of your player base if you decide to keep it as a permanent feature instead of the fuzzy logic system.


...On a positive note: Have you considered Combinators ? https://wiki.factorio.com/Circuit_network#Combinators

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests