list of games "to join" (beginner)
list of games "to join" (beginner)
Hello,
i'm currently developing a first simple multiplayer-game.
When you click on the link you get to see the opening page which just consists of a list of games you can join + a create new game button.
The problem is how to get the list and keep it updated.
Whenever a game has started, it shouldnt be in the list anymore (but it is still a room in the zone of course), and i dont want the info about this game-room to be sent around by server to new arrivals. How can i make sure that when a new user asks RoomList that he only gets info on those he can join and not those already started? (once game started they become 'invisible'?)
Also, when there are 200 games to join, how can i make sure only the first 20 are sent?
remark: i am getting it right he? When you enter a room you get all the rooms in it (roomlist), once in the room you only get the 'updates' if there's a new room or a room is destroyed?
thanks in advance
i'm currently developing a first simple multiplayer-game.
When you click on the link you get to see the opening page which just consists of a list of games you can join + a create new game button.
The problem is how to get the list and keep it updated.
Whenever a game has started, it shouldnt be in the list anymore (but it is still a room in the zone of course), and i dont want the info about this game-room to be sent around by server to new arrivals. How can i make sure that when a new user asks RoomList that he only gets info on those he can join and not those already started? (once game started they become 'invisible'?)
Also, when there are 200 games to join, how can i make sure only the first 20 are sent?
remark: i am getting it right he? When you enter a room you get all the rooms in it (roomlist), once in the room you only get the 'updates' if there's a new room or a room is destroyed?
thanks in advance
extra
once a client starts a game (opens a new game room) he waits for 2 other players...however with a maximum of 3 minutes or 180 seconds.
This timing info should also be seen in the opening screen! (where you see a list of games you can join)
...
This timing info should also be seen in the opening screen! (where you see a list of games you can join)
...
You need first to look at the game examples that come with the swfs.
You need to learn how to use the "onRoomListUpdate" event. By default the SFS will send you all the rooms in the zone you joined. You can limit this to only 20 rooms using an extension, or you can only display 20 rooms in the client code (although you will recieve all rooms);
You can also set roomVariables. When the first user (the creator) enters the room you could set a room variable like startedAt equals with the current UTC time in milliseconds. This way you can see on any client the when the room was created.
This rises some problems. Flash is a client side and if you use the Date Object on the flash client to set a variable on the server it will set the date as the user has it on his PC. So you can't use this.
With the use of an extension you can set a variable on the server side inside the init Method. This brings up the need to use extensions on the server side.
After you'll manage to set the variable indicating the date when the server was initiated you will need to read it inside the client swf.
Problem is that a single number won't help you and you will need to build a time magement object inside your swf.
Basically when you connect you read from SFS another variable that will tell you the server's current time, and when you display the rooms you see the (server) time at wich the rooms were created. Based on this data you can display how many seconds are left for each room before destroying itself because of insufficient users.
Hope I made things a little clear
You should start with the tutorials and examples. Read them all and see what SFS offers you, and then you will be able to plan you multiplayer game.
Good luck
You need to learn how to use the "onRoomListUpdate" event. By default the SFS will send you all the rooms in the zone you joined. You can limit this to only 20 rooms using an extension, or you can only display 20 rooms in the client code (although you will recieve all rooms);
You can also set roomVariables. When the first user (the creator) enters the room you could set a room variable like startedAt equals with the current UTC time in milliseconds. This way you can see on any client the when the room was created.
This rises some problems. Flash is a client side and if you use the Date Object on the flash client to set a variable on the server it will set the date as the user has it on his PC. So you can't use this.
With the use of an extension you can set a variable on the server side inside the init Method. This brings up the need to use extensions on the server side.
After you'll manage to set the variable indicating the date when the server was initiated you will need to read it inside the client swf.
Problem is that a single number won't help you and you will need to build a time magement object inside your swf.
Basically when you connect you read from SFS another variable that will tell you the server's current time, and when you display the rooms you see the (server) time at wich the rooms were created. Based on this data you can display how many seconds are left for each room before destroying itself because of insufficient users.
Hope I made things a little clear
You should start with the tutorials and examples. Read them all and see what SFS offers you, and then you will be able to plan you multiplayer game.
Good luck
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
how to?
...
So, when i only want to show the games-you-can-join: I add a room-variable to the game-rooms that says "gamestarted Y or N", and when joining the room you get a list with ALL the game-rooms, you check the room-variable started or not (together with timing info) and if started you just dont show the game.
When a game has started this should be reflected instantly to all users in the waiting room. But the room-variable that shows this info is only sent to the users in the game room! not to those in waiting room...so how do they know the game has started?
(when a game is created or deleted you get the info through the roomlistupdate, so you know it (altough resending all the game-rooms seems a waiste of bandwidth) but how do you know a game has started?
hans.
So, when i only want to show the games-you-can-join: I add a room-variable to the game-rooms that says "gamestarted Y or N", and when joining the room you get a list with ALL the game-rooms, you check the room-variable started or not (together with timing info) and if started you just dont show the game.
When a game has started this should be reflected instantly to all users in the waiting room. But the room-variable that shows this info is only sent to the users in the game room! not to those in waiting room...so how do they know the game has started?
(when a game is created or deleted you get the info through the roomlistupdate, so you know it (altough resending all the game-rooms seems a waiste of bandwidth) but how do you know a game has started?
hans.
For this kind of smarter lobby I make my own extension for the room or zone. When a user selects a room some additional info and variables about the room are requested from the server and displayed. I check if a tournament has already started and display or not the join button.
Don't think of sending all the info to all the user again, cause this is indeed a waste of bandwidth. Think of requesting them from the server when you need them.
When you recieve an onRoomListUpdate you have the roomObject with all the getVariables() method. You can read the gameStarted right then.
You can't use for this purpose the "onRoomVariablesUpdate" because as you said "A client receives these notifications only from the room(s) where he's currently logged in."
You may want to try building an extension that would do the setting of roomVariables for you and also send a message to all users in the zone.
Don't think of sending all the info to all the user again, cause this is indeed a waste of bandwidth. Think of requesting them from the server when you need them.
When you recieve an onRoomListUpdate you have the roomObject with all the getVariables() method. You can read the gameStarted right then.
You can't use for this purpose the "onRoomVariablesUpdate" because as you said "A client receives these notifications only from the room(s) where he's currently logged in."
You may want to try building an extension that would do the setting of roomVariables for you and also send a message to all users in the zone.
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
sorry but...(to make sure i understand)
when entering the waiting room you get a list of all the gameroomID's (just once) and by use of the roomvariable 'gamestarted' you show them or not.
when a game starts; gamestarted is set on Y and next i should ask the server to sent this as a 'message' to all those in waiting room so they can change their list and dont show this game anymore? (for example sending (remove, game-id))
Remark; when a gameroom is created or deleted, how get this info to users in waiting room without resending info? ALSO by letting the server sent a message to all users in waiting room so they can change their list? Or is there a more direct way built in in smartfoxserver?
thanks a lot for your replies!
now that i think of it; the number of users already in the game should be shown to all users in waiting room also. So when a player joins a game this info should also be sent by the server like (addplayer, game-id))?
when entering the waiting room you get a list of all the gameroomID's (just once) and by use of the roomvariable 'gamestarted' you show them or not.
when a game starts; gamestarted is set on Y and next i should ask the server to sent this as a 'message' to all those in waiting room so they can change their list and dont show this game anymore? (for example sending (remove, game-id))
Remark; when a gameroom is created or deleted, how get this info to users in waiting room without resending info? ALSO by letting the server sent a message to all users in waiting room so they can change their list? Or is there a more direct way built in in smartfoxserver?
thanks a lot for your replies!
now that i think of it; the number of users already in the game should be shown to all users in waiting room also. So when a player joins a game this info should also be sent by the server like (addplayer, game-id))?
You can still use the onRoomListUpdate events on the client sideRemark; when a gameroom is created or deleted, how get this info to users in waiting room without resending info?
If I were you I would build an extension that would send a message like "remove" to all users in the zone. This however should be handled inside each room when the game begins.
An example code would look like the following (I dont have SFS here but I hope it will work);
Code: Select all
function gameStartedInRoom(id){
var responseObj = {};
responseObj._cmd = "remove";
responseObj.roomId = id;
var allRooms = _server.getCurrentZone().getRoom();
for (var x in allRooms){
_server.sendResponse(responseObj, -1, null, allRooms[x].getAllUsers());
}
}This is however bandwidth consuming and I would advise you to send this kind of messages only to the users connected to the lobby (the autojoin room usually).
Maybe like this
Code: Select all
function gameStartedInRoom(id){
var responseObj = {};
responseObj._cmd = "remove";
responseObj.roomId = id;
_server.sendResponse(responseObj, -1, null, _server.getCurrentZone().getRoom(_server.getCurrentZone().getAutoJoinRoom()).getAllUsers());
}Hope this helps
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
Hi,
I'm working with Hans on this game project.
For the 180 sec. question...
I think we should make an Extension (Server Side) at the Zone Level, which means one instance of the extension running and managing all the rooms of our game. The rooms have the following extra properties:
-timer (integer, number of seconds left to join the room)
-isStarted (boolean)
For the timer, the best solution would be to keep the information on the server (roomVariable will disappear if the user that created it leaves...) but what should I do for the countdown... A setInterval on the server-side ? Then will what informations will be send ?
I see it that way:
1. setInterval on the ext server side... doesn't send any message just keep the timer value up-to-date
2. if one of the timer is = or below 0 then we delete the rooms and we send all the informations up-to-date to all users (from the server xt)
3. other message should be send when i room is created or when a game is started...
I think that way we avoid sending message every second...
Am I right ?
thanks for your time
I'm working with Hans on this game project.
I think we should make an Extension (Server Side) at the Zone Level, which means one instance of the extension running and managing all the rooms of our game. The rooms have the following extra properties:
-timer (integer, number of seconds left to join the room)
-isStarted (boolean)
For the timer, the best solution would be to keep the information on the server (roomVariable will disappear if the user that created it leaves...) but what should I do for the countdown... A setInterval on the server-side ? Then will what informations will be send ?
I see it that way:
1. setInterval on the ext server side... doesn't send any message just keep the timer value up-to-date
2. if one of the timer is = or below 0 then we delete the rooms and we send all the informations up-to-date to all users (from the server xt)
3. other message should be send when i room is created or when a game is started...
I think that way we avoid sending message every second...
Am I right ?
thanks for your time
Yes, for sure you want to avoid sending messages that often. On a slow connection it would take more than one second for the user to recieve the message
.
Here's how I see it.
> Create a room that has an extension attached.
> on init read the timeToWaitForUsers variable.
> on init set a roomVariable initAt equal with getTimer();
> Set an interval (not one that repeats each second) but one that calls a function to destroy the current room after the timeToWaitForUsers passes.
> One the zone level you will have one main extension that will manage all room requests. When you send the info about each room also send a variable timeLeftToJoin = getTimer - roomVariable initAt;
> When the roomsList reach the client (you should not relay on the server's onRoomListUpdate - you should build your own custom management rooms extensions) then you set an interval inside the client that repeats each second and after the timer passes removes the room from the list.
Why would you do all this?
1. Because you will send only one message for each room for each user. No more adittional messages to keep the timers updated.
2. Because on the server time you don't waste resources repeating for each room a function that checks if the timer ran out when you can call the function when the timer actually rans out.
What can go wrong?
When you send the info to the users, based on the bandwidth and the ammount of traffic, the roomInfo may take some time to reach the client. This means that if it takes more than 2 seconds (let's assume) there will be a 2 seconds delay between the actuall killing of the room and what the client sees. It means that I (as a user) could click on a room that isn't there anymore (destroyed one second ago).
So you need to check for errors.
Hope this helps. it's just an ideea though.
Here's how I see it.
> Create a room that has an extension attached.
> on init read the timeToWaitForUsers variable.
> on init set a roomVariable initAt equal with getTimer();
> Set an interval (not one that repeats each second) but one that calls a function to destroy the current room after the timeToWaitForUsers passes.
> One the zone level you will have one main extension that will manage all room requests. When you send the info about each room also send a variable timeLeftToJoin = getTimer - roomVariable initAt;
> When the roomsList reach the client (you should not relay on the server's onRoomListUpdate - you should build your own custom management rooms extensions) then you set an interval inside the client that repeats each second and after the timer passes removes the room from the list.
Why would you do all this?
1. Because you will send only one message for each room for each user. No more adittional messages to keep the timers updated.
2. Because on the server time you don't waste resources repeating for each room a function that checks if the timer ran out when you can call the function when the timer actually rans out.
What can go wrong?
When you send the info to the users, based on the bandwidth and the ammount of traffic, the roomInfo may take some time to reach the client. This means that if it takes more than 2 seconds (let's assume) there will be a 2 seconds delay between the actuall killing of the room and what the client sees. It means that I (as a user) could click on a room that isn't there anymore (destroyed one second ago).
So you need to check for errors.
Hope this helps. it's just an ideea though.
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
i think this is a good idea and think we will go for this.
[remark; I first tried some solutions without server extensions
(like, first user creates roomvariable 'timecreated' when second one comes he copies this locally, if first one leaves this means roomvariable timecreated is lost, second one notices this he creates new roomvariable with same timecreated that he has stored.....)
but this seems not so elegant and i wanted to avoid using server cpu, but i guess sending these messages takes even more from cpu + between deleting roomvariable because nr1 leaves and creation of new one by other player is an interval where we dont have time for this game!]
just one thing; why cant we use the standard onRoomListUpdate?
when room gets created; server adds roomvariable initAt,
when roomlistupdate; server sends list of rooms with roomvariable initAt for each room and it is 'the client' that does the subtraction
timeLeftToJoin= timeToWaitForUsers - (gettime - initAt)
(that way we dont have to change the OnRoomListUpdate)
and other remark: we will let clients timer run out something like 2 seconds before server to avoid a user clicking "join room" on a room that has already been destroyed by server (of course we will still include error)
thanks again for your input
[remark; I first tried some solutions without server extensions
(like, first user creates roomvariable 'timecreated' when second one comes he copies this locally, if first one leaves this means roomvariable timecreated is lost, second one notices this he creates new roomvariable with same timecreated that he has stored.....)
but this seems not so elegant and i wanted to avoid using server cpu, but i guess sending these messages takes even more from cpu + between deleting roomvariable because nr1 leaves and creation of new one by other player is an interval where we dont have time for this game!]
just one thing; why cant we use the standard onRoomListUpdate?
when room gets created; server adds roomvariable initAt,
when roomlistupdate; server sends list of rooms with roomvariable initAt for each room and it is 'the client' that does the subtraction
timeLeftToJoin= timeToWaitForUsers - (gettime - initAt)
(that way we dont have to change the OnRoomListUpdate)
and other remark: we will let clients timer run out something like 2 seconds before server to avoid a user clicking "join room" on a room that has already been destroyed by server (of course we will still include error)
thanks again for your input
Well.. Here we need Lapo's oppinion.Just one thing; why cant we use the standard onRoomListUpdate?
when room gets created; server adds roomvariable initAt,
when roomlistupdate; server sends list of rooms with roomvariable initAt for each room and it is 'the client' that does the subtraction
timeLeftToJoin= timeToWaitForUsers - (gettime - initAt)
As you probably know there is, among the onRoomListUpdate event on the client side, a onRoomVariablesUpdate event.
I'm not sure it the onRoomListUpdate will catch the variable beeing set when the roomInitialises, but it might catch it if you make sure you set your variables in the init() function of the room Extension.
I think you are right. This might be a lot easyer than I sugested
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
another question;
you say; let the server kill a gameroom thats 'over time',
BUT the user that created this room (or another that joined) is still in the room!
What happens to a user who is still in the room when server destroys it?
does it happen like this; server doesnt destroy the room with "destroyRoom" command (didnt find anything like that) but by forcing LeaveRoom to player that is still in it??
ok, but when you read doc it says "Force a user to leave a room. This command is the equivalent of the leaveRoom() method on the client side. It can be user when working in "multi-room" mode. "
So when we are not in multi-room mode the LeaveRoom command by server doesnt work? He doesnt automatically sends the user back to autojoinroom? We have to let users be in autojoinroom AND gameroom until gamestarted = Y?
(actually this gives a very nice side-effect; until gamestarted=Y we still receive all the updates meant to users in autojoinroom (= waitingroom) and when game is not started we dont have to reload the whole games list because we kept receiving updates to users in!
you say; let the server kill a gameroom thats 'over time',
BUT the user that created this room (or another that joined) is still in the room!
What happens to a user who is still in the room when server destroys it?
does it happen like this; server doesnt destroy the room with "destroyRoom" command (didnt find anything like that) but by forcing LeaveRoom to player that is still in it??
ok, but when you read doc it says "Force a user to leave a room. This command is the equivalent of the leaveRoom() method on the client side. It can be user when working in "multi-room" mode. "
So when we are not in multi-room mode the LeaveRoom command by server doesnt work? He doesnt automatically sends the user back to autojoinroom? We have to let users be in autojoinroom AND gameroom until gamestarted = Y?
(actually this gives a very nice side-effect; until gamestarted=Y we still receive all the updates meant to users in autojoinroom (= waitingroom) and when game is not started we dont have to reload the whole games list because we kept receiving updates to users in!
I don't knowBUT the user that created this room (or another that joined) is still in the room!
What happens to a user who is still in the room when server destroys it?
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
One more thing.
Note that calling the destroy() method of one room extension doesn't destroys the room! That is only a handler for developers to put additional code - used by the server when the room is destroyed.
Disconnecting all users from a non permanent room will lead to the room beeing deleted and the code in the destroy() handler for the xtension in that room beeing called.
If I were you I would disconect users from lobby when they enter the game room. What's the point for a user to recieve updates if he plays a game?
Note that calling the destroy() method of one room extension doesn't destroys the room! That is only a handler for developers to put additional code - used by the server when the room is destroyed.
Disconnecting all users from a non permanent room will lead to the room beeing deleted and the code in the destroy() handler for the xtension in that room beeing called.
If I were you I would disconect users from lobby when they enter the game room. What's the point for a user to recieve updates if he plays a game?
function onJoin(usr) {if (usr.getName() == "Lapo") trace ("All Hail Lapo");}
well i would let them be in both rooms (waiting room + game room) until the game actually starts (roomvariable gamestarted=Y => then only in game room)...
Why? Because we have to take care of all 'special cases':
[when a game room opens the game doesnt really start before 3rd one enters or until timer runs out (if there are 2 players!)]
-> someone can open a gameroom, pick a pawn and after 10 seconds decides he doesnt want to wait and wants to go back to list to join another (if we went out the waiting room we would have to resend the whole list, if he just stayed in he got the updates because he was in both rooms)
-> someone can open a game room and if no-one joins him, he will be kicked out of game room by server after 180 sec and goes back to list of games (again same, if he went out of waiting room....)
but i must say this whole timing thing is a special case, asked by the 'business'
(who would wait for 3 minutes anyway)
Why? Because we have to take care of all 'special cases':
[when a game room opens the game doesnt really start before 3rd one enters or until timer runs out (if there are 2 players!)]
-> someone can open a gameroom, pick a pawn and after 10 seconds decides he doesnt want to wait and wants to go back to list to join another (if we went out the waiting room we would have to resend the whole list, if he just stayed in he got the updates because he was in both rooms)
-> someone can open a game room and if no-one joins him, he will be kicked out of game room by server after 180 sec and goes back to list of games (again same, if he went out of waiting room....)
but i must say this whole timing thing is a special case, asked by the 'business'
(who would wait for 3 minutes anyway)