Mixinto into LUA?

Not with that attitude; that’s for certain.

The method used to do that sort of stuff is called monkey patching, amongst other names. You can see an example in (old) Frostfeast’s code:

function frostfeast:_three_headed_monkeys()
   local victim = radiant.mods.require('stonehearth.services.server.game_master.controllers.encounters.script_encounter')
   victim.start = function(self, ctx, info)
      if info.script then
         local script = radiant.create_controller(info.script, ctx, info.data)
         self._sv.script = script
         radiant.verify(script, "script encounter could not find script %s", info.script)
         script:start(ctx, info.data)
      end

      -- Override: Allow the script to define the next campaign
      if not info.script_triggers_next_encounter then
         ctx.arc:trigger_next_encounter(ctx)
      end
   end
end

lua functions are variables, lua classes are tables (using metatable magic). Therefore, you can re-assign them as you please. If you know what you’re doing, you can get quite far. In Stonehearth, it’s usually possible to monkey patch almost every single lua object and services, with the exception of some stuff that is running at the very beginning (and therefore before your code).

In the code above, I’m patching the start method of the script encounter. I’m doing a full replace of the method, but you could also do partial replaces, like this old, outdated example from the cookmod:

local old_fnc = stonehearth.game_master.start

stonehearth.game_master.start = function(self, ...)
  local ret = { old_fnc(self, ...) }

  self:_start_campaign('other')
  return unpack(ret)
end

I’m calling the original method, save its return values, then do my stuff and return the values, basically wrapping the old method with my code.

When I messed around with the firepit, back in FF15 I think, I wasn’t able to find a nice way to patch it though - it was too deeply ingrained if I remember correctly. So I overwrote the component, and since big mods weren’t a thing back then and Frostfeast kind of was a complete overhaul anyway, I took the liberty to allow myself that.

But technically speaking, you could get the component (require the necessary file, take a look at the class that is returned, then override the specific method). In that case, it might just work.

2 Likes