Irrelon / ige

The Isogenic Game Engine
525 stars 140 forks source link

Got "Undefined" when trying to retrieve an entity by its ID over the network. #249

Closed Firnael closed 11 years ago

Firnael commented 11 years ago

Hi,

On the my ServerNetworkEvents I go like this :

_onPlayerEntity: function (data, clientId) {

    var self = ige.server;
    if(!self._players[clientId]){
        self._players[clientId] = new Character(clientId)
            .addComponent(PlayerComponent)
            .id('player_' + clientId)
            .setType(0)
            .drawBounds(false)
            .drawBoundsData(false)
            .isometric(true)
            .translateTo(0, 0, 0)
            .streamMode(1)
    }
    ige.network.send('playerEntity', self._players[clientId].id(), clientId);
    ige.server.log("onPlayerEntity"+self._players[clientId].id());
}

When I receive the message on my client, I would like to get my entity (the player) and mount it on my tilemap :

_onPlayerEntity: function (data) {

    if (ige.$(data)) {
        ige.$(data).mount(ige.client.tileMap1);
        ige.client.vp1.camera.lookAt(ige.$(data));
        ige.client.vp1.camera.trackTranslate(ige.$(data), 50);
    }
    else {
        var self = this;
        self._eventListener = ige.network.stream.on('entityCreated', function (entity) {
            if (entity.id() === data) {
                // Tell the camera to track out player entity
                ige.$(data).mount(ige.client.tileMap1);
                ige.client.vp1.camera.lookAt(ige.$(data));
                ige.client.vp1.camera.trackTranslate(ige.$(data), 50);

                // Turn off the listener for this event now that we
                // have found and started tracking our player entity
                ige.network.stream.off('entityCreated', self._eventListener, function (result) {
                    if (!result) {
                        this.log('Could not disable event listener!', 'warning');
                    }
                });
            }
        });
    }
}

But when I log the " ige.$(data)" part, it says "undefined". Did I miss something about getting the entoty by its ID over the network ?

Thanks in advance.

Irrelon commented 11 years ago

If it is undefined that means the entity does not exist on the client. I couldn't see where you were logging ige.$(data)... are you doing it in the correct place? Remember that just because you create an entity on the server and set it's stream mode so it will stream, doesn't mean it will be instantly created on the client. Other network messages can arrive before streaming for an entity has started.

The reason you can't log ige.$(data) immediately is probably because you need to wait for it to be created on the client in the "self._eventListener = ige.network.stream.on('entityCreated', function (entity) {" function. Have you tried logging in there once the entity has been received by the client?

Firnael commented 11 years ago

I removed the logging lines to make it clearer. Here's what I have :

_onPlayerEntity: function (data) {

    if (ige.$(data)) {
        ige.$(data).mount(ige.client.tileMap1);
        ige.client.vp1.camera.lookAt(ige.$(data));
        ige.client.vp1.camera.trackTranslate(ige.$(data), 50);
    }
    else {
        var self = this;

        console.log("First log");

        self._eventListener = ige.network.stream.on('entityCreated', function (entity) {
            if (entity.id() === data) {

                console.log("Second log");
                ige.$(data).mount(ige.client.tileMap1);
                ige.client.vp1.camera.lookAt(ige.$(data));
                ige.client.vp1.camera.trackTranslate(ige.$(data), 50);

                ige.network.stream.off('entityCreated', self._eventListener, function (result) {
                    if (!result) {
                        this.log('Could not disable event listener!', 'warning');
                    }
                });
            }
        });
    }

The first log appears, but the second never shows up.

Irrelon commented 11 years ago

Hey, are you setting streamMode on the entity you are expecting to be sent to clients?

On 28 March 2013 11:38, Firnael notifications@github.com wrote:

I removed the logging lines to make it clearer. Here's what I have :

_onPlayerEntity: function (data) {

if (ige.$(data)) {
    ige.$(data).mount(ige.client.tileMap1);
    ige.client.vp1.camera.lookAt(ige.$(data));
    ige.client.vp1.camera.

trackTranslate(ige.$(data), 50); } else { var self = this;

    console.log("First log");

    self._eventListener = ige.network.stream.on('entityCreated', function (entity) {
        if (entity.id() === data) {

            console.log("Second log");
            ige.$(data).mount(ige.client.tileMap1);
            ige.client.vp1.camera.lookAt(ige.$(data));
            ige.client.vp1.camera.trackTranslate(ige.$(data), 50);

            ige.network.stream.off('entityCreated', self._eventListener, function (result) {
                if (!result) {
                    this.log('Could not disable event listener!', 'warning');
                }
            });
        }
    });
}

The first log appears, but the second never shows up.

— Reply to this email directly or view it on GitHubhttps://github.com/coolbloke1324/ige/issues/249#issuecomment-15584003 .

Firnael commented 11 years ago

Here is how I create my entity :

_onPlayerEntity: function (data, clientId) {

    var self = ige.server;
    if(!self._players[clientId]) {
        self._players[clientId] = new Character(clientId)
            .addComponent(PlayerComponent)
            .id('player_' + clientId)
            .setType(0)
            .drawBounds(false)
            .drawBoundsData(false)
            .isometric(true)
            .translateTo(0, 0, 0)
            .streamMode(1)
    }
    ige.network.send('playerEntity', self._players[clientId].id(), clientId);
    ige.server.log("onPlayerEntity"+self._players[clientId].id());
}

The streamMode(1) attribute should be enough to set the entity streaming property right ?

Irrelon commented 11 years ago

Can you paste your console log from your client and then in a separate post, the one from your server?

I'd like to see the startup logs.

Firnael commented 11 years ago

Server logs :

IGE log [IgeBox2dComponent] : Physics component initiated! IGE log [IgeBox2dComponent] : World created IGE log [IgeNetIoComponent] : Network component initiated with Net.IO version: 1.0.0 IGE log [IgeNetIoComponent] : Starting net.io listener on port 2000 IGE log [IgeNetIoComponent] : Starting client/server clock sync... IGE log [NetIo.Server] : Server is listening on port 2000 IGE log [IgeEngine] : Starting engine... IGE log [IgeEngine] : Engine started IGE log [IgeStreamComponent] : Setting delta stream interval to 120ms IGE log [IgeStreamComponent] : Starting delta stream... IGE log [IgeNetIoComponent] : Server now accepting connections! IGE log [NetIo.Server] : Client connecting... IGE log [IgeNetIoComponent] : Accepted connection with id 2a58e37f4612c20 Login request received { username: 'bob123', password: 'moo123' } Sending login accepted... IGE log [Server] : onPlayerEntity id : player_2a58e37f4612c20

Client logs :

IGE log [IgeNetIoComponent] : Network component initiated with Net.IO version: 1.0.0 IgeClass.js:85 IGE log [IgeBox2dComponent] : Physics component initiated! IgeClass.js:85 IGE log [IgeBox2dComponent] : World created [...](texture loading) IGE log [IgeEngine] : All textures have loaded IgeClass.js:85 IGE log [IgeInputComponent] : Setting up input event listeners... IgeClass.js:85 IGE log [IgeEngine] : Starting engine... IgeClass.js:85 IGE log [IgeEngine] : Engine started IgeClass.js:85 IGE log [IgeNetIoComponent] : Connecting to net.io server at "http://localhost:2000"... IgeClass.js:85 IGE log [NetIo.Client] : Net.io client starting... IgeClass.js:85 IGE log [NetIo.Client] : Connecting to server at http://localhost:2000 IgeClass.js:85 IGE log [IgeNetIoComponent] : Connected to server! IgeClass.js:85 IGE log [IgeNetIoComponent] : Received network command list with count: 12 IgeClass.js:85 IGE log [Client] : Server accepted our login request... IgeClass.js:85 IGE log [Client] : Starting game... IgeClass.js:85 IGE log [Client] : Map data received... IgeClass.js:85 entity id cote client : player_2a58e37f4612c20

I wonder if I have to mount the entity server side before sending it to the client. Because in the examples, the entity is mounted on the tilemap server-side before being sent.

Irrelon commented 11 years ago

Hey ya,

Basically the engine is a scenegraph... think of it like a tree with lots of branches and each branch can have more branches. If you don't attach a branch to the tree then it is not part of the tree at all. That is the same for mounting so yes, you definitely need to mount the entity before it is processed.

If you imagine, when you create an entity it is just a bit of data in memory, the engine doesn't know about it at all... will not process it, will not stream it etc. Only if you add it to the engine by mounting it to the scenegraph will it know about the entity and process it each engine tick.

:)

Hope that helps to clarify a bit how the engine works. Let me know if mounting it does the trick.

Firnael commented 11 years ago

Alright, that's what we thought. Here is the tree we have client-side :

ige (IgeEntity) => vp1 (IgeViewport) ==> mainScene (IgeScene) ===> gameScene (IgeScene) ===> backDrop (IgeEntity) ===> tileMap1 (IgeTileMap2d) ==> uiScene (IgeScene)

It's basically the one on the example. We want to mount the entity on tileMap1

Do we have to reproduce the exact same tree server side to be able to mount the entity on it, then process it over the network ? I find it strange to have a viewport on the server.

Firnael commented 11 years ago

I got this error : "Cannot mount non-existent object!"

I don't understand, I'm using the .mount() method of an object, it can't not exist Oo

Irrelon commented 11 years ago

Gotta shoot of out of the office for a while so just firing this link at you: http://www.isogenicengine.com/documentation/isogenic-game-engine/versions/1-1-0/manual/networking-multiplayer/realtime-network-streaming/

You should find all you need in there. You have to pass an object to mount to in the mount() call!

On 28 March 2013 14:33, Firnael notifications@github.com wrote:

I got this error : "Cannot mount non-existent object!"

I don't understand, I'm using the .mount() method of an object, it can't not exist Oo

— Reply to this email directly or view it on GitHubhttps://github.com/coolbloke1324/ige/issues/249#issuecomment-15591614 .

Irrelon commented 11 years ago

Do we have to reproduce the exact same tree server side to be able to mount the entity on it, then process it over the network ? I find it strange to have a viewport on the server.

The scenes and viewport all need to exist on the server AND the client. It might seem strange to need a viewport on the server-side but consider that it is part of the scenegraph and the engine has to process server-side trees just like the client so in order to maintain consistency the viewport needs to exist on the server too.

Basically when you are copying an example, the code in there is not accidental, if you pull something out of an example and change it you should test the change first since the system may depend on it! :)