Slow Tick Rate Compensation : Nuts and Bolts of Implementation

  • On large servers, running multiple mods, for many reasons the tick rate can slow down below 20 ticks/second. This makes all industrialcraft machines run proportionally slower, and this can be quite annoying.


    Well, another post suggested making machines compensate for the tick rate by doing more in the same ticks. I put some thought into how to implement this, and it's pretty simple.


    First of all, once every 20 ticks the code needs to check the system time and then calculate the tick rate scaling multiplier. This number goes from 0 to 40, and is the time elapsed (in seconds) for 20 ticks. So if it takes 20 seconds for there to be 20 ticks, the multiplier = 20.


    The following items and blocks need to be edited :



    Charging functionality of MFSU/batbox/MFE
    Canning Machine
    Crops
    Miner
    Electric Machines. The time til completion of the current operation is decremented by 1 tick * the scaling multiplier. Just a few lines of code to the electric machines base class file. For example, the code has stuff like
    tickstilcompletion--; which just has to be changed to tickstilcompletion -= tickscalingmultiplier;


    All generators
    Just find the line where the energy to be outputted is calculated, and multiply it by the tickscaling multiplier.


    EnergyNet : the limit for wire in EU/packet before the wire melts is also multiplied by this tickscaling multiplier.


    And that's it.


    Terraformers can be left alone, because they create lag in of themselves, and making them run faster worsens the problem.


    This would in some cases reduce the precision of the simulation : for example, if the tick rate were very slow, a machine might finish an operation on every tick, and be unable to run any faster.


    However, I think that's an acceptable tradeoff for allowing machines to run at a decent rate on a slow server.

  • Ideally the code would be altered to allow more than one operation per tick, but if not then machines will have to be working on a MC tick basis.
    Otherwise a properly OCed a machine could consume extra power with no actual benefit.

  • how to calculate time offset for this rates?


    local server time is not option, attempt to alter tickrate result in hurge shitshtorm of errors. (last tested in 110 bukkit)

    Unsafe.putObject(42,Unsafe.staticFieldOffset(42.getDeclaredFields()[42]),43);

  • That's why you don't change MC's tick rate. Instead you have IC2 only update every so many ticks.


    If it's scaled at a 10:1 ratio, then you have IC2 only update EU when the tick counter is a multiple of 10.

  • If you did this (like the OP said), it would have to be done in a way such that the machines do larger amounts of work in each tick rather than updating twice as fast (Otherwise the increased computation would just slow tickrate more). That is, instead of having a macerator take energy/process ore twice in one tick (or twice as fast) you would have to have it consume twice as much energy but process 2 pieces of ore at once (obviously this would have to be consistent with how it currently operates in terms of LV/HV and energy usage/work done).


    e.g.
    if (mctick % scale == 0)
    updateMacerator(); // or whatever


    Obviously the code is more complicated than this, but I'm assuming this is what you were suggesting. The problem would be that (assume IC updates every 10 MC ticks) when the scale goes from 10->5 the machine updates twice as fast which is good in that it removes any obvious slowdown BUT if IC is the reason for the slowdown it will just make the server slow more. (and if the scale goes down more, it will increase lag more....etc etc)


    A way to avoid this as I said before, in the case of the macerator at least, would be to process more ore at once while using a proportional amount of EU. The problem would (probably) be that the machine would have to ask for more EU effectively making it higher voltage. So, you would have to add a similar scaling in the energy net code, which would probably be very annoying. Furthermore you probably cant do this with all machines, the terraformer for example would have no benefit from this, since the computationally intense process it uses is manipulating blocks. (so unlike the macerator you cant just go use 2x energy -> take 2 ore from itemstack -> make 4 dust, you still have to modify two blocks or whatever).


    Ok I admit I have little idea how the IC code works, but from a coding standpoint and what little I understand I assume the situation is similar, at the very least it would take a significant rewrite of code to implement this.


    Edit: Haha, I have to admit I didn't read all of the OP, and just happened to pick terraformers as something that wouldn't benefit as well. Well my post is pretty redundant but I'll leave it here anyway.

  • Carto :


    1. Machines have a time before they are done with the current operation that decrements every tick. For instance, the recycler takes 45 ticks to recycle something. Each time the code governing the recycler is called, it subtracts 1 from that number. I'm having it subtract the tick-rate compensation from the number instead.


    This obviously has a limit to the speedup : if the server is extremely lagging, with a tick rate down to less than 1, it could get to where every time a recycler recycles something, it instantly finishes in a single tick, but can go no faster. The point of this hack is the compensate for slow tick rate with the least code changes, so I would not bother to make it able to do multiple items in a tick.


    2. There's a single point in the energy net code where it decides whether or not to burn up a wire. I'd have to lift that limit by tick rate. For instance, when it checks the limit, it does basically


    if (Packet_size > Threshold)
    BurnUpWire;


    Now it just has to be
    if (Packet_size > Threshold * TickRateCompensation)
    BurnUpWire;


    Here's the thing : I have limited coding time. I'd want one of the IC2 coders to sign off on the idea before I write this mod. As in, if the idea works well, they would incorporate it into the main branch of IC2 so I don't have to reapply the changes needed every time a new version is released.

  • That's a bit more advanced than I was thinking.
    I was thinking that the scaling ratio should be set in the config files and only able to change via reboot.


    Machines need to either be running on every MC tick or capable of processing multiple items per tick.
    EU can update once or twice a second with a negligible impact on player experience, but as things work now a stack of 64 items can be processed in as little as 3.2 seconds. If machines ran at a lower tick rate without being able to process multiple items per tick then that same stack would take 32 or 64 seconds to process.


    Personally? I favor the multiple items per tick solution, as that both removes the cap on overclocker returns and further reduces overhead.