How do I create a multiplayer "text game" ?

Just started using Construct 2? Post your questions here

Post » Mon Dec 05, 2016 4:35 pm

Hello everyone,

I need to create a game for a research project (in linguistics), but I don't know anything about creating games. I have been trying to use Construct 2 and I think it is a very interesting tool. Nevertheless, I am not sure if what I am trying to do is possible. Here is a description of what I am trying to do :

I need to create a multiplayer game in which players use a chat box to communicate. So, I am currently using the multiplayer chat room example as a basis. The purpose of the game is to name creatures. So, basically, players see a picture of a creature, they enter the name they want in a textbox, and they click on a "vote" button. They can chat during the whole process to come to an agreement. Players get points according to the number of other players who gave the same answer as them. Players must be separated in different chatrooms, so they can't communicate with everybody, but only with the people in their room.

For example, if there are 9 players, they are divided in 3 groups of 3 players. Each player can chat with the two others in the same group, but not with the 6 others from the other groups. However, they get points even if people from others groups gave the same name as they did.

I know it doesn't sound like a very entertaining game, but remember it's for research purpose. So here is a list of the most important questions I have :
- Does this project seem doable on Construct 2 ?
- Is it possible to make the system do an action only when every player answered ? (waiting for everyone to vote, then compare answers, give points and change picture)
- Is it possible to compare a text answer across several chat rooms ?
- Is it possible to make players change from one room to another, randomly, during the game ?

Also, I saw there are a looooot of tutorials out there. So it would really help if you could indicate me which are the one you think will be the most important for me to read. And of course, any advice is welcome !

If anything was not clear or you need more details, please ask.

Edit : I realised that it was actually better to use a timer instead of waiting for every player to do an action, so forget about question 2.

Here I am having a little problem : I am trying to make a random sprite appear every X seconds. I have a global variable "spawn" which is set to a floor random value between 1 and 30 every time an X second timer reach 0. And then I asked the system to create sprite 1 when "spawn" = 1, sprite 2 when "spawn" = 2, etc. On the debugger, I can see the "spawn" variable changing exactly as I wanted to, but the sprite never appear. Any idea what I did wrong ?
B
7
Posts: 18
Reputation: 311

Post » Tue Dec 06, 2016 5:27 pm

Message: Zakeru can only post plain text URLS until they have 500 rep. 1 URLS modified. Why?
Hello again everybody,

I am sorry for the double post, but I wanted to narrow down my questions and share my capx for people who think they can help me.

So the link is here : https://www. dropbox.com/s/vzce7mxqet4o12d/ChatProject.capx?dl=0 (I don't know if I am doing this right)

As you can see, the game is not very sophisticated. Actually, I don't have the sprites I want to use in the end, so I just use random pictures for now. I have 3 major problems so far:

- I found a way to lead players to different chatrooms, but I am not satisfied since I have no way to keep balance between the different rooms. For exemple, I know I will be working with exactly 18 players, so I want to have exactly 6 in each room, but it has to be random.

- I want the "creatures" (presently represented with big numbers from 1 to 30) to appear in a random order and appear only once. A new one should appear every time the timer reaches 0. Here, I can't even make them appear at all and I don't understand why.

- I still have no idea at all for how to compare what players wrote in the "answer" textbox and give them point for every other player that gave the same answer. Also it would be cool if I could save what is written so it could appear on the "previous creatures" page later.

Once again, I don't want you to do it for me, but just to tell me if you think this seems possible and what tutorial I should read. Thank you in advance for your help.
B
7
Posts: 18
Reputation: 311

Post » Wed Dec 07, 2016 9:26 pm

On the debugger, I can see the "spawn" variable changing exactly as I wanted to, but the sprite never appear. Any idea what I did wrong ?


Try this:
  1. Add a family containing all the sprites, e.g."Sprites"
  2. Add a family instance variable, e.g. "index"
  3. Edit that variable for every Sprite and set it to the Sprite's number (don't set it in the event sheet, set it in the object properties)
  4. Delete that long chain of conditions you referred to (Spawn=X, Spawn=Y,...) and replace it by this:
Image

____________________________________________________________

I know I will be working with exactly 18 players, so I want to have exactly 6 in each room, but it has to be random.

I found a way to lead players to different chatrooms, but I am not satisfied since I have no way to keep balance between the different rooms.

In your .capx, I can't find the way you are managing the different chatrooms...

The way I would go about this, is the following:
  • since the Multiplayer-plugin included rooms can't communicate between each other, we need to have multiple game rooms in one actual multiplayer room
  • To assign peers to different rooms on joining, I'd use a global variable storing the room number you are in and using that variable to differentiate between messages that come from the host (to determine whether that message is important to you).
I'd also use three dictionaries, one for each room, to determine how many people there are in one room and whether it is full or not.
Those dictionaries are used by the host. When a peer joins, the host will go through the dictionaries one by one. As soon as one room is found where the dictionary's keycount is below 6, it will send the room number to the peer and add the peer to the dictionary. Randomness should be easy to add here.

________________________________________________________________

I want the "creatures" (presently represented with big numbers from 1 to 30) to appear in a random order and appear only once.


I'd recommend you using @blackhornet 's Smart Random plugin which allows you to get a random value out of a set amount of numbers while assuring that a set amount of numbers doesn't appear multiple times.

_________________________________________________________________

A new one should appear every time the timer reaches 0. Here, I can't even make them appear at all and I don't understand why.

I'd recommend giving the "creature distribution" task to the host only.
The host would either have a "Every X seconds" or a "timer" behavior.
(If you use the timer, broadcast the random value under the "On timer" event. Immediately after that, start a new timer)

Try to transfer this task to the host only and see whether that fixes the issue, we will deal with that later if the problem remains.

__________________________________________________________________

I still have no idea at all for how to compare what players wrote in the "answer" textbox and give them point for every other player that gave the same answer.

Again, the best solution is to give those tasks to the host.

Answer textbox:
When a peer submits the content of the "answer" textbox, it will send it to the host. The host will store that in a dictionary, one for each room, or a single array.
When the host receives an answer, he will check whether that answer already exists in the appropriate dictionary/array coordinate. If it does, it will add one to the value (dictionary) or the array's Z/Y value (array).
If it doesn't exist yet, the host will add a new key (dict) or a new Y value (array).
(In the array, the X value will be the room.)
Note: dictionaries for this will be easier to handle, while an array will be more compact.


Points for players:
This will be a combination of host-/peer-sided to improve performance on the host.
The host will use the same dictionaries /array as mentioned above.
(But since points are room-independent, we don't need to compare the room variables here)
Depending on whether you want the points to be given immediately after one creature round is over or after the whole game is over, there are different approaches.

Immediately:

When the peer submits an answer, he will save what he submitted in a variable to be able to send that to the host at the end of the creature round.
When the round is over, he will send that value to the host.
The host then checks with his dictionaries/array and see whether (and how many times) that answer has been given and send the appropriate amount of points to the peer that sent the answer.


At the end:

The peer will store all his answers in a dictionary, sorted historically.
When the game is over, the peer will send his dictionary (as JSON) to the host. The host will have a dictionary for each peer which he loads from the JSON he just received.
he will then go through his dictionaries/array and see how many times each item in the dictionary has been given before and give points.
Note: since it's probably very unlikely that the same name will appear multiple times across different creatures, we can compare all the dictionaries/the whole array without differentiating between rounds.

______________________________________________________________

tell me if you think this seems possible

Not a casual task, but yes, it is possible.
Though I'd recommend you exporting the project to NW.js later since all that comparing on the host-side will take up some CPU and NW.js can use more CPU power than a browser tab.
(Assuming, you don't use necessarily use high-end PCs only for that project)

_____________________________________________________________

what tutorial I should read

That depends on what topics you think you need help with. I won't put out links for every single object/behavior that will be used in this project, since that would be quite an amount.
And since your project is a very specific, non-generic one, there won't be a tutorial tailored to your project.
If you don't feel sure about a specific element in your project (e.g. arrays or dictionaries), just search for a tutorial for that or ask here or in the forum.

___________________________________________________________________
___________________________________________________________________

That should be about it.
*phew*

PS: Don't think I am a C2 expert. I started using C2 in September this year, so I am in no way worth saying that I know everything about it. I just provide what I think is the best option.
I am sure there are better ways to do this (that I don't know of), but this is the way I would do it.
Last edited by randomly on Fri Dec 09, 2016 4:25 pm, edited 1 time in total.
"We can't solve problems by using the same kind of thinking we used when we created them."
- Albert Einstein
B
27
S
11
G
8
Posts: 528
Reputation: 7,091

Post » Thu Dec 08, 2016 9:57 am

Wow, what a long and detailed answer. Thank you very much for your help, I will try everything you suggested !

Also, I realized the login/login events layouts does not appear when you open the .capx, maybe that is why you couldn't see what I did to send players to different rooms.

Edits :

- I can't use families right now because I am using the free version, but I should be able to buy a license soon, so I will keep that for later.
- By the way, concerning the CPU power. I'm planning to have everybody playing in the same place, so I guess I could use a LAN and that would help a lot, right ?
- The changes I made to login/login events layouts have not been save apparently, my bad.
B
7
Posts: 18
Reputation: 311

Post » Thu Dec 08, 2016 4:20 pm

By the way, concerning the CPU power. I'm planning to have everybody playing in the same place, so I guess I could use a LAN and that would help a lot, right ?

Well, that would at least double the upload/download speed.
This would not decrease the amount the host has to deal with though since the data stays the same, it is just delivered faster.
"We can't solve problems by using the same kind of thinking we used when we created them."
- Albert Einstein
B
27
S
11
G
8
Posts: 528
Reputation: 7,091

Post » Fri Dec 09, 2016 2:28 pm

Message: Zakeru can only post plain text URLS until they have 500 rep. 1 URLS modified. Why?
So your advices made me think about something : let's consider that everybody is on the same room, but the host acts as a filter for messages and thus creates the "groups" of players.

All I need is a global variable "group" for each player that is set on connection by smart random (start 1, end 3, threshold 0). Doing this would guarantee the balance between groups right ?

This solution, if it works, would be good for several reasons. I actually need to create several versions of the game with slightly different parameters. Sometimes, I would need more than 3 groups (so I would need to change only the "end" value of the smart random). Sometimes, I would like to have just 1 player being able to see messages from 2 or more groups (so I would just need to add "& X & Y" to his "group" value).

What do you think about it ? I haven't tried it yet, I'm actually thinking about how to do it properly.

Also, when you say it will be hard for the host CPU, do you think that would actually take a lot of time to deal with all the comparisons ? More than 30 seconds ? Several minutes ? Of course it depends on the computer, but it's just to get an idea of how long it would take.

Do you think it is best if the host is not a player and I just use my best computer only to deal with the host's tasks ?

Edit : Ok, I tried something but I don't know if that would work. So, upon joining the room, each player get a random group value (smart random, 1, 3, threshold 0)

When you are a peer, you send message with a tag corresponding to your group value. And even if you get messages from everyone, you display only those that has a tag corresponding to your group value.

When you are the host, you also send message with a tag corresponding to your group value and you broadcast every message you get. However, you only display those who have a tag corresponding to your group value.

I updated the capx. file, I edited the yellow information texts in event sheets to explain what I intended to do. Do you think that would work ?
https://www. dropbox.com/s/247hslkh28garey/ChatProject.capx?dl=0
B
7
Posts: 18
Reputation: 311

Post » Fri Dec 09, 2016 5:16 pm

All I need is a global variable "group" for each player that is set on connection by smart random (start 1, end 3, threshold 0). Doing this would guarantee the balance between groups right ?

Well, actually it would have to be a bit different.
Since there is a player limit for each room, you need to take into consideration whether the room is already full or not.

The variable "group" won't be set on connection by the peer but by the host.
The host will have three dictionaries, one for each room, in which he stores who is in that room.
When a peer connects, the host will check the first dictionary whether it is full. If there is space, he will add the player to the dictionary and send him his group number.
If the group is full, check the next dictionary.

You can add randomness by multiple ways.
One would be to have every player set a preferred group on start which is generated randomly (pun not intended). This value is sent to the host when connected. The host will then first look in the dictionary with the number that has been sent and continue looking numerically. (System condition "For each ordered").

___________________________________

Sometimes, I would need more than 3 groups

You will have to add the appropriate amount of dictionaries and change the random generation like you said.
(Checking of the dictionaries won't be affected since "For each" automatically looks at the count of the objects)

You will also have to add events to the host "On [groupX] message" to cover all groups.

______________________________________

Also, when you say it will be hard for the host CPU, do you think that would actually take a lot of time to deal with all the comparisons ? More than 30 seconds ? Several minutes ?

I don't have much experience with this, but I'd say not that much. Several minutes? Definitely not.
It depends on many factors.
Of course, it depends on the computer's specs, a bit on the internet speed (not that much though) and on the amount of messages that are posted by the players at the same time.

You would really have to test this out.
One thing to experiment with would be to create a new project, designed for the host only.
This would be started first, would be no player, and his only task would be to handle everything host-related.
Having a separate host instance would increase the performance for everyone, since there won't be one player who is always doing the host tasks and the host won't have to deal with the peer-only stuff.

________________________

When you are the host, you also send message with a tag corresponding to your group value and you broadcast every message you get. However, you only display those who have a tag corresponding to your group value.


Assuming, you don't go with the separate host, that is correct.
As a host, when receiving a message, you would have to get the group number of the user the message came from.
(Compare "FromID" with ID in group dictionary)
Then, you would broadcast the message to everyone with a group tag attached to it.
As a peer, when receiving such a message from the host, you would have to parse the message to retrieve the group number. Shouldn't be too difficult. (If you need help, PM me or google for it)

_________________________________________

When you are a peer, you send message with a tag corresponding to your group value. And even if you get messages from everyone, you display only those that has a tag corresponding to your group value.

When you are the host, you also send message with a tag corresponding to your group value and you broadcast every message you get. However, you only display those who have a tag corresponding to your group value.

Almost correct! (Again, assuming, you don't have a separate host)
As a host, you wouldn't need to send the message with a tag corresponding to your group value, thus, a regular message like a peer would send.
You can simply broadcast it, since the peers will only display messages that come from the host and are declared as "host broadcasts messsage". (Like in your .capx, you probably just wrote that wrong)

________________________________________

Something not related to the Multiplayer part:

I noticed you still have the many, many Sprite1, Sprite2, Sprite3,... events.
Did you try what I wrote on my first post? This would make it more compact and easier to handle.
randomly wrote:Try this:

  1. Add a family containing all the sprites, e.g."Sprites"
  2. Add a family instance variable, e.g. "index"
  3. Edit that variable for every Sprite and set it to the Sprite's number (don't set it in the event sheet, set it in the object properties)
  4. Delete that long chain of conditions you referred to (Spawn=X, Spawn=Y,...) and replace it by this:
Image
"We can't solve problems by using the same kind of thinking we used when we created them."
- Albert Einstein
B
27
S
11
G
8
Posts: 528
Reputation: 7,091

Post » Fri Dec 09, 2016 6:08 pm

Since there is a player limit for each room, you need to take into consideration whether the room is already full or not.


But with a threshold of 0 in the smart random, I would always get a balanced distribution. So even if I do not check if the group is full, the balance would still be maintained. For example, if the smart random generates something like this : 1-3-2 / 2-1-3 / 3-1-2 / 3-1-2 / 3-2-1 / 2-3-1 / 1-3-2 / 1-2-3 / 1-3-2 / ... (where "/" represents the end of a loop)

As long as I have a number of player that is a multiple of 3, I would always get the exact same number of players in each group, right ? I am sorry to insist, I just want to be sure I understood what is wrong with this solution.

Did you try what I wrote on my first post? This would make it more compact and easier to handle.


I wanted to try it, but I am using the free version for now, so I can't use "families" right now. I will have to keep that for later (I mentioned it in one of my edits above, but since it's a mess, you may have missed it XD)

Edit : By the way, I will go for a non separated host for now and think about an alternative if the game is really running too slow. Because that is one fewer computer to put in a room, and that is a non negligible advantage :)

Once again, thank you very much for your help (you definitely earned a special place in my thesis' acknowledgments section ha ha).
B
7
Posts: 18
Reputation: 311

Post » Fri Dec 09, 2016 10:57 pm

But with a threshold of 0 in the smart random, I would always get a balanced distribution. So even if I do not check if the group is full, the balance would still be maintained.

I'm not sure if I misunderstand you. If I comprehend you correctly, you want to generate the group number from the peer, right? Each peer generates his own group number?
If that is correct, I'll tell you why that won't work:
The peer can generate a random number, 1, 2 or 3 and every number is generated just once.
But the peer doesn't know whether a room is full.
So if he generates 2, and keeps that number, he will be in room 2.
But what if there were already 6 users in that room?
Only the host should generate group numbers since _he_ knows whether a room is full.

(I have the feeling, I really didn't understand you..)

___________________________

I wanted to try it, but I am using the free version for now, so I can't use "families" right now.

Ah, right, I forgot about that, sorry.
"We can't solve problems by using the same kind of thinking we used when we created them."
- Albert Einstein
B
27
S
11
G
8
Posts: 528
Reputation: 7,091

Post » Sat Dec 10, 2016 12:38 pm

Well it is still very confusing to me how this whole multiplayer thing work, so maybe my explanations are not good. But let's suppose I don't actually put a limit to the number of member in a group. So nobody check for that (neither host nor peer nor the system or whatever).

Instead, the group value is just given to every player by one and only infinite string of "1-2-3" loops (in random order) generated by the smart random. Upon connexion, every player gets the next value in the smart random list. Of course, this would work only if it is possible to use the same string of "1-2-3" to set the group value of every player. If this is possible, then, everytime the total number of player is a multiple of 3, I would automatically get a balanced distribution of player. The advantage is that I would not need to make any modification if I want to have bigger groups, just keeping sure the total number of player is a multiple of 3 would guarantee that the groups are balanced.

I don't know if this is more clear...
B
7
Posts: 18
Reputation: 311

Next

Return to Beginner's Questions

Who is online

Users browsing this forum: plinkie and 1 guest