add a random / unique number combinator

Post your ideas and suggestions how to improve the game.

Moderator: ickputzdirwech

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

add a random / unique number combinator

Post by mrvn »

TL;DR
Sometimes a bit of randomness is wanted. Sometimes a unique signal is required.
What ?
I suggest a new combinator, or extension to the constant combinator, to output a random or unique number on a chosen signal.
Why ?
Some algorithms that one can implement using circuits require a random or unique number to function. In my case I want to implement a message protocol with many stations communicating over a common wire. Each station needs an unique ID to use as source or destination address. If multiple stations want to send at the same time they also need a wait to wait a random number of ticks so that when they retry to send they don't try at the same time again.

Roxor128
Fast Inserter
Fast Inserter
Posts: 163
Joined: Sun Oct 02, 2016 9:48 am
Contact:

Re: add a random / unique number combinator

Post by Roxor128 »

You could make your own pseudo-random number generator out of the existing combinators. There's enough operations to implement a few algorithms already.

Hell, I've used a rather hacky approach of a few iterations of x = x*x % c as a way to make some pseudo-random numbers in a shader in the past. The snow it made was good enough for what I was doing, though it did have its problems.

Koub
Global Moderator
Global Moderator
Posts: 7199
Joined: Fri May 30, 2014 8:54 am
Contact:

Re: add a random / unique number combinator

Post by Koub »

Don't forget that whatever yo do, the game must remain deterministic or the multiplayer will desync. So whatever randomness you generate, it must be always the same given initial contitions (so only a pseudo-random).
Koub - Please consider English is not my native language.

User avatar
HL65536
Inserter
Inserter
Posts: 29
Joined: Sat Aug 20, 2016 8:21 pm
Contact:

Re: add a random / unique number combinator

Post by HL65536 »

for the original idea to put random combinators in, it is very easy to have something pseuderandom without desync, map generation is pseudorandom after all. But im not sure if it is necessary as it is technically already in the game (you can build whatever algorithm the game uses for pseudorandom numbers ingame with combinators, make a blueprint one time and be happy afterwards (or ask people that know how to do it))


Now to the communication problem that i think can be solved better:

I saw this and immediately thought of the CAN bus which uses arbitration to avoid collisions. (in electronics, a bus is one or more shared wires between transceivers)
Then i thought how do something similar in factorio:
As factorio signals add up when different sources put a signal on the bus, you cant use full bandwidth while arbitration is in progress, but you can after the process finishes and decided who won.
I came up with 2 ideas:

for both ideas:
every stations needs a unique ID that noone else uses to send
You can prioritize who can send if multiple stations want to send, higher ID values have higher priority
every station starts sending at the exact same instant (a one tick long pulse on the bus every couple of ticks should be enough to let everyone know when to start sending.)
the "decide if continue talking" calculations in both ideas need time, so a few ticks need to be waited after each step (idea 1 has only 1 such step)

Idea 1: you dont have many communication stations (<=30):
ID1 uses 1 as its identifier
ID2 uses 2
ID3 uses 4
ID4 uses 8
........
basically the << operator (1<<ID)
as one station starts talking, the first it does is it puts the identifier on the bus.
now it reads the bus and checks if the number on the bus is more than double of its identifier.
If it is, stop talking
if it is not, continue with rest of message
the receiver extracts the sender ID by reading the highest bit.(<2 means ID1, <4 means ID2, <8 means ID3, ...)



Idea 2: many stations needed, arbitration takes more bandwidth
take the ID apart into its bits (%operator and then test if>0)
bit 1 is (ID%1)>0
bit 2 is (ID%2)>0
bit 3 is (ID%3)>0
.....
your ID can have 32 bits to fit into one number in factorio (4294967295 different IDs should be enough xD)

{now send bit 32 on the bus while reading the number currently on the bus.
if the number is not 0 but the senders bit is 0, the sender stops talking immediately and waits for the other station to finish talking
otherwise, continue}
repeat everything inside {} for bits 31, then 30, then 29, ... until bit 1
if the sender passed all checks, it sends the rest of the message.

you can use less bits, e.g. 16, replace all 32s with 16s and it should work (max ID then is 65535, arbitration only needs half the time)

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: add a random / unique number combinator

Post by mrvn »

Roxor128 wrote:You could make your own pseudo-random number generator out of the existing combinators. There's enough operations to implement a few algorithms already.

Hell, I've used a rather hacky approach of a few iterations of x = x*x % c as a way to make some pseudo-random numbers in a shader in the past. The snow it made was good enough for what I was doing, though it did have its problems.
You can make one pseudo-random number generator. But a blueprint of it will always output the same sequence of numbers. And when you blueprint two and they end up starting at the same tick they will always output the same number every tick. That doesn't work for communications.

To make each pseudo-random number generator different you need a unique seed, which gets back to the "unique number combinator". So the second part of the suggestion allows building the first yourself.

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: add a random / unique number combinator

Post by mrvn »

HL65536 wrote: every stations needs a unique ID that noone else uses to send
You can prioritize who can send if multiple stations want to send, higher ID values have higher priority
every station starts sending at the exact same instant (a one tick long pulse on the bus every couple of ticks should be enough to let everyone know when to start sending.)
the "decide if continue talking" calculations in both ideas need time, so a few ticks need to be waited after each step (idea 1 has only 1 such step)
That is basically what I'm trying to do. Hence the need for "unique number combinator". Otherwise you can not blueprint this and have to wait for the construction bots and manually set the unique ID.

Also priorities are not such a good idea. A low priority station can be blocked forever. Usualy you detect a collision and then have each station wait a random time and try again. That way each station has an equal chance to be the only sender next time. This requires random numbers that are different for each station, hence the suggestion to add a rnadom number combinator. You can build one if you have a unique number too.

justarandomgeek
Filter Inserter
Filter Inserter
Posts: 300
Joined: Fri Mar 18, 2016 4:34 pm
Contact:

Re: add a random / unique number combinator

Post by justarandomgeek »

I too wanted unique IDs at one point, and found that locations are a pretty good ID value, if you don't mind mods. Each one is unique, as long as you don't mind combining two (or three, if you use surfaces) values to form your Unique ID. If you use a relatively small slice of the worlds and only the overworld, you could do something like (X<<16 | Y&65535) to get unique individual values.

Also a good option would be a variant of this mod that includes the combinators unit_number (hmm, maybe i should drop that on U or I or something...)

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: add a random / unique number combinator

Post by darkfrei »

As suggestion, we can use x and y signals with position of this combinator to get unique ID. Another way is to iterate ID on every placing of constant combinator.

It can be done with some mod, but not in vanilla.

justarandomgeek
Filter Inserter
Filter Inserter
Posts: 300
Joined: Fri Mar 18, 2016 4:34 pm
Contact:

Re: add a random / unique number combinator

Post by justarandomgeek »

darkfrei wrote:As suggestion, we can use x and y signals with position of this combinator to get unique ID. Another way is to iterate ID on every placing of constant combinator.

It can be done with some mod, but not in vanilla.
In fact, it's precisely what my mod linked the the post before yours *does* ;)

Kazuar
Long Handed Inserter
Long Handed Inserter
Posts: 81
Joined: Mon May 19, 2014 1:21 pm
Contact:

Re: add a random / unique number combinator

Post by Kazuar »

mrvn wrote:Hence the need for "unique number combinator".
A random (or pseudo-random) number doesn't guarantee a unique number. For once, because (as you have noticed yourself) using the same blueprint/seed leads to the same sequence of numbers, making them non-unique, but also, because even a true random number can just so happen to be one already generated.

Makes sense if you think about it - rolling a dice is random, but you can still roll the same number twice in a row.

I'd suggest to you to use a consecutive, serial number instead of a random one. Find the biggest unique number in the system, add 1, you now have a unique number. Or, if you start your consecutive number at one - store the UID in a memory cell, with the "set" condition of the cell triggered by the cell being empty, and another decider set to (cell=empty, then output one "I am empty" to the larger network). In a central location, an arithmetic combinator is set to ("next UID" + "i am empty", output as "next UID"), with that combinators output tied to its own input and also broadcasted to the network. Since the memory cell on your UID-requesting setup is empty, it is saving signals "sent" to it, and we'd want to send from another arithmetic combinator ("next UID" + zero as "UID") - this also means that, when the combinator/memory cell setup isn't yet connected to the larger network, "next UID" is zero, zero + zero equals zero, which means the memory remains empty (since signals that equal zero are not transmitted), until it is connected to the network, and the moment it is connected, it stores your global "next UID" signal as "UID, and "next UID" increments by one (since it is sending the "i am empty" to the network for the one instant in which it is becoming set).

No new combinator type, or mod, needed to solve this problem :)
[Note: I'm actually sorry if my posts come off as rude; english is not my native language, and I'm not aware of all it's nuances. Please do point out my misadoptions in tone!]

mrvn
Smart Inserter
Smart Inserter
Posts: 5704
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: add a random / unique number combinator

Post by mrvn »

Kazuar wrote:
mrvn wrote:Hence the need for "unique number combinator".
A random (or pseudo-random) number doesn't guarantee a unique number. For once, because (as you have noticed yourself) using the same blueprint/seed leads to the same sequence of numbers, making them non-unique, but also, because even a true random number can just so happen to be one already generated.

Makes sense if you think about it - rolling a dice is random, but you can still roll the same number twice in a row.

I'd suggest to you to use a consecutive, serial number instead of a random one. Find the biggest unique number in the system, add 1, you now have a unique number. Or, if you start your consecutive number at one - store the UID in a memory cell, with the "set" condition of the cell triggered by the cell being empty, and another decider set to (cell=empty, then output one "I am empty" to the larger network). In a central location, an arithmetic combinator is set to ("next UID" + "i am empty", output as "next UID"), with that combinators output tied to its own input and also broadcasted to the network. Since the memory cell on your UID-requesting setup is empty, it is saving signals "sent" to it, and we'd want to send from another arithmetic combinator ("next UID" + zero as "UID") - this also means that, when the combinator/memory cell setup isn't yet connected to the larger network, "next UID" is zero, zero + zero equals zero, which means the memory remains empty (since signals that equal zero are not transmitted), until it is connected to the network, and the moment it is connected, it stores your global "next UID" signal as "UID, and "next UID" increments by one (since it is sending the "i am empty" to the network for the one instant in which it is becoming set).

No new combinator type, or mod, needed to solve this problem :)
No, the other way around. A unique number gives you a pseudo random number generator with a unique sequence.

And you can't make that unique number yourself. Because whatever algorithm you use will run identical on two instances of a blueprint. No way to make the 2 instances see each other and come to an agreement to use different numbers. Like in your case both instances would get the same next UID and the global counter would increment by 2.

User avatar
ssilk
Global Moderator
Global Moderator
Posts: 12888
Joined: Tue Apr 16, 2013 10:35 pm
Contact:

Re: add a random / unique number combinator

Post by ssilk »

https://mods.factorio.com/mods/coltonj9 ... ombinators
has a random combinator.
Cause that is really simple to mod but I don't see very much use in it I see that as implemented.
Cool suggestion: Eatable MOUSE-pointers.
Have you used the Advanced Search today?
Need help, question? FAQ - Wiki - Forum help
I still like small signatures...

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: add a random / unique number combinator

Post by darkfrei »

ssilk wrote:https://mods.factorio.com/mods/coltonj9 ... ombinators
has a random combinator.
Cause that is really simple to mod but I don't see very much use in it I see that as implemented.
Random is not unique, but n=n+1 is.
https://mods.factorio.com/mods/darkfrei/UniqueSignal

justarandomgeek
Filter Inserter
Filter Inserter
Posts: 300
Joined: Fri Mar 18, 2016 4:34 pm
Contact:

Re: add a random / unique number combinator

Post by justarandomgeek »

darkfrei wrote:
ssilk wrote:https://mods.factorio.com/mods/coltonj9 ... ombinators
has a random combinator.
Cause that is really simple to mod but I don't see very much use in it I see that as implemented.
Random is not unique, but n=n+1 is.
https://mods.factorio.com/mods/darkfrei/UniqueSignal
Location is also unique, unless you explore beyond 2^32 from the origin...
https://mods.factorio.com/mods/justaran ... combinator

Qon
Smart Inserter
Smart Inserter
Posts: 2119
Joined: Thu Mar 17, 2016 6:27 am
Contact:

Re: add a random / unique number combinator

Post by Qon »

Why is this in implemented suggestions? Constant combinators don't have an automatic unique signal and there's no location combinator! There are (outdated) mods linked in the thread, but this is the "Factorio Direction > Ideas and Suggestions > Implemented Suggestions" board so it is for things implemented in vanilla Factorio, not for things that are supplied by mods. So why is this thread here?

A blueprint can contain rails with a locomotive, a schedule to a train stop name and a train stop with a name. And the train stop can read a unique id from a locomotive in automatic mode. But the blueprint can't save the automatic mode of the locomotive so it will always be placed as a manual only thing. So you need to manually set it to auto mode. And then you can just set a manual signal to something unique in a constant combinator anyways.

Did I miss some feature of some combinator that can be used to generate a unique signal?

Bilka
Factorio Staff
Factorio Staff
Posts: 3129
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: add a random / unique number combinator

Post by Bilka »

Qon wrote:
Fri May 03, 2019 5:25 pm
Why is this in implemented suggestions?
No idea, it was moved about 2 years ago. Back it goes.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

justarandomgeek
Filter Inserter
Filter Inserter
Posts: 300
Joined: Fri Mar 18, 2016 4:34 pm
Contact:

Re: add a random / unique number combinator

Post by justarandomgeek »

Qon wrote:
Fri May 03, 2019 5:25 pm
There are (outdated) mods linked in the thread,
Location Combinator has simply been folded into Utility Combinators, as indicated by the giant link from the page linked in the post immediately before yours. (And the last version of it would also still work on the current version of Factorio.)

Qon
Smart Inserter
Smart Inserter
Posts: 2119
Joined: Thu Mar 17, 2016 6:27 am
Contact:

Re: add a random / unique number combinator

Post by Qon »

Bilka wrote:
Fri May 03, 2019 5:26 pm
Qon wrote:
Fri May 03, 2019 5:25 pm
Why is this in implemented suggestions?
No idea, it was moved about 2 years ago. Back it goes.
Thanks!
justarandomgeek wrote:
Fri May 03, 2019 5:30 pm
Qon wrote:
Fri May 03, 2019 5:25 pm
There are (outdated) mods linked in the thread,
Location Combinator has simply been folded into Utility Combinators, as indicated by the giant link from the page linked in the post immediately before yours.
Yeah, I know, and I do have it installed already for the location combinator (thanks jarg). I meant that some of the mods linked are outdated and thus even less qualify this as "implemented". But even if they were all alive it doesn't make sense to move it to "implemented in vanilla" since it's just not. But Bilka fixed the thread position quickly.

Qon
Smart Inserter
Smart Inserter
Posts: 2119
Joined: Thu Mar 17, 2016 6:27 am
Contact:

Re: add a random / unique number combinator

Post by Qon »

I've made a vanilla ID generator. If two ID circuits are built at the same time (one starts before the other completes) then those might get the same ID.
The ID (I) is unique for a certain circuit network only. Two separate circuit networks can have the same ID numbers. As long as you don't merge the networks after the IDs are assigned to any units in the subnetworks this is not a problem for me because I have a global network and I want to differentiate between units on that network. If units were on different networks I could differentiate them by the network connection + ID anyways.

It works by having a counting signal (C) that all units have a constant combinator send 1 on. So the network has C = #units on that wire. Whenever a new unit is built it adds 1 to C and takes C as its ID, which is saved in a memory cell. To only save this count once, when the unit is built, the ID (I) should be written to on the conditions:
  • ID is 0
  • constant C combinator sends 1 to increment the count (by reading it with other the cable colour)
  • Connected to the main network (C > 1)
That way it will take a new id as soon as possible but only if the circuit is complete. So pretty simple as long as you don't build any new units before the previous completes. If you are building with recursive blueprints then you can place the next ID generator automatically after you see C increment and you get a response from a unit with ID number C.

If you get a collision then that can be detected by having a CPU that requests all units with ID x to send 1 H signal (raise your Hand if your name is ID 5 please). If H > 1 then the units know someone else also has their ID.
Resolving this requires randomness.
Sources of randomness
But just don't build 2 ID circuits at the same time and and then you don't need ID conflict resolution.

Qon
Smart Inserter
Smart Inserter
Posts: 2119
Joined: Thu Mar 17, 2016 6:27 am
Contact:

Re: add a random / unique number combinator

Post by Qon »

Here's the blueprint. Just tile it on the big poles to see it work its magic. The leftmost constant combinator is there to "reserve" ID 1 for the first unit. So ID 1 is for a CPU that coordinates communications. Without a C signal of at least 1 on the wire the circuit on the right sees that they are the first on the network which means they can't have a connection to ID 1 yet so they wait.

I used the number display by cid0rz and preppie22 to show IDs. North of the substation is all display logic. South of it is the small ID circuit.

Had to add a timer (every 10 ticks, could probably be even shorter I just picked a random number that looked more than a roundtrip loop through the circuit) that retries setting the ID as long as all the conditions are fulfilled. I had to because the circuit as described in the previous post failed if the ID memory cell got built last because it missed the one time write signal. I think this makes it completely reliable now as long as an ID is assigned before the next unit is started and you never remove the constant combinators that send C = 1 to the network.

I might take a look at ID conflict resolution in case I want to build these in parallel.

And if you can make this fail somehow by manipulating the build order/timing then please tell me!

The ID 1 unit could fairly simply monitor C and increment it whenever it drops (because a C = 1 constant is deconstructed or destroyed) to make sure the C can never decrease.


Post Reply

Return to “Ideas and Suggestions”