Multiplayer

Sora574
07 Apr 2013, 17:33
Sorry if my comments and questions everywhere are getting annoying but I'm wondering...
How much work would it be to implement multiplayer into Quest?
I've found various threads that relate to multiplayer, such as this, but not a lot of talk about it lately it seems.
With the current Quest version, it seems easy to have different players, but the server would be impossible right now, am I right?

So how could we get around that? Or can we?

sonic102
07 Apr 2013, 19:14
I don't think you can make a MUD in Quest5, but it is possible in Quest4.

Alex really shouldn't have removed that, eh. :(

Sora574
07 Apr 2013, 19:50
I agree. I think it should be re-implemented into Quest 5... After all, from what I've read, there's so much more stuff to work with in 5 than in 4.

Pertex
08 Apr 2013, 08:56
As I remember right nobody has used the ability of multiuser support in Q4 so why wasting time with it in Q5, too? And integrating real multiplayer would make it necessary to rewrite Q5. There would be lots of problems to solve such as respawning objects, containers,... But if you look deep inside Q5 perhaps you will find a way to create a multiplayermode ;-)

Sora574
08 Apr 2013, 09:31
Well... Technically all you would need is a server and a way to connect to it. You could log in, the server could save everything for specific players...
So really spawning/respawning would be a simple MoveObject on the server-side...

NOTE: From this point on is random ideas I feel I should write down. (AKA rambling)

Of course, you would need an OnConnect script or something. I think a 'player.user' would be necessary for some things. This would also allow for multiple characters per user...
Basically, the server has all the code. The client just needs to login (maybe via users for the quest website?) and connect.

But... We need someone that knows how to script servers. Could Alex do it with enough time?

OH another thing -- if the new Dictionary type can hold Object Lists, then you could use that to save player inventories.
Same thing with statuses... except with String Lists...
Well... Now that I think about it, you don't need to put them inside dictionaries. They could just have the same names as the charac-- Oh wait.
You shouldn't have to save statuses and inventories... They stay there as long as the character is there...
There needs to be a character per user limit. Maybe 3?
Also... There should be a set time for clearing out characters that haven't been active for a while.

Um... Sorry if you get lost in that. I usually have a hard time figuring out what I talk about too lol

EDIT: @Pertex Maybe now that you can actually do more things with Quest, people would make/play more multiplayer games... They can be so much more interesting now. (Or at least, I assume... I wasn't around for Q4)

SECOND EDIT: Also @Pertex I don't know if you're joking or not (about maybe it can still be done)... If you were, count this as rambling: Quest 5 has absolutely no way-- Wait.

JavaScript?... Is that possible?...
...I think along with HTML you could make a login screen...
Maybe...
I don't know much JavaScript grr -- someone look into this!!!
Of course, Alex would need to give us the code or whatever to access the website's user database

THIRD EDIT: ^Don't count that as rambling^ READ IT.

Sora574
08 Apr 2013, 16:39
Found something that might be useful.

http://nodejs.org/

It looks like it's open source...
This could be used to create a local server with pure javascript (I think it would have to be wired into the Quest source code?)

I also figured out that the layout would basically have to be
     server
/ \
user user

Basically, it's a standard multiplayer server
The whole path for connection would be something like
user request (login) ---> server verifies request* ---> if it's valid, the user connects to the server ---> server sends JS to all clients, saying something like 'User: online', while adding the username to a dictionary of online users ---> every time a user does something, that user's client sends the information to the server via JS ---> the server then sends that JS to every online user (via the dictionary of online users) ---> stuff happens ---> when a user goes to log off, they send a JS to the server, which sends a message ('User: offline') to every other online user and removes the logged off user from the dictionary

*still not quite sure where it would get user authentication from...

I'll try to test this myself, but again, I don't know JS that well so I might not be able to do it. Could someone else give it a shot? Maybe a short demo or something, while they host a server?

REMINDER: If you do decide to test it, you must first realize that the server opens a port on your computer. This may leave you vulnerable to hacking if you don't know what you're doing... So BE CAREFUL.

jaynabonne
08 Apr 2013, 17:11
I don't know if you'd need to integrate the server code with Quest, unless you're planning on peer-to-peer type communication (where each player's game connects to others and is, in turn, connected to). Even with that, you'd need a way for the various clients to find each other, unless you're talking about this being just a LAN type MUD. So you're still talking about needing a central server to allow the clients to connect and find each other. I would be a bit hesitant to do P2P type stuff, though, as you would (as you mention) get into needing open ports, which can be a bit tricky to configure with home systems to expose a machine outside routers, etc.

So you'd probably need a central server. I don't know if Alex would want to host that. For a test, somebody would.

As far as Quest additions, we'd need Javascript on the client side to talk to the server. I haven't tried this - hopefully it doesn't trigger any security measures for JS code to open a socket outside its domain. That would be an interesting first test.

Here is the general purpose JS/browser socket interface: http://dev.w3.org/html5/websockets/. It requires special handling on the server side, since the protocol is very specific.

Sora574
08 Apr 2013, 17:26
I was actually just setting up a websocket server lol...
I found that page and this

https://npmjs.org/package/websocket

Which enables websocket servers in node... I'm working on the client-side now. (Hopefully it will work)
And... I think LAN and P2P (I'm assuming is online?) should both work.

Of course, there's always Hamachi if you don't want to open any ports. It basically puts all users onto a virtual network, essentially tricking the computers into thinking they are using LAN.

jaynabonne
08 Apr 2013, 18:06
Just to brainstorm a bit (since that's half the fun), as you said, all the logic would be on the server side, and the client would just need to reflec the state of the server. If you're sticking with a Quest metaphor, then you'd have objects in rooms, and each player in some room to view what is going on and manipulate things.

If you could forsee a very large map, then you might not want to try synchronize your local view with everything that happens on the server. In that case, you could sync as locally as the room you're in, if you good enough latency such that when you switch rooms, you can download the state for that room quickly enough that it doesn't become tedious. Or you could have each client also "listen" and update state for rooms perhaps one or two exits away.

As a player manipulates the environment, you would probably need to reflect that in other players' views, not only in the object model but also in the player's view. So if I take a key and you're also in the room, your client would ( at least) remove the key from your visible objects list and then spit out something like, "Jay takes the key." That implies not only changes in object state but also notification of how the change came about.

Beyond that, given that this is a text-based medium, you would probably want to be quite verbose about what is going on. If you're interested, I have code for game I have in development that involves a number of NPCs performing autonomous actions (perhaps a multi-player would want that as well?). At any rate, I have a library called StoryText which takes events coming in from multiple characters and generates more or less human-readable output in paragraph form. So if Jim enters (event: "Jim enters") and John enters (event: "John enters"), and Amy drops a book (event: "Amy drops a book") and picks up a flower (event: "Amy picks up a flower"). it would output:

Jim and John enter the room. Amy drops a book and picks up a flower.

To that end, I have some nice verb conjugation code I'd be willing to donate.

Sora574
08 Apr 2013, 19:00
I didn't even think about the whole 'room only' idea... That would probably make things run faster.
Same goes for the 'manipulating environments'. Adding onto that, for certain things, like something for a 'mission', I think we could add something that says who took it last and how long it would be to get it back...
This could also set up a Capture the Flag match.

As for the library, that would probably make things a lot simpler. It's better than starting from scratch, anyways.

OH. I almost forgot... I got the WebSockets to work :D I might put together a demo (and yes, I would host the server for a bit) after I finish, if anybody wants to test it out.

The Quest 'server' can't actually start up the Node.js server without proper coding (which is beyond me). You have to start the Node server manually. But, even if you start them separately, they still get linked together. I think it's safe to say that Node as a separate program isn't too terribly difficult if you know what you're doing, but it would be way more user-friendly if Quest borrowed the code and stuck it into the source...

TriangleGames
08 Apr 2013, 20:31
I don't quite get what's being discussed here. I'm not even trying to understand the code, but the whole text-adventure MUD concept is confusing to me. At first, when I saw "MUD" my brain was thinking of "SCUMM," so I thought you meant like "point-n-click" games. It helped a LOT when I figured out how off-track that was! Even so, I've never seen a multi-player text game before, and I'm having trouble picturing how the game-play would work. Is there one online somewhere that I could check out to see what it's like? Is it basically like "World of Warcraft," but in text? Does MUD specifically mean a text based game, or just multi-player?
(Just for the record, I don't play WoW, but I get how it works.)

jaynabonne
08 Apr 2013, 20:39

Sora574
08 Apr 2013, 20:58
I can't seem to get the server and client to want to send messages back and forth...
I have the Quest JS down, it's just the server seems to not want to cooperate...
Of course, I'm trying to use tutorials, so maybe just starting from scratch would work better. I wish I knew more JS...

Anyways, @Triangle:
Most of everything I've said in this thread has been rambling, so sorry if I'm confusing you about this.
Essentially, what this is supposed to accomplish is force Quest to have multiplayer functionality, like some of the ones in jay's link above.

jaynabonne
08 Apr 2013, 21:44
Are they connecting? Which port are you using? And what is your setup (same machine, same LAN, etc)? Just curious in case anything jogs a thought. :)

Sora574
08 Apr 2013, 21:56
jaynabonne wrote:Are they connecting? Which port are you using? And what is your setup (same machine, same LAN, etc)? Just curious in case anything jogs a thought. :)

:lol: speaking of jogging a thought...

I forgot to put a connect script into the client :oops: So no, they weren't connecting but they are now.
Now I can continue...

Oh, and for future reference, I'm using port 8080 and I'm using the same machine to do everything.

EDIT: BTW... When the client stops the game, it automatically disconnects. That saves work.

SECOND EDIT: I changed my port to 8080.

Sora574
10 Apr 2013, 22:47
So, either I've done everything wrong or... Quest cannot use JavaScript to connect to a Web Socket.
Well, it's more like it CAN connect -- it just won't send anything.
And if it doesn't send anything, it's useless, because that means that the server can't receive anything to send to other clients. (Which the clients wouldn't be able to receive it anyway, as this is also not working.)

However, I'm not a big JavaScript person. If there's anyone that wants to give it a shot that has more experience, please try. There might also be other ways besides Web Sockets to do it that might work, but I haven't found anything.

Links that might be helpful:
[list]http://nodejs.org/ -- The 'Node' program I was using to host a server written in JavaScript.
https://npmjs.org/package/websocket -- The package I was using for Node to create a Web Socket on the server. I got Quest to connect to it, but it wouldn't send any messages.
https://npmjs.org/package/socket.io -- I also tried this, but I couldn't even get Quest to connect to the server, let alone send messages.[/list:u]

By the way... I also figured out that you can put virtually any HTML into a message in Quest, and have Quest spit it out like a normal web page would.
By figuring this out, I did manage to create a 'login' page. Although it doesn't currently do anything except make a new player.

Anyways, if anyone's brave enough to try to enable multiplayer, good luck. Otherwise, I guess we'll have to wait for someone who can.

EDIT: Login test uploaded.
[list]LINK: http://www.textadventures.co.uk/review/1197/[/list:u]

jaynabonne
11 Apr 2013, 17:23
Would it be worthwhile to take what you have so far and see if it can be moved forward to working? That's as opposed to going back to the sources you started from and basically re-creating what you did. I'd be willing to take a look at what you've tried.

Sora574
11 Apr 2013, 20:57
What I ended with is nothing worth looking at, I think. I pretty much just reverted back to the tutorials toward the end, and I forgot to make a backup of the version that actually connected...

But if you want, you can look at it anyway I guess.


To start the server, install node, go to your computer's command console, type 'npm install websocket', then once that's done, type 'cd (path to the folder)', then type 'node createserver. The 'serverclient.js' is supposed to be included into your Quest game. After that, run the script, in Quest, 'JS.connectToServer ()'...
Obviously, it does absolutely nothing. I'm 100% sure I did something wrong though lol

jaynabonne
11 Apr 2013, 21:35
Thanks, I'll check it out. :)

jaynabonne
11 Apr 2013, 21:52
I tried just dropping the client into Quest, and I got an error right away. I added the .js file to a new project, and then I added:

JS.connectToServer()

into my game start script. Looking at the console in Quest, I see:

Uncaught SyntaxError: Not enough arguments serverclient.js:2

Basically, new WebSocket takes a URL parameter. I changed the code to this:

function connectToServer() {
var socket = new WebSocket('ws://localhost:8080/');
//server.connect();

socket.onopen = function(){
console.log('<p class="event">Socket Status: '+socket.readyState+' (open)');
socket.send('Connected.');
}

socket.onmessage = function(msg){
console.log('<p class="message">Received: '+msg.data);
}

socket.onclose = function(){
console.log('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
}
}


and I now get in output:

<p class="event">Socket Status: 3 (Closed)

So it's at least not erring any more. I do not have the server running yet. I'll try that next.

Sora574
11 Apr 2013, 22:00
Oops, sorry about that error. I forgot I had added the server.connect...
Anyways, you said you got an output? Where at?

jaynabonne
11 Apr 2013, 22:51
My output is just that the connection got closed, probably because I don't actually have a server running. :) But it didn't give JS errors any more.

Sora574
11 Apr 2013, 23:14
OH... Duh... I knew that :lol:
Well, again, good luck.

Sora574
12 Apr 2013, 03:45
Not sure if it would help much, but for what it's worth, I found a little tutorial on how to make a game with Node and socket.io in the browser...

http://rawkes.com/articles/creating-a-real-time-multiplayer-game-with-websockets-and-node.html

I tried it out, and it works perfectly in the browser. Maybe if you check out that code it would help with what we're trying to accomplish?...
Or at least, it might give a better hands-on example to help get you used to coding with Web Sockets.
Of course, Quest is a bit pickier than normal browsers are (obviously) so it might not be as straight-forward as that tutorial.

Anyways, if it helps -- great. If not -- sorry for wasting time lol
Good luck, again.

jaynabonne
12 Apr 2013, 10:08
That is helpful. Thanks!

I set up the server side with node.js, and I have the server running. If I hit the server with a web browser (e.g. "http://192.168.0.107:8000"), then I get a response which says "Welcome to socket.io.", but no logging from the server about a connection being made. So it must be happening at a different level.

I tried these three client arrangements:
1) Quest Websocket connection from different machine - closed event before connects
2) Chrome Websocket connection from different machine - closed event before connects
3) Chrome Websocket connection on same machine - closed event before connects

So at least it's not Quest-specific. And if I point the Quest client to this: 'ws://echo.websocket.org', then it successfully connects and receives data, which means the client websocket client code in Quest is capable of working. (The page for that is: http://www.websocket.org/echo.html)

For some reason, it just doesn't want to connect to the node.js server. Actually, it comes back right away. If I pick a different port, it takes much longer to close (still with no error reported on the "onerror" function), so something is going on.

When I have some time, I'll focus on the server side.

jaynabonne
12 Apr 2013, 11:15
Ok, so things are becoming clearer now.

socket.io is not just a WebSockets server. It seems to be its own protocol on top of WebSockets. So you *must* use socket.io on both the client and server sides, else it will not be able to communicate. When I upped the log level, I got:

destroying non-socket.io upgrade

in the server log. What this means to me is that when the http connection got upgraded to WebSockets (via the protocol request), the resulting upgraded connection wasn't a "socket.io" specific connection, and so it closed it.

Bottom line: we either need WebSockets only on client and server, or we need to integrate socket.io into the client to match the server so they can talk to each other. I think the latter might be more straightforward at this point.

Sora574
12 Apr 2013, 12:31
Did you try adding this before the JS.connectToServer, in the start script of Quest?
msg ("<script type=\"text/javascript\" src=\"http://192.168.0.107:8000/socket.io/socket.io.js\"></script>")

This is basically HTML to call for the client-side JavaScript that the Node console throws out. I'm not sure if it works the way it should, but it's worth a shot

jaynabonne
12 Apr 2013, 21:43
I got it to work. I ended up downloading socket.io.js (the latest, 0.9 - if you use an earlier version, it gives all sorts of weird errors) and including it directly in the Quest project.

The server file is game.js. Run that with "node". The NodeTest folder contains the client code.

You will need to change the IP address (and port if you want).

What's cool about how socket.io is set up is that you can "emit" events, and the data that goes along with the event is an object. So you can package up all sorts of nice parameters and send them across. No need to parse strings. (I assume it uses JSON to serialize the message data).

I have implemented a "quest message" event and a "send <message>" command. So within the game, if you type something like:

send This is a message

then on the server side, you should see:

onQuestMessage: This is a message

The log level is set a bit high right now (the sample had 2, but I set it to 20). You might want to lower it again to weed out some of the noise.

Let me know if you have any problems!

Sora574
12 Apr 2013, 23:03
...Wow. I can't believe it works...
Thanks so much for that -- Now all it needs is a way for the server to send messages to Quest (which shouldn't be too terribly difficult)...

I might try to do this part on my own, so if you want to stop for now, that's okay. I may need you again though so don't go too far :lol:

jaynabonne
12 Apr 2013, 23:36
Here is a page I had come across. It migh help... :)

https://github.com/LearnBoost/Socket.IO ... .7+#client

Good luck!

Sora574
13 Apr 2013, 00:10
Hmm... Every time I try to use 'io.sockets.emit' or 'socket.broadcast.emit' I get this:
TypeError: Cannot call method 'emit' of undefined

And if I try 'io.sockets.send' or 'socket.broadcast.send', I get this:
TypeError: Cannot call method 'send' of undefined


It seems like it doesn't like 'socket.broadcast' or 'io.sockets' at all...
However, the client is sending via the 'playerMove' event. I do this:
move player test
//move player #text1#

This comes up in the console:
Moving player: test

And then the errors appear and the server shuts off

EDIT: Nevermind -- I changed 'socket.broadcast' to 'this.broadcast' and it works fine. Not sure why, but whatever :)

Sora574
13 Apr 2013, 04:35
I have successfully created both 'move' and 'create' object scripts that both work in the server. They both have the same parameters as the Quest functions, except they have to be names, not objects -- Syntax is this:
// Moving objects
JS.moveObject ( object name, location name )
// Creating objects
JS.createObject ( object name, object type name )
// Note: Parameters can't be null.

I'll work on making a quick demo later, along with the codes.
P.S. I updated the 'serverclient.js' to use the built-in Quest Log by changing 'console.log(message)' to 'ASLEvent('Log', message)'
P.S.S. I'm working on chatting, too. This is probably the easiest part, because all it is is ASLEvent calls to 'OutputText' and a few if/thens

Sora574
14 Apr 2013, 19:06
So.
The server has successfully been set up.
The client has successfully been set up.
The client has successfully been published to the website.
What's next?...

TESTING. That's what.
If anyone wants to help test out the first Quest5 server ever, just reply saying you want to. (Everyone's welcome to join!)
Of course, we'll need a set time to test it (as I don't want to run the server all day) but that can be decided later, depending on who accepts.
The web player can play it, so there's no need to download it, but if you prefer downloading the server is cross-compatible, so no worries there.

The game itself is very simple. All it is is two rooms ('room' and 'other room' -- I know, creative, right?)
Currently, all you can do is move between the rooms and chat with each other. Every user gets their own name and they can choose their gender.

Again, everyone's invited -- just reply and we'll figure out the date/time... Then, I'll post the link to the game here.

jaynabonne
14 Apr 2013, 19:19
I'm in! :)

Beyond just text adventures or MUDs, this opens up the possibility of other uses for multi-player games. A number of years ago, I worked for a startup tht was trying to get a kids website off the ground. I dabbled briefly with some small multiplayer games written in Java, games that encouraged the kids to work together to solve a problem. There are some interesting possibilties here in the educational space!

Sora574
14 Apr 2013, 20:16
Wow, that was fast :lol:

I haven't really thought about the educational side of this... It would certainly open up new possibilities, though.
If we could turn the server into some sort of library, it would be incredibly easy to create a new educational game with multiplayer, along with Quest's GUI.

By the way, I've done 2 tests for the browser on machines other than the one I'm hosting the server on. These tests were all performed with the browser version on the opposite machine, and the desktop version on the machine the server is on, to test if the opposites can see users that are working perfectly (as the desktop works perfectly every time.)
Results:
[list][*]PC (Windows 7)
Google Chrome Stable, Beta, Canary (FAILED) -- Successful handshake. Connected to server with ID. Created player successfully. Could move back and forth between rooms. However, the other online users it created for client-side, if it decided to create them at all, would not function. Chat somehow disabled.
Internet Explorer (FAILED) -- Successful handshake. Would not receive an ID, however, so nothing happened.[/*:m]
[*]Tablet (Android)
Google Chrome Beta (FAILED) -- Successful handshake. Connected with ID. Wouldn't do much else at all.
Google Chrome Stable (SUCCESS w/exceptions) -- Successful handshake. Connected with ID. If players were already online, it wouldn't show them, though. New players were created successfully. Wouldn't receive the 'You say:', but would still send messages to other players in the same room and receive other player messages.
Default Android 'Browser' (FAILED... MISERABLY) -- Successful handshake. Same results as IE on the PC, with the added bonus of occasionally crashing the server and not letting it start up again until you restart Node completely. See bottom.
Dolphin Browser (FAILED) -- Successful handshake. Did absolutely nothing else.
Firefox Stable, Beta (FAILED) -- Successful handshake. Connected with ID. Chat gets sent to other players, but it won't show or create other players at all.[/*:m][/list:u]
Lots of fails... I don't think the web player likes using JavaScript very much. I would definitely recommend downloading the game.

Testers: 1 + me

Pertaining to the Android 'Browser':

Sora574
27 Apr 2013, 01:13
Just updating this a bit:

First, I still need more testers. (Maybe 2 would be fine, but still)
Second, I've been playing around with the server a bit, and I've figured out that it's capable of virtually anything we want. However, I'm not updating the test client because that's all it is -- a test. No need to make it more detailed right now.

Sora574
10 May 2013, 21:52
Okay, so I guess it's been enough time to start testing, even though it's just me and Jay.

That makes it pretty simple to come up with a good time to do it...
So, when's good?

jaynabonne
10 May 2013, 22:10
I'm on quite a bit any time from 10am GMT to 2am GMT. :)

Sora574
10 May 2013, 22:44
Ah, that works out. So, can you do some time tomorrow around 9pm GMT?

Sora574
14 May 2013, 22:30
Well, it seemed like the online multiplayer test successfully accomplished what it was supposed to.
Still a lot of bugs in the web player, though. Maybe that's something I could fix on my end, maybe not. In time, I might see what I could do.

Anyways, I feel like I should release a library with all the coding. I realized that instead of adding JavaScript files, it might work better if I put the scripts in HTML <script> tags, that way I could pack all of it into one library file, instead of separate JavaScript files. I'm not sure if it would work, but it's worth a shot.
Of course, I'm still not done with the coding yet. I just got finished adding actual object movements, so objects can be used in the game now.

Maybe someone can help think up stuff for my (as of now) to-do list:
[list][*]Add messages whenever a player does something! Jay said he had some sort of dynamic text library thing?[/*:m]
[*]Update room descriptions when players/objects move in and out. This would require re-coding Quest's built-in functions, I think, or maybe I should just start from scratch, and change the 'Room Descriptions' setting for 'Objects list' to 0... Then use HTML maybe? <span> tags? Ideas needed...[/*:m]
[*]Change Quest multi-command parsing. I'd rather not have someone type 'say Hi. Blahblahblah' and have an error pop up while all they send is 'Hi'[/*:m]
[*]Web editor version -- Is there a way to detect if the user is using a browser? Maybe I could change the code if they are?[/*:m][/list:u]

That's pretty much it for now. Feel free to help with those, or you can throw out any random new idea to improve multiplayer. I'll try to implement as many recommendations as possible.

P.S. Should I do an open beta? As in give the link to everyone and open the server for a short time? Or is anyone willing to open one for a long-ish time to give more people a chance?

george
20 Oct 2013, 18:38
Hey, I'm curious about where this is at. Have you worked on it more?

Sora574
14 Nov 2013, 09:22
george wrote:Hey, I'm curious about where this is at. Have you worked on it more?


Sorry, I've been kind of busy inrl the last few months.
However, I'm pretty much free now so... I'm planning on releasing a code library tomorrow, when it's uh... NOT 4 o'clock in the morning.

Today, I managed to convert all the JavaScript code into general formats. Instead of using JS.eval() calls, there are now 7 individual client-side functions that you'll need to send information to the server on occasion. For example, objects and players move automatically among the server -- every time a player makes a "turn", the server updates -- but if you want, say, a ghost that floats around different rooms, that's where functions such as TSMoveObject come in. (TS meaning ToServer -- there's also FS (guess what that is) but you should almost never have to use that client-side... they're all mainly for background stuff)

I'll explain more either tomorrow or Friday (uh... *today or tomorrow, technically?) whenever I post the library. :D

Sora574
20 Nov 2013, 03:55
Sorry for the delay, but I finally got the library all ready. You can find it here -> viewtopic.php?f=18&t=4013

If you have any questions, post them in that thread.