Game Development Community

Something cool (adding named fields)

by Daniel Buckmaster · in General Discussion · 02/16/2010 (7:14 pm) · 4 replies

I just realised that you can get multiple script members of an object to refer to the same code-side member. So in PlayerData::initPersistFields:
addField("renderFirstPerson", TypeBool, Offset(renderFirstPerson, PlayerData));
addField("renderingInFirstPerson", TypeBool, Offset(renderFirstPerson, PlayerData));
Now you can add either renderFirstPerson or renderingInFirstPerson to your PlayerData datablock.

Nothing earth-shaking, but it might be of interest. For example, I'm writing a generalised class for 'sensors' which detect other objects. The detection is handled by a bunch of rules in the datablock - for example, angle check, range check, or typemask check. The rules are stored as an array of ruletypes and an array of values. Up until now I just called the value array 'value' in script, so the sensor datablock looks something like:
rule[0] = "angle";
value[0] = 90.0; //90 degree angle check

rule[1] = "range";
value[1] = 50.0; //50m radius range check
Now, I could assign the names 'angle' and 'range' to the code-side 'value' array, so I could do this instead:
rule[0] = "angle";
angle[0] = 90.0;

rule[1] = "range";
range[1] = 50.0;
A very small thing, but it increases usability and readability. Especially when I'm actually dealing with three different value arrays - it's difficult to remember what each different value does for each check. By providing specific names for the value arrays for different rule types, it becomes easier to define the rules in a user-friendly way.

About the author

Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!


#1
02/17/2010 (5:16 pm)
In addition to addField you can also use addFieldV. This way you can validate the value to ensure that only legal values can be used.

Something like that:

#include "console/typeValidators.h"


addFieldV("Age", U8, Offset(age, PlayerData), new FRangeValidator(1, 100));
#2
02/17/2010 (5:33 pm)
Any idea what happens if the value is invalid - does it get clamped? Seems like a good way to do it, instead of working everything out in the datablock's preload function.
#3
02/17/2010 (5:51 pm)
I guess the validator will change the value to max if the given value was > max. And change the value to min if the given value was < min.

Sorry, my mistake: The class FRangeValidor is used for floats and IRangeValidor for integer. The example above should be

addFieldV("Age", U8, Offset(age, PlayerData), new IRangeValidator(1, 100));

If you use FRangeValidator don't forget to write the "f" behind the value.

FRangeValidator(1.0f, 34.0f)
#4
10/13/2010 (12:54 am)
Also, another cool thing I stumbled upon: protected fields.

addProtectedField("myVar", S32, Offset(mMyVar,PlayerData), &setMyVar, &defaultProtectedGetFn, "");

Whenever you set this member in script (e.g., by calling %myobject.myVar = 1;), the function setMyVar is called. The function looks like this:

static bool setMyVar(void* obj, const char* data)
{
   Player* p = static_cast<Player*>(obj);
   p->mMyVar = dAtoi(data);
   // Do something like set mask bits or whatever
   return true;
}
Note that you can also provide a function for the getting method the same way.

This allows you to have 'getter/setter' functionality code-side but with a simple script-side interface.