Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
He's right in the youtube comment - even though it's 3.8 sec, it's still a drop in the tick rate, which is what he wanted to avoid. And we can't. Right now there's no way to split the paste job up into smaller units that could be laid out over multiple ticks.
Posts: 4,628
Threads: 115
Joined: Dec 2011
Thanks: 693
Given 494 thank(s) in 423 post(s)
If we'd create an API in WorldEdit that allows you to execute a string using loadstring, a plugin could override cBlockArea:Write to set an X amount of blocks instead of the whole lot.
Posts: 3
Threads: 0
Joined: Jun 2015
Thanks: 0
Given 0 thank(s) in 0 post(s)
Hi everyone.
NiLSPACE contacted me on youtube regarding WorldEdit for Cuberite. I took the liberty of looking at WorldEdit's source code. It looks like it would be possible to make it lag free. All you need to do is (I assume that commands in Cuberite are executed in the main thread same as in Bukkit):
1. Fork the command to a new thread
2. Store all block changes
3. Place the changed block in packages from a task thats running on the main thread.
In addition you also need to provide a safe way to read the world from non main thread.
Posts: 3
Threads: 0
Joined: Jun 2015
Thanks: 0
Given 0 thank(s) in 0 post(s)
Ok I understand that its fast and it works directly on chunks (btw. NiLSPACE thats what I'm currently adding to AsyncWorldEdit). What I said was for global WorldEdit operations not only the paste operation. You have a lock while writing to the world and that causes lag.
<< IF COMMANDS ARE EXECUTED IN A NEW THREAD IGNORE THIS >>
You can also experience lag while you load the schematic into the object (or are the commands done in a different thread?). C++ is fast and there is no doubt about it but still you need to consider the IO operations while reading the file, therefore you might experience tps drop when you load the schematic into memory.
Regarding the block placing, thats exactly what I had in mind. You need to place the blocks in chunks, not all at once. Its best if you do it one by one adding a delay between each place to allow other threads world access.
Posts: 783
Threads: 12
Joined: Jan 2014
Thanks: 2
Given 73 thank(s) in 61 post(s)
For us, the easiest way to ensure delays would be to use the scheduleTask function. You can schedule all the tasks ahead of time, and execute them in n tasks spread over m ticks. As for spliting up into chunks, it would be more efficient to create a write overload that allows writing of part of a blockarea. It would be relatively easy to add to the server.
Posts: 3
Threads: 0
Joined: Jun 2015
Thanks: 0
Given 0 thank(s) in 0 post(s)
Ok now I c. how it works and what you can and can't do using the current API. In my opinion you should add additional classes to the server API (and do not touch underlying logic!) that are used for threading. The plugins don't need to be multi-thread in the basic mode but if someone wants to use multi-threading allow it! If something fails its his/hers problem.
What classes I would add:
cLock --> simple mutex. It allows read write synchronization point
cReaderWritterLock -> a more complex mutex that allows single writer access or multiple readers
cSemaphore -> a multi thread barrier that allows X clients to enter into the critical section
cThreadPool -> a class that allows you to run a method in a new thread,
The bare minimum: cLock and a method to allow to tun a method on a new thread.
If you do not have any threading you will be able to implement the async mode to WorldEdit similar to first release of AsyncWorldEdit. The world editing is done in chunks (stage 2) and the blocks preparation (stage 1) is done on the main thread. This is ok for 75% of all situations, but its not enough for extremely large edits. Don't get me wrong because you are using C++ as the base it will work for much larger edits then in Bukkit/Spigot.