A unified tick-based code handling mod

This is the place to request new mods or give ideas about what could be done.
Degraine
Filter Inserter
Filter Inserter
Posts: 282
Joined: Wed Aug 13, 2014 10:49 am
Contact:

A unified tick-based code handling mod

Post by Degraine »

We were discussing this on IRC earlier today, when it was pointed out that one mod (instead of twenty) handling on_tick timers and triggering the relevant function for each mod's on_tick trigger through a remote interface might be more efficient. There might also be a market for some common functions to handle things like adding intermediate products to the 'limitation' field of productivity modules.

So what I'm envisioning here is a similar approach to what Rseding has used in his mods - the ticking mod maintains a 'cron' table with indexes that are numbers corresponding to future game ticks. On any given tick, if it finds a matching entry in the cron table, it calls a remote interface defined in the corresponding mod/s, which run their code and then return a number that denotes how many ticks to wait before triggering the remote call again. This allows mods to reduce the amount of work they do if nothing much is happening. Or they can just keep running at a constant rate. It's up to the author of the mod.

So for this basic setup to work, I think there's four things needed:
  • A remote interface in this mod that can be called to add a mod's first cron trigger to the table.
  • Code to be run during the on_tick event that handles stated everything above.
  • Standardised conventions for identifying and interaction between mods.
  • Examples like the modding tutorial to help new users understand just how the hell they use the thing, how to implement a backoff algorithm, and so on.
So my question is this: Are people interested in making their mods compatible with (and/or dependent on) a library like this? The major selling point of this system would be offloading the logic for tick timing to another mod that can handle it very efficiently. Possibly with some generic code chunks that can be dropped into a mod's control script to make setting it up even easier.Thoughts?
Koub
Global Moderator
Global Moderator
Posts: 7784
Joined: Fri May 30, 2014 8:54 am
Contact:

Re: A unified tick-based code handling mod

Post by Koub »

Hi,

Afforess has started a standard library that's supposed to offer to the modding community a toolkit with frequently needed functions and tools. Maybe what you propose could be integrated in this library.
The topic : viewtopic.php?f=96&t=23181
Koub - Please consider English is not my native language.
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: A unified tick-based code handling mod

Post by Adil »

Koub wrote:Hi,

Afforess has started a standard library that's supposed to offer to the modding community a toolkit with frequently needed functions and tools. Maybe what you propose could be integrated in this library.
The topic : viewtopic.php?f=96&t=23181
Nah, that library a collection of functions that can be copypasted inside your mod so that you don't spend your time reinventing them. Interfaces don't allow passing functions around, so it's pretty much a single instance of library per mod. (it's probably possible to toy around with fancy requires paths, but each mod will get independent instance of it anyway.)

Shared ticker on the other hand at its very core has an idea of being a single instance shared over all the mods so that only a single instance of event handler is in existence and is interacted with via interface.
I mean, (now that I remembered that require "__othermod__/lib.lua" trick) it is still possible to mash those together, but that would still be entangling two conceptually different chunks of code together.
As for the suggested common code, the idea crossed my mind as well, but I doubt that even a hundred of integer comparisons that are usually performed on each tick by each mod would make a much of impact on performance, and the rest of the code is usually module unique. So due to shortage of time no notable amount of work was invested in it by myself.

However, this idea appeases my quirks, so if the mod makes it into existence I'd use it.
Last edited by Adil on Fri Apr 15, 2016 9:38 pm, edited 1 time in total.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: A unified tick-based code handling mod

Post by Adil »

I'd like to add some more separate remarks about this.

Not just on_tick handler, but a unified handlers for all the other mods might be good as well. Of course, those handlers are not as performance hitting but as Rseding91 posted here some nasty collisions might occur there and some more collision solving, than is allowed by default syntax might be good. (Say, have a mod inform the handler that a particular entity is dummy and should be only given to this mod handler, which would or would not provide a true entity for other mods to gnaw at.)
(Actually, having all that in vanilla would be pretty good too.)

A worthwhile primitive in the mod would be an intermittent updater of an array (A particular element handled once per a period of update, few elements are updated each tick.)
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
Choumiko
Smart Inserter
Smart Inserter
Posts: 1352
Joined: Fri Mar 21, 2014 10:51 pm
Contact:

Re: A unified tick-based code handling mod

Post by Choumiko »

I don't see much use as a replacement for sth. like

Code: Select all

function on_tick(event)
  if global.updateTick[event.tick] then
    for _, train in pairs(global.updateTick[event.tick]) do
      --do stuff here
    end
    global.updateTick[event.tick] = nil
  end
end
global.updateTick gets data added whenever a train arrives at a station or sth like that. I think calling the interface of the "unified tick handler" to tell him that i want to call function X in tick Z, which in turn then makes the tick handler call an interface from my mod, creates more overhead than it saves?

I like the idea of having a every 60 ticks event though, only condition is that it doesn't run every mod on tick % 60 == 0 but instead spreads the mods, so that only if 61 mods use it, 2 mods do their stuff in the same tick.

Having a filtered on_entity_build/mined/died event (as Adil suggested, if i got that right) sounds fairly useful, as i think a lot of mods mostly only care about the entities they added and don't need to know whether 100 walls/concrete/whatever got placed by bots.
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: A unified tick-based code handling mod

Post by Adil »

This idea keeps me thinking even though I have other matters I should be better worried about.
I revoke my revokation this is incorrect
Choumiko wrote: global.updateTick gets data added whenever a train arrives at a station or sth like that. I think calling the interface of the "unified tick handler" to tell him that i want to call function X in tick Z, which in turn then makes the tick handler call an interface from my mod, creates more overhead than it saves?
I thought the idea that currently many mods do calls to their own global.updateTick. And with something like:
Code
only one mod would do the tick checking on every tick. Surely, a single mod would be faster without that construct, but what about half a dozen?
I guess for smeared updaters that are run every tick, that would indeed not be a good solution. But there are cases that aren't exactly handled by on_60_tick event, single run timers for example.
Last edited by Adil on Fri Apr 15, 2016 9:38 pm, edited 2 times in total.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
Degraine
Filter Inserter
Filter Inserter
Posts: 282
Joined: Wed Aug 13, 2014 10:49 am
Contact:

Re: A unified tick-based code handling mod

Post by Degraine »

Choumiko wrote:I don't see much use as a replacement for sth. like

Code: Select all

function on_tick(event)
  if global.updateTick[event.tick] then
    for _, train in pairs(global.updateTick[event.tick]) do
      --do stuff here
    end
    global.updateTick[event.tick] = nil
  end
end
global.updateTick gets data added whenever a train arrives at a station or sth like that. I think calling the interface of the "unified tick handler" to tell him that i want to call function X in tick Z, which in turn then makes the tick handler call an interface from my mod, creates more overhead than it saves?

I like the idea of having a every 60 ticks event though, only condition is that it doesn't run every mod on tick % 60 == 0 but instead spreads the mods, so that only if 61 mods use it, 2 mods do their stuff in the same tick.

Having a filtered on_entity_build/mined/died event (as Adil suggested, if i got that right) sounds fairly useful, as i think a lot of mods mostly only care about the entities they added and don't need to know whether 100 walls/concrete/whatever got placed by bots.
I think I see what you mean in your first point - obviously if an author wants to run code every tick no matter what, then there's no need for them to engage another mod to handle the (non-)delay for them. But for mods that don't require that - Forcefields, say, or Klonan's various generators, or indeed, Slipstream Chests, there's A) savings to be made, and B) offloading tick checking logic makes life easier.

I do definitely want to do something for entity creation/destruction too, for sure. It's just a matter of figuring out what form the interface should take.

I'm afraid I don't understand a bit of what Adil's talking about with importing code with require so a vanilla-style handler could be used.
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: A unified tick-based code handling mod

Post by Adil »

Degraine wrote: I'm afraid I don't understand a bit of what Adil's talking about with importing code with require so a vanilla-style handler could be used.
I'm afraid I don't either. I should stop coming here before sleep.

For some reason I've though you could use require to obtain bits from other mods like you can obtain pictures in data lua. Apparently you can't. Unless the files are stored in data/core/lualib/.
The idea was that if this trick was a thing, it'd be possible to have a mod which would have the unified handler in dependencies and import some interface sweetener:

Code: Select all

stl_script={
    on_event = function(event_id, function_handle)
         --insert clever code here
    end
}
so that user-modder would invoke unified handler functions in a same fashion as he invokes functions from script object.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
Degraine
Filter Inserter
Filter Inserter
Posts: 282
Joined: Wed Aug 13, 2014 10:49 am
Contact:

Re: A unified tick-based code handling mod

Post by Degraine »

Oh, okay, so I wasn't just going crazy then. All right.
seronis
Fast Inserter
Fast Inserter
Posts: 225
Joined: Fri Mar 04, 2016 8:04 pm
Contact:

Re: A unified tick-based code handling mod

Post by seronis »

Adil wrote:it'd be possible to have a mod which would have the unified handler in dependencies and import some interface sweetener:

Code: Select all

stl_script={
    on_event = function(event_id, function_handle)
         --insert clever code here
    end
}
so that user-modder would invoke unified handler functions in a same fashion as he invokes functions from script object.
Im tired but isnt that what http://lua-api.factorio.com/0.12.29/LuaRemote.html is for ?
Degraine
Filter Inserter
Filter Inserter
Posts: 282
Joined: Wed Aug 13, 2014 10:49 am
Contact:

Re: A unified tick-based code handling mod

Post by Degraine »

All right, so, I've been mulling over this for a little while, and forgive me if I don't get the presentation right by professional standards, but here's what I've got so far on this:

Trigger (my working name) adds a remote interface that can be called like so:

Code: Select all

remote.call("cron", "add", arg)
Where 'arg' takes the form of a table with three required named indexes and an arbitrary number of other indexes as you see fit. Eg:

Code: Select all

{delay = 10, interface = "pt", func = "testing", info = 10}
  • delay: The number of ticks to wait before Trigger should call the original mod's own remote interface.
  • interface: name of the interface to be called.
  • func: name of the function to be triggered.
'info' is just an example of additional data that can be included in this table. Trigger will send the entirety of the table back to the calling function as a single argument, so mod makers can include an arbitrary number of their own arguments. In this example, it calls the "pt" interface's "testing" function of my Personal Touches mod and passes the original table back to it. Worked like a charm.

What else should the cron interface include? I was thinking about a 'register' function that creates a separate list of regular 'wait 60 ticks' jobs and spreads them out without the source mod having to worry about load distribution against other mods. Probably an 'unregister' function too.
Supercheese
Filter Inserter
Filter Inserter
Posts: 841
Joined: Mon Sep 14, 2015 7:40 am
Contact:

Re: A unified tick-based code handling mod

Post by Supercheese »

Degraine wrote:What else should the cron interface include? I was thinking about a 'register' function that creates a separate list of regular 'wait 60 ticks' jobs and spreads them out without the source mod having to worry about load distribution against other mods. Probably an 'unregister' function too.
Auto-distributing on_60_ticks would be great. I remember randomly selecting a number for the modulo check in Orbital Ion Cannon, thinking, "Well there's only a 1/60 chance that someone else's mod would use this number".

Code: Select all

if game.tick % 60 == 37 then
Lo and behold, another mod also had 37 in their if check, and both mods ended up running on the same tick, which was exactly what I was trying to avoid!
(For the curious, I've since changed it to 47.)
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: A unified tick-based code handling mod

Post by Adil »

Interesting release was done here.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
Post Reply

Return to “Ideas and Requests For Mods”