Forum BigDB Random selection

Discussion and help relating to the PlayerIO database solution, BigDB.

Random selection

Postby INS » June 28th, 2010, 6:00 am

Hi!

Is there any way to select random object from BigDB table?

I want my game to select level randomly, and I also have level editor, so amount of levels will grow in time and I can't use "loadRange" and select random index with server code.

First, i wanted to implement "played" property to count times the level was played, then sort this in ascending way and select the lowest so that gameplay would distribute evenly, but then I understood that new levels having "zero" played times will always be on top and being played more and more by the same players untill they get common "played" value, and old levels would become unreachable. So this is not the way either.

The best way i see this is selecting random index with some limitation options. In SQL it would be smth like this:

SELECT * FROM my_levels WHERE level_id not in ("levels", "i have", "already", "played", "today") ORDER BY rand() LIMIT 0,1

Any advice?

UPD:

I've suddenly got an idea to change "played" counter to "last played" datetime value, so level would be played only once and then "timestamped". Is this the best decision, at least for now?
INS
 
Posts: 12
Joined: June 19th, 2010, 8:22 am

Re: Random selection

Postby INS » June 28th, 2010, 6:59 am

And one more stupid question, not subject related (sorry, i'm null at C# programming). I'm not quite sure I can explain this in words, so i will try to do this with code samples. Will this structure work?

A game loads level when a room is created. When new players join this room, they get level info via Player.send.

Code: Select all
    public class Level
    {
        private BigDB db;
        public byte[] level_data;

        public Level(BigDB database)
        {
            this.db = database;
        }

        public void InitGame()
        {
            db.LoadSingle("Levels", "ByPlayed", null, levelLoaded);
        }

        private void levelLoaded(DatabaseObject lvl)
        {
        // parse level data
        level_data = lvl.GetBytes("data");
        }
}

public class GameCode : Game<Player>
    {

        private Level _level;

        public override void GameStarted()
        {
            this._level = new Level(PlayerIO.BigDB);
            _level.InitGame();
        }

        public override void UserJoined(Player player)
        {
             player.Send("Here, have this level", _level.level_data);
        }
}


Can I be sure that when user joins the room, _level.level_data is already loaded from BigDB? For example, if i create a room using multiplayer.createJoinRoom, a room is being created and user joins it at the same moment?

UPD:

Test showed I can not :)
INS
 
Posts: 12
Joined: June 19th, 2010, 8:22 am

Re: Random selection

Postby fox1980 » June 28th, 2010, 12:21 pm

I don't believe BigDB supports fetching random objects, you can however select ALL objects from a table and then pick one up randomly in C#. Not very elegant, but would work fine if the table doesn't have too many objects.
For your second question, you can't be sure when the results are returned from BigDB unless you use a sucess callback.
You can for instance stop sending messages to the client, and ignore messages sent from the client until data is loaded.
Create a variable to check if data was loaded:

Code: Select all
private Boolean ready=false;


in your sucess callback:

Code: Select all
ready=true;


then in gotmessage function you just ignore whatever you receive until the data is loaded:

if (ready!=true)
{
return;
}
fox1980
 
Posts: 206
Joined: April 1st, 2010, 10:39 pm

Re: Random selection

Postby INS » June 28th, 2010, 1:27 pm

That's exactly what I just did, added 1 second timer to recall initializing function if level is not loaded. I'm pretty sure I should do this more accurate using "delegate" callbacks, but as far as I'm totally new in C# - i left it with timer recall for now.

you can however select ALL objects from a table and then pick one up randomly in C#


As I already said above, this method is not possible due to big level amount in db in future (i have level editor, so I actually hope it will grow). I've implemented level selection by "DateTime last_played", so it should work almost as needed, though it's still not the best way.

Hope there will be random index selection in BigDB in future.
INS
 
Posts: 12
Joined: June 19th, 2010, 8:22 am

Re: Random selection

Postby Oliver » June 28th, 2010, 1:49 pm

There will never be random index selection in BigDB.

However, There are lots of ways to accomplish the same thing.

For instance, if you give each item a random id between 0 and int.max value, then you can pick a random object by getting the first item in the range [random-id -> int.max] (you' have to generate random-id yourself).

- Oliver
User avatar
Oliver
.IO
 
Posts: 1159
Joined: January 12th, 2010, 8:29 am

Re: Random selection

Postby INS » June 28th, 2010, 3:22 pm

Oliver, that's not good way either:

level_1, random_index = 200
level_2, random_index = 555
level_3, random_index = 1000

Searching for random level:

searchFrom = rand(0,int.max) ; // = 5000 for example
loadRange(searchFrom, int.max); // returns null (empty object)

so i need to know current maximum, that's at least one more query (load single, descending order of random_index) to do
loadRange(searchFrom, current_max-1);

Works, but not very good code.
INS
 
Posts: 12
Joined: June 19th, 2010, 8:22 am

Re: Random selection

Postby Oliver » June 28th, 2010, 4:07 pm

Correct yea, you'd need to know the current maximum... OR insert a level at int.maxvalue (which might get picked very often)

.
User avatar
Oliver
.IO
 
Posts: 1159
Joined: January 12th, 2010, 8:29 am


Return to BigDB



cron