Skip to content

Vehicle variants [newgrf] #8446

andythenorth started this conversation in Features
Vehicle variants [newgrf] #8446
Dec 27, 2020 · 4 comments · 5 replies

Dec 27, 2020

I don't have a neat pitch for this, so here goes.

Per and many similar suggestions / request / discussions in past.

Vehicle newgrf authors like to provide alternate liveries (paint schemes) for vehicles.

These are generally separate from company colour schemes.

So livery choices might be things like

  • "DHL, FedEx or Deutsche Post" for mail trucks
  • "SNCF, SNCB, Railion or DB Schenker" for train engines
  • "British Airways, Air France, or Quantas" for planes

Many newgrfs implement this using 'cargo subtypes' (callback 19).

This use dates back to at least 2006 or so

For players, the options implemented via callback 19 are made via the refit-in-depot menu for trains.

This has survived as a solution for a long time, and is implemented in many newgrfs.

It has a few issues.

  • UI is clunky
    • number of options is number of liveries x number of cargos
    • requires a lot of scrolling, e.g. with an industry grf like FIRS or XIS present, and 4 liveries, the menu might have 256 entries
    • options are text, not images, but the only purpose of liveries is eye candy, so pictures would be better when choosing
    • when a train consist contains vehicles that offer multiple different liveries and cargo refits, the menu for refitting the entire consist becomes...confusing
  • can't really be used with 'refit at station' orders
  • can't be supported by auto-replace (no mapping or translation between subtypes for different vehicles)
  • callback 19 solution mixes up separate concepts: cargo refit, and livery

An aside, the callback 19 feature has also been used for a few other novelty examples of changing vehicle properties, e.g.

  • changing how many vehicles in a tram
  • changing capacity of ships
  • changing power and speed of engines

Callback 19 relies on having a cargo in the vehicle so that choices can be made about the subtype.
Sometimes vehicle grf authors introduce an extra 'magic' cargo dedicated for changing liveries or vehicle properties.
This can break industry sets, as the cargo conflicts with the ones that the industry set provides.

Background, generally industry sets work well if only one is used, or only known-compatible industry sets are used. When other entities (vehicles, houses) start defining cargos, things go wrong, resulting in broken gameplay. e.g.

When this happens it imposes a burden on grf authors and sometimes core developers in unpicking these cases. For example industry sets have to maintain a list of incompatible grfs.

However the industry case is a side effect and less interesting than the main case of supporting livery choices

What to do?
We have lots of evidence of what authors want to do with this:

  • it's not a niche case of the spec where one author uses it once, and it's never touched again
  • it's widely used in vehicle grfs
  • the current solution is clearly survivable, but I don't think it's good

I propose 3 different options for improving this.
I don't know if any are viable.
Other solutions may be better.

Proposals are in separate items for further commenting

  • variants, using extra vehicle IDs
  • variants per vehicle, using a subtype property on a single ID
  • variants per grf, defined as list of constants, and individual vehicles can choose which variants they implement


5 replies

Dec 27, 2020
Collaborator Author

Variants using extra vehicle IDs

We have 65535 vehicle IDs per grf.
There is an upper limit of 16384 IDs when using articulated vehicles.

This is plenty. Large grfs might get through a couple of thousand IDs.

Vehicle variants could be implemented by using multiple IDs, one for each vehicle.

The 'same model' could have 10 liveries by using 10 different IDs, with all other properties set to the same values, and sharing all switches except the graphics chain.

Why don't authors do this already?

  • it clutters the buy menu
  • my guess is that most authors:
    • aren't using a compile that can duplicate vehicles trivially, and generate all the properties and switches
    • would think duplicating a vehicle manually 10 times for 10 liveries makes no sense, and is busy work
    • might be worried about using up too many IDs
    • haven't thought of it
    • have been told to use the cargo subtypes (referred to as 'liveries' frequently), or have cargo-culted it from other sets
  • the buy menu has no nice way to display the livery as part of the vehicle name, as the strings will get quite long

Advantages of this route

  • auto-replace trivially supported
    • can even change one livery to another for a whole fleet of the 'same' engine, which is impossible using cargo subtypes
    • because auto-replace is explicit on ID, it's very easy to see which trains can be refitted from e.g. 'DB' to 'SNCF' or vice versa
  • UI is easier, just directly choose the train you want
  • where authors want to vary vehicle properties (not just livery), it's trivial: just vary the properties for specific vehicle IDs

Disadvantages of this route

  • does clutter the buy menu
  • also clutters the auto-replace menu
  • randomisation of properties like reliability and introduction date could lead to inconsistencies between vehicles
    • we have a method now to synchronise introduction dates
    • some other properties might be possible to synchronise using cb36?

We could:

  • give a vehicle a new optional property: 'is a child of vehicle x'.
  • then hide all child vehicles by default in the buy menu and auto-replace menus
  • then provide +/- disclosure icons on the parent vehicle, to show/hide the children
4 replies

For example, this could be used to group multiple similar vehicles together, with (in this case) the highlighted vehicle in the group being the vehicle that's shown by default.


Grouping similar vehicles could be nice


As someone making a NewGRF with a purchase list of 40~ trains and counting - I have thought of it and quicky disregarded it. One train has about 5 liveries on average so we're looking at 200 trains down the purchase menu. And the set is meant to be used alongside other sets from the same country....that'd be one hell of a purchase menu!

However, I do like the enhancements proposed that would make the buy menu smaller through dropdowns. I also like how by being a child vehicle of x there might therefore be the chance to have a child vehicle say be +10kmp/h faster or less powerful etc. Though this sounds more like the proposes below once you get enchancements in.


andythenorth Dec 28, 2020
Collaborator Author

I did a mockup for the show / hide some while ago 😉

+/- opens / closes the list. Clicking on the 'parent' vehicle also opens the list
We already have the exact UI widget type we would need in other places, including (irony here...)...cargo subtypes 🤣


Dec 27, 2020
Collaborator Author

Variants per vehicle, using a subtype property on a single ID

We could

  • introduce a new action 0 property for vehicles: variant
  • this might have 16 possible values, or 256, or 65536 (exact implementation doesn't matter at this stage)
  • authors could read this property in varaction 2 chains
    • can be used to set livery sprites
    • can be used to adjust properties (cb 36)
  • variants could be exposed to buy menu as +/- icons for show / hide
  • variants could be exposed to autoreplace
    • as +/- icons for show / hide
    • but autoreplace works on replacing vehicles by ID, it would have to be extended to handle changing the variant

We could also

  • allow player to change the variant using a new UI menu for 'livery' or 'variant'

We may or may not want to permit the newgrf to change the property via CB36

  • I don't know what the benefits and downsides of that would be, or the use case


  • easy for authors to understand
  • no (false) dilemma about using up too many IDs


  • existing auto-replace wouldn't work with it (see above)
  • no way to replace to the same livery across different vehicles
    • subtype ID can't be relied on if values are scoped per vehicle ID
0 replies

Dec 27, 2020
Collaborator Author

Variants per grf, defined as list of constants, and individual vehicles can choose which variants they implement

We could introduce some new vehicle grf entity, which defines all the available liveries for that grf.

The implementation isn't important here, but it could be something like a table using labels, similar to cargotable and railtypetable.

Vehicles would

  • use a property to list which livery variants they provide
  • player would choose which livery
    • when building the vehicle, using something like +/- hide/show list in the buy menu, or an explicit new livery choosing window
    • players might be able to change the livery on existing vehicles
  • vehicles use the 'current' livery as a var in the graphics chain to resolve to the correct sprites
  • livery variants could be exposed to autoreplace
    • as +/- icons for show / hide
    • but autoreplace works on replacing vehicles by ID, it would have to be extended to handle changing the variant


  • liveries (or variants) become explicit and can be persisted when vehicles are auto-replaced, if supported by the replacement vehicle
  • possibly simple to understand
  • livery names can be simply provide as one set of strings for the whole grf, instead of repeating in each vehicle
  • wagons could trivially take their livery from the lead engine (if supported), by reading what the current livery is
    • this wouldn't preclude defining explicit liveries for wagons, it's just a convenience


  • existing auto-replace wouldn't work with it (see above)
1 reply

I think plays should be able to change liveries on exisiting vehicles - it's possible now with refit and there are NewGRFs out there that limit liveries by date giving players an insentive to "refurbish" their old trains/liveries (SBB set for one). One other thing I would hope this supports is liveries by year, as I've seen some sets with switching to give you a pre-determined livery by year (eg; BR green then BR blue after 1980).

I also prefer this you've mentioned wagons as well - and I think it's important to continue wagon refit or "livery" support which many have fudged through cargorefits and reading IDs of the lead vehicle etc.

Apr 21, 2021
Collaborator Author


0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
4 participants