NML 0.6.0 released August 15th 2021

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

Moderator: Graphics Moderators

Post Reply
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5649
Joined: 31 Mar 2007 14:23
Location: Lost in Music

NML 0.6.0 released August 15th 2021

Post by andythenorth »

0.6.0 (2021-08-15)

Windows executable: nml-standalone-0.6.0-win64.zip
Source tarball: nml-0.6.0.tar.gz

As usual, the latest version is also available through `pip`.

Thanks to all who helped.

This release adds major enhancements to switches:
  • Switches can now be used as functions inside expressions
  • Switches can now define parameters, which are passed by callers for usage inside the switch
  • NML now applies optimisations to switches and chains of switches
  • optimisation and deprecation warnings can be suppressed with nmlc flags, see 'nmlc --help' (#230)
Support for NewGRF additions of OpenTTD 12.0:
  • Add: rail vehicle property and callback 'curve_speed_mod' (rail vehicle property 0x2E) (#222)
Support for NewGRF additions of OpenTTD 1.11:
  • Update: Increase number of OTTD_GUI sprites to 186 (#183)
  • Add: Industry spec_flag 'IND_FLAG_DO_NOT_CLAMP_PASSENGER_PRODUCTION' (#183)
  • Add: Vehicle variables 'tile_(supports|powers|is)_(rail|road|tram)type' (#183)
  • Add: Vehicle variable 'tile_has_catenary' (#183)
  • Add: General variable 'inflation', which reports the game setting (#183)
  • Add: Alternative string constants introduced in OpenTTD/OpenTTD#8392 (#176)
Other changes and fixes:
  • Add: industry variable for 'town_index' (var 0x41)
  • Add: constants GROUNDSPRITE_GRASS, GROUNDSPRITE_DESERT_2_2, GROUNDSPRITE_GRASS_1_3, GROUNDSPRITE_GRASS_2_3, GROUNDSPRITE_GRASS_3_3
  • Add: builtin functions for round() and sqrt()
  • Add: plural form 14 for Romanian
  • Change: Check that user code doesn't try to use reserved registers (#189)
  • Change: warn when a deprecated constant is used
  • Change: progress display shows input filename when reading files
  • Change: improve error message when invalid features are used
  • Add: More-obvious error for trailing '.' in a string id (#145)
  • Change: Clean up language definitions (#208)
  • Fix #184: Share townname bits when possible (#185)
  • Fix: Compatibility with Pillow 8.1.0 (#182)
  • Fix #180: No proper error message was given, if an unreferenced String was unable to allocate an id (#181)
  • Fix: Access to persistent-storage of towns (#173)
  • Fix: Don't suppress errors for incorrect [size=13px][font=Monaco,Consolas,'Lucida Console','Courier New',serif][backcolor=#dedede]hide_sprite[/backcolor][/font][/size] values (#168)
  • Fix: Remove trailing whitespaces in NFO output (#164)
  • Fix: town_euclidean_dist was returning incorrect value (#206)
  • Fix: rename MAP_TYPE_RECTANGULAR to MAP_TYPE_SQUARE (#201)
  • Fix: LZ77 compatibility with Python 3.9+ (#215, #228)
  • Fix: access to persistent-storage of towns was broken (#173)
  • Fix: use most likely defined position when reporting error (#226)
  • Update: VS generation script syntax (#233)
User avatar
2TallTyler
Route Supervisor
Route Supervisor
Posts: 490
Joined: 11 Aug 2019 18:15
Contact:

Re: NML 0.6.0 released August 15th 2021

Post by 2TallTyler »

Woot! I’ve been using the new “switches as functions” feature for some time by compiling NML myself, and can attest that it’s a game-changer. If anyone wants to see examples, check out Improved Town Layouts.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: NML 0.6.0 released August 15th 2021

Post by 3iff »

Managed to use a switch as a function...surprisingly a first time success.

I was even able to call the switch as a function, use that switch to jump to another switch and return home...and it works perfectly.
Managed to save perhaps 50 lines of repeated code. I shall be looking to expand on this success.

An excellent addition.
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5649
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: NML 0.6.0 released August 15th 2021

Post by andythenorth »

3iff wrote: 19 Aug 2021 09:10 Managed to use a switch as a function...surprisingly a first time success.
Happy days ;)

flherne, frosch and glx particularly have contributed to this nml release, and we had some nice drive-by contributions from others also
michael blunck
Tycoon
Tycoon
Posts: 5948
Joined: 27 Apr 2005 07:09
Contact:

Re: NML 0.6.0 released August 15th 2021

Post by michael blunck »

Since m4nfo already had procedures (nfo var7E) from the beginning, I'm a bit curious about
Switches can now define parameters, which are passed by callers for usage inside the switch
i.e. use of parameters for procedures.

Since there are conceptually different ways to map parameters to registers, I'd be interested to see an NML example how it is done for multiple parameters in connection with
By moving the logic to a chain of switches, it can be easier to read and understand the code
Are there examples?

regards
Michael
Image
Bad_Brett
Transport Coordinator
Transport Coordinator
Posts: 355
Joined: 01 Feb 2007 17:59
Location: Stockholm, Sweden

Re: NML 0.6.0 released August 15th 2021

Post by Bad_Brett »

This is huge! Fantastic update! Great work! :bow:

I've been playing around with the curve_speed_mod property, but I'm not sure how to use it. What is the proper value range?
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: NML 0.6.0 released August 15th 2021

Post by 3iff »

Not using a procedure (as they didn't exist for me when I wrote this code...)

When checking proximities of conflicting industry types, I now do something like this (going from memory) so it won't be 100% accurate.

// see if any conflicting industries are too close to a potential new build

switch(.... ,check_proximity_forest, [
industry_distance(sawmill) < 50
+ industry_distance(paper_mill) < 25
(and as many more industry types as you want)
]) {
0: allow build;
disallow build;

So I tot up any conflicting industries closer than the specified distance, and even 1 point would disallow the build.
I think the code is "industry_distance" but it might be something else.

I find this approach is instantly readable and all done within one switch rather than cascading up, sometimes for 10+ industry checks. I can see at a glance whether an industry is included or not and can see al the range details.

I'm still getting into procedures (added a couple so far) but they look to be very useful.
User avatar
sevenfm
Engineer
Engineer
Posts: 117
Joined: 25 Jul 2016 23:44
Location: Soviet Russia

Re: NML 0.6.0 released August 15th 2021

Post by sevenfm »

I wonder if using this code

Code: Select all

switch (FEAT_INDUSTRIES, SELF, check_same_town_industry_distance, 
		industry_distance(grocers) < min_town_industry_distance || 
		industry_distance(petrol_pump) < min_town_industry_distance || 
		industry_distance(hardware_store) < min_town_industry_distance || 
		industry_distance(town_hall) < min_town_industry_distance || 
		industry_distance(builders_yard) < min_town_industry_distance ||
		industry_distance(scrap_yard) < min_town_industry_distance ||
		industry_distance(scrap_merchants) < min_town_industry_distance ||
		industry_distance(recycling_depot) < min_town_industry_distance ){
	1: return CB_RESULT_LOCATION_DISALLOW; CB_RESULT_LOCATION_ALLOW; 
}
instead of adding everything would allow check to quit after the first TRUE condition? It does work like that in C/C++, but in NML?
I mean for code optimization.
User avatar
3iff
Tycoon
Tycoon
Posts: 1093
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: NML 0.6.0 released August 15th 2021

Post by 3iff »

That's probably even better.
Bad_Brett
Transport Coordinator
Transport Coordinator
Posts: 355
Joined: 01 Feb 2007 17:59
Location: Stockholm, Sweden

Re: NML 0.6.0 released August 15th 2021

Post by Bad_Brett »

Bad_Brett wrote: 23 Aug 2021 01:17 This is huge! Fantastic update! Great work! :bow:

I've been playing around with the curve_speed_mod property, but I'm not sure how to use it. What is the proper value range?
Alright, I RTFM and got it to work on sharp curves :). However, single curves don't seem to affect the speed... Is this by design or am I doing anything wrong?
curvespeedmod.png
curvespeedmod.png (394.64 KiB) Viewed 8769 times
I have set the curve_speed_mod property to -0.9.
User avatar
jfs
Tycoon
Tycoon
Posts: 1743
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: NML 0.6.0 released August 15th 2021

Post by jfs »

Yes that's what the "realistic acceleration" game setting controls. See the description on the wiki here: https://wiki.openttd.org/en/Manual/Game ... cs/#trains
User avatar
sevenfm
Engineer
Engineer
Posts: 117
Joined: 25 Jul 2016 23:44
Location: Soviet Russia

Re: NML 0.6.0 released August 15th 2021

Post by sevenfm »

I tried to install it on Win7 but failed, it wants Python 3.9 but 3.9 doesnt work on Win7, is there some way to workaround it, like using older python version or something else?
Or do I have to only use old and unsupported NML version only since I cannot update the OS at the moment?
Bad_Brett
Transport Coordinator
Transport Coordinator
Posts: 355
Joined: 01 Feb 2007 17:59
Location: Stockholm, Sweden

Re: NML 0.6.0 released August 15th 2021

Post by Bad_Brett »

jfs wrote: 24 Aug 2021 16:48 Yes that's what the "realistic acceleration" game setting controls. See the description on the wiki here: https://wiki.openttd.org/en/Manual/Game ... cs/#trains
What's great about the curve_speed_mod though, is that I have the ability to give different engines different bonuses/penalties, that will affect the gameplay whether or not the player chooses to use realistic acceleration... :) And while speed, power, tractive effort and total train weight are great variables to calculate semi-realistic slope speeds, vehicle/train length are not good variables to calculate curve speed (i.e a 4-8-4 is longer than a 0-8-0 but should be much better at handling curves at high speeds). If I understand it correctly, what I'm trying to do is not possible (at least not at the moment).

I realise that there might be good reasons why it was implemented this way. And I'm still really thankful for the curve_speed_mod, which adds a lot of possibilities. :)
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5649
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: NML 0.6.0 released August 15th 2021

Post by andythenorth »

I might do this (parameterised procedure):

Code: Select all

       switch (FEAT_INDUSTRIES, SELF, check_min_town_industry_distance, industry_name 
		min_town_industry_distance(industry_name) > min_town_industry_distance) {
	return;
	}
	
        switch (FEAT_INDUSTRIES, SELF, check_same_town_industry_distance, 
		check_min_town_industry_distance(grocers) || 
		check_min_town_industry_distance(petrol_pump) || 
		check_min_town_industry_distance(hardware_store) || 
		check_min_town_industry_distance(town_hall) || 
		check_min_town_industry_distance(builders_yard) ||
		check_min_town_industry_distance(scrap_yard) ||
		check_min_town_industry_distance(scrap_merchants) ||
		check_min_town_industry_distance(recycling_depot)){
	1: return CB_RESULT_LOCATION_DISALLOW; CB_RESULT_LOCATION_ALLOW; 
}
But it's a matter of taste which is better :)

FIRS and Iron Horse have lots of examples of procedures with and without parameters, but the source code is often hard to follow because of the templating. The generated code is easier.

One word of warning: it's easy to get caught out by procedures returning 15 bit results. This is generally fine, but when working with signed 16 bit values it causes the signed bit to be dropped. This is (1) hard to debug (2) exposes the typical nml author to a lot more byte code facts than is ideal :twisted: e.g. something that should yield -1 will yield 32768 instead. If this makes no sense, I am not the person to explain, but google will find explanations of how signing works with 16 bit words.
sevenfm wrote: 24 Aug 2021 18:20 I tried to install it on Win7 but failed, it wants Python 3.9 but 3.9 doesnt work on Win7, is there some way to workaround it, like using older python version or something else?
Or do I have to only use old and unsupported NML version only since I cannot update the OS at the moment?
I am using it with Python 3.8 no issues, but that's not on Windows. Can't help more, sorry :(
User avatar
warp
Engineer
Engineer
Posts: 6
Joined: 22 Nov 2021 07:07
Contact:

Re: NML 0.6.0 released August 15th 2021

Post by warp »

sevenfm wrote: 24 Aug 2021 18:20 I tried to install it on Win7 but failed, it wants Python 3.9 but 3.9 doesnt work on Win7, is there some way to workaround it, like using older python version or something else?
Or do I have to only use old and unsupported NML version only since I cannot update the OS at the moment?
Hi sevenfm,
It's been a while since your post. Have you found a way to use the current NMLC version?
I had similar problem with the v0.6 on my old Win7 and I wasn't willing to upgrade to Win10.
Luckily I was already using msys2. I just installed nmlc using pip and I'm still using it to this day - see attachment below.

Cheers
warp

Code: Select all

warp@Compaq MINGW64 ~
$ nmlc --version
0.7.0

nmlc: D:/msys2/mingw64/bin/nmlc
LZ77 implementation: C (native)

Library versions encountered:
  PIL: 9.2.0
  PLY: 3.11

Python: D:/msys2/mingw64/bin/python.exe
version 3.10.8 (main, Nov  6 2022, 23:27:16)  [GCC 12.2.0 64 bit (AMD64)]

warp@Compaq MINGW64 ~
$
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 5 guests