Would this cause lag?

Discussion in 'Plugin Development' started by MrZoraman, Jul 21, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    MrZoraman

    My friend wants me to make him a plugin that would make his map stay in nighttime 24/7. If I ran a scheduler that set the time to nighttime every tick or so, would this cause lag?. I think I would want to do it as fast as possible so that it gives the effect that the moon isn't moving.

    I was just thinking something like this:
    Code:
    World world = Bukkit.getWorld("world");
       
        public void setNight()
        {
            world.setTime(20000);
        }
       
        Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable()
        {
            public void run()
            {
                setNight();
            }
        }, 1L, 1L);
    There are probably some things very wrong with that code. I don't know if I'm even using the scheduler right or if I'm breaking some major rule or something. It won't let me set the time in the run(), but I feel like I'm just sneaking my away around that by making a method to do it. Am I taking a wrong approach to this?
     
  2. Offline

    ZeusAllMighty11

    Why are you trying to make it night every tic? Why not just every time the sun is about to start coming up?
     
  3. Offline

    MrZoraman

    So it would look like the moon isn't moving
     
  4. Offline

    p000ison

    Yep this will cause lag :p
    Im very sure
     
  5. Why are you that sure?
     
    ZeusAllMighty11 likes this.
  6. Offline

    McLuke500

    Because it's changing the time 20 times a second. I would do it every minute or 30 seconds.
     
  7. So changing the time 20x/second is causing lag cause you're changing the time 20x/second? This is the best explanation ever... If you would say it forces the server to send a packet to every player 20x/second that's something we could start talking about, but then I would tell you that plugins like TheDarkness do the same but don't even use a scheduler for it. They just use player.setPlayerTime() and similar functions... And they don't cause lag...

    So again p000ison and McLuke500 Why are you that sure?
     
  8. Offline

    MrZoraman

    alright. How many ticks are in night?
     
  9. Offline

    McLuke500

    It would be better to use a longer time to have the world always nighttime Enless you ment you wanted the time to stay the exact same...
     
  10. time updates are send every second to the client (i believe it was that delay, not sure) so if you set the time every second, the effect may be the same as now, even whitout the more lagg from more than 1 time setting the time
     
  11. It would be better != the other way would automatically cause lag. Also he wants the time to stay exactly the same. The more time passes between the time resetting the more likely you have a glitchy moon.

    MrZoraman Just use the scheduler, but make it a bit better:
    Code:java
    1. public class TimeFreezer implements Runnable
    2. {
    3. private final String world; //Save the worlds name instead of the world.
    4. private int pid;
    5.  
    6. public TimeFreezer(World world)
    7. {
    8. this.world = world.getName();
    9. }
    10.  
    11. public void setPid(int pid)
    12. {
    13. this.pid = pid;
    14. }
    15.  
    16. public void run()
    17. {
    18. World world = Bukkit.getWorld(this.world); //Get the world from the name
    19. if(world == null) //If it's null (a plugin like multiworld unloaded it, for example)...
    20. Bukkit.getScheduler().cancelTask(pid); //...stop the task
    21. else
    22. world.setTime(18000L);
    23. }
    24. }

    Then call it like this:
    Code:java
    1. TimeFreezer tf = new TimeFreezer(world);
    2. tf.setPid(Bukkit.getScheduler().scheduleSyncRepeatingTask(this, tf, 0L, 1L));

    I don't think this will cause lag.

    Sorry for not using the edit, but it would delete the spaces at the code example and I'm to lazy to re-add them atm.

    MrZoraman you could also profile it like this:
    Code:java
    1. public class TimeFreezer implements Runnable
    2. {
    3. private final String world; //Save the worlds name instead of the world.
    4. private int pid;
    5.  
    6. private long runningTime = 0L;
    7. private short counter = 0;
    8.  
    9. public TimeFreezer(World world)
    10. {
    11. this.world = world.getName();
    12. }
    13.  
    14. public void setPid(int pid)
    15. {
    16. this.pid = pid;
    17. }
    18.  
    19. public void run()
    20. {
    21. long start = System.getCurrentTimeMillis();
    22. World world = Bukkit.getWorld(this.world); //Get the world from the name
    23. if(world == null) //If it's null (a plugin like multiworld unloaded it, for example)...
    24. Bukkit.getScheduler().cancelTask(pid); //...stop the task
    25. else
    26. world.setTime(18000L);
    27. runningTime += System.getCurrentTimeMillis() - start;
    28.  
    29. if(++counter == 20) //Do the following every 20 ticks, so every second
    30. {
    31. System.out.print("Running time in 1 second: "+runningTime+"ms.");
    32. counter = 0;
    33. runningTime = 0L;
    34. }
    35. }
    36. }

    To see if it may cause lag. But I'll bet you wont get higher than 20ms/second, so no measurable lag.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
    MrZoraman likes this.
  12. Offline

    MrZoraman

    Thank you! I learned a bit from your example. So Why would I save the world name instead of the world?
     
  13. Cause the world can unload but if you would still holding the world object the GC couldn't remove it from ram -> memory leak. Also you may get weird errors if you try to set the time in a unloaded world.
     
    TheButlah and ferrybig like this.
  14. Offline

    MrZoraman

    OH that makes sense. I'd take that I wouldn't want to do that with the Player object either?

    Edit: Oh it looks like it says so in ferrybig's signature.
     
  15. Right. Whenever you store a world, a block, a player, ... over time (so for more than one tick) use a reference and get it from there later. In case of a world and a player you can simply use the name, in case of a block, a location, ... use the world name and the x, y and z coordinates (for a location the yaw and pitch, too, if needed). Then you're save from memory leaks and/or weird errors that occur if you operate on a object that changed or doesn't exist anymore.
     
  16. Offline

    MrZoraman

    Thank you! Man now I should probably comb through all of my plugins and fix that. I wish I had known that sooner. I guess it should have been intuitive. Now I feel like a noob :p . Thanks again for your help!
     
  17. Offline

    p000ison

    Because sending the double amount of packages each tick isnt that good: https://github.com/Bukkit/CraftBukk...a/org/bukkit/craftbukkit/CraftWorld.java#L436

    So bukkit sends the packet each tick. And when you set the time it send another one.
     
  18. Offline

    Briggybros

    12000
     
  19. p000ison Well, in fact minecraft sends a time update only each second: https://github.com/Bukkit/CraftBukk...et/minecraft/server/MinecraftServer.java#L537 So updating the time every tick would send 20x more packages.
    But I still don't believe that this would cause lag. But if you want to underline your statement that it would feel free to use the code I posted here and profile it.

    //EDIT: http://pastie.org/4304950 - If 0-4 ms for 20 executions and 2 players online is lag for you... It would be measurable lag if it would be > 20ms, but still no feelable lag as a tick is 20 ms so 20 ms in 20 ticks would be 1ms/tick...

    //EDIT²: This measuring was performed while the machine (not the MC server) was under heavy load, so chances are high that the Java process was putted to sleep to allow the other CPU hungry processes to run. A new measuring doesn't go any higher than 1ms...
     
Thread Status:
Not open for further replies.

Share This Page