Corrupted Chunks?

Discussion in 'Plugin Development' started by SycoPrime, Mar 8, 2011.

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

    SycoPrime

    Blegh, had the whole thing typed out and hit back button, eating my post.
    I'll be brief: There is something wrong with MoveCraft. It has been broken since Beta 1.3.
    The issue seems to be that when traveling in to certain chunks, the craft becomes deformed and disappears. In my tests, I have found that it seems the craft is slowly eaten away at one of its dimensions (X or Z) as it enters the "zone". It always seems to be on the edge line of a chunk.
    It is difficult to test, because it seems it may not be the entire chunk, but only a certain vertical space, and even then, once found and tested, reloading the world removes the glitchiness from the area.

    I have isolated the following code to report on the problem, though whether it's the cause, or merely a victim, I've yet to be able to determine. It is a snippet from the move function in the Craft class, and only slightly different from the latest git commit:
    Code:
    // scan to know if any of the craft blocks are now missing (blocks removed, TNT damage, creeper ?)
            // and update the structure
            for (int x = 0; x < sizeX; x++) {
                for (int y = 0; y < sizeY; y++) {
                    for (int z = 0; z < sizeZ; z++) {
                        int craftBlockId = matrix[x][y][z];
    
                        // remove blocks from the structure if it is not there anymore
                        if (craftBlockId != -1 && craftBlockId != 0
                                && !(craftBlockId >= 8 && craftBlockId <= 11)) {
    
                            //int blockId = world.getBlockAt(posX + x, posY + y, posZ + z).getTypeId();
                            int blockId = getWorldBlock(x, y, z).getTypeId();
    
                             // regenerate TNT on a bomber
                            if (craftBlockId == 46 && type.bomber)
                                continue;
    
                            // block is not here anymore, remove it
                            if (blockId == 0 || blockId >= 8 && blockId <= 11) {
                                // air, water, or lava
                                if (waterType != 0 && y <= waterLevel)
                                    matrix[x][y][z] = 0;
                                else
                                    matrix[x][y][z] = -1; // make a hole in the craft
    
                                blockCount--;
                                MoveCraft.instance.DebugMessage("Removing a block of type " + craftBlockId + 
                                        " because of type " + blockId);
                            }
                        }
                    }
                }
            }
    The code in question calls this function, which essentially is a wrapper of sorts for Block.setTypeId:
    Code:
        public void setBlock(int id, Block block) {
            if (id < 0 || id > 255) {
                // MoveCraft.logger.log(Level.SEVERE, "Invalid setBlock : id=" + id
                // + " x=" + x + " y=" + y + " z=" + z);
                MoveCraft.logger.log(Level.SEVERE, "Invalid setBlock : id=" + id);
                System.out.println("Invalid block type ID. Begin panic.");
                return;
            }
            if (block.setTypeId(id) == false)
                System.out.println("Could not set block type ID. This is very bad, indeed.");
        }
     
  2. Offline

    Raphfrk

    One (annoying) option would be to do a binary search to see if you can isolate the commit that caused it. However, that doesn't work if it has been broken since 1.3 was implemented (and suggests something more fundamental).

    Another option would be to see if you can detect the error.

    The method:

    world.getBlockTypeId(x,y,z)

    bypasses the cache. Maybe after the craft is moved, you could scan the craft using that method to see if the craft has moved properly. You could also try to scan the craft using world.getBlockAt().getTypeId() and see if they give the same answer.
     
  3. Offline

    SycoPrime

    You're incredibly helpful, as always. And since I've been making sarcastic posts lately, I unfortunately feel the need to stress that I'm not being sarcastic in saying that.
    I didn't understand the first part (binary searching git commits), but I am 99% certain it had to do with a change in how things are handled from a minecraft / craftbukkit standpoint, and is not an error that came about from a change in my code, but rather something I'm doing that became an incompatibility.

    I will, however, attempt to do that bypass the cache part. That sounds promising.
     
  4. Offline

    Raphfrk

    I mean pick find a commit where it works and one where it doesn't and then test the commit that is midway between the 2. If that fails, then you know that the offending commit is before that point.

    However, if that is "upgrade to 1.3", then it doesn't help much. I guess you could test before and after the 1.3 upgrade and see if that is the change.

    Tha cache is in Bukkit so if it is a problem with the server, then it won't make much difference.
     
  5. Offline

    Myers Carpenter

  6. Offline

    SycoPrime

    Thank you for pointing that out. I'm frankly not exactly sure? I don't think I understand my problem well enough to know.
    I can't say with any degree of honesty that I understand what is happening.
    Before, chunks would not allow me to enter. When I tried to test if it was all sides of a chunk, it turned out to be all chunks in a line.
    Today, I encounter the issue again (just when I thought it was gone, too!), and rather than sticking around until I restart the server, it goes away after a few minutes.
    The very nature of the bug, what it exists in, boggles my mind completely.

    This is the elaborated setBlock function I was running. The line about "I tried to fix it" showed up at what appeared to be once per block for the side of the craft that was entering the chunk, but other than that the console reported nothing.
    Code:
    public void setBlock(int id, Block block) {
            if (id < 0 || id > 255) {
                System.out.println("Invalid block type ID. Begin panic.");
                return;
            }
    
            if(block.getTypeId() == id) {
                System.out.println("Tried to change a " + id + " to itself.");
                return;
            }
    
            if (block.setTypeId(id) == false) {
                if(world.getBlockAt(block.getLocation()).setTypeId(id) == false)
                    System.out.println("Could not set block of type " + block.getTypeId() +
                            " to type " + id + ". I tried to fix it, but I couldn't.");
                else
                    System.out.println("I hope to whatever God you believe in that this fix worked.");
            }
        }
    Each time it fired, it was 0 (air) to 42 (iron), no glass (20).

    Also, I don't think it's something about local cache, since I've found the issue in freshly generated chunks (new world, moving linearly), and in worlds fresh on a server start that have had no occasion to unload the chunks.
    Unless chunk load / unload only happens when changes are made to them, in which case I understand the way the server works less than I thought I did.
     
  7. Offline

    Raphfrk

    Most of that is consistent with the issue.

    Chunks load and unload in a line (mostly). Each player is surrounded by a square of chunks. If you move forward from one chunk to another, a line of chunks will load and another will unload.

    Weak chunk references are queued for removal by the garbage collector. When that happens, CraftChunk will auto-relink the chunk.

    What might be worth trying to to use VMware to watch heap memory. When GC happens, it will drop down. You could see if that is the moment when the chunk fixes itself. It might take 2 GC cycles.

    When you say moving linearly, presumably mean that you never moved back to a place you already were? Hmm, that can't really be explained.
     
Thread Status:
Not open for further replies.

Share This Page