Using GameAnalytics (Retention and Monetisation) (Ez mode)


#22

Figured it out. Had to hard-code the keys into your script. Just putting them into the initialization function doesn’t work.


#23

Ya just resolved. Thanks to @NewFissy for pointing the error out and how to fix it.


#24

There’s also an issue that I fixed by switching these two lines:


#25

Right now it’s

PlayerData[Player.Name] = Functions.AnnotateEvent:InvokeClient(Player)
PlayerJoinTimes[Player.Name] = os.time()

And your diagram infers that’s right, but I assume that’s not what you mean?

What’s the issue too, please?


#26

I kept getting errors when the player left saying that the player never had a PlayerJoinTime.

Also I added a :WaitForChild() between Functions and AnnotateEvent because I was getting race conditions.


#27

Thanks, I implemented both these changes.


#28

Still having trouble. I can’t get it to work. I have HTTP enabled and the correct keys where they should be. :confused: The site doesn’t show anything an no errors.


#29

There is a delay on the real time display of 15-45 minutes. Is it printing out the right things?


#30

It’s been about 40 minutes and there’s 0 data. Even the ‘Live feed’ for Latest 10 processed events is blank. The script appears to be running without issue.


#31

I assume you’re adding players right? It won’t do anything if you don’t add a player lol. Does it print out the request_init worked?

If it does, then check if SubmitEvents is being fired. To check for that being successful there is the following print “Submit Events Succeeded! Delete me on line 175”, which is actually on 202, does that print?


#32

It’s on a place with 1,200 players online. Yes, I printed to make sure it wasn’t erroring inside of a pcall or something.


#33

Does it print Submit Events Succeeded though?


#34

What line is that on?


#35

Alright. May I point out a few things that you could consider adding in this module ?

  1. You should actually store the amount of sessions that the user has (by saving it in a datastore and sending that data to GA). At the moment you don’t do this, causing a lack in data regarding that point :wink:

“The SDK should count the number of sessions played since it was installed (storing locally and incrementing). The amount should include the session that is about to start.”
Source : http://www.gameanalytics.com/docs/rest-api-doc

  1. A lovely feature would be a DEVELOPMENT key branch and a PRODUCTION key branch, also don’t record any data when you are currently testing in Studio. That doesn’t make sense and will cause false data !

  2. Add the math to actually cut the tax of the ROBUX transactions. The Game developers only should see the money that is actually coming in his account.


#36

This method allows even more catergories :wink: Oh and the fact that they got a Controller in there PC is faulty, there are also a lot of players that like playing with a Controller on a PC

local userInputService 		=	game:GetService("UserInputService");
local guiService 			=	game:GetService("GuiService")


local function getPlatform()

	local Platform 			=	"windows";

	-- If touch enabled we have either an Phone, Tablet or an PC (future)
	if userInputService.TouchEnabled then
		
		-- Computers don't have Gyroscopes or Accelerometers.
		if userInputService.GyroscopeEnabled or userInputService.AccelerometerEnabled then 

			-- http://devforum.roblox.com/t/how-do-you-determine-what-platform-the-player-is-playing-on/27539/11
			if game:GetService("Workspace").CurrentCamera.ViewportSize.Y > 600 then
				Platform 	=	"Tablet";
			else
				Platform 	=	"Phone";
			end

		end
	else

		-- If we have an TenfootInterface.
		if guiService:IsTenFootInterface() then
			Platform 		=	"Console";
		end

	end

	return Platform;
end 

local function getOS()
	local Platform 			=	getPlatform();
	local OS 				=	"android 4.4.4";

	if Platform == "PC" then
		local isWindows 	=	guiService:IsWindows();

		if isWindows then
			OS 				=	"windows";
		else
			OS 				=	"mac";
		end
	end

	return OS;
end

local function createInformation()
	local platform 			=	getPlatform();
	local os_version		=	"windows 8.1";

	if platform == "Tablet" then 
		os_version			=	"android 4.4.4";
		platform 			=	"android";
	elseif platform == "Phone" then 
		os_version			=	"android 4.4.4";
		platform 			=	"android";
	end

	return 	{
			["platform"] 	=	platform,
			["os_version"]	=	os_version;
	}
end

#37

What data is it missing? I talked to the folks at game analytics (because it’s not set up for games like roblox, it’s set up for things like apps), and they said this would be fun.

I could explicitly add that in I guess, and probably will do when I come to update it shortly. For the time being I recommend just changing out the keys.

I considered this strongly, but instead I decided against it and went with how Roblox displayed their data. I may make this toggleable so you choose if you want to deduct tax and chose if you want it to convert to USD

Ty for your input :smiley:


#38

What data is it missing? I talked to the folks at game analytics (because it’s not set up for games like roblox, it’s set up for things like apps), and they said this would be fun.

Hmmm, the thing with SESSION_NUM is that they actually use it to get the returning users, DAU / etc (Dashboards > Overview tab)


#39

That’s not true, they store this internally and process it themselves. I think Session_Num like that is if you’re logged in on multiple devices or smtn else and therefore are running multiple sessions. It could be what you suggest it’s for as well, but it works w/o it.

The data you referenced for this is complete in it’s entirety for Castle Defenders which uses this module.


#40

Interesting. Or perhaps when the device doesn’t has internet so they can send it when the device becomes online again or anything in that nature :slight_smile:


#41

It might be a good idea to add the following code to Analytics.ServerInit().

game:BindToClose(function()
wait(1)
Run()
end)

The Run() function in PlayerRemoving didn’t fire for me while testing in PlaySolo, causing the SubmitEvents function not to get called either.