Workaround for the teleport "black hole" problem.

Discussion in 'Plugin Development' started by Uberman, Dec 29, 2011.

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

    Uberman

    I have, I think, found a code solution to the "black hole" (a.k.a., "missing chunk") issue with the player teleport command. I've had this active on my server all day, and the black holes are gone. Apologies if this has already been found/posted here.

    The trick is fairly simple: just to get the server to load in the chunk before the user teleports to the location. I am doing this by having the server access a block at the location, thus forcing that chunk into memory before the player arrives. In code, it's just this:

    Code:
    ...
    
    World w = player.getWorld();
    org.bukkit.Location block_loc = new org.bukkit.Location(w, loc.getX(), loc.getY() - 5, loc.getZ());
    Block b = w.getBlockAt(block_loc);
    b.getTypeId();
    
    
    if(player.teleport(loc))
    {
            ...
    The only reason I've got the getTypeId() call in there is so that 'b' is not flagged as unused.

    Hope this helps somebody out. :)
     
  2. Offline

    immac636

    Wait... If this was for teleporting a player to another player, wouldn't this be redundant? Or is it for warping?
     
  3. Offline

    paalbra

    Why not just:
    Code:java
    1. Chunk c = loc.getChunk();
    2. if (!c.isLoaded())
    3. c.load();
    4. player.teleport(loc);

    You might also wanna check the value returned by load() depending on what the location actually is.
    E.g. if you have a command /tp x y z, you might not want a player to be able to teleport to a location which hasn't been generated.
     
  4. Offline

    mindless728

    @paalbra i think you actually need to give the server some time to actually load the chunk, only a few server ticks, so the actual teleporting needs to be done as a delayed task, or, if i remember correctly, the chunk won't have time to reload
     
  5. Offline

    bergerkiller

    @paalbra The second bit is not needed:
    Code:
    if (!c.isLoaded()) c.load();
    Since loc.getChunk() already loads the chunk if it can't find it.

    And nope, it's not needed to wait a tick. Everything is synchronized, so it will load the chunk and then teleport the player.

    NoLagg simply adds a delay between player connecting and chunk sending, this way you don't even have to load the chunk: NoLagg does that for you :)
     
  6. Offline

    paalbra

    Oh. That's not a behavior that i would expect and might not be the wanted behavior. The docs dosn't really say much:
    http://jd.bukkit.org/apidocs/org/bukkit/Location.html#getChunk()

    But as i previously posted you might not want a player to be able to teleport to a chunk that isn't generated.

    I've looked a bit around in the docs and found that this function would be the one to use:
    http://jd.bukkit.org/apidocs/org/bukkit/World.html#loadChunk(int, int, boolean)

    So your code would be something like:
    Code:java
    1. World w = player.getWorld();
    2. boolean gen = w.loadChunk(loc.getBlockX(), loc.getBlockY(), false);
    3. if (gen)
    4. player.teleport(loc);
    5. else
    6. // Do not teleport since the chunk hasn't been generated

    But this would of course depend on the behavior you want :)
     
  7. Offline

    codename_B

    BananaChunk fixes that (and still works)
     
Thread Status:
Not open for further replies.

Share This Page