Various NML related questions

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

Moderator: Graphics Moderators

Post Reply
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Various NML related questions

Post by 3iff »

When defining an industry (a farm in this case), there's a line for setting production when the industry is built.

prod_multiplier: [7, 5]; // (Grain and Plant Fibres - from FIRS)

Grain is set for 7 per 256 ticks, Plant Fibres at 5 per 256 ticks...subject to the industry production rating.

Is there any way to randomise the 7 and 5 so that it might be possible for grain to be (say) range 5-9 and plant fibres range 5-9 so that there's the opportunity for plant fibres to be produced at a higher level than grain at some farms?

The desire is to have industries with varied production levels. I can get different production levels at game start but here I have the problem that grain production is always higher than plant fibres at all farms, there's always a fixed relationship between the cargos. I want more variation.

Is it possible?
Last edited by 3iff on 09 Jul 2015 10:08, edited 1 time in total.
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 988
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: Randomising prod_multiplier values

Post by frosch »

Yes, but it is requires a bit more than a single line.

Using the production callback you can modify all aspects of production:
* Disable the default production mechanics: prod_multiplier: [0,0]
* Enable automatic handling of production changes: spec_flags: IND_FLAG_AUTOMATIC_PRODUCTION_MULTIPLIER
* Enable custom production: callback produce_256_ticks -> produce(..., 0, 0, 0, 4 + (random_bits & 7), 4 + ((random_bits >> 3) & 7)

Note that using custom production mechanics disables the "smooth economy" setting of OpenTTD. If you also want finer random production changes, you need to add a monthly_prod_change callback with the CB_RESULT_IND_PROD_SET_BY_0x100 result, and some magic computation from the random bits and the previous production multiplier.
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Thanks for that. It looks complicated but I'll have a play around. I may be back with more questions later.

I'm building my own version of Firs with a lot of changes (including no in-game industry production variations) so I should be able to get something I'm happy with if I can make this work. It's pretty much at the edge of my capabilities at the moment but I'm gradually getting better.

What exactly does ((random_bits >> 3) & 7) mean? I'm guessing & 7 means the last three bits? Not sure what the >> 3 is.
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5601
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Randomising prod_multiplier values

Post by PikkaBird »

3iff wrote:What exactly does ((random_bits >> 3) & 7) mean? I'm guessing & 7 means the last three bits? Not sure what the >> 3 is.
">> 3" shifts 3 bits, so while "& 7" reads the value of bits 0-2, ">> 3 & 7" reads bits 3-5.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Thanks, it makes more sense now. I've seen that in various places but never knew what it meant.

I now have something that works exactly as I wish. I'm going to have to play around with numbers to get the output value ranges I'm looking for but I will soon be spreading this to other 'produce only' industries where there are 2 cargo products.

------

I've managed to amend the grf with the changes you suggested. I did find that adding

spec_flags: bitmask(IND_FLAG_AUTOMATIC_PRODUCTION_MULTIPLIER);

caused some bizarre values for my sheep farm and dairy farm (some 4-10 times the intended amounts) so I removed the spec_flag change and everything now seems fine. I wasn't sure if the bitmask() part was required but I added it as all other spec_flag entries had it.

I shall be playing around with values but it's very close to what I wanted. I'll be doing some proper testing when I get a chance.
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 988
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: Randomising prod_multiplier values

Post by frosch »

Without that flags, production will never change.
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

frosch wrote:Without that flags, production will never change.
That's fine, because I don't want it to change.

I've managed to do a bit of in-game testing and it's all working as I want it to, so I'm very happy.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Probably not related but I might as well keep my questions in the same place.

Forest production is all over the place. This is in standard OTTD (nightly 27238), no grfs loaded.

I know there are either 8 or 9 production cycles per month and for coal mines (for example) they exhibit that behaviour. Productions oscillate from 176-198 or 160-180 or 56-63, just as expected.

Forests don't do that. I'm getting 35-72, 72-108, 66-99 and 90-135. I can't spot any reason why they do that. Forest production hasn't changed in that period.

They behave exactly the same way when I use my own industry set or FIRS, but as it's in the default game then it's not my grf causing the problem.

Anyone have any idea what's going on?
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 988
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: Randomising prod_multiplier values

Post by frosch »

That is caused by the "min_cargo_distr" property (Minimal amount of cargo before transporting to stations).

For most of the default industries it is "5". For forests, candyfloss forest and battery farm it is 30. For fruit and rubber plantation it is 15. For the temperate bank it is 2.
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Thanks,

I'll set/change that value and see what happens.
-----------------
Yes, that's it.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Another problem...

I have an industry that has a fixed output (LVST) and a random output (FICR or GRAI).

Currently, these are set via: prod_cargo_types: [LVST,FICR]; but FICR might be GRAI instead (or possibly others). At the moment this is hardcoded and it causes problems elsewhere. Nothing game breaking but the info isn't correctly provided to the minimap.

I can set the cargo_output values to LVST and the random cargo but I need a way to load the random cargo into... prod_cargo_types: [LVST,FICR]; or prod_cargo_types: [LVST,GRAI];

I can't figure out a way to do it - if it can be done. Any ideas?
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Randomising prod_multiplier values

Post by planetmaker »

3iff wrote:Another problem...

I have an industry that has a fixed output (LVST) and a random output (FICR or GRAI).

Currently, these are set via: prod_cargo_types: [LVST,FICR]; but FICR might be GRAI instead (or possibly others). At the moment this is hardcoded and it causes problems elsewhere. Nothing game breaking but the info isn't correctly provided to the minimap.

I can set the cargo_output values to LVST and the random cargo but I need a way to load the random cargo into... prod_cargo_types: [LVST,FICR]; or prod_cargo_types: [LVST,GRAI];

I can't figure out a way to do it - if it can be done. Any ideas?
When you change the produced cargo types of an industry at runtime, then the game has no chance to figure that out. All information provided on the minimap for cargo support and for the industry chain view which deviate from the industry's defaults will be wrong as they rely on the default property values you provide in the NewGRF instead of the values as changed by callbacks.

(Or was it something else you were asking? Then please re-phrase :) )
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

No, that's what I was asking. (I think).

It's what I thought as I'm doing something 'unexpected'. The only logical way around it is to have real alternative industries rather than randomise existing industries.

I'll have to rethink how I do this... I'm slowly getting a handle on how all this fits together, it's a slow process. :(

Thanks.
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Randomising prod_multiplier values

Post by planetmaker »

3iff wrote:It's what I thought as I'm doing something 'unexpected'. The only logical way around it is to have real alternative industries rather than randomise existing industries.
Yes indeed. But as you can (meanwhile in trunk) have 128 different industries in your NewGRF, that probably is not a big issue (you could mostly duplicate the code except for cargo and some other minor details)

http://hg.openttd.org/trunk.hg/rev/3fc58450901b
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Yes, that's a possibility. I haven't yet tried the later nightlies (... but soon).

I've removed the randomising for now and will look to expanding the industry set, maybe. It's easy enough to do but I'm wary of adding new things that aren't actually needed. I don't want it to become too complex.

Thanks again for the advice.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Randomising prod_multiplier values

Post by 3iff »

Another question.

(LOAD_PERM(1) > SOMEVALUE ? 1 : 0)

Does this mean if the value of LOAD_PERM(1) is greater than SOMEVALUE then it returns 1 otherwise it returns zero?

and what is the meaning of the ? symbol. It's been puzzling me for a while.

And another one that I cannot even guess at...

(VALUE) / (1 << 21) - what does (1 << 21) mean?
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4763
Joined: 09 Sep 2007 05:03
Location: home

Re: Randomising prod_multiplier values

Post by Alberth »

3iff wrote:Another question.
Actually, it's three questions, but never mind :)
3iff wrote:(LOAD_PERM(1) > SOMEVALUE ? 1 : 0)

Does this mean if the value of LOAD_PERM(1) is greater than SOMEVALUE then it returns 1 otherwise it returns zero?
That is what it means.
3iff wrote:and what is the meaning of the ? symbol. It's been puzzling me for a while.
It's the ternary ?: operator. Its form is "<cond> ? <true-val> : <false-val>" which is similar to "if <cond> then return <true-val> else return <false-val> end", except the ?: form is an expression and not a statement, thus ((x > 1) : 1 : 2) + y works.
The ternary operator comes from C/C++.
3iff wrote:And another one that I cannot even guess at...

(VALUE) / (1 << 21) - what does (1 << 21) mean?
The << means 'shift to the left', (there is also >>, which means 'shift to the right). In the binary system, shifting is logical (see below). In the decimal system that we normally use, "x << 1" is equal to "x * 2", x << 2 = (x << 1) << 1, so 1 << 21 thus means 1 * 2 * 2 * ... * 2 (=1 * 2^21 = 2097152).

The more sane explanation is if you don't use the decimal system, but switch to binary numbers instead. Decimal value 1 in the binary system is 1 or 00000000000000000000000000000001 for a 32 bit number (just as with the decimal system, adding prefix zeroes is allowed, 5 == 0000005).
In the binary system "shifting" means literally shifting.
1 = 1 << 0 = 00000000000000000000000000000001, 1 << 1 = 00000000000000000000000000000010, 1 << 2 = 00000000000000000000000000000100, etc. The '1' shifts to the left each time.
1 << 21 is thus 00000000001000000000000000000000.
An this is what it is used for normally. It allows for very compact notation of bit patterns, especially when you use hexadecimal numbers (since four 0/1 bits become a single digit then). It takes some getting used to however.

While 'shifting' may be a new term for you, the concept itself also exists in the decimal system, it is known as 'exponent'. we write 2000 as 2e03 or 2e3 (= 2*10^3).
Being a retired OpenTTD developer does not mean I know what I am doing.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

Thanks, and I'm almost sorry I asked! I'll have to try and read that a few times to understand it. Coding in binary is something I haven't really done. It's a bit of a culture shock.

So, (1 << 21) is a clever way of saying ~2 million

I'm reading some of the nml code in other grfs and I have an eye on including some of it in my code, but most of it is a case of trial and error as a lot of it is currently beyond my comprehension. Some of my code is quite long winded at the moment (but it mostly works and that's what counts).

I should have asked this in the general NML thread. I'll do that next time.

Your patience is appreciated. :wink:
Eddi
Tycoon
Tycoon
Posts: 8254
Joined: 17 Jan 2007 00:14

Re: Various NML related questions

Post by Eddi »

3iff wrote:So, (1 << 21) is a clever way of saying ~2 million
while that is technically true, it's usually not used that way. it's usually meant in the more literal "i want bit 21 set to 1, and all other bits set to 0", the decimal value of such a construct is usually not interesting for anybody.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

I see. In the example I was looking at, (setting a price_factor) a very large number is generated (using decimal numbers) then it needs to be divided by something around 2 million. There didn't seem to be any particular reason to just set bit 21 to do the division.

I do know about bit manipulation but I almost never use it (so far).
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 5 guests