I used NowJS to implement the server<->client communication. Support for NowJS has ceased, as has further development. So the same (reluctantly!) goes for my Multiplayer behavior.
(DISCLAIMER: I wrote this plugin/behavior as a means of exploring the practicalities of using Construct 2 in a multiplayer context. It's offered here in that spirit, rather than as a fully functional way of making multiplayer games with Construct 2.)
NOTE: It's not touch-enabled and has only been tested in PC browsers (Firefox, Chrome, Safari).
So first up, here's my MultiPlayer in action, over the internet, in a really simple two-player game, Cleaners. You move your mop around the board, trying to clean more tiles than your opponent. If you collide with him/her/it, you lose.
NOTE: You may find there's quite a lag between your pressing keys and your mop moving. That lag depends on a variety of factors, to be discussed in a later post.
First, you'll see:
Hopefully, you'll not have too long to wait before you'll see, if you're the first to join the game:
If there's already another player who's waiting for you to show up, you'll see:
... and you can now start moving your mop (arrow keys) and cleaning - while the other player, with the grey mop, does the same - and tries to clean more tiles than you.
If you've been the first to join, you'll have to wait for another player - if no-one shows up, you can fire up another browser and try to move two mops at once. There are multiple game rooms, so a number of games can be played simultaneously.
Now for a peek behind the scenes. My main aim has been to explore multiplayer gaming possibilities using a Construct 2 front end. I also wanted to make a MultiPlayer plugin/behavior that Constructors could use at a high level, IOW they/you shouldn't have to manipulate Socket.IO messages and break them apart in order to extract their meaning. You can see that in how the Cleaners C2 code handles the update of a web player:
One way in which I managed to simplify the C2 front end was to make my MultiPlayer a behavior that attaches itself to an object (typically a Sprite), rather than a separate plugin to act as a controller. I originally started off down the plugin road with my PhotonPlayer plugin. That combined the controller with a Sprite in a single unit, but it meant that it had to handle all the complex drawing routines itself. Now, my MultiPlayer behavior delegates that tricky business to the object that it's attached to, leaving it free just to send moves to the game server and to get back from the server updated location information and other data (such as scores). (More detail later about its dealings with the server.)
OK, so you're wanting to try out my MultiPlayer behavior for yourself, on your own server. Here's what you'll need to do (you may have already done steps 1 and 2):
1) Set up a NodeJS server - you'll find download and set up instructions here. (Warning: I'm contracting out of offering any help with this step - if you need it, you can find lots on the interweb.)
2) Install these NodeJS modules: Express, NowJS. (Same warning applies here.)
3) Download my Cleaners server.
4) Unzip it into a subfolder of your NodeJs installation.
5) Run the game server by entering at the command line in that folder: node server.js.
6) Open up a browser window at this location: localhost:7000 (pick a different port if you have 7000 already in use by some other application - you'll also need to change the port number in line 34 of server.js). You should see the first screenshot above (with 'localhost:7000' as the address this time).
7) Open up another browser window at the same location: localhost:7000. You should see the third screenshot above, with the player positions reversed.
8) Move the mop in one window and you'll also see its grey counterpart move in the other.
9) Switch from window to window and see if you can beat yourself!
So where's Construct 2 in all this? I hear you ask. Well, if you look in the 'public' folder, you'll see 'c2runtime.js'. That's Construct 2's contribution to Cleaners. It came from my Construct 2 Cleaners project.
If you now download my Cleaners capx and look at its event sheet in Construct 2, you'll find that there's no game logic there. In an industrial strength multiplayer game, an authoritative server handles all the logic. The only location data that the Construct 2 "game" sends to the server is the direction of a move (left/right/up/down) made by the object that the MultiPlayer behavior is attached to. It doesn't send its x/y coordinates, because this would be a really easy way for a rogue client "game" to cheat.
Likewise, the server maintains score and health data and sends these to the client players (along with any necessary other data on the game state). That doesn't leave much for the Construct 2 "game" to do! In fact, you'll see that it really has just two tasks:
1) send moves to the game server, and
2) display the current game state.
I've made a simpler Multiplayer Workout for you to use as a basis for experimenting for yourself. Here's how:
1) Download my MultiPlayer behavior and see that it ends up in your Construct 2\exporters\html5\behaviors folder.
2) Download my Multiplayer Workout capx.
3) Download my Multiplayer Workout NodeJS server] and unzip it into another subfolder of your NodeJs installation.
4) Open up a browser window at localhost:7700.
5) Open up other browser windows (as many as you like) at the same address.
6) Move the sprite in one window and you'll also see its differently coloured counterparts move in the others:
It's not a game! (I said it was simpler.) For one thing, there're no separate game rooms, and, as you've just seen, there's no enforced limit on the number of players.
Over to your imagination to experiment with it. But NOTE that you won't be able to preview it in the usual way! That's because it doesn't know what to do if it can't connect to the game server. So here's the workflow you need to follow:
1) Edit Multiplayer Workout in Construct 2 (of course!).
2) Export your project as a HTML5 website to the public folder of the NodeJs subfolder that you created in Step 3 above. DON'T minify the script - the NowJS 'now' object confuses the Google Closure Compiler.
4+) The next steps are the same as steps 5-9 in the first set of numbered instructions above.
To make a game of your own from scratch using my MultiPlayer behavior, you'll need to know what it offers you - here are its conditions (events), actions, and expressions that you can make use of:
- Condition: New web player has joined
- Condition: Web player has been updated
- Condition: On collision with another player
- Condition: Web player/s to be created
- Condition: On my player moved
- Condition: Web player has left (use this to destroy the associated sprite)
- Condition: Game server is ready
- Action: Set the web player's ID (from the C2-allocated UID)
- Action: Initialise data of web player to create (from the server-allocated client ID and its current x/y coordinates)
- Expression: Get current X co-ordinate of web player
- Expression: Get current Y co-ordinate of web player
- Expression: Get web player's C2 UID
- Expression: Get number of web players to make
- Expression: Get the player's server-allocated UID
- Expression: Get the player's name
- Expression: Get the player's current score
- Expression: Get the player's current health
(The last three expressions are not used in my sample projects.)
There are many multiplayer issues that I haven't dealt with. For example, I've not attempted to compensate for latency (the time taken in moving data to and from the server) or lag (the delay between a player's action and its result - partly caused by latency). Here's a useful explanation of those issues by Rob Hawkes in a Google TechTalk, telling of his attempts to create a MMOG in HTML5 (he's particularly good on dealing with cheats - he carries the scars from multiple encounters).
And I'll discuss those issues as they affect my MultiPlayer behavior in a later post, as well as explain why this is a tile-based behavior rather than one that allows pixel-by-pixel motion (you can probably guess why).
My aim has been to create a practical experimental context in which we can explore and discuss the possibilities and issues of using Construct 2 in developing multiplayer games. Let me know if this helps.