gameanalytics / ga-sdk-roblox Goto Github PK
View Code? Open in Web Editor NEWRepository for GameAnalytics Roblox SDK
License: MIT License
Repository for GameAnalytics Roblox SDK
License: MIT License
No way to disable debug messages in studio without modifying SDK code
The "dequeueMaxEvents" function in Events.lua has a couple of incorrect references to "self" in the case where the number of events in the queue exceeds MAX_EVENTS_TO_SEND_IN_ONE_BATCH.
I have noticed that the module sends wrong arguments to Rest API. Severity of the error should be lowercased. Errors don't show up in GA.
Hi there,
Great work ! Just a heads-up for you guys, ROBLOX is releasing the bit module of Lua soon to the platform, it might be better to do this instead of using Lockbox in the future.
https://developer.roblox.com/en-us/resources/release-note/Release-Notes-for-392
Postie's been updated and GameAnalytics needs to update. In the update, coroutine.resume and coroutine.wrap were switched out for BindableEvents and fast spawns to avoid obscuring errors and a critical bug with Postie.InvokeServer was fixed (though I don't believe GA uses this function).
The updated version can be retrieved from: https://www.roblox.com/library/2884729639/Postie
I love using this module and this tool entirely, and I do want to ensure that I'm always running the latest version with all the new additions, however going over here to Github for every new update, however small it may be, can definitely seem like a bit of a waste of time.
They have released instructions on how to actually add a module into RoStrap which can be seen here.
What this would allow is for users to just simply press a button in the RoStrap plugin and easily update to the latest version, without even needing to leave studio.
I'm trying to add the SDK to my game and have followed the steps to add the module, move scripts to the right place, and add my keys, but I'm getting errors related to scripts trying to require a script named Table:
10:06:53.743 - Attempted to call require with invalid argument(s).
10:06:53.743 - Stack Begin
10:06:53.744 - Script 'ServerStorage.GameAnalytics.GAResourceFlowType', Line 1
10:06:53.744 - Stack End
Contents of GAResourceFlowType:
local Table = require("Table")
return Table.ReadOnly({
Source = "Source";
Sink = "Sink";
})
I can't find anything called Table.
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 262 in aafb558
UIS.TouchEnabled will be true for laptops with touchscreens, so the existing function will flag these devices as mobile when they're not. This can be fixed by checking if a mouse exists as well:
function getPlatform()
if (GS:IsTenFootInterface()) then
return "Console"
elseif (UIS.TouchEnabled and not UIS.MouseEnabled) then
return "Mobile"
else
return "Desktop"
end
end
string.len is deprecated. To get the length of a string, use # e.g. local s = "string" print(#s)
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 96 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 101 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 983 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1016 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1024 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1025 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1069 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1084 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1257 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1305 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1386 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1606 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1732 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 2157 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 2515 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 2578 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3364 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3367 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3370 in aafb558
I have plans of opening a pull request adding this feature sometime this week (if I remember).
My idea:
MarketplaceService:UserOwnsGamePassAsync()
(Unfortunately developers will need to insert a list of game pass IDs into settings manually because Roblox doesn't provide an API to retreive the game's game passes)MarketplaceService:GetProductInfo()
to get info about the game passesThis should be pretty easy to implement, maybe an hour at most. The biggest down side to this is that if the price changes between a player purchasing it and opening the game the event sent to GameAnalytics will be inaccurate, but this probably wouldn't happen very often.
LocalizationService:GetCountryRegionForPlayerAsync()
API Reference
This was introduced in September but I just found out about it today and this could be a really great addition to this!
The HttpApi.HashLib.Base64 is named "base64" but the script calls it as "Base64".
I don't know how if this is required for GA, but this seems like a huge oversight.
I know you can use :initialize
, but it still seems too easy to mess that up.
Rojo 0.4 is end of life, you should upgrade to Rojo 0.5 There is an migration guide here: https://rojo.space/docs/0.5.x/guide/migrating-to-epiphany/.
This gives the benefit of not only continuous support, but also rojo build
, which would replace generate_rbxmx_file.py
.
This causes all sorts of slowness in adding new events. Half the time it's already ordered properly.
Use insertion properly.
If a player leaves before their data is loaded from the datastore then this line in ga:PlayerRemoved() will cause an error:
if not PlayerData.PlayerTeleporting then
There should be a check to determine if the data exists before checking the PlayerTeleporting variable.
Not sure if I'm missing something, but the rate is .0035, not .35. This would suggest that every 100 Robux spent, I would get $24.50 (I wish).
Also, why is it floored?
Removing an event from the threading queue is O(n), with large number of queued events, this causes errors.
Related to #21
--Validate
if script.Parent.ClassName ~= "PlayerScripts" then
error("GameAnalytics: Disabled client")
return
end
error("Test")
Info/GameAnalytics: Add ERROR event: {severity:error, message:error("Test"):1: Test}
Info/GameAnalytics: Event queue: Sending 1 events.
16:09:13.818 - Warning/GameAnalytics: Event queue: Failed to send events.
Debug/GameAnalytics: Failed Events Call. Bad request. Response: [{"event":{"session_num":1,"severity":"error","category":"error","manufacturer":"unknown","os_version":"uwp_desktop 0.0.0","message":"error(\"Test\"):1: Test","v":2,"device":"unknown","client_ts":1551910380,"platform":"uwp_desktop","build":"alpha-1.26.2","session_id":1,"user_id":"DummyId","sdk_version":"roblox 1.2.2"},"errors":[{"error_type":"wrong_type","path":"/session_id"}]}]
I checked the API error received, and it's a 6: bad request. Not sure if this is an issue with the sandbox API, or something internal with the formatting. Will investigate further.
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 170 in aafb558
It is necessary for ProcessReceipt callbacks to explicitly return a ProductPurchaseDecision enum value or else the purchase will fail and the buyer will be refunded in a few days. This function should return Enum.ProductPurchaseDecision.PurchaseGranted when the purchase is successful. See this page for more information:
https://developer.roblox.com/api-reference/callback/MarketplaceService/ProcessReceipt
I shouldn't have to edit the code inside, I should just be able to git submodule add
and have it just work.
I am running into an issue where I am trying to submit events for players who have not yet loaded - I think the library is waiting for the player data to load from the datastore. Is there a way to determine if a player is ready for events, or could one be added?
I also want to add custom dimensions to each player, and this is tricky to time. Maybe a callback could be added that is triggered after the player is loaded?
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 170 in aafb558
MarketplaceService.ProcessReceipt is a callback that can only be registered to one function. When the GameAnalytics SDK registers a callback, any developer callbacks will be overwritten and no longer invoked. When a developer registers a callback, the GameAnalytics callback will be overwritten and no longer invoked.
The GameAnalytics SDK should require developers to manually give it purchase information -- not hook into ProcessReceipt directly -- so that it does not create conflicts like this.
Game keys aren't even set in manual configuration mode. You have to use the Settings.lua file.
I didn't want to conflict with existing names, however GameAnalytics requires this specific name in this specific service.
It would be great if you could move code from GameAnalyticsServer to the main module. I don't see why we would have to use two server scripts to setup game analytics. The Settings table should also be moved to GameAnalyticsServerInitUsingSettings instead of being a table inside of the GameAnalytics module. At the moment every time I want to update GameAnalytics to the latest version I have to save my Settings module, replace all files with the new ones and add my settings back to the module. Ideally, there should be only 1 server script where we modify the settings which we can send to the "initialize" method. Initialization should accept all arguments which the Settings module has at the moment.
My server script should look something like this
local ServerStorage = game:GetService("ServerStorage")
local GameAnalytics = require(ServerStorage.GameAnalytics)
GameAnalytics:Initialize({
Build = "0.1";
GameKey = "";
SecretKey = "";
EnableInfoLog = true;
EnableVerboseLog = false;
AutomaticSendBusinessEvents = true;
ReportErrors = true;
AvailableCustomDimensions01 = {};
AvailableCustomDimensions02 = {};
AvailableCustomDimensions03 = {};
AvailableResourceCurrencies = {};
AvailableResourceItemTypes = {};
AvailableGamepasses = {};
})
Documentation link on the README file links to https://gameanalytics.com/docs/roblox-sdk
, but should link to https://gameanalytics.com/docs/item/roblox-sdk
instead. The current link leads to a 404.
Enum name lookup should use table (dictionary/map) instead of an if-statement
This happens in init.lua
Should be store.PlayerCache[playerId] = playerData
The sha2_256 module is very resource-intensive and triggers CPU spikes that lock up Roblox for a few frames. This can be fixed by yielding for a very short time. A developer has elaborated on this process here:
https://devforum.roblox.com/t/using-gameanalytics-retention-and-monetisation-ez-mode/41083/16
Player sessions can be double-initialized. There is nothing stopping it from happening multiple times.
The current init.lua is just an empty module. It should be an API with a method to call the code of GameAnalyticsClient and the code of GameAnalyticsScript (nit pick, should be Server not Script) so that it's easier to integrate as a submodule.
Currently the SDK will end a session when teleporting out of a server into another server. A way to pass sessions to different sessions along into different servers would fix this. Relevant thread: https://devforum.roblox.com/t/official-gameanalytics-module-and-teleporting/256435
Player state is not validated on setCustomDimension()
calls, resulting in blind error
:setCustomDimension(123456, { ... })
for a non-existent playerExpected behavior: A warning
table.getn is deprecated. To get the length of a table, use # e.g. local t = {1,2,3} print(#t)
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 149 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 152 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 155 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 158 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 161 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 968 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 974 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 975 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1610 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1843 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3454 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3460 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3467 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3472 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 3480 in aafb558
If you add more than 1 event a second to the SDK, the SDK will eventually sort threads until Roblox forces a time out
This causes high pings and errors
GameAnalytics:setAvailableResourceCurrencies({"test"})
addResourceEvent
with the currency "test".test
is an invalid currencyThis line of code reads from settings.AvailableResourceCurrencies
, which is never written when you call GameAnalytics:setAvailableResourceCurrencies
. It should be checking the internal store version instead.
.rbxmx files on GitHub are extremely annoying to make PRs to. Script syncers like Rojo will sync Roblox Scripts/folders as normal folders and .lua files. This is immensely easier to read and make PRs to.
If you search the code for PlayerCache
, no place ever clears it, resulting in a gradual memory leak as the server is played more and more.
If you log 100 errors in one hour, every 180 seconds, GameAnalytics will hit the DataStore with 100 IncrementAsync requests, even if nothing changed.
This is unseen because
The rojo config used in this repository is in the pre 0.5.0 format, which is no longer supported in modern versions of rojo.
The docs state that the progression02 and progression03 arguments can be nil for progression events, but if this is the case the event will silently fail and not be sent to the server. This is because line Events:427 attempts to concatenate the nil arguments into a string.
The method stringArrayContainsString is slow and should use hashmap (Lua's tables)
Apparently Rojo doesn't have a "rojo build" command or anything of the sort, but this would still be neat to have so PRs aren't expected to update it every time and it's easier to get a copy.
In a number of places (linked below), the SDK accesses services via game.SERVICENAME instead of game:GetService("SERVICENAME"). This will break if the service names are ever changed (developer of game changed them, or the default name for the service changes). The SDK should be updated to use GetService whenever it accesses services. If a service is used multiple times in a script, it is good practice to save it in a variable at the top of the script i.e.:
local replicatedStorage = game:GetService("ReplicatedStorage")
rather than using GetService every time it is accessed.
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 58 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 62 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 65 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 69 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 72 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 76 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 80 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 81 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 82 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 83 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 173 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 222 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 227 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 232 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 254 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 255 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 611 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 637 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 689 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 701 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 714 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 731 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 747 in aafb558
GA-SDK-ROBLOX/GameAnalyticsSDK.rbxmx
Line 1395 in aafb558
Roblox recently released Premium Payouts. Because of this, it's now much more important to track premium players and stuff like their session length, play time, and how many active premium players are playing your game.
In both GameAnalyticsScript.server and GameAnalyticsScript.client, the warn function is used after a check to confirm that they are in ServerScriptStorage or PlayerScripts respectively. Is this intentional or should both be using the error function?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.