Some questions on limits of industry NewGRF
Moderator: Graphics Moderators
Re: Some questions on limits of industry NewGRF
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???
0 is equivalent to logical FALSE
1 is equivalent to logical TRUE
| is binary OR
& is binary AND???
- andythenorth
- Tycoon
- Posts: 5705
- Joined: 31 Mar 2007 14:23
- Location: Lost in Music
Re: Some questions on limits of industry NewGRF
Yes
There are two bitwise operators for OR: | and ||. In expressions, I usually use || for OR. Similarly there are operators for AND as both & and &&.| is binary OR
& is binary 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

FIRS Industry Replacement Set (released) | HEQS Heavy Equipment Set (trucks, industrial trams and more) (finished)
Unsinkable Sam (ships) (preview released) | CHIPS Has Improved Players' Stations (finished)
Iron Horse ((trains) (released) | Termite (tracks for Iron Horse) (released) | Busy Bee (game script) (released)
Road Hog (road vehicles and trams) (released)
Unsinkable Sam (ships) (preview released) | CHIPS Has Improved Players' Stations (finished)
Iron Horse ((trains) (released) | Termite (tracks for Iron Horse) (released) | Busy Bee (game script) (released)
Road Hog (road vehicles and trams) (released)
Re: Some questions on limits of industry NewGRF
Thank you very much for pointing me to the relevant code fragment:andythenorth wrote: 23 Sep 2023 10:41There are two bitwise operators for OR: | and ||. In expressions, I usually use || for OR. Similarly there are operators for AND as both & and &&.| is binary OR
& is binary 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 beforehttps://github.com/OpenTTD/nml/blob/mas ... er.py#L184
Which means & and && as well as | and || are totally equivalent in NML and one of them is dedundant?!?"&": nmlop.AND,
"|": nmlop.OR,
"&&": nmlop.AND,
"||": nmlop.OR,
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.
- andythenorth
- Tycoon
- Posts: 5705
- Joined: 31 Mar 2007 14:23
- Location: Lost in Music
Re: Some questions on limits of industry NewGRF
I asked in discord: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?!?
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
FIRS Industry Replacement Set (released) | HEQS Heavy Equipment Set (trucks, industrial trams and more) (finished)
Unsinkable Sam (ships) (preview released) | CHIPS Has Improved Players' Stations (finished)
Iron Horse ((trains) (released) | Termite (tracks for Iron Horse) (released) | Busy Bee (game script) (released)
Road Hog (road vehicles and trams) (released)
Unsinkable Sam (ships) (preview released) | CHIPS Has Improved Players' Stations (finished)
Iron Horse ((trains) (released) | Termite (tracks for Iron Horse) (released) | Busy Bee (game script) (released)
Road Hog (road vehicles and trams) (released)
Re: Some questions on limits of industry NewGRF
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.
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
Patch Pack, Github
Re: Some questions on limits of industry NewGRF
NML questions part 123 (or so)
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
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?

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) |
...
Now, I would like to do the same for an airport but there are only the following pre-defined TILE_CLASSswitch(FEAT_INDUSTRYTILES, SELF, Road_Vehicle_Maintenance_Depot_tile_1_lc_0,
(nearby_tile_class( 1, 1) == TILE_CLASS_ROAD) |
...

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?
Re: Some questions on limits of industry NewGRF
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 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
Re: Some questions on limits of industry NewGRF
Not even with something likePikkaBird 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.
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???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;
Re: Some questions on limits of industry NewGRF
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.
Re: Some questions on limits of industry NewGRF
Because an airport is considered to be a "station feature" or something like that and not an "industry feature", right?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.
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?
Re: Some questions on limits of industry NewGRF
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 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".
Re: Some questions on limits of industry NewGRF
I can kind of achieve what I want usingPikkaBird 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.
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.switch(FEAT_INDUSTRYTILES, SELF, Market_Hall_tile_1_lc_0,
(nearby_tile_class( 1, 1) == TILE_CLASS_HOUSE) |
...
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;
}
Re: Some questions on limits of industry NewGRF
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:
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.
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:
However, is it possible to only show such a message when a player clicks on a wrong tile?item(FEAT_INDUSTRIES, Furniture_Factory, 17) {
property {
... }
graphics {
extra_text_industry: return string(STR_EXTRA_Furniture_Factory);
...
}
}
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.
Re: Some questions on limits of industry NewGRF
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)?
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)?
Re: Some questions on limits of industry NewGRF
Did you resolve your OpenTTD crash with the town zone check?
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.
Yes. As the specs indicate, you can return a string from the location check callback to show that string as the error message.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.
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.My question is about the use of the STORE/LOAD_TEMP vs. STORE/LOAD_PERM
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.
Re: Some questions on limits of industry NewGRF
No, need to play around further to narrow it down and also did not save the "test game"
Thank you very much, did solve that by using the following code: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.
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;
}
Since it is still not completely clear to me: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.
"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?
Re: Some questions on limits of industry NewGRF
Yes, that's right.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?
Re: Some questions on limits of industry NewGRF
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.
Re: Some questions on limits of industry NewGRF
Thank you very much for pointing me to the GitHub site of OTTD for the reporting of crashes.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
However, I first need to reproduce and narrow down the problem, since I did not save the test game

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

Who is online
Users browsing this forum: No registered users and 10 guests