Using random_switch for industry

Discussions about the technical aspects of graphics development, including NewGRF tools and utilities.

Moderator: Graphics Moderators

Post Reply
Michpi
Engineer
Engineer
Posts: 62
Joined: 03 Feb 2021 18:51

Using random_switch for industry

Post by Michpi »

Hello!
I used random_switch for industry and needed to re randomise it.
WIKI says that "Industry tiles can rerandomise both their own random bits as well as the random bits of the industry (via type PARENT)." So I did a test. I created 4 independent random_switch for industry, which stores 4 variables and placed them in monthly_prod_change callback
[+] Spoiler

Code: Select all

switch(FEAT_INDUSTRIES, SELF, test44, STORE_PERM(4, 3))
{ }
switch(FEAT_INDUSTRIES, SELF, test43, STORE_PERM(3, 3))
{ }
switch(FEAT_INDUSTRIES, SELF, test42, STORE_PERM(2, 3))
{ }
switch(FEAT_INDUSTRIES, SELF, test41, STORE_PERM(1, 3))
{ }
random_switch(FEAT_INDUSTRIES, SELF, farm_industry_randomize4)
{
 1: test41;
 1: test42;
 1: test43;
 1: test44;
}
switch(FEAT_INDUSTRIES, SELF, test34, STORE_PERM(4, 2))
{ farm_industry_randomize4; }
switch(FEAT_INDUSTRIES, SELF, test33, STORE_PERM(3, 2))
{ farm_industry_randomize4; }
switch(FEAT_INDUSTRIES, SELF, test32, STORE_PERM(2, 2))
{ farm_industry_randomize4; }
switch(FEAT_INDUSTRIES, SELF, test31, STORE_PERM(1, 2))
{ farm_industry_randomize4; }
random_switch(FEAT_INDUSTRIES, SELF, farm_industry_randomize3)
{
 independent: farm_industry_randomize4;
 1: test31;
 1: test32;
 1: test33;
 1: test34;
}

switch(FEAT_INDUSTRIES, SELF, test24, STORE_PERM(4, 1))
{ farm_industry_randomize3; }
switch(FEAT_INDUSTRIES, SELF, test23, STORE_PERM(3, 1))
{ farm_industry_randomize3; }
switch(FEAT_INDUSTRIES, SELF, test22, STORE_PERM(2, 1))
{ farm_industry_randomize3; }
switch(FEAT_INDUSTRIES, SELF, test21, STORE_PERM(1, 1))
{ farm_industry_randomize3; }
random_switch(FEAT_INDUSTRIES, SELF, farm_industry_randomize2)
{
 independent: farm_industry_randomize3;
 independent: farm_industry_randomize4;
 1: test21;
 1: test22;
 1: test23;
 1: test24;
}

switch(FEAT_INDUSTRIES, SELF, test14, STORE_PERM(4, 0))
{ farm_industry_randomize2; }
switch(FEAT_INDUSTRIES, SELF, test13, STORE_PERM(3, 0))
{ farm_industry_randomize2; }
switch(FEAT_INDUSTRIES, SELF, test12, STORE_PERM(2, 0))
{ farm_industry_randomize2; }
switch(FEAT_INDUSTRIES, SELF, test11, STORE_PERM(1, 0))
{ farm_industry_randomize2;}
random_switch(FEAT_INDUSTRIES, SELF, farm_industry_randomize1)
{
 independent: farm_industry_randomize2;
 independent: farm_industry_randomize3;
 independent: farm_industry_randomize4;
 1: test11;
 1: test12;
 1: test13;
 1: test14;
}

monthly_prod_change: farm_industry_randomize1;
And I placed random_switch in random trigger of industry tiles in order to re randomize the first 4.
[+] Spoiler

Code: Select all

switch(FEAT_INDUSTRYTILES, PARENT, farm_industry_randomizex, STORE_PERM(LOAD_PERM(4)+1, 4))
{
}
random_switch(FEAT_INDUSTRYTILES, PARENT, farm_industry_randomize, bitmask(TRIGGER_INDUSTRYTILE_256_TICKS))
{
 2: farm_industry_randomizex;
}

random_trigger: farm_industry_randomize;
I expected my variables to change every month, but the actual result was very surprising to me.
In fact, my variables only changed their values once. And they were never changed again. Moreover, the variables of different farms took the same value.
[+] Spoiler
1.jpg
1.jpg (44.31 KiB) Viewed 4442 times
And what surprised me the most is that each time I did this test (new game), I got the same sequence of variables: 1, 1, 1, 2. How this could be?

After that I decided to determine how often in fact the random_trigger triggers.
If I understood the WIKI correctly, the frequency of the random_trigger call depends on random_switch trigger event.
So I created 3 counters 0->5 and place one of them in produce_256_ticks callback. The other 2 were placed in random_trigger, which called random_switch with TRIGGER_INDUSTRYTILE_256_TICKS
[+] Spoiler

Code: Select all

switch(FEAT_INDUSTRIES, SELF, counter1, [
	STORE_PERM(LOAD_PERM(0)+1, 0),
	STORE_PERM(LOAD_PERM(0)>5 ? 0 : LOAD_PERM(0), 0),])
{
}

produce_256_ticks: counter1;
-------------------------------------------------------------
switch(FEAT_INDUSTRYTILES, PARENT, farm_industry_counter2, [
	STORE_PERM(LOAD_PERM(1)+1, 1),
	STORE_PERM(LOAD_PERM(1)>5 ? 0 : LOAD_PERM(1), 1),])
{
}
random_switch(FEAT_INDUSTRYTILES, SELF, counter2, bitmask(TRIGGER_INDUSTRYTILE_256_TICKS))
{
 2: farm_industry_counter2;
}
     
random_trigger: counter2;
-------------------------------------------------------------
random_switch(FEAT_INDUSTRYTILES, SELF, farm_industry_counter3, bitmask(TRIGGER_INDUSTRYTILE_256_TICKS))
{
 2: return 0;
}
switch(FEAT_INDUSTRYTILES, PARENT, counter3, [
	STORE_PERM(LOAD_PERM(2)+1, 2),
	STORE_PERM(LOAD_PERM(2)>5 ? 0 : LOAD_PERM(2), 2),])
{
	farm_industry_counter3;
}

random_trigger: counter3;
I expected my counters to change at the same time or at the same frequency. But in fact the last 2 counters (placed in random_trigger) changed it's value faster. The farm has only 1 tile of these types, if it does matter.

So the questions are
What I was doing wrong or misunderstanding?
Is there any way to re randomize random_switch for industry?
How often does random_trigger called?
peter1138
OpenTTD Developer
OpenTTD Developer
Posts: 1728
Joined: 30 Mar 2005 09:43

Re: Using random_switch for industry

Post by peter1138 »

I'll hazard a guess that this is because rerandomization happens in an undocumented callback 1, which means random switches inside other callback chains are never seen during rerandomization. The solution would be to repeat your random switches in a manner that they are seen outside the callback chains.
He's like, some kind of OpenTTD developer.
michael blunck
Tycoon
Tycoon
Posts: 5948
Joined: 27 Apr 2005 07:09
Contact:

Re: Using random_switch for industry

Post by michael blunck »

@Michpi

See discussion between Peter and me on missing re-randomisation in callback chains for stations and vehicles.

regards
Michael
Image
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Using random_switch for industry

Post by 3iff »

I had exactly the same problem and I got around it by setting a random value then calling a standard switch and setting the return values on return...something like this...

STORE_TEMP( random_bits & 15, 2): << I think that's how it's done - this has the random value of 0-15
then call

switch (..... LOAD_TEMP(2))
{
0..2: return 1;
3..8: return 2;
9: return 3;
return 4;
}
(syntax is not guaranteed to be 100% accurate!)
You can obviously set your own numbers, extend the random range or even do

return [STORE_PERM(1,7)]; returning a 1 into register 7 (for example).

I would have preferred being able to call a random number within a random_switch but it doesn't do that at the moment.

Hope this helps.
michael blunck
Tycoon
Tycoon
Posts: 5948
Joined: 27 Apr 2005 07:09
Contact:

Re: Using random_switch for industry

Post by michael blunck »

Just for the record, in m4nfo this is done by using function rerandom() like this:

Code: Select all


[...]
// top platform
def(6) randomcb(_TOP, ARRIVE, 16, ref(1),  ref(2), ref(2), ref(3))

// bottom platform
def(7) randomcb(_BOTTOM, {ARRIVE, NOCARGO}, 16, ref(1),  ref(2))

def(8) plt_num(
    self(
        ref(6) if(0) // top platform
        ref(7) else // bottom platform
    )
)

[...]

def(9) rerandom(_TOP,
    ref(0) // graphics
)

def(10) rerandom(_BOTTOM,
    ref(0) // graphics
)

def(11) plt_num(
    self(
        ref(9) if(0) // top platform
        ref(10) else // bottom platform
    )
)

// check callbacks
def(12) callback(
    ref(8) if(CB_LAYOUT)
    ref(11) else // graphics / re-randomisation
)
regards
Michael
Image
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 3 guests