Game state tutorial

This is an example on how to manage a simple farming game, where the player will gather new vegetables and add them to his farm.

Gamedonia calls will only work under a valid Gamedonia session. This means there needs to be a user logged in with Gamedonia. The main exceptions are, for obvious reasons, creating and logging users in.

Data Structure

This is the definition of the main game object. It represents a single farm. Every player will have his own farm, and depending on the player's actions during the game, each farm will produce more or less vegetables.

{
    "owner": {user_id},
    "farm_name": {string},
    "stored_food": [
        {
            "food_type": {tomatoes, carrots, lettuces},
            "amount": {integer}
        }
    ],
    "max_fields": {integer},
    "fields": [
        {
            "food_type": {tomatoes, carrots, lettuces},
            "last_time_gathered": {integer}
        }
    ]
}

The fields are described as follows:

  • owner - User ID of the farm owner.
  • farm_name - The name that the player gave to his farm.
  • stored_food - A list of the food gathered by the player. Every time the player harvests a field, the generated food will be stored in the corresponding slot of this list.
  • max_fields - Maximum number of fields the player is allowed to have.
  • fields - A list of the fields planted by the player. Every entry contains the type of the field ( which type of food is planted in it) and a timestamp indicating the last time the crops were gathered to know when the field will generate new food.

The first step is creating a new private collection on the Dashboard. This way the player who creates a new entry will be the only one who can read and modify that entry.

Go to the Gamedonia Dashboard and on the left panel, under Data Storage select Collections. Click on the Create button to add a new collection, insert the name of the collection, for instance farms, and set only read/write permissions for the owner. Click on the Save button and the collection will be created.

Create a new Farm

In order to create a new farm, we are going to create a new script that will do the job and then call it from the client.

On the dashboard, go to Server Code > Custom Scripts. Click on Create Script and insert a new name for the script in the pop-up window. Let's call this script createfarm. Click on Create Script button, then we will edit the script.

The script will be executed with the user rights who invoked it, so we don't have to worry about having users modifying other users' farms. The system will do all this verification for us, because you have set the permissions in the collection.

The content of the createfarm script is:

function checkParams() {

    if (request.params.farm_name == null || request.params.farm_name.equals("")) {

        log.error("farm_name is required"); 
        return false;
    }
    
    return true;
}
 
if (checkParams()) {
 
    var food = new Object();
    food.food_type = "carrots";
    food.amount = 10;
    
    var farm = gamedonia.data.newEntity(); 
                    
    farm.owner = request.user.id;  
    farm.farm_name = request.params.farm_name;
    farm.stored_food = [food];
    farm.max_fields = 3;
    farm.fields = [];
                        
    gamedonia.data.create("farms", farm, {
        success: function(entity) {
            response.success(entity);
        },
        error: function(error) {
            log.error(error);
            response.error("Could not create a new farm.");
        }
    });
 
} else {
 
    response.error("No farm_name specified.");
}

To create a new farm, and depending on the platform, we are going to introduce the following code on the client side to run the script we just created:

Dictionary<string,object> parameters = new Dictionary<string, object>(){{"farm_name", "My Pretty Farm"}};
GamedoniaScripts.Run("createfarm", parameters, delegate (bool success, object data) {

	if (success) {

		// TODO: data contains the new created farm
	} else {
		// TODO: the farm could not be created
	}
});
void MyClass::createFarm(CCString* farmName) {

    CCDictionary* parameters = CCDictionary::create();
    parameters->setObject(farmName->getCString(), "farm_name");

    GamedoniaSDKScript::run("createfarm", parameters, this, gamedoniaResponseData_selector(MyClass::onFarmCreated));
}

void MyClass::onFarmCreated(bool success, CCDictionary* data) {
    if (success) {
        //TODO: data contains the new created farm
    } else {
        //TODO: the farm could not be created
    }
}
NSDictionary * parameters = [NSDictionary dictionaryWithObjectsAndKeys:@"My Pretty Farm",@"farm_name",nil];
    
[[Gamedonia script] run:@"createfarm" parameters:parameters callback:^(BOOL success, NSDictionary *data) {
    if (success) {
        // TODO: data contains the new created farm

    } else {
        // TODO: the farm could not be created
    }
}];
var parameters:Object = new Object();
parameters.farm_name = "My Pretty Farm";

GamedoniaScripts.run("createfarm", parameters, function (success:Boolean, data:Object):void {

    if (success) {

        // TODO: data contains the new created farm
    } else {
        // TODO: the farm could not be created
    }
});
local OnFarmCreated = function (succes, data)
    if success then
        -- TODO: data contains the new created farm
    else
        -- TODO: the farm could not be created
    end
end

local parameters = {}
parameters.farm_name = "My Pretty Farm"
Gamedonia.Scripts.run("createfarm", parameters, OnFarmCreated)

Retrieve Farm Data

Every time you want information from a specific farm, you will need to query the farms collection using the userID parameter.

string query = "{'owner':'" + GamedoniaUsers.me._id + "'}";
			
GamedoniaData.Search ("farms", query, delegate (bool success, IList data) { 

	if (success) { 

		// TODO data contains a list with only one item: the requested farm.
		if (data != null && data.Count == 1) {

			Dictionary<string, object> farm = (Dictionary<string, object>) data[0];
		}

	} else {
		// TODO The farm was not found 
	}
});
void MyClass::GetFarm(CCString* farmName) {
    CCString* query = CCString::createWithFormat("{\"owner\":\"%s\"}}", GamedoniaSDKUser::getMe()->_id);

    GamedoniaSDKData::search ("farms", query->c_str(), this, gamedoniaResponseData_selector(MyClass::FarmSearchCallback));
}

void MyClass::FarmSearchCallback(bool success, CCArray* movie) {
    if (success) {
        //TODO data contains a list with only one item: the requested farm.
    } else {
        //TODO The farm was not found
    }
}
NSString *query = [NSString stringWithFormat:@"{\"owner\":\"%@\"}}", [[[Gamedonia users] me] _id]];

[[Gamedonia data] search:@"farms" query:query callback:^(BOOL success, NSArray *data) {
    if (success) {

        // TODO data contains a list with only one item: the requested farm.

    } else {
        // TODO The farm was not found
    }
}];
var query:String = "{'owner':'" + GamedoniaUsers.me._id + "'}}";

GamedoniaData.search(farms", query, function(success:Boolean, data:Object):void {

    if (success) {

        // TODO data contains a list with only one item: the requested farm.

    } else {

        // TODO The farm was not found
    }
});
query = "{'owner':'" .. Gamedonia.Users.me._id .. "'}}"

local searchCB = function (succes, data)
    if success then
        -- TODO data contains a list with only one item: the requested farm.
    else
        -- TODO The farm was not found
    end
end

Gamedonia.Data.search ("farms", query, searchCB)

Modify Farm Data

Modifying farm data involves querying for it before as in the previous example. Once you have the original farm, you can modify it and call the Update

// IDictionary farm ... farm object with modified fields
(farm["stored_food"] as IList).Add(new Dictionary<string,object>(){{"food_type","lettuce"},{"amount","5"}});

GamedoniaData.Update ("farms", farm, delegate (bool success, IDictionary data) {

	if (success) {

		// TODO Your success processing

	} else {

		// TODO Your fail processing
	}
});
void MyClass::UpdateFarm(CCDictionary* farm) {
    //CCDictionary farm ... farm object with modified fields
    GamedoniaSDKData::update ("farms", farm, true, this, gamedoniaResponseData_selector(MyClass::FarmUpdatedCallback));
}

void MyClass::FarmUpdatedCallback(bool success, CCDictionary* data) {
    if (success) {
        //TODO Your success processing
    } else {
        //TODO Your fail processing
    }
}
// NSMutableDictionary farm ... farm object with modified fields

[[Gamedonia data] update:@"farms" 
                  entity:farm
                  overwrite:true
                  callback:^(BOOL success, NSDictionary *data) {

    if (success) {

        // TODO Your success processing

    } else {

        // TODO Your fail processing
    }           
}];
// Object farm ... farm object with modified fields
GamedoniaData.update("farms", farm, true, function(success:Boolean, data:Object):void {

    if (success) {

        // TODO Your success processing

    } else {

        // TODO Your fail processing
    }
});
-- Object farm ... farm object with modified fields

local updateCB = function (succes, data)
    if success then
        -- TODO Your success processing
    else
        -- TODO Your fail processing
    end
end

Gamedonia.Data.update ("farms", farm, true, updateCB)