11.) MMO From Scratch - Iron Mines & Ground Items

Results 1 to 10 of 10
  1. #1
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    11.) MMO From Scratch - Iron Mines & Ground Items


    RaGEZONE Recommends

    RaGEZONE Recommends

    Previous (Inventory)
    Table of Contents (Introduction)
    Next (Coming Soon)

    In the last tutorial I complained about how I implemented inventory and coupled it to herbs. Today, we'll make some changes to the inventory and to the Slire Herb system, and we'll also implement two new features: Iron Mines and ground items.

    The Server
    I decided how I was going to implement every new game object. Basically, m.game.objects will be an object containing, well, game objects. Every game object will have it's own file. We already had one made for herbs, but I also made one for iron mines.In the objects extension, I'll manually add these game objects much like I do with plugins on the client. Update: In the objects extension, the files will be automatically shoved into the m.game.objects object.

    Each game object will have 2 special properties: class and instance. The class property is assigned to the class for that object. For example, the herbs game object has a property 'class', that points to the Herbs class. Of course this is JavaScript so technically Herbs isn't a class, but whatever Herbs is, it's assigned to the class property. The instance property is assigned null, and is meant to be a place for an instance of the class property to sit on. I created a helper function named setupGameObj(obj, objClass) to set up these two properties for us.
    /private/extensions/objects.js
    Code:
    "use strict";
    var Herbs = require('./objects/herbs.js');
    var IronMines = require('./objects/ironMines.js');
    
    function setupGameObj (obj, objClass) {
        Object.defineProperties(obj, {
            "class": {
                value: objClass,
                writable: false,
                configurable: false,
                enumerable: false
            },
            "instance": {
                value: null,
                writable: true,
                configurable: false,
                enumerable: false
            }
        });
    }
    
    module.exports = function (m) {
        m.game.objects = {
            herbs: {},
            ironMines: {}
        };
        setupGameObj(m.game.objects.herbs, Herbs);
        setupGameObj(m.game.objects.ironMines, IronMines);
    };
    Hm.. I just noticed something. It should be possible to preload and automatically set up these game objects. So, I'll go a step further and do that now.
    Code:
    "use strict";
    function setupGameObj (obj, objClass) {
        Object.defineProperties(obj, {
            "class": {
                value: objClass,
                writable: false,
                configurable: false,
                enumerable: false
            },
            "instance": {
                value: null,
                writable: true,
                configurable: false,
                enumerable: false
            }
        });
    }
    module.exports = function (m) {
        var dir = m.fs.readdirSync('./private/extensions/objects');
        var index, objName;
        m.game.objects = {};
        for (index in dir) {
            if (dir[index].match(/[a-z]\.js/)) {
                objName = dir[index].substr(0, dir[index].indexOf('.'));
                m.game.objects[objName] = {};
                setupGameObj(m.game.objects[objName], require('./objects/' + dir[index]));
            }
        }
        console.log("Set up game objects:", m.game.objects);
    };
    There. Now anytime we make a .js file in the /private/extensions/objects directory, it will be automatically shoved into the m.game.objects object. It should be noted that the file doesn't have to end with .js, the match is satisfied if it see's a lower-case letter followed by '.js' anywhere in the filename. So a file named 'herbs0.js' or 'herbs_.js' or 'herbs_OLD.js' will be ignored, and a folder or non-JavaScript file named 'thisIsNot.jsFile' will be imported. The error thrown by the require function from an invalid module will crash the server more/less immediately after it's started, so this isn't a big deal to me. Further, the solution is to name things nicely, so I consider the side effect a feature rather than a known bug.

    Moving on.

    I coded /private/extensions/objects/IronMines.js very much the same way I coded /private/extensions/objects/herbs.js. I did have different needs though. Herbs are supposed to be created and deleted often, where iron mines are pretty much stationary. A player can't take an iron mine off of the map, nor may a player place one onto the map. This may be a feature for admins later down the road, but I can just as easily open up a mongo shell and create iron mines manually. Iron mines do need to be updated often, though. I decided on a 10 second replenishing time for now. I also decided Iron Mines should have a fixed amount of iron bits they can contain. I put this number at 128 for now. So every 10 seconds, the iron mine accumulates 1 additional iron bit. Once the iron mine accumulates 128 iron bits, it cannot produce any more until it is mined.

    I wrote this code in /private/extensions/objects/mines/iron.js. Everytime the iron mine runs an interval that adds an iron bit, it calls a callback function. The IronMines class uses this callback to tell MongoDB to update that mine in the DB, and it also forwards this information to a self.cycleCallback. Like the Herbs class, IronMines requires a callback as the second argument, that is assigned to self.cycleCallback. Also like Herbs, self.cycleCallback may be changed at anytime after instantiation during the lifetime of the program.

    I entered a mongo shell and created an iron mine:
    Code:
    db.mines.insert({name: 'iron', place: [300, 300], bits: 0});
    Someday in the future, I'll have more metals/minerals to mine in this game. In the first version I want to release, the only type of mine will be an iron mine. This schema is intended to be future-compatible.

    Now that we have an iron mine, I really want to get it on the game canvas! Before we can do that, we need to create a channel to send this mine at (300, 300) to the client. So I created a file named /private/channels/mines.js to communicate with the client.

    It didn't take me long to figure out that I was checking if the state was 4 in just about every socket emition. Wherever I wasn't checking if it was state 4, it was most-likely an error. So I went into /private/extensions/socket.js and added a method to the session called state4Broadcast. It will cycle through every connection, check if the state is 4, and if so will emit the packet.

    After I got that sorted out, I updated the herbs channel to use state4Broadcast instead of system events, and I feel much better about the style now. Events are cool and all, but I was using them for the wrong reasons in respect to herb operations. Then I went back to my /private/channels/mines.js file and continued working.

    The users interact with mines to get iron bits- and that's it. So I added a socket event listener for 'iron-mined', that takes the id of the mine they attempted to mine from. I check that the state is 4 and that the iron mine with that ID actually exists, and I then check if the player is close enough to that mine to interact with it. Finally, I check if it was possible to add iron to the user's inventory, and if so I subtract the iron.bits by 1, and tell the mines instance about the change. Whether the iron bit was added to the inventory successfully or not, I send an update to all of the clients using my fancy new state4Broadcast emitter.

    To ship the iron mines to the clients, I listen on the session's 'game-ready' event, and send the client all of the mines, tagged 'mines-init' . To tell the client when an iron mine's amount of iron bits changes, I send an 'iron-updated' emit using state4Broadcast.

    Then, I was compelled to move the inventory to it's very own channel. So I created /private/channels/inventory.js. In the last tutorial I put the inventory communications in the herbs channel, but now I needed to generalize items a little bit. So I created 2 socket listeners- 'item-placed' and 'item-picked'. I also created a server-side groundItems object. For now, I decided not to store groundItems in the DB, but I will almost certainly use the DB for them later. A ground item has a schema like this:
    Code:
    {
        _id: <String: unique identifier>, 
        name: <String: item name>, 
        place: <Array:Int(2): coordinates of ground item>
    }
    The switch to a database will rely on the exact same schema, so little code should need to be changed. There is 1 condition at the moment, that will most certainly need to be changed once I add more herbs. I check if the name is 'slire', and if so I run the 'herb-planted' system event. When an herb is placed on the map, it needs to became an Herb instance so it can reproduce and be alive. Every other item at the moment isn't alive once it's placed.. Well, we only have iron bits and herbs right now.. Anyway, at some point I need to have a more educated mapping system that will determine what items should do when they are placed.

    When a ground item is picked up, we check if the user is close enough to the item, is state 4, if the item really exists, if the user has inventory space, etc etc- then delete the ground item from the server's list and use our fancy state4Broadcast function to tell all the other users the item was removed. If the item couldn't be removed, then we tell the client who tried to pick it up that the item was created- as the client will optimistically destroy the ground item before it receives confirmation from the server.

    That about sums it up for the server changes this round. Now let's see what I did to get mining and ground items working on the client!

    The Client
    On the client we update /public/js/inventory.js to work for more general items, rather than only slire herbs. I then create a file, /public/js/objects/mines.js. It works very much the same as /public/objects/herbs.js does in the last tutorial. The difference is, instead of removing the sprite from the game canvas when adding iron to the inventory, we just leave the sprite alone. I did make one condition for the appearance of the sprite, though. If there are 0 iron bits in the mine, I tint the sprite to a darker color to indicate that the mine has been exhausted. As soon as bits are available, the sprite is restored to a normal tint.

    I used clever naming of files to get the inventory working for iron bits. The sprite for an iron mine is in /public/assets/game/ironrock.png. In the items folder- which is where the inventory grabs the image for items in the inventory, the name of the image is iron.png. Since the name of the mine is also iron, it works great. In order for ground items to work, though, we must create a plugin for them. So I created a file named /public/js/objects/groundItems.js.

    Ground items must be initialized when the user first enters the game, and then may be placed/picked up by any player by clicking on them. Like anything else, the player must be close to a ground item in order to pick it up. The same rules do not apply for placing items- and that is a bug in the game we will soon fix.

    Previous (Inventory)
    Table of Contents (Introduction)
    Next (Coming Soon)
    Last edited by s-p-n; 2 Weeks Ago at 06:38 PM.


  2. #2
    Deep thoughts 11.) MMO From Scratch - Iron Mines &amp; Ground Items Joopie is offline
    Alpha MaleRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,596Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    I like to read your progress, keep it going!

    I looked at your demo but I was not able to walk arround, it was jumping me back to the previous position.

  3. #3
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Quote Originally Posted by Joopie View Post
    I like to read your progress, keep it going!

    I looked at your demo but I was not able to walk arround, it was jumping me back to the previous position.
    Interesting, may I ask what browser you were testing in? Or if you got any errors in the console/network logs?

  4. #4
    Deep thoughts 11.) MMO From Scratch - Iron Mines &amp; Ground Items Joopie is offline
    Alpha MaleRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,596Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Quote Originally Posted by s-p-n View Post
    Interesting, may I ask what browser you were testing in? Or if you got any errors in the console/network logs?
    The latest version of Chrome (Versie 48.0.2564.109 m (64-bit)).

    Console log:
    Spoiler:
    Code:
    VM1949:4 status: Object {status: "Processing Login.."}
    io.js:26 content: Object {selector: "#canvas", html: "<script>↵if (window.gameObj === void 0) {↵    window.….log(gameObj);↵initializeGame(gameObj);↵</script>"}
    VM1954:6 Object {}
    phaser.min.js:11    Phaser v2.4.4 | Pixi.js v2.2.9 | Canvas | WebAudio     http://phaser.io ♥♥♥
    herbs.js:34 got herbs init:
    herbs.js:35 Object {56bba39f66c750e52ccefa97: Object, 56bba45766c750e52ccefad4: Object, 56bbaa5ce7ba31862d928588: Object, 56bbaa5ce7ba31862d928589: Object, 56bbaa5de7ba31862d92858a: Object…}
    groundItems.js:31 Ground items init: Object {}
    mines.js:43 got mines init:
    mines.js:44 Object {56bb953d52bf8ea4c2979203: Object}
    others.js:78 got other update Object {username: "foo", game: Object}
    others.js:55 queue size: 1
    others.js:19 moving to:  Object {x: 287.5, y: 227.5}
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c58865e7ba31862d9287ac
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c58822e7ba31862d9287a6
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c56ed3e7ba31862d9287a2
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c5885be7ba31862d9287ab
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c5881ee7ba31862d9287a5
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c58828e7ba31862d9287a8
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c55f76e7ba31862d928799
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c58826e7ba31862d9287a7
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c56e96e7ba31862d9287a0
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c58828e7ba31862d9287a9
    main.js:19 is close? true
    herbs.js:47 herb deleted
    herbs.js:48 56c58829e7ba31862d9287aa
    player.js:96 steps: 1 0
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 107
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 104
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 104
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 113
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 104
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 107
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 106
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 106
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 104
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 107
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 111
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 104
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 106
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 112
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 117
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 104
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 112
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 113
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 105
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 109
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 112
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 110
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 108
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 110
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 114
    player.js:162 player-move: Object {x: 250, y: 250, inventory: Array[2]}
    player.js:165 lag: 110

  5. #5
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Hm. It appears the server never accepted your move. I'll start working on a better way to log things so I can figure out what happened next time. Right now I'm just baffled. It could be a "moving too fast" error, but that's purely speculation.

  6. #6
    Fuck. SheenBR is offline
    ModeratorRank
    Feb 2008 Join Date
    Jaú, BrazilLocation
    2,391Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    It doesn't work for me either, cant move. firefox 44.0.2
    Spoiler:

    Code:
    content: Object { selector: "#canvas", html: "<style> #loginContainer {     position…" } io.js:26:3
    Campos de senha presentes em uma página insegura (http://). Este é um risco de segurança que permite que credenciais de login do usuário sejam roubadas.[Saiba mais] <desconhecido>
    Campos de senha presentes em um formulário que será enviado a uma página insegura (http://). Este é um risco de segurança que permite que credenciais de login do usuário sejam roubadas.[Saiba mais] <desconhecido>
    action: login Array [ Object, Object, Object ] io.js:18:1
    status: Object { status: "Processing Login.." } jquery.js line 2 > eval:4:3
    status: Object { status: "(1) No Bueno.", code: 1 } jquery.js line 2 > eval:4:3
    action: login Array [ Object, Object, Object ] io.js:18:1
    status: Object { status: "Processing Login.." } jquery.js line 2 > eval:4:3
    status: Object { status: "(1) No Bueno.", code: 1 } jquery.js line 2 > eval:4:3
    action: login Array [ Object, Object, Object ] io.js:18:1
    status: Object { status: "Processing Login.." } jquery.js line 2 > eval:4:3
    status: Object { status: "(3) Unable to find user.", code: 3 } jquery.js line 2 > eval:4:3
    status: Object { status: "Processing Registration.." } jquery.js line 2 > eval:4:3
    content: Object { selector: "#canvas", html: "<script> if (window.gameObj === voi…" } io.js:26:3
    Object { game: Object, map: Object, player: Object, herbs: Object, mines: Object, groundItems: Object, utils: Object, objects: Object } jquery.js line 2 > eval:6:1
    "Phaser v2.4.4 | Pixi.js v2.2.9 | Canvas | WebAudio | http://phaser.io" phaser.min.js:11:26341
    got herbs init: herbs.js:34:9
    Object { 56bbaa5ce7ba31862d928588: Object, 56bbaa99e7ba31862d92858d: Object, 56bbaad8e7ba31862d928597: Object, 56bbaad9e7ba31862d928598: Object, 56bbab16e7ba31862d9285a5: Object, 56bbab17e7ba31862d9285a6: Object, 56bbab18e7ba31862d9285a7: Object, 56bbab56e7ba31862d9285b7: Object, 56bbab91e7ba31862d9285c3: Object, 56bbab91e7ba31862d9285c4: Object, 390 mais… } herbs.js:35:9
    Ground items init: Object {  } groundItems.js:31:9
    got mines init: mines.js:43:9
    Object { 56bb953d52bf8ea4c2979203: Object } mines.js:44:9
    is close? true main.js:19:13
    herb deleted herbs.js:47:9
    56c588d7e7ba31862d9287b3 herbs.js:48:9
    is close? true main.js:19:13
    herb deleted herbs.js:47:9
    56c5889be7ba31862d9287ae herbs.js:48:9
    is close? true main.js:19:13
    herb deleted herbs.js:47:9
    56c588d7e7ba31862d9287b4 herbs.js:48:9
    herb created herbs.js:42:9
    Object { name: "slire", place: Array[2], _id: "56c6bbfe82e6cf6054cfec3a", sprite: Object } herbs.js:43:9
    herb created herbs.js:42:9
    Object { name: "slire", place: Array[2], _id: "56c6bbfe82e6cf6054cfec3b", sprite: Object } herbs.js:43:9
    steps: 1 0 player.js:96:17
    player-move: Object { x: 250, y: 257.5, inventory: Array[3] } player.js:162:9
    lag: 221 player.js:165:9
    player-move: Object { x: 250, y: 257.5, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 191 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[2] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 182 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 178 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 187 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 176 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 186 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 196 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 172 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 171 player.js:165:9
    player-move: Object { x: 250, y: 257.5, inventory: Array[1] } player.js:162:9
    lag: 173 player.js:165:9
    player-move: Object { x: 250, y: 257.5, inventory: Array[1] } player.js:162:9
    lag: 171 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[2] } player.js:162:9
    lag: 178 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 179 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 172 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[2] } player.js:162:9
    lag: 170 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[1] } player.js:162:9
    lag: 178 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[1] } player.js:162:9
    lag: 182 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[1] } player.js:162:9
    lag: 177 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[2] } player.js:162:9
    lag: 191 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 176 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 192 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 179 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 173 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 172 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175

  7. #7
    Hardcore Member Theo is offline
    MemberRank
    Nov 2006 Join Date
    118Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Oh Man! i want give to you Beer! :-) this is realy perfect help for developers :) I inspired from it to our MMORPG Legend of Azulgar. Is here chance for any cooperation with you on our SCI-FI project?
    Legend of Azulgar - www.azulgar.com - 2D/3D Sci-Fi MMORPG
    Webhosting - www.netstormhost.com - Unlimited domains per services

  8. #8
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Quote Originally Posted by SheenBR View Post
    It doesn't work for me either, cant move. firefox 44.0.2
    Spoiler:

    Code:
    content: Object { selector: "#canvas", html: "<style> #loginContainer {     position…" } io.js:26:3
    Campos de senha presentes em uma página insegura (http://). Este é um risco de segurança que permite que credenciais de login do usuário sejam roubadas.[Saiba mais] <desconhecido>
    Campos de senha presentes em um formulário que será enviado a uma página insegura (http://). Este é um risco de segurança que permite que credenciais de login do usuário sejam roubadas.[Saiba mais] <desconhecido>
    action: login Array [ Object, Object, Object ] io.js:18:1
    status: Object { status: "Processing Login.." } jquery.js line 2 > eval:4:3
    status: Object { status: "(1) No Bueno.", code: 1 } jquery.js line 2 > eval:4:3
    action: login Array [ Object, Object, Object ] io.js:18:1
    status: Object { status: "Processing Login.." } jquery.js line 2 > eval:4:3
    status: Object { status: "(1) No Bueno.", code: 1 } jquery.js line 2 > eval:4:3
    action: login Array [ Object, Object, Object ] io.js:18:1
    status: Object { status: "Processing Login.." } jquery.js line 2 > eval:4:3
    status: Object { status: "(3) Unable to find user.", code: 3 } jquery.js line 2 > eval:4:3
    status: Object { status: "Processing Registration.." } jquery.js line 2 > eval:4:3
    content: Object { selector: "#canvas", html: "<script> if (window.gameObj === voi…" } io.js:26:3
    Object { game: Object, map: Object, player: Object, herbs: Object, mines: Object, groundItems: Object, utils: Object, objects: Object } jquery.js line 2 > eval:6:1
    "Phaser v2.4.4 | Pixi.js v2.2.9 | Canvas | WebAudio | http://phaser.io" phaser.min.js:11:26341
    got herbs init: herbs.js:34:9
    Object { 56bbaa5ce7ba31862d928588: Object, 56bbaa99e7ba31862d92858d: Object, 56bbaad8e7ba31862d928597: Object, 56bbaad9e7ba31862d928598: Object, 56bbab16e7ba31862d9285a5: Object, 56bbab17e7ba31862d9285a6: Object, 56bbab18e7ba31862d9285a7: Object, 56bbab56e7ba31862d9285b7: Object, 56bbab91e7ba31862d9285c3: Object, 56bbab91e7ba31862d9285c4: Object, 390 mais… } herbs.js:35:9
    Ground items init: Object {  } groundItems.js:31:9
    got mines init: mines.js:43:9
    Object { 56bb953d52bf8ea4c2979203: Object } mines.js:44:9
    is close? true main.js:19:13
    herb deleted herbs.js:47:9
    56c588d7e7ba31862d9287b3 herbs.js:48:9
    is close? true main.js:19:13
    herb deleted herbs.js:47:9
    56c5889be7ba31862d9287ae herbs.js:48:9
    is close? true main.js:19:13
    herb deleted herbs.js:47:9
    56c588d7e7ba31862d9287b4 herbs.js:48:9
    herb created herbs.js:42:9
    Object { name: "slire", place: Array[2], _id: "56c6bbfe82e6cf6054cfec3a", sprite: Object } herbs.js:43:9
    herb created herbs.js:42:9
    Object { name: "slire", place: Array[2], _id: "56c6bbfe82e6cf6054cfec3b", sprite: Object } herbs.js:43:9
    steps: 1 0 player.js:96:17
    player-move: Object { x: 250, y: 257.5, inventory: Array[3] } player.js:162:9
    lag: 221 player.js:165:9
    player-move: Object { x: 250, y: 257.5, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 191 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[2] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 182 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 178 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 187 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 176 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 186 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 196 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 172 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 171 player.js:165:9
    player-move: Object { x: 250, y: 257.5, inventory: Array[1] } player.js:162:9
    lag: 173 player.js:165:9
    player-move: Object { x: 250, y: 257.5, inventory: Array[1] } player.js:162:9
    lag: 171 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[2] } player.js:162:9
    lag: 178 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 179 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 172 player.js:165:9
    player-move: Object { x: 242.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[2] } player.js:162:9
    lag: 170 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[1] } player.js:162:9
    lag: 178 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[1] } player.js:162:9
    lag: 182 player.js:165:9
    player-move: Object { x: 250, y: 242.5, inventory: Array[1] } player.js:162:9
    lag: 177 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[2] } player.js:162:9
    lag: 191 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 176 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 192 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 179 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 173 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 172 player.js:165:9
    player-move: Object { x: 257.5, y: 250, inventory: Array[1] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[2] } player.js:162:9
    lag: 174 player.js:165:9
    player-move: Object { x: 250, y: 250, inventory: Array[1] } player.js:162:9
    lag: 175
    Well.. 50% of the users (not counting me) can move. And according to both of the logs posted here, people are trying to move and the server is rejecting the move and responding with the entry position- 250, 250. The reason for this is the server gets invalid lag data.
    Code:
    cmd: left lag: -6749 step: 1
    Client supplied invalid lag data! undefined
    I calculate the lag using Date.now() on the client, and subtracting Date.now() on the server from the time passed by the client. So (psuedo code: server.epochTime - client.epochTime).

    It occurs to me that this logic should work in theory, but is flawed in practice. Date.now() returns the Epoch time- that is, the amount of seconds since 1/1/1970. Now, according to the log above, your computer is almost 7 seconds ahead of my server in Epoch Time.

    In theory that's impossible- but in practice, there are a lot of reasons why this is possible. I assume you're not living 7 seconds in the future, and I'll assume your connection to my server isn't 7 seconds faster than the speed of time. So I'm gonna take a shot in the dark here, and guess that either the server or the 50% of clients that cannot move, is a computer that is out of sync with Epoch Time.

    The solution is... Well to be honest, I'm not using the lag data for anything anyway, so I'm checking it for no reason. I'll just delete some code and we'll see if that works.

    I won't be uploading any code (this includes the fix for the issues with moving) until the next tutorial.


    Quote Originally Posted by Theo View Post
    Oh Man! i want give to you Beer! :-) this is realy perfect help for developers :) I inspired from it to our MMORPG Legend of Azulgar. Is here chance for any cooperation with you on our SCI-FI project?
    Thanks, tell me more about the SCI-FI project- you can PM me so we don't drift off topic in this thread ;)
    Last edited by s-p-n; 22-02-16 at 04:29 PM.

  9. #9
    Programmer cyberinferno is offline
    True MemberRank
    Jun 2009 Join Date
    BangaloreLocation
    469Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Is this project on Github?
    Have a look at my simple Discord bot https://github.com/cyberinferno/discord-chum

  10. #10
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,148Posts

    Re: 11.) MMO From Scratch - Iron Mines & Ground Items

    Quote Originally Posted by cyberinferno View Post
    Is this project on Github?
    Yes. Somehow the link was lost. Thanks for asking this question, the links work again.
    https://github.com/s-p-n/surfaceTension




Advertisement