Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by MatthieuB

Hello, I try to create a multiplayer RPG type or another. By changing "php comet chat" I have come to establish a client-server communication. When one player is connected, the game is 70 fps, but when a second player connects, the game falls to 5-7 fps for each players ...
I don't understand what creates the slowdown.
Attached the code of my file 'main.js'
Thank you in advance!
ig.module( 
	'game.main' 
)
.requires(
	'impact.game',
	'impact.font',
	'plugins.gamelobby',
	'game.levels.beginning',
	'impact.debug.debug'
)
.defines(function(){

EntityFigther = ig.Entity.extend({ 
	size: {x:32, y:48},   
    // Load an animation sheet
    animSheet: new ig.AnimationSheet( 'media/figther.png', 32, 48 ),
    
    init: function( x, y, settings ) {
        // Add animations for the animation sheet
		this.addAnim( 'idle', 0.1, [0] );
        this.addAnim( 'bas', 0.2, [0,1,2,3] );
		this.addAnim( 'gauche', 0.2, [4,5,6,7] );
		this.addAnim( 'droite', 0.2, [8,9,10,11] );
		this.addAnim( 'haut', 0.2, [12,13,14,15] );
        
        // Call the parent constructor
        this.parent( x, y, settings );
    },
	update: function() {
        // User Input
        if( ig.input.state('left') ) {
			this.currentAnim = this.anims.gauche;
        }else if( ig.input.state('right') ) {
			this.currentAnim = this.anims.droite;
		}else if( ig.input.state('up') ) {
			this.currentAnim = this.anims.haut;
        }else if( ig.input.state('down') ) {
			this.currentAnim = this.anims.bas;
		}else{
			this.currentAnim = this.anims.idle;
		}
        
        this.parent();
    }
});

EntityFigther2 = ig.Entity.extend({ 
	size: {x:32, y:48},   
    // Load an animation sheet
    animSheet: new ig.AnimationSheet( 'media/figther.png', 32, 48 ),
    init: function( x, y, settings ) {
		this.parent( x, y, settings );
		
		this.addAnim( 'idle', 1, [0] );
    },
	update: function() {
		this.currentAnim = this.anims.idle;
        //this.parent();
    }
});
	
MyGame = ig.Game.extend({
	// Load a font
	font: new ig.Font( 'media/04b03.font.png' ),
	fontback: new ig.Font( 'media/04b03b.font.png' ),
	clearColor: '#000',
        timer: 0.24,
        state: 'ingame',
        message: "",
        messageState: false,
        lobby: new GameLobby(this),
        name: Math.random(),
		mmoplayer: new Array(),
	
	init: function() {
		this.loadLevel( LevelBeginning );
		ig.input.bind(ig.KEY.LEFT_ARROW, 'left');
        ig.input.bind(ig.KEY.RIGHT_ARROW, 'right');
		ig.input.bind(ig.KEY.UP_ARROW, 'up');
        ig.input.bind(ig.KEY.DOWN_ARROW, 'down');
		// Initialize your game here; bind keys etc.
		this.player = this.spawnEntity( EntityFigther, 200, 200 );
		this.timer = new ig.Timer(0.24);
		this.lobby.setPlayer( {name: this.name,id: "0"} );
		this.lobby.sendMessage(200+';'+200);
		this.timer2 = new ig.Timer(0.25);
	},
	
	update: function() {
		var player = this.getEntitiesByType( EntityFigther )[0];
		if( player ) {
			this.screen.x = player.pos.x - ig.system.width/2;
			this.screen.y = player.pos.y - ig.system.height/2;
			if( ig.input.state('left') ) {
				player.pos.x -= 2;
			}else if( ig.input.state('right') ) {
				player.pos.x += 2;
			}else if( ig.input.state('up') ) {
				player.pos.y -= 2;
			}else if( ig.input.state('down') ) {
				player.pos.y += 2;
			}
		}
		if (this.timer.delta() > 0) {
			this.timer.reset();
			var player = this.getEntitiesByType( EntityFigther )[0];
			if( player ) {
				if( ig.input.state('left') || ig.input.state('right') || ig.input.state('up') || ig.input.state('down')){
					this.lobby.sendMessage(player.pos.x+';'+player.pos.y);
					//$.post('entry.php', {id:this.name,pox:player.pos.x,poy:player.pos.y});
				}
			}
			
		}
		// Update all entities and backgroundMaps
		if (this.timer2.delta() > 0) {
			this.timer2.reset();
			var syncData = this.lobby.messages;
			if ( syncData != null && syncData != ""){
				syncData = syncData.split(';');
				if(syncData.length > 0){
					for(i=0;i<(syncData.length-1);i+=3){
						if(typeof(this.mmoplayer[syncData[i]]) == "undefined"){
							this.mmoplayer[syncData[i]] = "check";
							this.entity = this.spawnEntity( EntityFigther2, syncData[i+1], syncData[i+2], {name:syncData[i]});
						}else{
							var entity = this.getEntityByName(syncData[i]);
							if(entity){
								entity.pos.x = syncData[i+1];
								entity.pos.y = syncData[i+2];
							}
						}
					}
				}
			}
		}
		
		this.parent();
		// Add your own, additional update code here
	},
	
	draw: function() {
		// Draw all entities and backgroundMaps
		this.parent();
		
		
	}
});


// Start the Game with 60fps, a resolution of 320x240, scaled
// up by a factor of 2
ig.main( '#canvas', MyGame, 60, 320, 240, 1 );

});

1 decade ago by Arantor

In your browser, open up whatever debugging tools you have (Chrome has the Inspector, Firefox has Firebug etc.) and look at the network transactions going on.

I wouldn't be at all surprised if it was a change in the way polling occurs - when you only have one player, it's probably functioning the way Comet is supposed to, i.e. long poll waiting for a response (though that's a BAD idea to implement in PHP unless you're doing it through nginx and PHP-FPM, or you never expect to have more than small double-digits worth of users online at a time, but that's another story entirely)

But when you have two players, it's probably consuming a lot of time polling, receiving and repolling for data - but the network tab would be able to tell you what's actually going on.

As for why PHP is a bad idea for Comet... Comet is a long poll architecture, which means it holds the connection open until it receives data. When implemented with Apache/PHP, that means you hold a connection including PHP instance open, which means that you're running 1 instance of PHP per connection, which will be capped firstly to the number of connections Apache is allowed to support, typically 256, and that pool is supposed to be used for all connections... then you have to contend with the fact that ~8MB of RAM per PHP instance is being used in memory. 10 connections = 80MB usage on the server, all sitting idle waiting for data. Putting it behind nginx or similar proxy model will mean that nginx will be managing the connection, not PHP.

1 decade ago by emati

According to Arantor, you can use nodeJS which is great for this type of multiplayer games. And i guess it would be easier for you to write some code in it than in php.

1 decade ago by Arantor

Sure you can, though that's sort of off topic. It actually doesn't matter so much what the back end is, because the interaction is still going to take place over conventional HTTP. Node.JS gives the same flexibility as far as nginx does with respect to handling connections (both do event driven epoll-type connections), so handling even many many connections is not a problem.

The upside is that you get to use JavaScript on the server, the downside is that you're building an app that is a physical web server. Which means either the chat server should be on a different port to handle just the game networking, or it needs to be a Node.JS app that can also serve files, like the files that actually run the game. (nginx can serve files quite happily and doesn't need baby-sitting, while Node.JS will by comparison)

I'd still venture to suggest that the problem isn't really the backend here. (The backend IS a problem for scalability, but it's not THE problem, almost certainly.)

1 decade ago by MatthieuB

Hi, first of all, thank you.
I installed socket.IO / NodeJS and it works better already.
But it must remain a problem in my code because there is always a significant slowdown, when an entity is added ...
Could you tell me how to use spawnentity when the game already started???

1 decade ago by drailing

hi,

just yesterday i added my implementation of a multiplayergame in the plugin section:
http://impactjs.com/forums/code/impactconnect-another-node-socket-io-plugin

i recommend to use 2 different browsers to test, like chrome and firefox.

firefox uses only one system process and all javascripts share this process, thats the reason the fps went down to 5-7 frames.

hope it works for you :)

1 decade ago by Arantor

That's the thing, there's no reason the drop should be to 1/10 the speed because it's not doing 10x the work, it's doing a little over 2x the work, so I'd expect the speed drop to be to a little under 1/2 of what it was before.

But yes, use two different browsers to test multiplayer, ideally on separate machines if possible.
Page 1 of 1
« first « previous next › last »