NML - a Newgrf Meta Language

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

Moderator: Graphics Moderators

Supercheese
Tycoon
Tycoon
Posts: 1660
Joined: 16 Dec 2007 22:24
Location: Idaho, USA

Re: NML - a Newgrf Meta Language

Post by Supercheese »

Eyecandy Road Vehicles | Fake Subways | Supercheese's NewObjects

"Fashions and cultures change, but steam trains shall always be majestic."
-Professor Hershel Layton
MarkSheppard
Engineer
Engineer
Posts: 58
Joined: 08 Nov 2004 12:56

Re: NML - a Newgrf Meta Language

Post by MarkSheppard »

Random idea -- how do you do an animation for a train sprite in OTTD?

It looks liek I could use the motion_counter variable to call a switch to pick sprites to display (there are four levels of animation in this spritesheet done by Paulicius25 for the SP Cabforward and UP Big Boy.).

Liek this pseudo NML:

Code: Select all

graphics
   {
	default: switch_spriteset_CabForward;
   }

....

switch(FEAT_TRAINS, SELF, switch_spriteset_CabForward,(motion_counter))
{
0:spriteset_CabForward1;
1:spriteset_CabForward2;
2:spriteset_CabForward3;
3:spriteset_CabForward4;
}
Supercheese
Tycoon
Tycoon
Posts: 1660
Joined: 16 Dec 2007 22:24
Location: Idaho, USA

Re: NML - a Newgrf Meta Language

Post by Supercheese »

Pretty much like that, although for a 4-frame animation you'll need to mod % the motion_counter by 4, since by default it varies from 0..15. See: http://newgrf-specs.tt-wiki.net/wiki/NM ... _variables

Code: Select all

graphics
   {
   default: switch_spriteset_CabForward;
   }

....

switch(FEAT_TRAINS, SELF, switch_spriteset_CabForward, motion_counter % 4)
{
  0:spriteset_CabForward1;
  1:spriteset_CabForward2;
  2:spriteset_CabForward3;
  3:spriteset_CabForward4;
  CB_FAILED;
}
Eyecandy Road Vehicles | Fake Subways | Supercheese's NewObjects

"Fashions and cultures change, but steam trains shall always be majestic."
-Professor Hershel Layton
Eddi
Tycoon
Tycoon
Posts: 8267
Joined: 17 Jan 2007 00:14

Re: NML - a Newgrf Meta Language

Post by Eddi »

you can only read other GRFs' parameters, not write them.

if you want to provide a parameter GUI for NARS, you have to change that GRF directly.
MarkSheppard
Engineer
Engineer
Posts: 58
Joined: 08 Nov 2004 12:56

Re: NML - a Newgrf Meta Language

Post by MarkSheppard »

Is there a way to set an expression via a parameter? e.g.

reliability_decay could be set to 20, 100, or 200 by selecting it in parameter?

EDIT I think I found a way in the code for Dutch Trams:

Code: Select all

//cargo refit options
if (param_refit == 1) {
	item (FEAT_ROADVEHS, tram_geta_70) {
		property {
			refittable_cargo_classes:	bitmask(CC_PASSENGERS, CC_MAIL, CC_EXPRESS);
		}
	}
}
EDIT II: Yep, I think it works.

EDIT III: For such a thing to work, it has to be placed last-ish in the NML file.
Eddi
Tycoon
Tycoon
Posts: 8267
Joined: 17 Jan 2007 00:14

Re: NML - a Newgrf Meta Language

Post by Eddi »

just put an if-section around the property, like this:

Code: Select all

if(param == 0) {
  property {
    blah : 30;
  }
} else {
  property {
    blah : 50;
  }
}
it doesn't really matter where in the code this is, provided you don't write to the property elsewhere.

there is also a "dynamic" way using a callback, but this should not be needed in this case.
MarkSheppard
Engineer
Engineer
Posts: 58
Joined: 08 Nov 2004 12:56

Re: NML - a Newgrf Meta Language

Post by MarkSheppard »

I need a little help in understanding the retire_early parameter:

I want to have a locomotive available for purchase from 1949-1950 only; what would I put in the following parameters to make that roughly possible?

Code below is rough placeholder.

Code: Select all

introduction_date: date(1949,6,01); // Delivered to UP in June 1949.
model_life: 5; // Returned to GE in March 1951 after two years in service.
retire_early: -10;
vehicle_life: 20;
Transportman
Tycoon
Tycoon
Posts: 2781
Joined: 22 Feb 2011 18:34

Re: NML - a Newgrf Meta Language

Post by Transportman »

MarkSheppard wrote:I need a little help in understanding the retire_early parameter:

I want to have a locomotive available for purchase from 1949-1950 only; what would I put in the following parameters to make that roughly possible?

Code below is rough placeholder.

Code: Select all

introduction_date: date(1949,6,01); // Delivered to UP in June 1949.
model_life: 5; // Returned to GE in March 1951 after two years in service.
retire_early: -10;
vehicle_life: 20;
I think that is not going to work the way you want it, since the game adds a random number of days to the introduction date (0-511 days). I think you should set model_life to 2 and retire_early to 0 to get the desired effect.
Coder of the Dutch Trackset | Development support for the Dutch Trainset | Coder of the 2cc TrainsInNML
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: NML - a Newgrf Meta Language

Post by planetmaker »

MarkSheppard wrote:I need a little help in understanding the retire_early parameter:

I want to have a locomotive available for purchase from 1949-1950 only; what would I put in the following parameters to make that roughly possible?

Code below is rough placeholder.

Code: Select all

introduction_date: date(1949,6,01); // Delivered to UP in June 1949.
model_life: 5; // Returned to GE in March 1951 after two years in service.
retire_early: -10;
vehicle_life: 20;
Generally that will not work properly:

* As pointed out, the introduction year varies by around two years
* The retire_early with negative argumented postpones expiration. Generally this property only makes sense for model_life longer than 8 years.
* you likely want simply a model_life of one or two years. The vehicle_life just tells how long the vehicle can live without getting too old be in need or replacement. model_life determines how long the vehicle will be up for sale.
Eddi
Tycoon
Tycoon
Posts: 8267
Joined: 17 Jan 2007 00:14

Re: NML - a Newgrf Meta Language

Post by Eddi »

How To Use Model Life Properly(tm)

first of all, model life is separated in three phases:
  • Phase 1: prototype and rising reliability (around 2 years)
  • Phase 2: steady reliability (variable number of years)
  • Phase 3: degrading reliability (from around 4 years before to around 4 years after the end of model_life)
and since you can only change the length of phase 2, short model lifetimes like "5 years" will not work at all. you will get an engine that never really reaches full reliability, and then drops reliability really fast, spending most of its (vehicle) lifetime broken down at 0%... (which may be "realistic", but nobody wants to play a game like that)

that means, model_life should never be lower than vehicle_life.

secondly, early retirement will change the way the vehicle is removed from the purchase screen. without early retirement, the vehicle is removed in the middle of phase 3, while early retirement is relative to the end of phase 2, so early_retirement = -4 would be the default behaviour.

thirdly, if you want a vehicle purchased at the latest possible date to have full reliability throughout its entire lifetime, early_retirement should be equal or larger than vehicle_life (-4), and the model_life be the purchase time and the vehicle lifetime combined.

thus, if you take as input data
  • intro_date: the first date the vehicle should be offered as prototype (+ random 0-511 days)
  • last_built: the last date the vehicle should be offered for purchase (this is typically the date the next vehicle of the same type becomes available)
  • decommissioned: the date when the last vehicle should be sold/replaced
the final formulas would be:

Code: Select all

vehicle_life = decommissioned-last_built
model_life = decommissioned-intro_date
retire_early = vehicle_life - 4
so for your example, with a little sanitising (purchase time is 5 years instead of 2, minimum vehicle life is 20)

Code: Select all

vehicle_life = 20
model_life = 25
early_retirement = 16
User avatar
Andrew350
Chairman
Chairman
Posts: 768
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML - a Newgrf Meta Language

Post by Andrew350 »

I'm having a problem getting plurals to work. All I'm trying to do is rename the 'passengers' cargo. I have the following in my lang file:

Code: Select all

##grflangid 0x00
##plural 0

STR_GRF_NAME             :Name
STR_GRF_DESC             :{}Desc

STR_CARGO_1_NAME_PLURAL         :Villagers
STR_CARGO_1_NAME_SINGULAR       :Villager
STR_CARGO_1_NAME_PLURAL_UNITS   :{SIGNED_WORD} villager{P 0 "" s}
It compiles correctly, but the grf crashes OpenTTD when I start a game with it. If I remove the {P 0 "" s} part, it all works fine (without the last string being plural of course). I found a post suggesting to look at the lang file from FIRS as an example, but as far as I can tell I have done everything the same. What am I missing?

Also on a related note, renaming the 'Passengers' cargo (or 'Mail' for that matter) like I've done seems to have no effect on the listing in the town information window (ie "Passengers/Mail last month:"). Are those names hard-coded in, and not changeable via NewGRF?

Also, just in case it's needed, here's the NML file:

Code: Select all

grf {
		grfid: "AZ\20\77";
		name: string(STR_GRF_NAME);
		desc: string(STR_GRF_DESC);
		version: 1;
		min_compatible_version: 0;
	}

cargotable {
		PASS
	}

item (FEAT_CARGOS, cargo_villagers, 00) {
	property {
	
	number:             00;
	type_name:          string(STR_CARGO_1_NAME_PLURAL);
	unit_name:          string(STR_CARGO_1_NAME_SINGULAR);
	units_of_cargo:     string(STR_CARGO_1_NAME_PLURAL_UNITS);
	items_of_cargo:     string(STR_CARGO_1_NAME_PLURAL_UNITS);
	cargo_label:        "PASS";
	
	}
}
User avatar
WWTBAM
Moderator
Moderator
Posts: 3689
Joined: 02 Apr 2005 07:01
Location: Sydney NSW Antipodea
Contact:

Re: NML - a Newgrf Meta Language

Post by WWTBAM »

I think I read somewhere, that current versions of NML can only be used to create GRFs for OpenTTD. Is that true? If so, what is the last version to create GRFs that are compatible universally?
Formerly known as r0b0t_b0y2003, robotboy, roboboy and beclawat. The best place to get the most recent nightly builds of TTDPatch is: http://roboboy.users.tt-forums.net/TTDPatch/nightlies/
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: NML - a Newgrf Meta Language

Post by planetmaker »

roboboy wrote:I think I read somewhere, that current versions of NML can only be used to create GRFs for OpenTTD. Is that true? If so, what is the last version to create GRFs that are compatible universally?
NML versions from the 0.2 branch create grf v7 which should work with TTDPatch.
http://bundles.openttdcoop.org/nml/releases/LATEST/
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 988
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: NML - a Newgrf Meta Language

Post by frosch »

roboboy wrote:I think I read somewhere, that current versions of NML can only be used to create GRFs for OpenTTD. Is that true? If so, what is the last version to create GRFs that are compatible universally?
It also depends on what features are used. OpenGFX worked at some point, but e.g. vehicles never worked because NML always writes extended bytes in the long form, which TTDP does not support in action 3.
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
User avatar
Andrew350
Chairman
Chairman
Posts: 768
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML - a Newgrf Meta Language

Post by Andrew350 »

Ahem...I don't mean to be pushy, but I get the distinct feeling that my above post from yesterday may have been unknowingly skipped over by most people.... :wink:

If not, just ignore me
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: NML - a Newgrf Meta Language

Post by planetmaker »

You're right, I missed your posting, sorry
Andrew350 wrote:I'm having a problem getting plurals to work. All I'm trying to do is rename the 'passengers' cargo. I have the following in my lang file:

Code: Select all

##grflangid 0x00
##plural 0

STR_GRF_NAME             :Name
STR_GRF_DESC             :{}Desc

STR_CARGO_1_NAME_PLURAL         :Villagers
STR_CARGO_1_NAME_SINGULAR       :Villager
STR_CARGO_1_NAME_PLURAL_UNITS   :{SIGNED_WORD} villager{P 0 "" s}
It compiles correctly, but the grf crashes OpenTTD when I start a game with it. If I remove the {P 0 "" s} part, it all works fine (without the last string being plural of course). I found a post suggesting to look at the lang file from FIRS as an example, but as far as I can tell I have done everything the same. What am I missing?
I honestly don't know. I compiled your NewGRF and started a new game: It works for me. Maybe you use an old OpenTTD version where such bug has not yet been fixed?
Also on a related note, renaming the 'Passengers' cargo (or 'Mail' for that matter) like I've done seems to have no effect on the listing in the town information window (ie "Passengers/Mail last month:"). Are those names hard-coded in, and not changeable via NewGRF?
Those strings are part of the OpenTTD translations, yes. Seems that the cargo names are not used. I agree though, that's a bit awkward and might need looking into.
Attachments
villagers.png
villagers.png (169.62 KiB) Viewed 2890 times
User avatar
Andrew350
Chairman
Chairman
Posts: 768
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML - a Newgrf Meta Language

Post by Andrew350 »

planetmaker wrote:You're right, I missed your posting, sorry

I honestly don't know. I compiled your NewGRF and started a new game: It works for me. Maybe you use an old OpenTTD version where such bug has not yet been fixed?
I was using 1.3.0, upgrading to 1.3.1 fixed it. :roll: Wouldn't have thought such a bug would be there in 1.3.0, but I guess that's all it was. :)
planetmaker wrote:
Also on a related note, renaming the 'Passengers' cargo (or 'Mail' for that matter) like I've done seems to have no effect on the listing in the town information window (ie "Passengers/Mail last month:"). Are those names hard-coded in, and not changeable via NewGRF?
Those strings are part of the OpenTTD translations, yes. Seems that the cargo names are not used. I agree though, that's a bit awkward and might need looking into.
I figured. Thanks for looking into that :)


One more question while I'm at it: Is there any technical reason why houses can't have a population of 0? Setting the mail_multiplier to 0 works, but setting the population to 0 causes a house to not show up in the game. Maybe I'm just being silly here and playing with things that shouldn't be done, but I was hoping to stop certain houses from producing any passengers.
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 988
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: NML - a Newgrf Meta Language

Post by frosch »

There is nothing special about population 0. In fact parks and other non-house houses have zero population.
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
Eddi
Tycoon
Tycoon
Posts: 8267
Joined: 17 Jan 2007 00:14

Re: NML - a Newgrf Meta Language

Post by Eddi »

i believe i once had a 0 population town that had only a church
User avatar
Andrew350
Chairman
Chairman
Posts: 768
Joined: 19 Dec 2011 07:54
Location: Washington State, USA
Contact:

Re: NML - a Newgrf Meta Language

Post by Andrew350 »

I'm sorry, I didn't describe the situation correctly at all. :oops: Let me try again.

What I've done is disabled all default houses and added two of my own. As long as one of the houses has a population of at least 1, map generation works fine and both houses will show up. But if I set both of these houses to have a population of 0 and try to start a new game, map generation fails, and I get a notice telling me no suitable town locations were found.

However, if a create a scenario and place a town with zero population manually, both houses still show up and I can play the scenario fine. Apparently at least one house in the game needs to have a population greater than zero, otherwise the game can't figure out where to build towns on map generation. Other than that, everything else seems to work fine.

So, I guess the question I should have asked is, "is there a reason why map generation requires at least one house to have a population above zero in order to work"?
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 25 guests