示例#1
0
 protected override void ProcessServerMessage(MessageType mt, Stream stm, Node n)
 {
     if (mt == MessageType.PLAYER_VALIDATOR_ASSIGN)
     {
         Guid       remoteActionId = Serializer.Deserialize <Guid>(stm);
         PlayerInfo info           = Serializer.Deserialize <PlayerInfo>(stm);
         PlayerData pd             = Serializer.Deserialize <PlayerData>(stm);
         OnPlayerValidateRequest(n, remoteActionId, info, pd);
     }
     else if (mt == MessageType.WORLD_VALIDATOR_ASSIGN)
     {
         Guid             remoteActionId = Serializer.Deserialize <Guid>(stm);
         WorldInitializer init           = Serializer.Deserialize <WorldInitializer>(stm);
         OnWorldValidateRequest(n, remoteActionId, init);
     }
     else if (mt == MessageType.NEW_PLAYER_REQUEST_SUCCESS)
     {
         PlayerInfo info = Serializer.Deserialize <PlayerInfo>(stm);
         OnNewPlayerRequestApproved(info);
     }
     else
     {
         throw new Exception("Client.ProcessServerMessage bad message type " + mt.ToString());
     }
 }
示例#2
0
 void OnWorldValidateRequest(Node n, Guid actionId, WorldInitializer init)
 {
     all.AddWorldValidator(init);
     //Log.LogWriteLine("Validating for world {0}", info.worldPos);
     //myHost.SendMessage(serverHost, MessageType.ACCEPT, actionId);
     RemoteAction.Sucess(n, actionId);
 }
示例#3
0
    public void EndGame()
    {
        CardGameVariables oponent = GetOponent(CardGameInitializer.playerName);
        var story = StoryManager.GetSingleton();

        story.SetInt("player_money", players[0].money);
        story.SetInt(oponent.oponentMoneyStore, players[1].money);
        WorldInitializer.LoadWorld(CardGameInitializer.returnPoint ?? new MapPath("default", "default"), CardGameInitializer.returnKnot);
    }
示例#4
0
    public WorldDraw(WorldInitializer init, bool isOwnedByUs, Action <Guid, GameObject> updateCamera, Action <WorldDraw> onDestruction)
        : base(init, null)
    {
        this.updateCamera  = updateCamera;
        this.onDestruction = onDestruction;
        sz = World.worldSize;

        walls = new Plane <GameObject>(sz);
        loots = new Plane <GameObject>(sz);

        foreach (Point pos in Point.Range(sz))
        {
            ITile t = this[pos];
            if (t.Solid)
            {
                PlaceBlock(pos);
            }
            else if (t.Loot)
            {
                GameObject loot = GameObject.CreatePrimitive(PrimitiveType.Quad);
                loots [pos] = loot;

                loot.transform.localScale    = new Vector3(.5f, .5f, 1);
                loot.renderer.material.color = Color.blue;
                loot.transform.position      = minecraft.GetPositionAtGrid(Position, pos);
                loot.transform.rotation      = Quaternion.AngleAxis(15f, UnityEngine.Random.onUnitSphere);
                loot.AddComponent <RotateSlowly>();
            }
        }

        background = GameObject.CreatePrimitive(PrimitiveType.Quad);
        background.transform.localScale = new Vector3(sz.x, sz.y, 1);
        background.transform.position   = minecraft.GetPositionAtGrid(Position, new Point(0, 0)) + new Vector3(sz.x - 1, sz.y - 1, 1) / 2;
        if (isOwnedByUs)
        {
            background.renderer.material.color = new Color(.6f, .6f, .6f);
        }
        else
        {
            background.renderer.material.color = new Color(.7f, .7f, .7f);
        }

        MessBackground();

        foreach (PlayerInfo inf in GetAllPlayers())
        {
            AddPlayer(inf);
        }
    }
示例#5
0
        public void WorldInit(WorldInitializer init)
        {
            if (!ValidateWorldInfo(init.info))
            {
                return;
            }

            MyAssert.Assert(world == null);

            world = data.generateWorld(init);
            foreach (WorldInfo inf in world.GetKnownNeighbors())
            {
                data.recordWorldInfo(inf);
            }
        }
示例#6
0
 protected override void ProcessWorldMessage(MessageType mt, Stream stm, Node n, WorldInfo inf)
 {
     if (mt == MessageType.WORLD_VAR_INIT)
     {
         WorldInitializer wrld = Serializer.Deserialize <WorldInitializer>(stm);
         OnNewWorldVar(wrld);
     }
     else if (mt == MessageType.WORLD_VAR_CHANGE)
     {
         ForwardFunctionCall ffc = ForwardFunctionCall.Deserialize(stm, typeof(World));
         worlds.At(inf.position).WorldAction(ffc, inf);
     }
     else
     {
         throw new Exception(Log.StDump(mt, inf, "unexpected"));
     }
 }
示例#7
0
 protected override void ProcessWorldMessage(MessageType mt, Stream stm, Node n, WorldInfo inf)
 {
     if (mt == MessageType.NEW_WORLD_REQUEST)
     {
         Point worldPos = Serializer.Deserialize <Point>(stm);
         OnNewWorldRequest(worldPos, null, 0);
     }
     else if (mt == MessageType.WORLD_HOST_DISCONNECT)
     {
         WorldInitializer w = Serializer.Deserialize <WorldInitializer>(stm);
         OnWorldHostDisconnect(w);
     }
     else
     {
         throw new Exception(Log.StDump("bad message type", mt));
     }
 }
示例#8
0
    private BlockType[] getNeighbourBlocks(int x, int y, int z)
    {
        int3 offset = InfiniteWorld.ChunkWorldPositionOffset;

        int3 arrayBasedChunkPos = new int3(chunkPosWorld.x - offset.x, chunkPosWorld.y - offset.y, chunkPosWorld.z - offset.z);



        BlockType x_minus;
        BlockType x_plus;

        BlockType y_minus;
        BlockType y_plus;

        BlockType z_minus;
        BlockType z_plus;

        int3 key;


        //Xminus
        if (x - 1 >= 0)
        {
            x_minus = blocks[x - 1, y, z].blockType;
        }
        else
        {
            key = new int3(arrayBasedChunkPos.x - 1, arrayBasedChunkPos.y, arrayBasedChunkPos.z);
            if (WorldInitializer.chunkArrayContainsKey(key))
            {
                x_minus = WorldInitializer.chunkArray[key.x, key.y, key.z].blocks[CONST.chunkSize.x - 1, y, z].blockType;
            }
            else
            {
                x_minus = BlockType.Air;
            }
        }

        //Xplus
        if (x + 1 <= CONST.chunkSize.x - 1)
        {
            x_plus = blocks[x + 1, y, z].blockType;
        }
        else
        {
            key = new int3(arrayBasedChunkPos.x + 1, arrayBasedChunkPos.y, arrayBasedChunkPos.z);
            if (WorldInitializer.chunkArrayContainsKey(key))
            {
                x_plus = WorldInitializer.chunkArray[key.x, key.y, key.z].blocks[0, y, z].blockType;
            }
            else
            {
                x_plus = BlockType.Air;
            }
        }


        //Yminus
        if (y - 1 >= 0)
        {
            y_minus = blocks[x, y - 1, z].blockType;
        }
        else
        {
            key = new int3(arrayBasedChunkPos.x, arrayBasedChunkPos.y - 1, arrayBasedChunkPos.z);
            if (WorldInitializer.chunkArrayContainsKey(key))
            {
                y_minus = WorldInitializer.chunkArray[key.x, key.y, key.z].blocks[x, CONST.chunkSize.y - 1, z].blockType;
            }
            else
            {
                y_minus = BlockType.Air;
            }
        }

        //Yplus
        if (y + 1 <= CONST.chunkSize.y - 1)
        {
            y_plus = blocks[x, y + 1, z].blockType;
        }
        else
        {
            key = new int3(arrayBasedChunkPos.x, arrayBasedChunkPos.y + 1, arrayBasedChunkPos.z);
            if (WorldInitializer.chunkArrayContainsKey(key))
            {
                y_plus = WorldInitializer.chunkArray[key.x, key.y, key.z].blocks[x, 0, z].blockType;
            }
            else
            {
                y_plus = BlockType.Air;
            }
        }


        //Zminus
        if (z - 1 >= 0)
        {
            z_minus = blocks[x, y, z - 1].blockType;
        }
        else
        {
            key = new int3(arrayBasedChunkPos.x, arrayBasedChunkPos.y, arrayBasedChunkPos.z - 1);
            if (WorldInitializer.chunkArrayContainsKey(key))
            {
                z_minus = WorldInitializer.chunkArray[key.x, key.y, key.z].blocks[x, y, CONST.chunkSize.z - 1].blockType;
            }
            else
            {
                z_minus = BlockType.Air;
            }
        }

        //Zplus
        if (z + 1 <= CONST.chunkSize.z - 1)
        {
            z_plus = blocks[x, y, z + 1].blockType;
        }
        else
        {
            key = new int3(arrayBasedChunkPos.x, arrayBasedChunkPos.y, arrayBasedChunkPos.z + 1);
            if (WorldInitializer.chunkArrayContainsKey(key))
            {
                z_plus = WorldInitializer.chunkArray[key.x, key.y, key.z].blocks[x, y, 0].blockType;
            }
            else
            {
                z_plus = BlockType.Air;
            }
        }


        BlockType[] neighbours = new BlockType[6];

        neighbours[0] = x_minus;
        neighbours[1] = x_plus;

        neighbours[2] = y_minus;
        neighbours[3] = y_plus;

        neighbours[4] = z_minus;
        neighbours[5] = z_plus;

        return(neighbours);
    }
示例#9
0
    private void zdir(float dirz)
    {
        GameObject placeHolder;

        if (dirz >= 1)
        {
            for (int iter = 0; iter < dirz; iter++)
            {
                for (int x = 0; x < arraySize.x; x++)
                {
                    for (int y = 0; y < arraySize.y; y++)
                    {
                        placeHolder = boxColliderGOs[x, y, 0];
                        for (int z = 0; z < arraySize.z - 1; z++)
                        {
                            boxColliderGOs[x, y, z] = boxColliderGOs[x, y, z + 1];
                        }

                        placeHolder.transform.position = new Vector3(
                            placeHolder.transform.position.x,
                            placeHolder.transform.position.y,
                            placeHolder.transform.position.z + arraySize.z);



                        int xa = Mathf.CeilToInt(placeHolder.transform.position.x) - 1;
                        int ya = Mathf.CeilToInt(placeHolder.transform.position.y) - 1;
                        int za = Mathf.CeilToInt(placeHolder.transform.position.z) - 1;


                        //Vector3 chunkcoords = new Vector3(0, 0, 0);
                        int3 chunkcoords = new int3(0, 0, 0);
                        int3 blockcoords = new int3(0, 0, 0);

                        int3 offset = InfiniteWorld.ChunkWorldPositionOffset;

                        /*
                         * chunkcoords.x = Mathf.CeilToInt(((float)xa / (float)chunkSize.x - (float)offset.x)) - 1;
                         * chunkcoords.y = Mathf.CeilToInt(((float)ya / (float)chunkSize.y - (float)offset.y)) - 1;
                         * chunkcoords.z = Mathf.CeilToInt(((float)za / (float)chunkSize.z - (float)offset.z)) - 1;
                         */
                        chunkcoords.x = xa / chunkSize.x - offset.x;
                        chunkcoords.y = ya / chunkSize.y - offset.y;
                        chunkcoords.z = za / chunkSize.z - offset.z;

                        //Debug.Log(xa + " " + chunkcoords.x + " " + chunkSize.x + " " + offset.x);
                        if (WorldInitializer.chunkArrayContainsKey(chunkcoords))
                        {
                            blockcoords.x = xa % chunkSize.x;
                            blockcoords.y = ya % chunkSize.y;
                            blockcoords.z = za % chunkSize.z;



                            if (blockcoords.x < 0)
                            {
                                blockcoords.x = chunkSize.x - Math.Abs(blockcoords.x);

                                chunkcoords.x -= 1;
                            }

                            if (blockcoords.y < 0)
                            {
                                blockcoords.y  = chunkSize.y - Math.Abs(blockcoords.y);
                                chunkcoords.y -= 1;
                            }

                            if (blockcoords.z < 0)
                            {
                                blockcoords.z  = chunkSize.z - Math.Abs(blockcoords.z);
                                chunkcoords.z -= 1;
                            }

                            if (chunkcoords.x < 0 || chunkcoords.y < 0 || chunkcoords.z < 0)
                            {
                                placeHolder.GetComponent <BoxCollider>().enabled = false;
                            }
                            else
                            {
                                blockTypes[x, y, arraySize.z - 1] = WorldInitializer.chunkArray[chunkcoords.x, chunkcoords.y, chunkcoords.z].
                                                                    blocks[blockcoords.x, blockcoords.y, blockcoords.z].blockType;

                                if (blockTypes[x, y, arraySize.z - 1] != BlockType.Air)
                                {
                                    placeHolder.GetComponent <BoxCollider>().enabled = true;
                                }
                                else
                                {
                                    placeHolder.GetComponent <BoxCollider>().enabled = false;
                                }
                            }
                        }
                        else
                        {
                            placeHolder.GetComponent <BoxCollider>().enabled = false;
                        }

                        boxColliderGOs[x, y, arraySize.z - 1] = placeHolder;
                    }
                }
            }
        }

        if (dirz <= -1)
        {
            for (int iter = 0; iter > dirz; iter--)
            {
                for (int y = 0; y < arraySize.y; y++)
                {
                    for (int x = 0; x < arraySize.x; x++)
                    {
                        placeHolder = boxColliderGOs[x, y, arraySize.z - 1];
                        for (int z = arraySize.z - 1; z > 0; z--)
                        {
                            boxColliderGOs[x, y, z] = boxColliderGOs[x, y, z - 1];
                        }

                        placeHolder.transform.position = new Vector3(
                            placeHolder.transform.position.x,
                            placeHolder.transform.position.y,
                            placeHolder.transform.position.z - arraySize.z);



                        int xa = Mathf.CeilToInt(placeHolder.transform.position.x) - 1;
                        int ya = Mathf.CeilToInt(placeHolder.transform.position.y) - 1;
                        int za = Mathf.CeilToInt(placeHolder.transform.position.z) - 1;


                        int3 chunkcoords = new int3(0, 0, 0);
                        int3 blockcoords = new int3(0, 0, 0);

                        int3 offset = InfiniteWorld.ChunkWorldPositionOffset;

                        /*
                         * chunkcoords.x = Mathf.CeilToInt(((float)xa / (float)chunkSize.x - (float)offset.x)) - 1;
                         * chunkcoords.y = Mathf.CeilToInt(((float)ya / (float)chunkSize.y - (float)offset.y)) - 1;
                         * chunkcoords.z = Mathf.CeilToInt(((float)za / (float)chunkSize.z - (float)offset.z)) - 1;
                         */
                        chunkcoords.x = xa / chunkSize.x - offset.x;
                        chunkcoords.y = ya / chunkSize.y - offset.y;
                        chunkcoords.z = za / chunkSize.z - offset.z;

                        if (WorldInitializer.chunkArrayContainsKey(chunkcoords))
                        {
                            blockcoords.x = xa % chunkSize.x;
                            blockcoords.y = ya % chunkSize.y;
                            blockcoords.z = za % chunkSize.z;

                            if (blockcoords.x < 0)
                            {
                                blockcoords.x  = chunkSize.x - Math.Abs(blockcoords.x);
                                chunkcoords.x -= 1;
                            }

                            if (blockcoords.y < 0)
                            {
                                blockcoords.y  = chunkSize.y - Math.Abs(blockcoords.y);
                                chunkcoords.y -= 1;
                            }

                            if (blockcoords.z < 0)
                            {
                                blockcoords.z  = chunkSize.z - Math.Abs(blockcoords.z);
                                chunkcoords.z -= 1;
                            }

                            if (chunkcoords.x < 0 || chunkcoords.y < 0 || chunkcoords.z < 0)
                            {
                                placeHolder.GetComponent <BoxCollider>().enabled = false;
                            }
                            else
                            {
                                blockTypes[x, y, 0] = WorldInitializer.chunkArray[chunkcoords.x, chunkcoords.y, chunkcoords.z].
                                                      blocks[blockcoords.x, blockcoords.y, blockcoords.z].blockType;
                                //Debug.Log(chunkcoords.x + " " + chunkcoords.y + " " + chunkcoords.z);
                                //Debug.Log(blockcoords.x + " " + blockcoords.y + " " + blockcoords.z);
                                if (blockTypes[x, y, 0] != BlockType.Air)
                                {
                                    placeHolder.GetComponent <BoxCollider>().enabled = true;
                                }
                                else
                                {
                                    placeHolder.GetComponent <BoxCollider>().enabled = false;
                                }
                            }
                        }
                        boxColliderGOs[x, y, 0] = placeHolder;
                    }
                }
            }
        }
    }
示例#10
0
    void Start()
    {
        int x = Mathf.CeilToInt(transform.position.x) - 1;
        int y = Mathf.CeilToInt(transform.position.y) - 1;
        int z = Mathf.CeilToInt(transform.position.z) - 1;

        //Debug.Log(x);

        playerLastFrameBlock = new Vector3(x, y, z);

        for (int xa = 0; xa < arraySize.x; xa++)
        {
            for (int ya = 0; ya < arraySize.y; ya++)
            {
                for (int za = 0; za < arraySize.z; za++)
                {
                    blockPositions[xa, ya, za] = new Vector3(
                        xa + loopStartPos.x + x - 0.5f,
                        ya + loopStartPos.y + y + 0.5f,
                        za + loopStartPos.z + z - 0.5f);

                    int ccx = xa + loopStartPos.x + x;
                    int ccy = ya + loopStartPos.y + y;
                    int ccz = za + loopStartPos.z + z;

                    int3 chunkcoords = new int3(0, 0, 0);
                    int3 blockcoords = new int3(0, 0, 0);

                    int3 offset = InfiniteWorld.ChunkWorldPositionOffset;

                    chunkcoords.x = ccx / chunkSize.x - offset.x;
                    chunkcoords.y = ccy / chunkSize.y - offset.y;
                    chunkcoords.z = ccz / chunkSize.z - offset.z;

                    boxColliderGOs[xa, ya, za] = new GameObject();
                    boxColliderGOs[xa, ya, za].AddComponent <BoxCollider>();
                    BoxCollider boxCollider = boxColliderGOs[xa, ya, za].GetComponent <BoxCollider>();
                    boxCollider.enabled = false;
                    boxColliderGOs[xa, ya, za].transform.position = blockPositions[xa, ya, za];



                    if (WorldInitializer.chunkArrayContainsKey(chunkcoords))
                    {
                        blockcoords.x = ccx % chunkSize.x;
                        blockcoords.y = ccy % chunkSize.y;
                        blockcoords.z = ccz % chunkSize.z;

                        blockTypes[xa, ya, za] = WorldInitializer.chunkArray[chunkcoords.x, chunkcoords.y, chunkcoords.z].
                                                 blocks[blockcoords.x, blockcoords.y, blockcoords.z].blockType;

                        if (blockTypes[xa, ya, za] != BlockType.Air)
                        {
                            boxCollider.enabled = true;
                        }
                    }
                    else
                    {
                        blockTypes[xa, ya, za] = BlockType.Air;
                    }
                }
            }
        }
    }
    private static List <Chunk> zdirFunction(int zdir, int3 offset)
    {
        List <Chunk> chunksToBeDrawn = new List <Chunk>();

        if (zdir >= 1)
        {
            for (int i = 0; i < zdir; i++)
            {
                ChunkWorldPositionOffset.z += 1;
                for (int x = 0; x < worldChunkSize.x; x++)
                {
                    for (int y = 0; y < worldChunkSize.y; y++)
                    {
                        for (int z = 0; z < worldChunkSize.z; z++)
                        {
                            if (z == 0)
                            {
                                //MeshGeneration.AddToRemoveQueue(WorldInitializer.chunkArray[x, y, z]);
                                MeshGeneration.AddToRemoveQueue(WorldInitializer.getChunk(x, y, z));

                                //ThreadPool.QueueUserWorkItem(new WaitCallback(WorldInitializer.chunkArray[x, y, z + 1].AddChunkDrawdataToMeshQueue));
                            }
                            else if (z == worldChunkSize.z - 1)
                            {
                                int3 pos = new int3(x + ChunkWorldPositionOffset.x, y + ChunkWorldPositionOffset.y, z + ChunkWorldPositionOffset.z);

                                WorldInitializer.setChunk(x, y, z, new Chunk(pos, offset));
                                if (!WorldInitializer.getChunk(x, y, z).anyNonAir)
                                {
                                    continue;
                                }
                                chunksToBeDrawn.Add(WorldInitializer.getChunk(x, y, z));

                                //ThreadPool.QueueUserWorkItem(new WaitCallback(WorldInitializer.chunkArray[x, y, z].AddChunkDrawdataToMeshQueue));

                                //ThreadPool.QueueUserWorkItem(new WaitCallback(WorldInitializer.chunkArray[x, y, z - 1].AddChunkDrawdataToMeshQueue));
                            }
                            else
                            {
                                //chunks[x, y, z] = chunks[x, y, z + 1];
                                WorldInitializer.setChunk(x, y, z, WorldInitializer.getChunk(x, y, z + 1));
                            }
                        }
                    }
                }
            }
        }
        else if (zdir <= -1)
        {
            for (int i = 0; i > zdir; i--)
            {
                ChunkWorldPositionOffset.z -= 1;
                for (int x = worldChunkSize.x - 1; x >= 0; x--)
                {
                    for (int y = worldChunkSize.y - 1; y >= 0; y--)
                    {
                        for (int z = worldChunkSize.z - 1; z >= 0; z--)
                        {
                            if (z == (worldChunkSize.z - 1))
                            {
                                //MeshGeneration.AddToRemoveQueue(WorldInitializer.chunkArray[x, y, z]);
                                MeshGeneration.AddToRemoveQueue(WorldInitializer.getChunk(x, y, z));


                                //ThreadPool.QueueUserWorkItem(new WaitCallback(WorldInitializer.chunkArray[x, y, z - 1].AddChunkDrawdataToMeshQueue));
                            }
                            else if (z == 0)
                            {
                                int3 pos = new int3(x + ChunkWorldPositionOffset.x, y + ChunkWorldPositionOffset.y, z + ChunkWorldPositionOffset.z);
                                WorldInitializer.setChunk(x, y, z, new Chunk(pos, offset));
                                if (!WorldInitializer.getChunk(x, y, z).anyNonAir)
                                {
                                    continue;
                                }
                                chunksToBeDrawn.Add(WorldInitializer.getChunk(x, y, z));
                                //ThreadPool.QueueUserWorkItem(new WaitCallback(WorldInitializer.chunkArray[x, y, z].AddChunkDrawdataToMeshQueue));
                                //ThreadPool.QueueUserWorkItem(new WaitCallback(WorldInitializer.chunkArray[x, y, z + 1].AddChunkDrawdataToMeshQueue));
                            }
                            else
                            {
                                //chunks[x, y, z] = chunks[x, y, z - 1];
                                WorldInitializer.setChunk(x, y, z, WorldInitializer.getChunk(x, y, z - 1));
                            }
                        }
                    }
                }
            }
        }
        return(chunksToBeDrawn);
    }
示例#12
0
        void OnNewWorldVar(WorldInitializer wrld)
        {
            Point pos = wrld.info.position;

            worlds.At(pos).WorldInit(wrld);
        }
示例#13
0
 public void AddWorldValidator(WorldInitializer init)
 {
     MyAssert.Assert(!worldValidators.ContainsKey(init.info.position));
     worldValidators.Add(init.info.position, new WorldValidator(init, host, myClient.GetServer()));
 }
示例#14
0
 void OnWorldHostDisconnect(WorldInitializer w)
 {
     //Log.Dump(mt, w.info);
     worlds.Remove(w.info.position);
     OnNewWorldRequest(w.info.position, w.world, w.info.generation + 1);
 }
示例#15
0
        void OnNewWorldRequest(Point worldPos, WorldSerialized ser, int generation)
        {
            if (worlds.ContainsKey(worldPos))
            {
                Log.Dump(worldPos, "world alrady present");
                return;
            }

            if (!validatorPool.Any())
            {
                throw new Exception("no validators!");
            }

            ManualLock <Point> lck = new ManualLock <Point>(worldLocks, worldPos);

            if (!lck.Locked)
            {
                Log.Dump(worldPos, "can't work, locked");
                return;
            }

            string hostName = "host world " + worldPos;

            if (generation != 0)
            {
                hostName = hostName + " (" + generation + ")";
            }
            OverlayEndpoint validatorHost = new OverlayEndpoint(validatorPool.Random(n => r.Next(n)), new OverlayHostName(hostName));

            WorldInitializer init;
            WorldInfo        newWorld;
            bool             hasSpawn = false;

            if (ser == null)
            {
                WorldSeed seed = new WorldSeed(r.Next(), RandomColor(worldPos));

                if (serverSpawnDensity == 0)
                {
                    if (worldPos == Point.Zero)
                    {
                        hasSpawn = true;
                    }
                }
                else if ((worldPos.x % serverSpawnDensity == 0) && (worldPos.y % serverSpawnDensity == 0))
                {
                    hasSpawn = true;
                }

                newWorld = new WorldInfo(worldPos, validatorHost, generation, hasSpawn);
                init     = new WorldInitializer(newWorld, seed);
            }
            else
            {
                hasSpawn = ser.spawnPos.HasValue;
                newWorld = new WorldInfo(worldPos, validatorHost, generation, hasSpawn);
                init     = new WorldInitializer(newWorld, ser);
            }


            OverlayEndpoint validatorClient = new OverlayEndpoint(validatorHost.addr, Client.hostName);

            RemoteAction
            .Send(Host, validatorClient, ProcessClientDisconnect, MessageType.WORLD_VALIDATOR_ASSIGN, init)
            .Respond(remoteActions, lck, (res, stm) =>
            {
                if (res != Response.SUCCESS)
                {
                    throw new Exception(Log.StDump("unexpected", res));
                }

                //if (hasSpawn == true)
                //    spawnWorlds.Add(worldPos);

                worlds.Add(newWorld.position, newWorld);

                //Log.LogWriteLine("New world " + worldPos + " validated by " + validatorHost.addr);

                foreach (Point p in Point.SymmetricRange(Point.One))
                {
                    if (p == Point.Zero)
                    {
                        continue;
                    }

                    Point neighborPos = p + newWorld.position;

                    if (!worlds.ContainsKey(neighborPos))
                    {
                        continue;
                    }

                    WorldInfo neighborWorld = worlds[neighborPos];

                    MessageWorld(neighborWorld, MessageType.NEW_NEIGHBOR, newWorld);
                    MessageWorld(newWorld, MessageType.NEW_NEIGHBOR, neighborWorld);
                }
            });
        }