2
\$\begingroup\$

I am building a 2d top down multiplayer mmo. very lightweight.

a note on architecture

I am using Unity as an engine, I have a backend Nodejs/socket.io websockets server. and a main Master client that defines what target monsters have, where people and NPCs are positioned in the world and who gets hit by projectiles etc so everyone is in agreement. Thing seem to be working pretty well. But I have thing weird problem where if I have 1 monster it works perfectly. However as I add more monsters to the game messages like for example (Enemy is moving) Get transmitted in the command promt as many times as there are monsters. Whats worse, if I delete those monsters through code (see below) the server still sends messages based on the amount of monsters that ever existed. until I restart the master client and normal client and start over. at which point itll reset everything.

I have been going over my code a great deal and cannot find the problem really. and could use a little help.

server code

    // Section for Enemy logic from Master Client


   socket.on('enemyRegister', function(data){

        // builds a monster on the client

   socket.broadcast.emit('enemyRegister', data);  



    socket.on('enemyMove', function(data){

        // moves the monster that matches the given ID

        console.log('enemy is moving', data);

    socket.broadcast.emit('enemyMove', data);

    });

    socket.on('enemyStopMove', function(data){

        // stops the monster that matches the given ID

        console.log('enemy stopped moving', data);

    socket.broadcast.emit('enemyStopMove', data);

    });

    socket.on('enemyTarget', function(data){

    // feeds a 'target' data string to the monster that matches the given ID

    console.log('setting target', data);

    socket.broadcast.emit('enemyTarget', data);

});

    socket.on('enemyLoseTarget', function(data){

    // remove a 'target' data string to the monster that matches the given ID

    console.log('removing target', data);

    socket.broadcast.emit('enemyLoseTarget', data);

});

    socket.on('enemyShoot', function(data){

     // Plays 'shoot' animation on the monster that matches the given ID   

    console.log('shooting on', data);

    socket.broadcast.emit('enemyShoot', data);

});


    socket.on('enemyMelee', function(data){

     // Plays 'hit' animation on the monster that matches the given ID   

    console.log('melee hit on', data);

    socket.broadcast.emit('enemyMelee', data);

});

    socket.on('hitPlayer', function(data){

     // Send damage information 
        var something = players[data.playerId];

        console.log('sending info to ', something.socketID);

    socket.broadcast.to(something.socketID).emit('hitPlayer', data);
});

    socket.on('deleteAllEnemies', function(data){

     // Deletes All enemies   

    console.log('deleting all enemies');

    socket.broadcast.emit('deleteAllEnemies');

});


    });

Master client enemy creation

    void Update () {

        if (Input.GetKeyDown("i"))
        {
            CreateMonster();
        }

    if (Input.GetKeyDown("o"))
    {
        foreach(KeyValuePair<string, Vector3> enemy in spawnedEnemies)
        {
            var thisEnemy = GameObject.Find(enemy.Key);
            Destroy(thisEnemy);

        }
        spawnedEnemies.Clear();
        mobNumber = 0;
        socket.Emit("deleteAllEnemies");

    }
}

void CreateMonster()
{
    var selectedSpawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];  // create a variable, 

    selectedSpawnPoint.transform.position = new Vector3(Random.Range(0, 10), Random.Range(0,10), 0);

    var spawnedEnemy = Instantiate(Enemy[Random.Range(0, Enemy.Length)], selectedSpawnPoint.transform.position, selectedSpawnPoint.transform.rotation);

    spawnedEnemy.name = "enemy " + mobNumber;
    mobNumber++;

    spawnedEnemies.Add(spawnedEnemy.name, spawnedEnemy.transform.position);

    numberOfMonsters = spawnedEnemies.Count;

    socket.Emit("enemyRegister", Network.MobIdAndLocationToJson(spawnedEnemy.name, spawnedEnemy.transform.position));
}

}

normal client enemy spawning code

    public void SpawnEnemy(SocketIOEvent e)
{
        var id = e.data["id"].str;
        var spawnPosition = new Vector3(e.data["x"].n, e.data["y"].n, 0);
        var enemy = Instantiate(orcShaman, spawnPosition, Quaternion.identity) as GameObject;

        enemy.name = id;
        enemies.Add(id, enemy);
}

code for deleting all enemies on client

    public void DeleteAll() // TODO Delete Before Launch
{
    foreach (KeyValuePair<string, GameObject> enemy in enemies)
    {
        var thisEnemy = GameObject.Find(enemy.Key);
        Destroy(thisEnemy);
    }
    enemies.Clear();
}

Any guidance or a push in the right direction would be greatly appreciated im at a loss as to what the issue could be. The server does not store an array of the monsters, only the master client does and the normal client do that. so I dont understand how the server is trying to send information for each monster that has been created. specially when the actions acctually come out correct in game.

thank you for reading.

\$\endgroup\$
2
\$\begingroup\$

Figured out the problem:

it was a remnant from a previous build in which I was trying to store all enemy data in variables and was not closing the registration of enemies properly:

changed

       socket.on('enemyRegister', function(data){

        // builds a monster on the client

   socket.broadcast.emit('enemyRegister', data); 

to

       socket.on('enemyRegister', function(data){

        // builds a monster on the client

   socket.broadcast.emit('enemyRegister', data); 

});

and its fixed. Silly mistake but maybe it could help someone some day.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.