Folgende Warnungen sind aufgetreten:
Warning [2] count(): Parameter must be an array or an object that implements Countable - Line: 795 - File: showthread.php PHP 7.4.33 (Linux)
File Line Function
/showthread.php 795 errorHandler->error




Dieses Forum nutzt Cookies
Dieses Forum nutzt Cookies um Anmeldeinformationen (keine Passwörter) zu speichern. Dabei werden diese Informationen als kleine Textdateien auf deinem Endgerät abgelegt. Sie können nur durch dieses Forum ausgelesen werden und stellen kein Sicherheitsrisiko dar. Neben deinem letzten Login wird auch abgespeichert, welche Themen du bereits gelesen hast.

Zudem wird ein Cookie angelegt, in dem abgespeichert wird, ob du diesen Hinweis gelesen hast. Damit wird er nicht jedes mal angezeigt.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
NML - NewGRF Meta Language
Verfasser Nachricht
planetmaker
Tycoon
*****

Beiträge: 1.309
Registriert seit: Oct 2008
Beitrag #1
NML - NewGRF Meta Language
Moin,

da sich hier auch gelegentlich Leute tummeln, die das eine oder andere NewGRF etwas modden oder schreiben, ein kurzer Hinweis auf ein neues Werkzeug, welches - zumindest meiner Meinung nach - das Schreiben von NewGRFs um einiges vereinfacht: NML

Worum geht's?
NML ist eine NewGRF Hochsprache mit Compiler, welcher nml-Dateien in newgrf - Dateien (und, so gewünscht, nfo) übersetzt.

Der Hauptautor ist Yexo, weitere wichtige Autoren sind Hirundo und Alberth. Inzwischen ist NML so weit gediehen, dass es offiziell bekannt geben werden kann, da es nicht mehr wahrscheinlich ist, dass der Syntax sich ändert.

Wie funktioniert's?
Ein NewGRF in NML zu schreiben funktioniert ähnlich dem Schreiben eines Programms in einer Programmiersprache - mit der Ausnahme, dass keine Sub-Routinen verfügbar sind; man kann die üblichen Zuweisungen und bedingten Anweisungen nutzen. Weiter unten habe ich eine kleine Gegenüberstellung von NFO und NML am Beispiel eines kleine Railtypes NewGRF angehängt. Einer der m.M.n. angenehmen Änderungen ist, dass NML erlaubt beliebige Bilddateien zu lesen (vorausgesetzt sie sind in 8bpp und der korrekten Palette und von der Python Image Library unterstützt). PNG bevorzuge ich persönlich, da Browser sie auch anzeigen können.

Das grf wird mit einem einfachen Kommandozeilen-Aufruf erzeugt:
Code:
nml2nfo --nfo swedishrails.nfo --grf swedishrails.grf swedishrails.nml
Die Erzeugung des NFO kann natürlich ausgelassen werden, da das grf direkt geschrieben wird; der NFO - Output dient eigentlich nur dem Vergleich für die Entwickler Lächeln

Was braucht man? Wo kriegt man's her?
Man braucht Python 2.5 ... < 3.0 und eine Reihe Module, insbes. die Python Image Library und Python lz77 sowie natürlich NML selbst.

Die neueste Version von NML gibt's hier und die Dokumentation findet sich hier welche leider aber noch sehr unvollständig ist.

Viele (die meisten?) wichtigen NewGRF - Features sind bereits implementiert in NML, aber hier und dort gibt's noch ein paar fehlende Punkte. Diese werden jedoch laufend weniger. Und wenn etwas bestimmtes fehlt, so kann man die Entwickler ansprechen, die dann diesen Wunsch ggf. relativ zügig umsetzen. Feedback, Kommentare, Feature-Requests und Fehlerberichte sind immer willkommen. Siehe auch unserenBug tracker.


Schließen möchte ich mit einem kleinen Vergleich zwischen traditioneller NFO - Programmierung mit der NML - Programmierung vorstellen. In den letzten Tagen habe ich am SwedishRails Set gearbeitet, welches ich in NML schreibe. Zuerst zeige ich den NFO - Code, im Anschluß das gleiche in NML. Teile, die nur bereits gesagtes wiederholen werde ich im gezeigten Sourcecode auslassen. Zwei vollständig in NML programmierte NewGRFs sind
OpenGFX+ und SwedishRails, insbes. in OpenGFX+ finden sich auch Beispiele für Fahrzeuge.

NFO
Zuerst definieren wir das NewGRF:
Code:
// Automatically generated by GRFCODEC. Do not modify!
// (Info version 7)
// Escapes: 2+ = 71 = D= = DR 2- = 70 = D+ = DF 2< = 7= = D- = DC 2> = 7! = Du* = DM 2u< = 7< = D* = DnF 2u> = 7> = Du<< = DnC
2/ = 7G = D<< = DO 2% = 7g = D& 2u/ = 7gG = D| 2u% = 7GG = Du/ 2* = 7gg = D/ 2& = 7c = Du% 2| = 7C = D% 2^ 2sto = 2s 2rst = 2r 2+
2ror = 2rot
// Format: spritenum pcxfile xpos ypos compression ysize xsize xrel yrel

0 * 4 \d416
1 * 92 08 07 "SER0" "ÞSwedish Rails  nightly-r52M" 00 "ÞSwedish rails are a replacement for the default rails" 00

Dann definieren wir die standard Schienen um und definieren sie kompatibel zu elektrifizierten Schienen. Wir weisen diesen Schienen neue Grafiken für Schienen, deren Unterbau, Tunnel und Depots zu. Da nur OpenTTD Railtypes unterstützt, tun wir dies nur, wenn dieses NewGRF unter OpenTTD läuft:
Code:
412 * 9 07 9D 04 \7! \dx00000001 04

413 * 18 00 10 \b2 01 FF \wx000A
08 "RAIL"
0E \b1 "ELRL"

414 * 22 03 10 01 0A \b5
01 \wx00FB
02 \wx00FC
07 \wx00FD
03 \wx00F8
08 \wx00FA
\wx00FE

Wir nutzen var40 um zu unterscheiden, ob wir schneebedeckte Grafiken verwenden oder normale:
Code:
383 * 6 01 10 \b1 FF \wx0004

384 src/gfx/tunnel_track_normal.png 75 0 01 31 64 -31 0
385 src/gfx/tunnel_track_normal.png 0 0 01 31 64 -31 0
386 src/gfx/tunnel_track_normal.png 75 50 01 31 64 -31 0
387 src/gfx/tunnel_track_normal.png 0 50 01 31 64 -31 0

388 * 7 02 10 FA \b1 \b0
\w0

389 * 6 01 10 \b1 FF \wx0004

390 src/gfx/tunnel_track_snow.png 75 0 01 31 64 -31 0
391 src/gfx/tunnel_track_snow.png 0 0 01 31 64 -31 0
392 src/gfx/tunnel_track_snow.png 75 50 01 31 64 -31 0
393 src/gfx/tunnel_track_snow.png 0 50 01 31 64 -31 0

394 * 7 02 10 F9 \b1 \b0
\w0

395 * 23 02 10 F8 89
40 00 \dx000000FF \b1
\wx00F9 \dx00000004 \dx00000004
\wx00FA

Wir liefern neue Grafiken für Tunnelportale im gemäßigten Klima - aber nur wenn TTDPatch läuft oder per NewGRF-Parameter nach gefragt wird:
Code:
2 * 9 0D 40 \D- 9D FF \dx00000000
3 * 5 0D 40 \D/ 40 40
4 * 9 0D 40 \D- FF 40 \dx00000001

5 * 5 0D 0A \D| 40 00
6 * 9 0D 41 \D- 83 FF \dx00000000
7 * 5 0D 41 \D/ 41 41
8 * 9 0D 41 \D- FF 41 \dx00000001
9 * 9 0D 42 \D- 0A FF \dx00000001
10 * 5 0D 42 \D/ 42 42
11 * 9 0D 42 \D- FF 42 \dx00000001
12 * 5 0D 40 \D& 41 42
13 * 9 07 40 04 \7= \dx00000000 11

48 * 5 0A \b1 \b8 \wx093D
49 src/gfx/temperate_rails_TTD.png 4 6 01 33 33 -31 -2
50 src/gfx/temperate_rails_TTD.png 52 6 01 38 40 -7 -38
51 src/gfx/temperate_rails_TTD.png 95 6 01 19 27 -31 2
52 src/gfx/temperate_rails_TTD.png 129 6 01 23 42 -9 -30
53 src/gfx/temperate_rails_TTD.png 177 6 01 18 25 8 3
54 src/gfx/temperate_rails_TTD.png 209 6 01 23 43 -31 -30
55 src/gfx/temperate_rails_TTD.png 258 6 01 33 33 0 -2
56 src/gfx/temperate_rails_TTD.png 295 6 01 38 40 -31 -38

109 * 2 10 11

Und nun das ganze in NML:
Code:
grf {
grfid : "SER0";
name : string(STR_GRF_NAME);
desc : string(STR_GRF_DESCRIPTION);
}
und in der Sprach-Datei, welche der OpenTTD-Konvention für Sprachdateien folgt:
Code:
lang: 7F
STR_GRF_NAME                                                    :Swedish Rails {VERSION}
STR_GRF_DESCRIPTION                                             :Swedish rails are a replacement for the default rails

Railtypes nur für OpenTTD definieren:
Code:
if (ttd_platform == PLATFORM_OPENTTD) {

item(FEAT_RAILTYPES, rail, 0x0A) {
  property {
   label: "RAIL";
   compatible_railtype_list: ["ELRL"];
   // We don't want to change rail properties. Just provide new graphics
  }
  graphics {
   TRACKOVERLAY: ground_switch_overlay;
   UNDERLAY: ground_switch_underlay;
   LEVEL_CROSSINGS: level_crossing_group;
   TUNNELS: tunnel_switch;
   DEPOTS: depot_normal_rail_group;
   track_overlay_group; // irrelevant, we just need one set here
  }
}
} // of OpenTTD only
Normale und verschneite Gleise für Tunnel definieren. Wir nutzen die gleichen Alignment-Informationen für beide Grafiken, da wir sie in identischen Dateien gespeichert haben:
Code:
template tmpl_tunnel_tracks() {
[ 75, 0, 64,31, -31, 0]
[ 0, 0, 64,31, -31, 0]
[ 75, 50, 64,31, -31, 0]
[ 0, 50, 64,31, -31, 0]
}

spriteblock(FEAT_RAILTYPES) {
spriteset(tunnel_overlay, "src/gfx/tunnel_track_normal.png") {
  tmpl_tunnel_tracks()
}
spritegroup tunnel_group {
  default: tunnel_overlay;
}
}
spriteblock(FEAT_RAILTYPES) {
spriteset(tunnel_overlay_snow, "src/gfx/tunnel_track_snow.png") {
  tmpl_tunnel_tracks()
}
spritegroup tunnel_snow_group {
  default: tunnel_overlay_snow;
}
}
switch(FEAT_RAILTYPES, SELF, tunnel_switch, terrain_type) {
TILETYPE_SNOW: tunnel_snow_group;
tunnel_group;
}

Ersetzen der Tunnelportale im gemäßigten Klima für TTDPatch oder wenn per Parameter erwünscht. Wiederum nutzen wir die Alignment-Informationen für die Tunnelsprites, um sie auch für andere Klimata zu nutzen - nur verschoben um einen konstanten Offset in vertikaler Richtung:
Code:
template tmpl_tunnel(y) {
[ 4, 6, 33,33, -31, -2]
[ 52, 6, 40,38, -7,-38]

[ 95, 6, 27,19, -31, 2]
[129, 6, 42,23, -9,-30]

[177, 6, 25,18, 8, 3]
[209, 6, 43,23, -31,-30]

[258, 6, 33,33, -0, -2]
[295, 6, 40,38, -31,-38]
}

param[10] = (ttd_platform == PLATFORM_TTDPATCH) | (param[0]); // Use TTD ground sprites

if (((climate == CLIMATE_ARCTIC) | (climate == CLIMATE_TEMPERATE)) & (param[10] == 1)) {

// Standard temperate rail sprites
replace (1037, "src/gfx/snow_rails_TTD.png") {
  tmpl_ttd_ground(358)
}

// Replacement of standard rail tunnels in temperate
replace (2397, "src/gfx/snow_rails_TTD.png") {
  tmpl_tunnel(6)
}
} // snow for arctic + temperate TTD mode

[Bild: 4q27gcl]
Schreib Deine eigenen NewGRFs, KIs oder Skripte. Siehe dazu DevZone, NML und Tutorien
17.06.2010 20:29
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Nachrichten in diesem Thema
NML - NewGRF Meta Language - planetmaker - 17.06.2010 20:29
RE: NML - NewGRF Meta Language - Eddi - 17.06.2010, 21:56
RE: NML - NewGRF Meta Language - Eddi - 21.06.2010, 08:58
RE: NML - NewGRF Meta Language - Eddi - 24.08.2011, 13:09
RE: NML - NewGRF Meta Language - mb - 24.08.2011, 15:53
RE: NML - NewGRF Meta Language - mb - 25.08.2011, 16:23
RE: NML - NewGRF Meta Language - mb - 25.08.2011, 10:59
RE: NML - NewGRF Meta Language - Eddi - 06.09.2011, 17:01
RE: NML - NewGRF Meta Language - Eddi - 11.09.2011, 19:25

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 2 Gast/Gäste