Difference between revisions of "NMLTutorial/NML Syntax"
(nml syntax theory) |
(comment examples) |
||
Line 148: | Line 148: | ||
| Airport tiles (visible part of airports) |
| Airport tiles (visible part of airports) |
||
|} |
|} |
||
+ | |||
+ | |||
+ | == Comments == |
||
+ | As said before, it's useful to add comments to your NML code to indicate what things are for. |
||
+ | |||
+ | Comments can be written as comment block or as inline comment. Comment blocks go between different lines of NML code, while inline comments can also go there as well as at the end of each line. |
||
+ | |||
+ | Comment block example: |
||
+ | |||
+ | <pre style="color:darkblue"> |
||
+ | /* |
||
+ | This is a comment block, it starts with a slash and an asterisk. |
||
+ | It can span multiple lines |
||
+ | Before it ends with an asterisk and a slash |
||
+ | */ |
||
+ | </pre> |
||
+ | |||
+ | Inline comment example: |
||
+ | |||
+ | <pre style="color:darkblue"> |
||
+ | //An inline comment is preceded by two slashes |
||
+ | //If you need multiple lines, each line gets two slashes in front |
||
+ | |||
+ | grf { |
||
+ | name: string(STR_GRF_NAME); //it can also go at the end of a line |
||
+ | |||
+ | } |
||
+ | </pre> |
||
Revision as of 18:52, 22 August 2011
This page will be a theoretical introduction to the NML syntax. It is very well possible that you don't understand anything of what is written here. If that is the case, please read the page carefully once and then just continue with the next page which will take you on an example journey through the world of coding in NML.
If you do understand this page completely, then it's very likely that you don't need the rest of this NML tutorial and just can look up what you need in the NML Documentation. At your option you can browse through the tutorial quickly or just start making your NewGRF and figure things out as you go.
NML is a programming language
NFO is not a programming language: it's hex editing. NML on the other hand is a human-readable programming language and contains things like if/else statements, operators such as &&, ||, !=, >= etc. and curly brackets to enclose groups of statements.
If you already know a programming language such as C++ or PHP, it's probably very easy to understand and adapt to the NML syntax. If you're new to programming, you should understand a few concepts:
If you're new to programming
- Name things the way you want
- If you define something, it's you who gives it a name. There's no set of rules how things should be called. If you want to name everything foo0001 through foo9999 that's up to you. That doesn't make it very easy to remember which is which, but it isn't wrong per se. However, don't use any fancy symbols in names: you may use (capital) letters a through z, numbers 0 through 9 and an underscore (_). Numbers furthermore cannot be at the beginning of the name of an identifier.
- When referencing something, it needs to exist
- If you want to use a string, the string needs to exists. That probably makes as much sense to you as that a circle is round, right? But it goes further than that: if you define a vehicle and want it to use this and that graphics, the graphics need to be defined before you define the vehicle that uses it. This applies to everything; if your reference something somewhere, that something needs to exists and essentially needs to be before the reference.
- Compilers don't understand typos
- If you make a typo, the compiler (in this case nmlc) doesn't understand what you mean. This especially applies to the names of things we discussed earlier. If you name your vehicle definition KirbyPaulTank, then you must use the exact capitalization everywhere. For a compiler, Kirbypaultank, kirbypaultank, kirbypaulTank etc. are all completely different things. You need to pay special attention to this if you come from Windows. In Windows there's no difference if you write a file or directory with or without captials; in a programming language with or without capitals is a completely different thing and essentially a typo when not used consistently.
- Add more comments than you think is necessary
- When working on a piece of code, you easily remember what does what and why you made it the way you did. However, if you don't look at a piece of code for a couple of months, chances are you have no clue what it does if you haven't commented it. Using decent names for definitions helps a great deal towards reducing the amount of comments, but ideally every code block should have a line stating what it's for and more complicated things also get comments as you go. If you do certain things differently for a reason, state why you did that. If you work with more people on one project, comments are vital in helping fellow developers understand what you did.
NML structure: blocks
NML files are mainly composed from blocks. A block starts with the type of the block, optional arguments and then the contents enclosed by curly braces. Some blocks are supplied with an identifier (ID, a name), some with even more arguments and some are only referenced by their type. The basic block syntax is as follows:
type { //block contents }
or
type name { //block contents }
or
type (name, argument1, [argument2 [,...]] { //block contents }
Currently, the following block types exist:
- grf
- item
- recolour_sprite
- template
- spriteset
- spritegroup
- spritelayout
- tilelayout
- switch
- produce
- random_switch
- cargotable
- railtypetable
- error
- disable_item
- deactivate
- engine_override
- replace
- replacenew
- font_glpyh
- alt_sprites
- town_names
- snowline
- basecost
Some special "blocks", which aren't really blocks but language constructs, exist as well:
- if
- else
Furthermore, there are too many functions to list here. For now you can forget these if you want, but it's good to have seen their names.
The blocks define things that can be referenced or make new things available in the game. Some blocks can contain sub-blocks. The grf
block can contain a param
subblock to add parameter settings. The item
block can contain property
, graphics
and livery_override
subblocks.
If you need to do some calculations you do those outside the blocks, or in some special cases in a block's expression argument, but never inside a block. if
s and else
s also have no place inside blocks and can only be used outside them.
Features
Some blocks can do multiple things. For example, the item
can define a train, but also a road vehicle, ship, or aircraft. In case of such a block, you need to set which feature the block is for and supply this to the block as an argument. Below is a table of available features:
Name | Description |
---|---|
FEAT_TRAINS | Trains |
FEAT_ROADVEHS | Road vehicles |
FEAT_SHIPS | Ships |
FEAT_AIRCRAFT | Aircraft |
FEAT_STATIONS | Train stations |
FEAT_CANALS | Canals |
FEAT_BRIDGES | Bridges |
FEAT_HOUSES | Town houses |
FEAT_GLOBALVARS | Various global variables |
FEAT_INDUSTRYTILES | Industry tiles (visible part of industries) |
FEAT_INDUSTRIES | Industries |
FEAT_CARGOS | Cargo types |
FEAT_SOUNDEFFECTS | Sound effects |
FEAT_AIRPORTS | Airports |
FEAT_SIGNALS | Train signals |
FEAT_OBJECTS | Non-interactive objects (example: lighthouse) |
FEAT_RAILTYPES | Rail types |
FEAT_AIRPORTTILES | Airport tiles (visible part of airports) |
Comments
As said before, it's useful to add comments to your NML code to indicate what things are for.
Comments can be written as comment block or as inline comment. Comment blocks go between different lines of NML code, while inline comments can also go there as well as at the end of each line.
Comment block example:
/* This is a comment block, it starts with a slash and an asterisk. It can span multiple lines Before it ends with an asterisk and a slash */
Inline comment example:
//An inline comment is preceded by two slashes //If you need multiple lines, each line gets two slashes in front grf { name: string(STR_GRF_NAME); //it can also go at the end of a line }
Conclusion
Yes, that's a bunch of stuff with little hands-on examples, but I warned you about that. You'll find (most of) these different blocks explained in the remainder of this tutorial. And, of course, how every block should be written is clearly documented in the block syntax chapter of the NML Documentation.
NML Tutorial: NML Syntax