Some questions on limits of industry NewGRF

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

Moderator: Graphics Moderators

ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

Another NML-related question since I did not find that mentioned in the tutorial:

0 is equivalent to logical FALSE
1 is equivalent to logical TRUE

| is binary OR
& is binary AND???
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: Some questions on limits of industry NewGRF

Post by andythenorth »

ebla71 wrote: 23 Sep 2023 00:10 0 is equivalent to logical FALSE
1 is equivalent to logical TRUE
Yes
| is binary OR
& is binary AND???
There are two bitwise operators for OR: | and ||. In expressions, I usually use || for OR. Similarly there are operators for AND as both & and &&.

https://newgrf-specs.tt-wiki.net/wiki/NML:Expressions

I don't know why nml offers both forms. I had to look up the actual source to see what the singular form does as I've never noticed it before :D https://github.com/OpenTTD/nml/blob/mas ... er.py#L184
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

andythenorth wrote: 23 Sep 2023 10:41
| is binary OR
& is binary AND???
There are two bitwise operators for OR: | and ||. In expressions, I usually use || for OR. Similarly there are operators for AND as both & and &&.

https://newgrf-specs.tt-wiki.net/wiki/NML:Expressions

I don't know why nml offers both forms. I had to look up the actual source to see what the singular form does as I've never noticed it before :D https://github.com/OpenTTD/nml/blob/mas ... er.py#L184
Thank you very much for pointing me to the relevant code fragment:
"&": nmlop.AND,
"|": nmlop.OR,
"&&": nmlop.AND,
"||": nmlop.OR,
Which means & and && as well as | and || are totally equivalent in NML and one of them is dedundant?!?

This page on syntax across languages says two-character form is short circuit and single character form is non-short circuit which means it always evaluates both arguments.
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: Some questions on limits of industry NewGRF

Post by andythenorth »

ebla71 wrote: 23 Sep 2023 11:08 Which means & and && as well as | and || are totally equivalent in NML and one of them is dedundant?!?
I asked in discord:
11:54]JGR: | and || are bitwise and logical respectively, same as usual
[11:57]glx: Internally they the same (grf spec limitation)
[11:58]glx: But nml does some magic
[11:58]JGR: NML will do the cast to bool for you if required when using the latter
User avatar
JGR
Tycoon
Tycoon
Posts: 2560
Joined: 08 Aug 2005 13:46
Location: Ipswich

Re: Some questions on limits of industry NewGRF

Post by JGR »

To follow up with a bit more detail:

NFO/NML does not support short circuit evaluation at all, |, ||, &, && and all other binary operators will evaluate both sides.
Don't try to use them as a way of avoiding expensive operations because that won't work, you'll need to use a switch block for that.

& and &&, and | and || are only interchangeable in the case where both arguments are already bool (i.e. both sides only ever have a value of either 0 or 1).
That said it's usually not a good idea to rely on that, and you should use the appropriate operator for what you are trying to do.

Code: Select all

1  & 2 --> 0
1 && 2 --> 1
1  | 2 --> 3
1 || 2 --> 1
Ex TTDPatch Coder
Patch Pack, Github
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

NML questions part 123 (or so) 8)

I want to restrict the location where industries can be placed quite a bit and for rail- and road-related ones this works as expected when checking all eight adjacent tiles using
switch(FEAT_INDUSTRYTILES, SELF, Rail_Vehicle_Maintenance_Depot_tile_1_lc_0,
(nearby_tile_class( 1, 1) == TILE_CLASS_RAIL) |
...
switch(FEAT_INDUSTRYTILES, SELF, Road_Vehicle_Maintenance_Depot_tile_1_lc_0,
(nearby_tile_class( 1, 1) == TILE_CLASS_ROAD) |
...
Now, I would like to do the same for an airport but there are only the following pre-defined TILE_CLASS :arrow:

TILE_CLASS_GROUND Clear ground and farmland
TILE_CLASS_RAIL Rail and rail depots
TILE_CLASS_ROAD Road, road depots and level crossings
TILE_CLASS_HOUSE Houses
TILE_CLASS_TREES Clear tile with trees
TILE_CLASS_STATION Station, waypoint, station part of oilrig
TILE_CLASS_WATER Sea, canal, ship depot
TILE_CLASS_INDUSTRY Industry tile
TILE_CLASS_TUNNEL_BRIDGE Tunnel entrance or bridge ramp
TILE_CLASS_OBJECTS Objects
TILE_CLASS_VOID

In the airport part of the NML documentation there is the function nearby_tile_airporttile_id but it looks like one would have to check for three return values 0x00aa, 0xFFbb, 0xFFFE which would mean 8x3 = 24 checks, if I get that correct.

Is there a more elegant (and short) way to figure out if a tile is part of an airport, much like TILE_CLASS_RAIL and TILE_CLASS_ROAD do?
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Some questions on limits of industry NewGRF

Post by PikkaBird »

ebla71 wrote: 24 Sep 2023 00:37 Is there a more elegant (and short) way to figure out if a tile is part of an airport
Not only is there no elegant way to do it, there is in fact no way at all - your industry can only detect that an airport tile is TILE_CLASS_STATION, it cannot differentiate what type of station (rail, airport, road or dock) it is.
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

PikkaBird wrote: 24 Sep 2023 01:19 Not only is there no elegant way to do it, there is in fact no way at all - your industry can only detect that an airport tile is TILE_CLASS_STATION, it cannot differentiate what type of station (rail, airport, road or dock) it is.
Not even with something like
switch(FEAT_INDUSTRYTILES, SELF, Aircraft_Maintenance_Depot_tile_1_lc_0,
(nearby_tile_airporttile_id == 0xFFbb) |
...
0: return CB_RESULT_LOCATION_DISALLOW;
Aircraft_Maintenance_Depot_tile_1_lc_1;
and then also checking the other seven tiles around the "base tile" plus 0x00aa and 0xFFFE which are supposed to indicate "The tile is an airport tile that is part of this GRF" and "The tile is an airport tile defined in another GRF" according to the documentation here???
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Some questions on limits of industry NewGRF

Post by PikkaBird »

Nope. Each "feature" can only make use of the variables that belong to it - an industry tile can't use airport tile variables, or vice versa.
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

PikkaBird wrote: 24 Sep 2023 01:42 Nope. Each "feature" can only use the variables that belong to it - an industry tile can't use airport tile variables, or vice versa.
Because an airport is considered to be a "station feature" or something like that and not an "industry feature", right?

So only "like features" can "talk to each other" but not those from different categories?!?

Which brings me to my next question - if I want certain industries to be rather close to a town/city center or rather "at the outskirts" or only in large/small "settlements".

Here, I could use either the Industry special flags

IND_FLAG_BUILT_NEAR_TOWN
IND_FLAG_ONLY_IN_TOWNS
IND_FLAG_ONLY_IN_LARGE_TOWNS

or town_zone as defined here???

Which would somewhat be against the statement that only "like features" can communicate with each other - or is "town zone" yet another category?
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Some questions on limits of industry NewGRF

Post by PikkaBird »

ebla71 wrote: 24 Sep 2023 01:56 Which brings me to my next question - if I want certain industries to be rather close to a town/city center or rather "at the outskirts" or only in large/small "settlements".
Yes, you can use the industry variables town_manhattan_dist, town_euclidean_dist, or town_zone to get the distance from the nearest town. And yes, to expand on "communicating with each other", in addition to the SELF scope, switches can also test variables in PARENT scope, which in the case of industries gives access to the variables of the nearest town. You can then use those variables to only allow building the industry near a town of, eg, a certain population.
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

PikkaBird wrote: 24 Sep 2023 02:16 Yes, you can use the industry variables town_manhattan_dist, town_euclidean_dist, or town_zone to get the distance from the nearest town. And yes, to expand on "communicating with each other", in addition to the SELF scope, switches can also test variables in PARENT scope, which in the case of industries gives access to the variables of the nearest town. You can then use those variables to only allow building the industry near a town of, eg, a certain population.
I can kind of achieve what I want using
switch(FEAT_INDUSTRYTILES, SELF, Market_Hall_tile_1_lc_0,
(nearby_tile_class( 1, 1) == TILE_CLASS_HOUSE) |
...
However, when I try to use the zown_zone functions as mentioned, OTTD crashes, which is something I have not experienced with any of the TOWN_CLASS_xxx functions or any other NewGRFs I have used in regular games for the last couple of years.

I tried the following code to check for town zones:
switch(FEAT_INDUSTRYTILES, PARENT, Market_Hall_tile_1_lc_10,
(town_zone( 1, 1) == TOWNZONE_CENTRE) |
...

switch(FEAT_INDUSTRYTILES, PARENT, Market_Hall_tile_1_lc_20,
(town_zone( 0, 0) == TOWNZONE_EDGE)) {
0: return CB_RESULT_LOCATION_DISALLOW;
Market_Hall_tile_1_lc_1;
}

switch(FEAT_INDUSTRYTILES, PARENT, Market_Hall_tile_1_lc_30,
(town_manhattan_dist( 0, 0) > 10)) {
0: return CB_RESULT_LOCATION_DISALLOW;
Market_Hall_tile_1_lc_1;
}

ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

I want to apply different limitations to where industries can be built.

To inform players about these limits, one can use the extra_text_industry callback to show string STR_EXTRA_industry_abc in the Fund new industry menue window using the code fragment below:
item(FEAT_INDUSTRIES, Furniture_Factory, 17) {
property {
... }
graphics {
extra_text_industry: return string(STR_EXTRA_Furniture_Factory);
...
}
}
However, is it possible to only show such a message when a player clicks on a wrong tile?

At the moment, only a generic message "Can't construct this industry type here ... site unsuitable" is displayed in such cases.

I want to make that more specific and individual for each industry - possible?

There seems to be some variation in the second part of the message possible, since it can also say "Not allowed while paused." or "Not enough cash - requires xyz" but I could not find an example in the documentation how this can possibly be changed?

What I want to achieve is a message like "Can't construct Furniture Factory here ... since this is too close to another industry", for example.
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

Another questions relates to production of cargo dependent on cargo previously delivered

This can be done with the incoming_cargo_waiting callback and I found example code how to do that which more or less works the way I want.

My question is about the use of the STORE/LOAD_TEMP vs. STORE/LOAD_PERM builtin functions:

It is said that "Addresses 0..127 are available for the GRF to use" (for TEMP) and "Addresses 0..255 are available for the GRF to use" (for PERM).

Are these limits:

a) total (for the whole game)
b) per type of industry
c) per "instance" of industry (if there are multiple ones of the same industry on a map)?

Furthermore, are the values indicated by "LOAD_TEMP(address)" local (and thus "shielded") from other industries or in all cases "global", meaning for example if industry_A uses STORE_TEMP(15) then industry_B could also refer to this value using LOAD_TEMP(15)?
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Some questions on limits of industry NewGRF

Post by PikkaBird »

Did you resolve your OpenTTD crash with the town zone check?
What I want to achieve is a message like "Can't construct Furniture Factory here ... since this is too close to another industry", for example.
Yes. As the specs indicate, you can return a string from the location check callback to show that string as the error message.
My question is about the use of the STORE/LOAD_TEMP vs. STORE/LOAD_PERM
Temporary storage exists only in the context of the current switch chain, ie as soon as you select a graphic or return a callback result, that storage is gone.

Permanent storage is on a per-industry basis, and is only accessible by the industry (and its tiles). Industries which share the same town can, to a limited extent, share information by reading and writing to the permanent storage of the town.
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

PikkaBird wrote: 25 Sep 2023 22:32 Did you resolve your OpenTTD crash with the town zone check?
No, need to play around further to narrow it down and also did not save the "test game"
PikkaBird wrote: 25 Sep 2023 22:32 Yes. As the specs indicate, you can return a string from the location check callback to show that string as the error message.
Thank you very much, did solve that by using the following code:
switch(FEAT_INDUSTRYTILES, SELF, Furniture_Factory_tile_1_lc_0,
(nearby_tile_class( 1, 1) == TILE_CLASS_INDUSTRY) |
...
(nearby_tile_class( 0, 1) == TILE_CLASS_INDUSTRY)) {
// 1: return CB_RESULT_LOCATION_DISALLOW;
1: return string(STR_ERROR);
return CB_RESULT_LOCATION_ALLOW;
}
PikkaBird wrote: 25 Sep 2023 22:32 Permanent storage is on a per-industry basis, and is only accessible by the industry (and its tiles). Industries which share the same town can, to a limited extent, share information by reading and writing to the permanent storage of the town.
Since it is still not completely clear to me:

"Per-industry basis" means "per individual instance of an industry"? For example, if I have three coal mines, they will all have separate permanent storage indexed as mentioned?
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: Some questions on limits of industry NewGRF

Post by PikkaBird »

ebla71 wrote: 25 Sep 2023 23:23 "Per-industry basis" means "per individual instance of an industry"? For example, if I have three coal mines, they will all have separate permanent storage indexed as mentioned?
Yes, that's right.
peter1138
OpenTTD Developer
OpenTTD Developer
Posts: 1732
Joined: 30 Mar 2005 09:43

Re: Some questions on limits of industry NewGRF

Post by peter1138 »

If the game crashes because of a NewGRF it's best to report that on https://github.com/OpenTTD/OpenTTD/issues
He's like, some kind of OpenTTD developer.
ebla71
Transport Coordinator
Transport Coordinator
Posts: 346
Joined: 14 Apr 2021 21:48
Location: Earth

Re: Some questions on limits of industry NewGRF

Post by ebla71 »

peter1138 wrote: 26 Sep 2023 10:38 If the game crashes because of a NewGRF it's best to report that on https://github.com/OpenTTD/OpenTTD/issues
Thank you very much for pointing me to the GitHub site of OTTD for the reporting of crashes.

However, I first need to reproduce and narrow down the problem, since I did not save the test game :D

But it was quite persistent and only happend when using the town_zone function - otherwise OTTD has not crashed for me in years, and I do abuse it with the "special menue" and modifying NewGRFs in game quite a bit 8)
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 14 guests