Find User here you can look for a user

My Colony 2 Stat Reporting Service for Developers

2mo
#1
Beginning with My Colony 2 v0.21.0, the game has a built-in stat reporting service that developers are free to take advantage of if they wish. This thread will stay updated as features are added and changes made to how stat reporting works.

MC2 players can easily opt in to a third party stat reporting service by opening the Statistics window of their game. The World section will provide an input box where players can enter a URL (or comma separated series of URL) endpoint for game stat collection.


Once set, the endpoints selected by the user will periodically receive JSON encoded game statistics via HTTP post. It is up to the endpoint maintainer to ensure that their URL can receive cross origin HTTP requests. Endpoints can be built with whatever technology the maintainer wishes.

To help get you started with developing a stat reporting endpoint, here are some code samples in both PHP and Python:

PHP: /viewpage.php?p=43258#p43308
Python: /viewpage.php?p=43258#p43308

The base JSON data that will be sent to the endpoint via HTTP post looks like this:

{
event: "eventCode",
sid: "server-uuid",
ses: "session-uuid",
cli: "client-uuid",
gid: "game-uuid",
aun: "ape apps username",
data: {}
}

Every post will be formatted as above and contain those seven fields, event, sid, ses, cli, gid, aun and data, data generally being an object containing further data. The data object will differ depending on the event code. The rest of the fields are as follows:

fieldinfo
eventcurrent possible event codes: serverConnected, serverDisconnected, statReport
sidserver id: a unique id for the current world (aka, save game). The server ID is also visible to the player as seen in the screenshot above, meaning an endpoint operator could theoretically use it as an authentication key if they wanted to.
sessession id: every time the user opens MC2, they are assigned a new session id. can be used to track how many unique times the player has opened the game
cliclient id: assigned the first time a player opens MC2 on a device and is retained. can be used to help identify multiple worlds from the same player
gidgame identifier: For stock My Colony 2, the game identifier will always be a999fe76-ff1c-5935-e365-755089ba8982 If a total conversion mod author knows what he/she is doing, their mod should have a different identifier from the base game (this can be set in the Metadata section of the game editor). This can be used to organize data based on mod (or to easily support future games based on the MC2 engine), but it does require that the mod author properly changed the game identifier on their mod.
aunape apps username: if the player is signed in and authenticated with their Ape Apps Account, this field will be set with their username.

Every post sent to the logging endpoint will contain the above fields, so you should be able to count on them when designing endpoint logic.

The data field will be different (or even blank) depending on the event code associated with the request. Below is a reference for the data currently sent with each endpoint. You may bookmark this page for reference, as it will be updated when new data points are added.

Event: serverConnected

fieldinfo
gameDataThis is a hashed checksum of all of the game data objects loaded for the current world. This will be the exact same hash for all players playing the same version of stock My Colony 2, and will be different when mods/addons are activated. This is useful if you are developing rankings/leaderboards and want to verify that all users are playing on an even field.
worldTypeIdThis is the uuid for the game data object associated with the current world (eg Red Planet, Water World, etc).
worldTypeNameThe readable name for the current world type above, as set in the game data object (not translated).
worldNameThe name of this world (the save game, not the planet type). ex Strange New World, or whatever the player chose.
gameVersionThe host version of My Colony 2 that this session is on (ex v0.21.0)
createdTimestamp of server first creation
hostOSWhat operating system this session is running under (ex windows, android, ios, etc)
gameSessionDiffering from the top level ses session id, the gameSession id is unique every time the game file is loaded. Can be used to link stats from connection to disconnection.
universethe universe code this world is connected to


Event: serverDisconnected

fieldinfo
gameSessionDiffering from the top level ses session id, the gameSession id is unique every time the game file is loaded. Can be used to link stats from connection to disconnection.


Event: statReport

fieldinfo
bannedPlayersTotal number of players currently banned from this game.
exploredChunksHow many chunks have been generated (aka "explored") on this world.
playersObjects containing extended information for each player in the game (detailed in below table)
settledChunksNumber of chunks that contain player built structures
settlementsObjects containing extended information for each settlement in the game (detailed in below table)
totalGDPquick reference containing the sum of all settlement GDPs in world
totalMoneyquick reference containing the sum of all player money balances in world
totalPlayersquick reference containing the sum of all players in world
totalPlaytimetotal time in minutes that this server has had at least 1 player connected and playing
totalPopulationquick reference containing the sum of all settlement populations in world
utilitiesObjects containing total utility output and consumption in world


Object: statReport.players

fieldinfo
adminboolean, is this player an admin
civdata object id for the civilization this player is playing as
colorplayer color hex code
idserver assigned unique player id
joinedtimestamp for when player first joined server
levelplayer's level
modboolean, is this player a moderator
moneyplayers current balance of money
playTimehow many minutes this player has been connected and active
researchhow much research the player currently has
usernameif signed in to Ape Apps Account, this is their username. Otherwise, null


This post will continue to be updated and maintained as changes are features are added to the reporting function. Please use this thread for questions/comments/suggestions/requests, etc.
Owner of Ape Apps, LLC
2mo
#2
Hey Bast, all of this sounds nice. I'll play around with it a bit more in the coming week.

To continue the discussion we had here, I would suggest that when creating a server, you can define a "default" or even "mandatory" endpoint for players joining the world.

For example I can create my Node.js sandalone server, and I want to monitor the activity of the players on my server. I define a default endpoint which leads to my server for example, and then all players entering my world will have this endpoint in their stats window by default. The endpoint can either be optional or mandatory to keep.

Look at this beautiful art :

(o-) is supposed to be a toggle switch

As for personal worlds (not sandalone but with other players able to connect), maybe the endpoints of the creator of the server can be put in the "default server" endpoints section but as an opt-in option
Creator of Coloniae
Admin of the MC2 translation project
2mo
#3
Hey @Sobeirannovaocc I should mention, that the Endpoints section only shows up for the game server, and connected client players do not even see this section. So when the Server itself is reporting every minute or so, it is sending data for all settlements/players on the entire server. This way each player who connects to a server does not even have to worry about it. This way traffic to the endpoint is reduced, as only one call needs to be made for all players on the server, VS all players reporting basically the same data.
Owner of Ape Apps, LLC
2mo
#4
Ooh ok I understand. This makes sense of course.
I have a question, I don't quite get what the "Server ID" section of the menu is for if it's sent in the stat report anyway...
Creator of Coloniae
Admin of the MC2 translation project
2mo
#5
It may have no use whatsoever for Coloniae.

The idea was that suppose somebody was creating a stats endpoint and wanted to be able to "whitelist" people first, so that only certain colonies could use the service. Maybe someone would have a Discord bot or just wanted a private stats pool for their server or what have you. They could require players to register their colony first by providing the server id, before giving them access to the URL. This is just an example, but that was what the thinking was there. To be able to support more specialized or private statistics databases.

It may be that it never gets used by anyone, but the option is there, @Sobeirannovaocc
Owner of Ape Apps, LLC
1mo
#6
I see. @bastecklein , do you confirm that the IDs (session id, server id, game id, and all game object IDs) will always be 36 chars in length ? it looks like 16 bytes in hex representation (=>32 chars) + 4 "-", but will this remain the same ?

edit : just to know if I can put char(36) in my db, or maybe there is a better way, how did you define it yourself ?
Creator of Coloniae
Admin of the MC2 translation project
1mo
#7
Yes the id strings should always be 36 characters long @Sobeirannovaocc

tbh in my testing database i stored them in a varchar field with length of 64, idk why.
Owner of Ape Apps, LLC
1mo
#8
Here is some sample PHP code to help get started in building a collection endpoint:


header("access-control-allow-origin: *");
header("access-control-allow-headers: Content-Type");

$json = file_get_contents('php://input');
$data = json_decode($json);

$event = $data->event;
$worldId = $data->sid;
$sessionId = $data->ses;
$clientId = $data->cli;
$gameId = $data->gid;
$apeAccount = $data->aun;

$extData = $data->data;
Owner of Ape Apps, LLC
1mo
#9
Here is a sample code in Python/Flask, and how to avoid CORS problems :


@api_blueprint.route('/mc2report', methods=['POST', 'OPTIONS'])
def mc2report():
if request.method == 'OPTIONS':
resp = make_response('this is the response to OPTIONS call.')
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers["Access-Control-Allow-Headers"] = "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
return resp
try:
event = request.json['event']
sid = request.json['sid']
ses = request.json['ses']
cli = request.json['cli']
gid = request.json['gid']
aun = request.json['aun']
except KeyError:
abort(400)
return
try:
data = request.json['data']
except KeyError:
data = {}
# do what you want
resp = make_response(jsonify({'success': True}))
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp

Maybe @bastecklein you can link your post for php as well as this post in the first post above for reference
Creator of Coloniae
Admin of the MC2 translation project
Welcome
Ape Apps, LLC is an independent software development company founded in 2010 by Brandon Stecklein. Over the years, Ape Apps has published over 400 apps and games across various platforms. You can get in touch with Brandon on Twitter or by leaving a post on his wall @bastecklein
App of the Day