[NaB] Game broken if .smod-files are not existent



Reproducing the “mod” from the official blog entry works only in case that the original .smod-files are remaining in the folder. If they are unzipped into folders and the initial .smod-files are removed, the game will not work properly after placing the camp standard.

The same happens with the game in general, i.e. without even starting to mod. The .smod-files seem to be mandatory.

Steps to reproduce:

  • Fresh installation of Stonehearth.
  • Unzip the .smod-files and turn them into folders.
  • Remove .smod-files.
  • Optional: Create a mod, e.g. “flagstone”.
  • Execute Stonehearth.
  • Place Camp Standard… game breaks.


Alpha r34


I’ve tracked the issue down to NewGameCallHandler:_on_mouse_event. The _radiant.call's callbacks are never called, although the function is executed on the server side. It looks like deferred functions are kind of… broken?

Edit: Kind of confirmed; _radiant.call on the client does not call any callback. It does work on the server side, however.


nice report, nice sleuthing… suppose this would be considered “confirmed”… :+1:


It’s not necessarily _radiant.call, as stonehearth:get_clock_object is client->server too and that works. I’m thinking of some disconnect issue right now.


between… client and server calls?


No, between server and client itself. Creating a citizen causes this odd behaviour; so self:place_citizen seems to be the cruelpit right now.

Whatever this function does is causing the call to be dropped from the client (i.e. no response is received). investigation on my stream continue~

Edit: Right. The issue seems to be the decompiling of the files, not the archive itself. As soon as anything that has an AI component is spawned (sheep, rabbit, human), the game seems to enter an endless loop somewhere in Thread, causing… well hell if I knew. The server seems to be unresponsive, calls are no longer processed.

Could we please get the normal lua files? If not in the normal release, at least as some sort of SDK?


I tracked the problem and something is definitely going wrong when decompiling thread.luac, the game will run with every file except that one decompiled so it’s definitely that file. I’m looking at the infinite loop and it’s definitely screwed it up. I’m going to attempt to debug it to what I think it should be from the decompiled stuff.


The game can handle mixed stuff though, can’t it? So just leaving thread.luac compiled should do the trick?


It does for me at least.


Yupp, I can confirm this seems to work. It might not be an elegant fix, but it’s something.


I seem to have fixed it. I folded the if back up into the while and got rid of the never ending repeat. I have no idea what the repeat was for but the while/if thing I’ve seen with other decompilers on for loops and it seems to work.

while #self._msgs > 0 do
    local msgs = self._msgs
    self._msgs = {}
    for _, msg in ipairs(msgs) do
      local msg_name = msg[1]
      self._log:detail("dispatching msg \"%s\"", tostring(msg_name))
      local private_msg = Thread.private_messages[msg_name]
      if private_msg then
        private_msg(self, select(2, unpack(msg)))
      elseif self._msg_handler then


Is it even necessary to decompile the .smod files with the new mixintos? I mean, besides poking around in them to find out what does what.


mixintos are about as useful to lua as gravitation is to flying. With lua still not documented even in the slightliest, the best you can do is to decompile the code, throw some debugging lines in there and understand how it works.

Also, @Xavion’s fix works. Cheers.


It looks like the decompiler is broken. Here’s the original source:

function Thread:_dispatch_messages()
   -- keep draining the queue till it's empty
   self._log:spam('starting dispatch message loop.')
   while #self._msgs > 0 do  
      local msgs = self._msgs
      self._msgs = {}
      for _, msg in ipairs(msgs) do
         local msg_name = msg[1]
         self._log:detail('dispatching msg "%s"', tostring(msg_name))
         local private_msg = Thread.private_messages[msg_name]
         if private_msg then
            private_msg(self, select(2, unpack(msg)))
         elseif self._msg_handler then

         if self._finished then
   self._log:spam('finished dispatch message loop.')

It looks like Xavion nearly nailed it, though he missed the break case if the thread finishes as the result of processing a message.

Generally, I think using the decompiled lua to read and understand the code is great, but who knows if it’s going to work if you try to run it, especially now that we know the decompiler has some rough edges. Longterm, we plan to have documentation for all the public interfaces and triggers for everything you’d want to hook into so modifying decompiled lua, monkey patching fuctions, etc. should all be unnecessary, but we’re still not quite there yet. Some of the most interesting mods are just impossible without doing some form of scripting, so I really really want to get there soon, but it will take some time given other higher priority things (like Save / Load).


Since this is not the only file the decompiler suddenly is failing at (scaffolding is another one)… Could we have access to the plaintext lua as a short term solution? Please? Pretty please? Pretty please with sugar on top? :grin:

I mean, for all I care, you could throw it through some cruel lua formatter that strips the comments.


Marking [NaB] because we’re not going to fix the decompiler you’re using (though you’re welcome to go file something against their devs).

Re: Source, we appreciate your letting us know what files you’re interested in, but we don’t have any plans of doing a mass-export of our code at this time. Please keep letting us know what kinds of things you want to be easily mod-able, though; that’s always useful to us.

Modding Manifesto!

Knowing that this is not a bug… could someone confirm that this is still the case? I am coming back to modding Stonehearth after a short break and have the feeling that the .smod-files are still required.


Well whether it was an .smod or not never mattered it was always just whether it was valid lua. So as long as the lua is not decompiled it is guaranteed to work perfectly regardless of whether it’s compressed, the decompiler seems to work at least 99% of the time and I’m nearly certain it’s been improved since this was encountered.

So the simplest answer is only decompile what you need to, whether it’s a plain folder or a .smod doesn’t matter at all.


I’m always working on extracted files - works like a charm. No smods.

The “new” Unwrp comes with a newer version of unluac, which seems to work pretty well with SH’s current code base. I have not encountered any decompilation error so far, be it semantic or syntactical.


@Xavion… slowly, slowly I remember :wink:. Thx.

@RepeatPan… maybe you are right and I should try Unwrp, as for me it did not work out so well that far. Thx.