Is it possible to override a Service?

Overriding lua files is officially frowned upon (while I can’t cite any public source, let me tell you that I’ve had a pretty clear response from Radiant in a PM stating that there will be no proper support for overriding lua files… the fact that it works right now is more or less an “accident”).

Because I usually just tell people that it’s bad but never go in an in-depth explanation, let’s do that.

Why overrides-ing lua files is bad

  1. Lua files have no fixed URI. They have no aliases attached to them and are usually not referred to by them (for example, all require functions explicitly do not allow you to specify the path because lua usually references other lua scripts with periods, not with (back-)slashes.)
  2. Stonehearth supports two file extensions for lua: .luac and .lua. As far as I know, there is not a guarantee which file gets called if both are existent.
  3. As with all overrides, overrides can only be done by one mod and should be used very sparingly. If two mods override the same file, it is not defined what happens (as far as I know there won’t be an obvious error, but only one mod will succeed in actually getting its code in place).

What are the alternatives?

Personal recommendation: Don’t override. If there really is no API for what you need, then use Jelly. Jelly is an independent, third-party mod (written by me and by now a few contributors) that aims to solve these issues by expanding the existing API. As with most things, this comes with advantages and disadvantages:

Advantages:

  • Mods don’t need to override lua files anymore
  • Multiple mods can access the same functionality because it’s in an isolated API
  • Because Jelly offers a fixed API, you rarely will notice version updates. Even if the API/services that Jelly uses change, this change will rarely make it to the “client API” (i.e. you). Your mods will need less maintenance.
  • For some special things, Jelly offers even JSON data that can be mixinto’d or overwritten instead. This is an easier/safer approach to handle things.
  • It’s open source - people are invited to make their own contributions.

Disadvantages:

  • Your mod will require that users install a recent version of Jelly, therefore creating a dependency.
  • Because Jelly is independent, it may take some while until it is updated for a new unstable version. Usually this happens within a few days. In-between, Jelly and some of its mods might not work, although this is rather rare.
  • Although most of the code should be documented and there’s a wiki for it, some features could use some documentation love.

In my opinion, the advantages outweigh the disadvantages by a lot, but I’m probably biased, too.


Back to this case: Could Jelly help? Currently, no. The way I see it, there’s two options:

  • You/I create an API for Jelly and push it, giving you access to override the costs for ladders (or adding new ladders, or or or…). I wouldn’t recommend this way, as this is the AI we’re talking about, so…
  • You simply create a new AI action (with higher priority?) that has the same name, mixinto it into the human-mixin and have that one used instead.

For free ladders, I suppose you would need to see what uses this action (I guess it’s a chain like get_item.take_item.move_to.build_ladder).

As for the AI part, I guess Jelly could use some mixinto magic love (maybe something like "!-key at the start of an entry in special areas means that it and key have to be removed) in the AI component that would allow removing things… Not sure what Radiant’s current approach is on improved mixintos (I would guess that because we haven’t heard anything for a long time and there have never been fixed plans, there isn’t much to tell us though).

7 Likes