• Advertisement

Recommended Posts

I am developing a cross platform game for which I needs to generate unique identifier (User ID) for each user. I known some platform (Android or iOS) specific approaches to get device related identifiers but I am looking for a solution independent of the device identifiers.

User ID Requirements:

 1. Independent of the device's platform
 2. Offline implementation (no communication with any servers)
 3. Without sign-up process

I have implemented one approach to create User IDs where I store the system time when the game was launched for the first time on the device.

I have following questions:

 1. Are there any other approaches to generate User IDs (which will meet the above requirements)?
 2. What are the common approaches to create unique identifiers with taking any information from the user?
 3. Are there any third party plug-ins to implement User IDs?

I would appreciate any suggestions and thoughts on this topic.

EDIT:

There are lot of responses to use UUID/GUID. Generally, this approach looks fine but I am looking for a solution which can generate same User ID even if the user reinstall the game.

Edited by Octane_Test
more information

Share this post


Link to post
Share on other sites
Advertisement

Guids are one thing you could look into.

So they have to be able to get an ID while they are offline and not signed up. If they are offline then it won't really matter what their ID is until they come online. Once they are online you can assign them a new ID that is unique throughout everyone else that is online.

I'd use an integer as their ID. when they sign up, give them the next available integer. that can be their user ID, so even when they are offline they will use that ID. If they need to get an ID without signing up, maybe do something like a session ID, so once someone connects online, they will get the next available session ID. again if they are offline the ID won't matter what it is, only when they come online.

One last thing you can do is get device specific information, like the hard drive serial number plus mac address plus some other hardware serial. This would of course go into your platform dependent section of code, since each platform is going to have different ways of getting this information. once you have that string of serials, just md5 hash it or something to get a normalized string so everyone uses the same string size for their ID.

I wouldn't use the time they started the app with, because it would be possible for multiple people to have started the app at the same time in their local machines time

Share this post


Link to post
Share on other sites

Generate a random 128-bit integer in some way. As iedoc said, you can do that by computing the md5sum of some machine-specific details, but you can also throw the timestamp of when the program was started in there, or some hardware-generated random numbers. You can also ask the user to take a picture (do you need a profile picture?) and take the md5sum of the image.

If you do a decent job of making the numbers random, 128 bits is enough to not expect any collisions ever. For instance, if you have 26 billion users, the probability of a collision is 10^-18. If for some reason you want to use 64 bits only, it might be OK, depending on how many users you expect: With 6 million users, the probability of a collision would be about 10^-6. I wouldn't go lower than 64 bits. See https://en.wikipedia.org/wiki/Birthday_problem

 

Share this post


Link to post
Share on other sites

Some things to also consider:

1) Will the game keep scores online for others to see?

2) Are there achievements?

3) Are there levels/progress points/character(s) stats?

If yes, you will have to support them using multiple devices with the same ID or to transfer their profiles to a new device without losing all their progress too.  So having them type 64-128 bit integer is likely not a great idea.  You might have to make a database that assigns IDs.

Share this post


Link to post
Share on other sites
15 hours ago, iedoc said:

Guids are one thing you could look into.

So they have to be able to get an ID while they are offline and not signed up. If they are offline then it won't really matter what their ID is until they come online. Once they are online you can assign them a new ID that is unique throughout everyone else that is online.

I'd use an integer as their ID. when they sign up, give them the next available integer. that can be their user ID, so even when they are offline they will use that ID. If they need to get an ID without signing up, maybe do something like a session ID, so once someone connects online, they will get the next available session ID. again if they are offline the ID won't matter what it is, only when they come online.

One last thing you can do is get device specific information, like the hard drive serial number plus mac address plus some other hardware serial. This would of course go into your platform dependent section of code, since each platform is going to have different ways of getting this information. once you have that string of serials, just md5 hash it or something to get a normalized string so everyone uses the same string size for their ID.

I wouldn't use the time they started the app with, because it would be possible for multiple people to have started the app at the same time in their local machines time

Thank you for the reply. I agree with your suggestion of using GUID (UUID) as User ID. I don't want to generate any identifier based device's hardware so that I don't violate Apple's or Google's guidelines.

Given I am fetching local machine's time in milliseconds, what are the chances of collision?

8 hours ago, Mike2343 said:

Some things to also consider:

1) Will the game keep scores online for others to see?

2) Are there achievements?

3) Are there levels/progress points/character(s) stats?

If yes, you will have to support them using multiple devices with the same ID or to transfer their profiles to a new device without losing all their progress too.  So having them type 64-128 bit integer is likely not a great idea.  You might have to make a database that assigns IDs.

Answers matching your questions:

  1. No
  2. No
  3. No

I am fine with if a new User ID is generated when a  player play the game on other device.

Share this post


Link to post
Share on other sites
19 hours ago, Octane_Test said:

There are lot of responses to use UUID/GUID. Generally, this approach looks fine but I am looking for a solution which can generate same User ID even if the user reinstall the game

If you want some kind of staticness you should take a look at Bitcoin. Some wallets give the feature to ressemble an Id by getting some kind of personal information into the generator process, a password for example or PIN. So even if a user would loose his wallet for some reason, chances are there to restore it from those informations.

But you know when going for Android there is a little chance that those data will be keeped for you even if a user uninstalles your app. We have had (even on newer Android versions) the problem that old game data was still there when we did not hard uninstall the app from ADB, an uninstall on the device gave those zombie data

Share this post


Link to post
Share on other sites
On 2/1/2018 at 6:43 AM, Octane_Test said:

There are lot of responses to use UUID/GUID. Generally, this approach looks fine but I am looking for a solution which can generate same User ID even if the user reinstall the game.

You definitely don't want to use the time. I just reread your original post and you said you keep track of the first time the user opens the app. there's only around 80 million milliseconds in a day, so it's highly likely that you will eventually have multiple people with the same id, especially since apps are open most often during certain times of day. I suppose you could use the datetime or epoch, that would be better, but still could result in duplicate id's if you were to say promote your game, and a bunch of people started playing your game that day. Also, where would you store that id? when they reinstall the app, or clear the app data, you'll probably lose that id unless you save it somewhere else on the phone

Could you clarify what you plan to do with the ID? Does the ID have to be the same every time the user comes online? or do you expect the ID to change every time they open the app? You don't want the user to get a new ID when they reinstall the app, but what if they change phones? can they get a new ID then?

Maybe a simple login system with username and password when they come online would do the trick, that way they will have the same ID no matter what, and you won't have to get information about their device or anything like that.

Share this post


Link to post
Share on other sites

For a mobile game i have been involved in, we used a server generated UUID and the mobiles unique device id to identify a user, then if they put in their email, later on which was optional, we could restore their account in case they reinstalled the app or changed their phone. 

Edited by flodihn

Share this post


Link to post
Share on other sites

Use the device's mac address?  If the user changes hardware, yeah, it'll change, but that's not super often.

Share this post


Link to post
Share on other sites
On 2/1/2018 at 4:43 AM, Octane_Test said:

User ID Requirements:

 1. Independent of the device's platform
 2. Offline implementation (no communication with any servers)
 3. Without sign-up process

 

On 2/1/2018 at 4:43 AM, Octane_Test said:

EDIT:

There are lot of responses to use UUID/GUID. Generally, this approach looks fine but I am looking for a solution which can generate same User ID even if the user reinstall the game.

I think with your edit you are completely out of luck with these requirements.  Cannot use any device based ID (MAC address, UUID/GUID, etc), no communication to servers to check for existing/duplicate IDs (which eliminates #3 as an option anyway) and now you want it to generate the same User ID even after a reinstall so anything date/time based is also out.

Share this post


Link to post
Share on other sites
On 2/1/2018 at 4:43 AM, Octane_Test said:

There are lot of responses to use UUID/GUID. Generally, this approach looks fine but I am looking for a solution which can generate same User ID even if the user reinstall the game.

If you want to deal gracefully with cases such as the user migrating to a new phone, then you are absolutely going to need to integrate with platform-specific APIs. Both Apple and Google seem to recommend generating a GUID on first install, and then storing it via their platforms' respective secure storage APIs, so that it gets backed up via the cloud and transferred to new devices.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By isu diss
      I'm trying to duplicate vertices using std::map to be used in a vertex buffer. I don't get the correct index buffer(myInds) or vertex buffer(myVerts). I can get the index array from FBX but it differs from what I get in the following std::map code. Any help is much appreciated.
      struct FBXVTX { XMFLOAT3 Position; XMFLOAT2 TextureCoord; XMFLOAT3 Normal; }; std::map< FBXVTX, int > myVertsMap; std::vector<FBXVTX> myVerts; std::vector<int> myInds; HRESULT FBXLoader::Open(HWND hWnd, char* Filename, bool UsePositionOnly) { HRESULT hr = S_OK; if (FBXM) { FBXIOS = FbxIOSettings::Create(FBXM, IOSROOT); FBXM->SetIOSettings(FBXIOS); FBXI = FbxImporter::Create(FBXM, ""); if (!(FBXI->Initialize(Filename, -1, FBXIOS))) { hr = E_FAIL; MessageBox(hWnd, (wchar_t*)FBXI->GetStatus().GetErrorString(), TEXT("ALM"), MB_OK); } FBXS = FbxScene::Create(FBXM, "REALMS"); if (!FBXS) { hr = E_FAIL; MessageBox(hWnd, TEXT("Failed to create the scene"), TEXT("ALM"), MB_OK); } if (!(FBXI->Import(FBXS))) { hr = E_FAIL; MessageBox(hWnd, TEXT("Failed to import fbx file content into the scene"), TEXT("ALM"), MB_OK); } FbxAxisSystem OurAxisSystem = FbxAxisSystem::DirectX; FbxAxisSystem SceneAxisSystem = FBXS->GetGlobalSettings().GetAxisSystem(); if(SceneAxisSystem != OurAxisSystem) { FbxAxisSystem::DirectX.ConvertScene(FBXS); } FbxSystemUnit SceneSystemUnit = FBXS->GetGlobalSettings().GetSystemUnit(); if( SceneSystemUnit.GetScaleFactor() != 1.0 ) { FbxSystemUnit::cm.ConvertScene( FBXS ); } if (FBXI) FBXI->Destroy(); FbxNode* MainNode = FBXS->GetRootNode(); int NumKids = MainNode->GetChildCount(); FbxNode* ChildNode = NULL; for (int i=0; i<NumKids; i++) { ChildNode = MainNode->GetChild(i); FbxNodeAttribute* NodeAttribute = ChildNode->GetNodeAttribute(); if (NodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh* Mesh = ChildNode->GetMesh(); if (UsePositionOnly) { NumVertices = Mesh->GetControlPointsCount();//number of vertices MyV = new XMFLOAT3[NumVertices]; for (DWORD j = 0; j < NumVertices; j++) { FbxVector4 Vertex = Mesh->GetControlPointAt(j);//Gets the control point at the specified index. MyV[j] = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]); } NumIndices = Mesh->GetPolygonVertexCount();//number of indices MyI = (DWORD*)Mesh->GetPolygonVertices();//index array } else { FbxLayerElementArrayTemplate<FbxVector2>* uvVertices = NULL; Mesh->GetTextureUV(&uvVertices); int idx = 0; for (int i = 0; i < Mesh->GetPolygonCount(); i++)//polygon(=mostly triangle) count { for (int j = 0; j < Mesh->GetPolygonSize(i); j++)//retrieves number of vertices in a polygon { FBXVTX myVert; int p_index = 3*i+j; int t_index = Mesh->GetTextureUVIndex(i, j); FbxVector4 Vertex = Mesh->GetControlPointAt(p_index);//Gets the control point at the specified index. myVert.Position = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]); FbxVector4 Normal; Mesh->GetPolygonVertexNormal(i, j, Normal); myVert.Normal = XMFLOAT3((float)Normal.mData[0], (float)Normal.mData[1], (float)Normal.mData[2]); FbxVector2 uv = uvVertices->GetAt(t_index); myVert.TextureCoord = XMFLOAT2((float)uv.mData[0], (float)uv.mData[1]); if ( myVertsMap.find( myVert ) != myVertsMap.end() ) myInds.push_back( myVertsMap[ myVert ]); else { myVertsMap.insert( std::pair<FBXVTX, int> (myVert, idx ) ); myVerts.push_back(myVert); myInds.push_back(idx); idx++; } } } } } } } else { hr = E_FAIL; MessageBox(hWnd, TEXT("Failed to create the FBX Manager"), TEXT("ALM"), MB_OK); } return hr; } bool operator < ( const FBXVTX &lValue, const FBXVTX &rValue) { if (lValue.Position.x != rValue.Position.x) return(lValue.Position.x < rValue.Position.x); if (lValue.Position.y != rValue.Position.y) return(lValue.Position.y < rValue.Position.y); if (lValue.Position.z != rValue.Position.z) return(lValue.Position.z < rValue.Position.z); if (lValue.TextureCoord.x != rValue.TextureCoord.x) return(lValue.TextureCoord.x < rValue.TextureCoord.x); if (lValue.TextureCoord.y != rValue.TextureCoord.y) return(lValue.TextureCoord.y < rValue.TextureCoord.y); if (lValue.Normal.x != rValue.Normal.x) return(lValue.Normal.x < rValue.Normal.x); if (lValue.Normal.y != rValue.Normal.y) return(lValue.Normal.y < rValue.Normal.y); return(lValue.Normal.z < rValue.Normal.z); }  
    • By nick1
      Hello,

      I have limited programming experience in C++, but have always had a passion for games.  Where do I start?  I have a rough idea of the type of game I want to develop and am ready to commit the time necessary to learn new languages.  Are mobile games too difficult to begin with? Should I begin learning the basics of keyboard controls before attempting touch screens?  I would appreciate any input or advice!
      Thanks!
      Nick1
    • By Strifexxx
      Hi guys, check out our new game about sticks. Feedback welcome!
      Download on Google Play: https://play.google.com/store/apps/details?id=com.stickman.destruction.annihilation4
      Youtube:
      Stickman Destruction 4 Annihilation is a sequel to the legendary game of survival, where to make incredible tricks, driving different transport and getting into different crash! The game is made in the best traditions of simulator games with ragdoll physics elements. Make incredible jumps and tricks and destroy the enemy! Your task is make the finish alive or dead!




      Website: http://strifexxx.wixsite.com/cyberpony
      Facebook: https://www.facebook.com/groups/577850349043463/
      VK: https://vk.com/club122273704
    • By EddieK
      Hi I am having this problem where I am drawing 4000 squares on screen, using VBO's and IBO's but the framerate on my Huawei P9 is only 24 FPS. Considering it has 8-core CPU and a pretty powerful GPU, I don't think it is not capable of drawing 4000 textured squares at 60FPS.
      I checked the DMMS and found out that most of the time spent was by the put() method of the FloatBuffer, but the strange thing is that if I'm drawing these squares outside of the view frustum, the FPS increases. And I'm not using frustum culling. 
      If you have any ideas what could be causing this, please share them with me. Thank you in advance.
    • By Descent
      Wow what a wild game by GalaXa Games Entertainment Interactive. Play now... it's really fun but IF you have epilepsy then don't play. It does not feature flashing pictures, but there is lots of animated stuff that might get ya. Anyway, 4 levels, 2 endings, insane action, BY INFERNAL. Please play it, right nao! Also , nice midi music composed by me is in the game.
       
      demons.rar
  • Advertisement