Bug #2816

livery overrides

Added by Hirundo almost 9 years ago. Updated almost 9 years ago.

Status:NewStart date:2011-06-29
Priority:NormalDue date:
Assignee:-% Done:


Target version:-



TTDPatch has the following requirements regarding livery override action3s:

  • It must immediately follow the action 3 entry of the engine, or another wagon override (no other kind of sprites allowed in-between) (This requirement is no longer present starting from 2.0.1 alpha 41.)
  • You can't skip just a livery override using action 7, you always have to skip all linked action 3's, i.e. from the engine action 3 to the last livery override.
  • You can have as many wagon override following an engine action 3 as you like, but they must not be interrupted by other sprites (except, since 2.0.1 alpha 41, a possible action 6).

The reason for these requirements is (as far as I could deduce) that TTDPatch just stores a pointer to the action3 to resolve the graphics. When looking for a wagon override, it starts at the engine action3 and checks the following sprites to see if there's an override for the wagon, stopping when encountering an action that is not 3 or 6. For this reason, inserting other actions in between breaks it, and action7 is at best a no-op (It might break various activation procedures, didn't check that).

OpenTTD is less strict, the main requirement is that the last action3 before the wagon override belongs to the engine.

NML currently does not enforce anything at this point. Thus NML can (easily!) produce buggy grfs, which I consider a bug.

From these requirements, we can draw an important conclusion: If a graphics block (ie action3) is skipped, all associated overrides must be skipped as well.


From a user's perspective, it makes little sense to define the wagon override in the item block of the engine. Rather, you'd want to define it at the wagon. Therefore I suggest the following setup:

Graphics blocks get an optional name, like this:

graphics engine_gfx { ... }

Livery overrides can specify a name of the graphics block associated with the engine they override, like so:
item (FEAT_TRAINS, wagon) {
    livery_override (engine_gfx) { ... }

It is a requirement for the graphics block and the override to be defined in the same if/else block, this is to be enforced by NML. This is only a little more strict than OpenTTD allows, but it allows us to maintain TTDPatch compatibility.

To implement this, the graphics block and the associated override(s) must be moved to a single location, preferably the location of the last override.
This avoids problems associated with moving forwards (parameters being not yet defined). However, problems akin to #2785 will arise with variable item IDs and (in the future) statements like 'return param[x]'. I guess, we will need a common solution for keeping parameter references valid when moving stuff.



#1 Updated by Hirundo almost 9 years ago

I suggest to wait for http://wiki.openttd.org/Frosch/Secondary_Related_Objects, which'll make this obsolete.

In the meantime, we can keep this as-is, as it sortof works and no-one has complained yet.

Also available in: Atom PDF