I know that some people already asked a similar question but their question was about challenges. My game is a city builder game similar to Clash Of Clans. I want at some point in the game the player will be able to get a random player in the same level and access his "scriptData". He will be changing the random's player data (Stealing Gold for example)
I don't think that this can be considered as a challenge, right? The other player in this case won't do anything except being robbed!
Best Answer
R
Ryan Fuller
said
about 7 years ago
So first of all you would want to do this with cloud code via an event. The problem is that the gamesparks system "player" collection is unqueryable via cloud code. But this is actually good for you because you probably don't want to store all the info you will need on a player for a city building game in the player's script data. That will get messy and complex really quickly. But there's a solution! Create a custom collection for storing all this info with a document for each player. See the article by gamesparks here for how to set that up:
Once you do that you'd have a playerList collection with id = player id and a level. Then you can create an event with cloud code something like this:
getRandomPlayerState();
function getRandomPlayerState(){
var query = {
"_id" : { "$ne" : Spark.getPlayer().getPlayerId() }//,
};
var fields = {};
// Iinefficient, switch to $sample aggregation when Gamesparks upgrades to mongodb v3.2
var count = Spark.runtimeCollection("playerList").find(query, fields).count();
var rand = Math.floor(Math.random()*count);
var results = Spark.runtimeCollection("playerList").find(query, fields).skip(rand).limit(1).toArray();
if(results){
var playerToRob = results[0];
}
}
That will grab a random playerList doc from the collection not including the player who is robbing (so he doesn't rob himself!). As far as matching the player level, you'd either first have to do a separate query for the robbing player's own level (if it's only stored in the playerList), or you might be able to write a really clever aggregation to get it. In fact, once gamesparks upgrades to mongodb v3.2 you might be able to make one really clever aggregation get the random player in one database query (something like $match all players $ne to self with level = to self level, $group to count, and then $sample to randomly pick one). To see an intro to aggregation by gamesparks check here:
From there you have a random player, you can call Spark.loadPlayer(playerToRob's id) to be able to debit currency from them. And finally you could then send a message to both the robber and the robbed players from cloud code to notify them. Whew, hope that helps you get started!
So first of all you would want to do this with cloud code via an event. The problem is that the gamesparks system "player" collection is unqueryable via cloud code. But this is actually good for you because you probably don't want to store all the info you will need on a player for a city building game in the player's script data. That will get messy and complex really quickly. But there's a solution! Create a custom collection for storing all this info with a document for each player. See the article by gamesparks here for how to set that up:
Once you do that you'd have a playerList collection with id = player id and a level. Then you can create an event with cloud code something like this:
getRandomPlayerState();
function getRandomPlayerState(){
var query = {
"_id" : { "$ne" : Spark.getPlayer().getPlayerId() }//,
};
var fields = {};
// Iinefficient, switch to $sample aggregation when Gamesparks upgrades to mongodb v3.2
var count = Spark.runtimeCollection("playerList").find(query, fields).count();
var rand = Math.floor(Math.random()*count);
var results = Spark.runtimeCollection("playerList").find(query, fields).skip(rand).limit(1).toArray();
if(results){
var playerToRob = results[0];
}
}
That will grab a random playerList doc from the collection not including the player who is robbing (so he doesn't rob himself!). As far as matching the player level, you'd either first have to do a separate query for the robbing player's own level (if it's only stored in the playerList), or you might be able to write a really clever aggregation to get it. In fact, once gamesparks upgrades to mongodb v3.2 you might be able to make one really clever aggregation get the random player in one database query (something like $match all players $ne to self with level = to self level, $group to count, and then $sample to randomly pick one). To see an intro to aggregation by gamesparks check here:
From there you have a random player, you can call Spark.loadPlayer(playerToRob's id) to be able to debit currency from them. And finally you could then send a message to both the robber and the robbed players from cloud code to notify them. Whew, hope that helps you get started!
J
Joseph Botros
said
about 7 years ago
Thanks a lot for the help :)
R
Ryan Fuller
said
about 7 years ago
No problem!
R
Ricardo Nardochone
said
over 6 years ago
I know this is quite old post, but I cant figure out how to load the random player ID into Unity. Can someone help?
R
Ryan Fuller
said
over 6 years ago
Hey it's the same guy who gave the original answer.
Are you saying you have all the stuff I wrote set up in cloud code but you don't know how to send the playerId of the random player to the client?
If so, all you need to do is use the script sendmessage api from cloud code, and then add a listener to your C# to receive the message and respond.
Yes I'm developing it in Unity, I have created a new Cloud Code named "FIND_PLAYER" with the code you wrote.
Then I was calling it from Unity something like:
new GameSparks.Api.Requests.LogEventRequest()
.SetEventKey("FIND_PLAYER").Send((response) => {
Here I dont know what to do to get the generated random ID
}
I cant find sendmessage in the api documentation to know how it works. I know is much to ask but you give me an example?
Thanks!
R
Ryan Fuller
said
over 6 years ago
So if you don't need to send a message to the random player, it's much simpler (i.e. if you only need the player who's sending the request to receive the response), you can just set the player to the scriptData in cloud code:
var randomPlayer = // Code you already have
Spark.setScriptData("randomPlayer", randomPlayer);
And as to how you grab it on the client, get it from the response scriptData:
new GameSparks.Api.Requests.LogEventRequest() .SetEventKey("FIND_PLAYER").Send((response) => {
if(response.HasErrors){
// Log the errors
}
else {
GSData randomPlayer = response.ScriptData.GetObject("randomPlayer");
// Get details about player (dependant on the structure of the player)
// For example:
// int level = randomPlayer.GetInt("level") ?? 0;
}
}
1 person likes this
R
Ricardo Nardochone
said
over 6 years ago
Yes, sorry I dint updated here that I alredy have it working! My problem was I dont fully understand how setScriptData works >.<
Now I do and I have it working and just a moment ago I was able to solve the next step, Load the enemy player data in Unity!
Thanks for the help Ryan!
G
Gabriel Aguiar
said
over 5 years ago
I know this question is a bit old, but would anyone actually know how to use aggregate as Ryan Fuller suggested? I basically need the same solution: find a random player within a level range, but I'm not really familiar with MongoDB hence the doubt.
Thanks!
R
Ryan Fuller
said
over 5 years ago
Ryan Fuller here, haha.
Assuming you have a runtime collection named "playerState" with a field on the documents named "level" something like the following should work:
var match = {"$match": { "level": { "$gte": MIN_LEVEL, "$lte": MAX_LEVEL } };
var sample = { "$sample": { "size": 1 } };
var result = Spark.runtimeCollection("playerState").aggregate(match, sample);
var randomPlayer = result[0];
1 person likes this
R
Ryan Fuller
said
over 5 years ago
Also note, using multiple aggregation stages (e.g. match and sample in this case) in GS is a little weird (unless they have fixed that).
-In the NoSQL explorer, if you have multiple aggregation stages, you have to put them in an array [{...}, {...}]
-According to the docs, in cloud code, the method signature is the first stage followed by an array of the rest of the stages
-But I have had success using 2 stages without an array in cloud code, like I showed above
All that to say if something's not working with the aggregation method call, play around with the params / putting them in an array.
G
Gabriel Aguiar
said
over 5 years ago
Hi Ryan, that's really fantastic! Thanks a lot!
I even slightly modified the match, so it doesn't peek the same player that does the request and to allow me to select a type of player:
Joseph Botros
Hello,
I know that some people already asked a similar question but their question was about challenges. My game is a city builder game similar to Clash Of Clans. I want at some point in the game the player will be able to get a random player in the same level and access his "scriptData". He will be changing the random's player data (Stealing Gold for example)
I don't think that this can be considered as a challenge, right? The other player in this case won't do anything except being robbed!
So first of all you would want to do this with cloud code via an event. The problem is that the gamesparks system "player" collection is unqueryable via cloud code. But this is actually good for you because you probably don't want to store all the info you will need on a player for a city building game in the player's script data. That will get messy and complex really quickly. But there's a solution! Create a custom collection for storing all this info with a document for each player. See the article by gamesparks here for how to set that up:
https://support.gamesparks.net/support/discussions/topics/1000070846
Once you do that you'd have a playerList collection with id = player id and a level. Then you can create an event with cloud code something like this:
That will grab a random playerList doc from the collection not including the player who is robbing (so he doesn't rob himself!). As far as matching the player level, you'd either first have to do a separate query for the robbing player's own level (if it's only stored in the playerList), or you might be able to write a really clever aggregation to get it. In fact, once gamesparks upgrades to mongodb v3.2 you might be able to make one really clever aggregation get the random player in one database query (something like $match all players $ne to self with level = to self level, $group to count, and then $sample to randomly pick one). To see an intro to aggregation by gamesparks check here:
https://docs.gamesparks.net/howtos/cloud-data/partial-updates
From there you have a random player, you can call Spark.loadPlayer(playerToRob's id) to be able to debit currency from them. And finally you could then send a message to both the robber and the robbed players from cloud code to notify them. Whew, hope that helps you get started!
- Oldest First
- Popular
- Newest First
Sorted by Oldest FirstRyan Fuller
So first of all you would want to do this with cloud code via an event. The problem is that the gamesparks system "player" collection is unqueryable via cloud code. But this is actually good for you because you probably don't want to store all the info you will need on a player for a city building game in the player's script data. That will get messy and complex really quickly. But there's a solution! Create a custom collection for storing all this info with a document for each player. See the article by gamesparks here for how to set that up:
https://support.gamesparks.net/support/discussions/topics/1000070846
Once you do that you'd have a playerList collection with id = player id and a level. Then you can create an event with cloud code something like this:
That will grab a random playerList doc from the collection not including the player who is robbing (so he doesn't rob himself!). As far as matching the player level, you'd either first have to do a separate query for the robbing player's own level (if it's only stored in the playerList), or you might be able to write a really clever aggregation to get it. In fact, once gamesparks upgrades to mongodb v3.2 you might be able to make one really clever aggregation get the random player in one database query (something like $match all players $ne to self with level = to self level, $group to count, and then $sample to randomly pick one). To see an intro to aggregation by gamesparks check here:
https://docs.gamesparks.net/howtos/cloud-data/partial-updates
From there you have a random player, you can call Spark.loadPlayer(playerToRob's id) to be able to debit currency from them. And finally you could then send a message to both the robber and the robbed players from cloud code to notify them. Whew, hope that helps you get started!
Joseph Botros
Thanks a lot for the help :)
Ryan Fuller
No problem!
Ricardo Nardochone
I know this is quite old post, but I cant figure out how to load the random player ID into Unity. Can someone help?
Ryan Fuller
Hey it's the same guy who gave the original answer.
Are you saying you have all the stuff I wrote set up in cloud code but you don't know how to send the playerId of the random player to the client?
If so, all you need to do is use the script sendmessage api from cloud code, and then add a listener to your C# to receive the message and respond.
GameSparks - Messaging
1 person likes this
Ricardo Nardochone
Yes I'm developing it in Unity, I have created a new Cloud Code named "FIND_PLAYER" with the code you wrote.
Then I was calling it from Unity something like:
new GameSparks.Api.Requests.LogEventRequest() .SetEventKey("FIND_PLAYER").Send((response) => {
Here I dont know what to do to get the generated random ID
}
I cant find sendmessage in the api documentation to know how it works. I know is much to ask but you give me an example?
Thanks!
Ryan Fuller
So if you don't need to send a message to the random player, it's much simpler (i.e. if you only need the player who's sending the request to receive the response), you can just set the player to the scriptData in cloud code:
And as to how you grab it on the client, get it from the response scriptData:
1 person likes this
Ricardo Nardochone
Yes, sorry I dint updated here that I alredy have it working! My problem was I dont fully understand how setScriptData works >.<
Now I do and I have it working and just a moment ago I was able to solve the next step, Load the enemy player data in Unity!
Thanks for the help Ryan!
Gabriel Aguiar
I know this question is a bit old, but would anyone actually know how to use aggregate as Ryan Fuller suggested?
I basically need the same solution: find a random player within a level range, but I'm not really familiar with MongoDB hence the doubt.
Thanks!
Ryan Fuller
Ryan Fuller here, haha.
Assuming you have a runtime collection named "playerState" with a field on the documents named "level" something like the following should work:
1 person likes this
Ryan Fuller
Also note, using multiple aggregation stages (e.g. match and sample in this case) in GS is a little weird (unless they have fixed that).
-In the NoSQL explorer, if you have multiple aggregation stages, you have to put them in an array [{...}, {...}]
-According to the docs, in cloud code, the method signature is the first stage followed by an array of the rest of the stages
-But I have had success using 2 stages without an array in cloud code, like I showed above
All that to say if something's not working with the aggregation method call, play around with the params / putting them in an array.
Gabriel Aguiar
Hi Ryan, that's really fantastic! Thanks a lot!
I even slightly modified the match, so it doesn't peek the same player that does the request and to allow me to select a type of player:
var match = {"$match": { "level": { "$gte": MIN_LEVEL, "$lte": MAX_LEVEL }, "type" : type, "player_id" : { "$ne" : playerID } } };
Thanks again! Really helpful!
1 person likes this
Ryan Fuller
Awesome! Glad to be of help.
-
Documentation Notes
-
Design issues with user events
-
Using NoSQL
-
Runtime Collections vs Metadata Collections
-
Anonymous authentication from browser app
-
Modules
-
Movement With Unity
-
Problem with url parameters for downloadables
-
Querying NoSql GameSparks database
-
Challenge accesType
See all 2487 topics