Most of you have probably noticed the server lagging quite a bit over the last week or so. I'd like to quickly explain why it was laggy and how I fixed it.
When I added the Auto-tools in the old PandaCraft, it was easiest at the time to put the code in the dispense event. That meant that my code would only run when a dispenser activated. It would then look at the blocks above and below it to figure out if it was an auto-tool, and go from there. Since it needed the dispenser to fire, the easiest way to use the auto-tools was to hook them up to clocks. This introduced the first problem.
Players would often use the fastest clocks they know how to build; usually 1-tick comparator clocks or the old-fashioned redstone torch burnout clocks. These clocks put a huge load on the server when they started being used for each auto-tool (this was before auto-tools were limited) and I had to come up with a solution. The easiest solution was to introduce a plugin that could replicate the functions of a clock but allowed specified intervals and required no redstone. My search led me to CraftBook, a plugin that offered not only the clock ICs, but also several other useful ICs like the ranged collector and even mechanisms like pipes.
Adding CraftBook took a large load off the server, but the problems continued to get worse as more players started playing and more auto-tools were used. Eventually, I limited the auto-tools as players began creating giant farms with 20+ auto-sieves.
Unfortunately, limiting the auto-tools alone wasn't enough. The minimum value for the clock ICs was 5, which meant a clock would run 4 times per second, or the same speed as a 1-tick clocks. I raised this limit to 10, meaning a clock IC would only run 2 times per second at the fastest. This helped a bit more, but there were just too many clocks.
Finally, I limited the clocks to a certain number per-island. This was done after the reset and it helped quite a bit. I even got around to adding in code that would search a chunk's tile-entities for signs that matched the Clock ICs when the chunk was loaded and would remove the clock if there were too many.
Alas, even this effort was in vain as the TPS continued to drop once more. Eventually I decided that no clock would be efficient enough to power the auto-tools and took on the rather daunting task of re-coding my auto-tools to run by themselves.
To give you a small idea of how much work was involved, I had to move the code out of the dispense event and into a custom function. From there, I had to create a scheduled task in an aSync thread (so it wouldn't run in the same thread as the main server functions), which should prevent them from ever lagging the server. Afterward, I created several functions to handle adding and removing auto-tools to/from a concurrent hashmap (basically a list), which stored all of their locations and the region names they were in. Then I created some listeners to add or remove the auto-tools to/from the lists on certain events, like when a chunk loads/unloads, when the block is powered/unpowered by redstone, when the auto-tool is created, when a player adds items to its inventory, when hoppers/droppers add items to its inventory, etc., etc. At this point, I was able to create some basic logic to handle safety checks, ensuring the auto-tools disabled/enabled properly and were properly limited per-island region. As of right now, the class file that handles the auto-tools is 834 lines long and contains 31,409 characters. It took me about 2 days to do this.
What does this all mean? It means the auto-tools fire only when they need to. If the inventory is empty, it shuts off. If the chunk is unloaded, it shuts off. If it's broken, it shuts off. If it doesn't have the right item in its inventory, it shuts off. Etc., etc. In addition, the code for the Clock ICs from Craftbook would be executed every 2 ticks (10 times per second), while my code for the auto-tools executes every 60 ticks (3 seconds) for the miners, 200 ticks (10 seconds) for the placers, and 3000 ticks (2.5 minutes) for the fishers. In other words, my plugin runs much less often and the code only executes for the auto-tools that are actually functioning. Using the clock ICs mean that code would run, regardless of whether the auto-tool was even working, 10 times per second.
Lastly, in addition to making my auto-tools completely automatic, I raised the think-ticks for the CraftBook ICs from 2 to 10. This means that things like ranged collectors and auto-crafters will run once per second, instead of 10 times per second. This has lowered the CPU usage of CraftBook by 700%.
To put it in perspective how much more efficient my code is; CraftBook's clocks would use 40-60% of the server's resources. My auto-tools use 0.12%. That's less than 1%. My entire plugin, including the auto-tools, uses 1% of the CPU.
- The auto-miners, auto-placers, and auto-fishers are now actually automatic. They no longer require redstone clocks.
- Clock ICs (MC1421) are disabled due to lag.
Additionally, you can disable the auto-tools by providing them with a redstone signal. This is useful if you're collecting items in a chest. You can use a comparator with the chest to detect when it's full. In case you don't know how, here's a quick tutorial:
Place a comparator next to the chest, facing away from it. Place a lever two blocks away from the side of the comparator (either side). Connect the lever to the side of the comparator with redstone dust. Flip the lever on. The comparator will now only emit a signal when the chest is full. Run redstone from the front of the comparator to the auto-tool. Now when the chest is full, the comparator will emit a signal and power the auto-tool. Once the auto-tool receives power, it'll stop running. This will keep items from falling all over the ground and your tools from getting used up. =)