Game Development Community

Datablock help for a C++ guy...

by Ron Barbosa · in Torque Game Engine · 07/18/2004 (11:08 pm) · 14 replies

Hey all...I've been reading through Ken Finney's book and also the Torque Docs...but I'm still not understanding the relationship between data blocks, objects, and classes.

I have a C/C++ background so if anyone can relate these topics using comparisons to C/C++ constructs...it would be MOST helpful.

I understand that datablock is a keyword in Torque Script, but I have not seen a keyword to define custom objects (such as the class or struct keywords in C/C++). But I have seen the new keyword which appears to have a different meaning in Torque Script than in C++. So it is my understanding that new is the keyword for class/object creation.

To be totally honest...I'm just about disgusted with the worthlessness of the docs in this regard. And Finney's book doesn't do datablocks, classes, or objects much justice either (although it is a good read and I do recommend it).

Any code samples would be greatly appreciated.

Thanks...
--RB

#1
07/18/2004 (11:14 pm)
Have you searched the forum at all, there are hundreds of posts on datablocks. maybe it would be easier if you could ask a specific question about datablocks?

a datablock is a group of static data that an object will have plugged into it at run time. it is static across all instances of that object which use the same datablock.
#2
07/19/2004 (4:48 am)
Ron, we actually have a very good update to the scripting chapter in the docs on the way (on the way = to be on the site in several days). Just so you know. Also, I thought Ken's book did quite a good job of covering datablocks... but, it can be confusing, so it's perfectly understandable to get frustrated.

In the mean time, let me point you to this illuminating thread. It may be hard to have the patience to read through the whole thing if you're frustrated, but it's not too awfully long. At least check out the last few posts there.

If you still have the same questions after reading that thread and doing some experimentation, feel free to ask away with some specifics. As for example code-- grep the demo scripts, and you'll have all the working example code you want. If you still want more though, that's cool too, just ask after you read the above.
#3
07/19/2004 (12:51 pm)
Hey all...thanks for the replies...and forgive the sour tone of my original post...it was getting pretty late in the evening and I still hadn't nailed down this concept yet.

So, with that said, I've read through the thread, and while I found it informative...I still am having a bit of trouble understanding when to use a datablock and when to use an object.

So...a few more specific questions. Do all objects have to be associated with a datablock...or can an object stand on its own? If so...how do I define a stand alone object to represent a person and keep track of their age and weight? I'd assume it's something along the lines of...

%handle = new Person()
{
   age    = 20;
   weight = 165;
};

I guess I'm a bit confused because as a C++ coder...I'm used to doing the following.

class Person
{
public:
   USHORT age;
   USHORT weight;
};

Person* NewPerson()
{
   Person pPerson = new Person;
   pPerson->age    = 20;
   pPerson->weight = 165;
   return(pPerson);
}

But since Torque Script is typeless...I guess there is no need to define the class/structure before instantiation. Thus ends my first question...can an object stand alone without a data block...and if so how is the class defined syntactically?

My next question would be when using a datablock with an object...what is the syntax?

Does it look like...

datablock PersonData(NewPerson)
{
   species = "Human";
};

%handle = new Person()
{
   age       = 20;
   weight    = 165;
   datablock = NewPerson;
};

Sorry...but this is just not sinking in...and I learn best through a combination of sample syntax and written explanation. I'm having a hard time finding both of those in the same location.

I appreciate the fast responses and I hope somebody can help me get a little bit further...thanks!
--RB
#4
07/19/2004 (1:28 pm)
Following the thread from Josh above will yield this:
Quote:A datablock is a class which exists solely to contain information about a type of object. For instance, the two orcs in the demo share the same datablock.

Datablocks are introduced for network effeciency, as far as I can tell. Meaning, you might have 3 player objects that each transmit their position, movement, etc. Their static properties (speed, jumpforce, etc.) are contained in a datablock. If this were C++, it would be like having a static object full of properties that some class contained as a member variable. So, you have a Player (or multiple) and each one has a member variable called PlayerData that contains the shared information. In fact, that's exactly how the Player class works in the engine - it contains a member variable of type PlayerData, a datablock. The PlayerData object is defined in script and sets some properties and is then assigned to the Player object.

Other areas of Torque work the same - the gui controls get a lot of their functionality from GuiProfiles. For the gui controls, the profiles serve as a sort of template to define a general appearence and behavior. For example, a scrollbar profile might allow scrolling and use a bitmap that has two arrows and a "block" (the slider). When you define an instance of a Gui slider control, it's profile would be set to the profile above.

(back to datablocks)
In general, you will NOT change the data in a datablock during a game - hence static (although you CAN change it if you want to). It's also shared data since all players will use the same speed/jumpforce (as an example). If you wanted each player to have a different speed, then the datablock will not work for you - there is a resource to do this very thing (have dynamic properties for a player).

-ner
#5
07/19/2004 (1:31 pm)
I've been trying this for a while now...and I'm using the tge.exe module that is included with Finney's book. I keep getting a console message that says, "Unable to instantiate non-conobject class PersonData"

I'm getting this message for both my datablock object and my object class.

Again...any help would be appreciated...this is the file I'm using...I'm trying to keep it small and simple...but it's still not working.

datablock PersonData(NewPerson)
{
   species = "Human";
};

function RonsFunc()
{
   %handle = new Person()
   {
      age       = 20;
      weight    = 165;
      datablock = NewPerson;
   };

   print(%handle.age);
}

RonsFunc();

That's the entire file...any pointers...GREATLY appreciated!
--RB
#6
07/19/2004 (1:51 pm)
This may confuse the hell out of you or it may make sense. This is sort of like some code that i've just been fooling around with on the side. I am not using this in any game projects right now but I may in the future for a single player game (no networking). This is one way that I've figured out to use datablock definitions to inherit data into a "script class". One mind set that you have to have going into scripting is that this is not c++ nor is it probably like any other scripting language you may have used before. Also would appreciate any comments concerning the "crackheadedness" of this code from anyone with more torque scripting experience than myself.

This datablock describes a Lifeform:
datablock GameBaseData(LifeformData)
{
   species = "Human";
   planet = "Earth";
   age = 20;
   weight = 165;
};

this code will instantiate some new Script Classes inheriting and overriding some values from LifeformData
%human = new ScriptObject( : LifeformData)
{
   superClass = "Lifeform";
   class = "Human";
// this guy's species and planet will be Human and Earth
// this guy's age and weight will be 20 and 165
};

%alien = new ScriptObject( : LifeformData)
{
   superClass = "Lifeform";
   class = "Alien";
   planet = "Mars";
   species = "Martian";
   age = 250;
   weight = 5000;
};

function Lifeform::Dump(%this)
{
  echo("Lifeform::Dump()");
}
function Human::Dump(%this)
{
   parent::Dump(%this);
   echo("Human::Dump()"); 
}
function Alien::Dump(%this)
{
   parent::Dump(%this);
   echo("Alien::Dump()");
}

Doing %human.dump() will result in output:
Lifeform::Dump()
Human::Dump()

Doing %alien.dump() will result in output:
Lifeform::Dump()
Alien::Dump()
#7
07/19/2004 (1:53 pm)
Oh concerning your above post, PersonData is not a native datablock object in the torque engine. You want to use something generic like SimDataBlock (absolutely generic) or GameBaseData (generic for an in-game object)

Same with Person() not being a native class in the engine. You want to use SimObject() instead.
#8
07/19/2004 (8:44 pm)
Quote:Oh concerning your above post, PersonData is not a native datablock object in the torque engine. You want to use something generic like SimDataBlock (absolutely generic) or GameBaseData (generic for an in-game object)

Same with Person() not being a native class in the engine. You want to use SimObject() instead.

Well then that might explain my problem right there. Am I to understand that one cannot define a custom class unless it inherits explicitly from some native Torque class? That would explain plenty.

Thanks for the additional assistance...
--RB
#9
07/19/2004 (9:15 pm)
You can always inherit from ScriptObject if you just want to create a class that isn't tied to a specific game object that's been pre-defined (like Player).
#10
07/20/2004 (4:04 am)
Ron, there are at least a couple good ways to tackle this:

1) Use engine-defined datablocks (PlayerData, etc, see [url=]the script-oriented datablock reference[/url]). Note that you could still define "PersonData" using this method, as such:

datablock GameBaseData(PersonData) // "PersonData" is the name of this 
                                   //  GameBaseData instance
{
    species = "human";             // Torque lets you define new, 
                                   //  dynamic fields in a datablock.  
}

Glen's longer post above is quite instructive.

2) Define a new datablock in C++ code. You can see how all the other datablocks do it, but if you want specific help, ask away.

So, you are correct in the post above, you can't just define a brand-spanking new datablock in script all by itself. However, you normally don't need to. You can base yours on a pre-defined datablock, at whatever level-of-detail you need. If you want a totally blank Datablock, use SimDataBlock, if you want something with hooked support for the editor and whatnot, use GameBaseData. If you want something that can support rendering, use ShapeBaseData. Etc. You can always add new fields however you see fit, all in script.

Hope that is helpful. I appreciate the questions, helps to refine our documentation. I look forward to releasing the new scripting chapter in the very near future.

Now, one last tip: you said above you are using a very stripped down file for testing. That is a very good idea, but let me suggest a few basic things to have in the file as well:

setLogMode(2);        // This turns on console logging, and tells the 
                      //  engine to replace the console log every time 
                      //  the engine is run.  Console logging saves 
                      //  all of the console output to a file called 
                      //  console.log, in whatever directory the 
                      //  game/demo is run from.

echo("start test");   // If you have read the 3DGPA1 book, or looked at our 
                      //  documentation, you are familiar with "echo".  
                      //  It outputs text to the console.  Extremely useful 
                      //  for testing.  


echo("end test");     // I always wrap my tests in these.


quit();               // Tells the engine to shutdown.  Without this line, 
                      //  you will have to manually close the engine each 
                      //  time it runs.  With this line, the engine will 
                      //  pop up, run your test script, and then quit.  
                      //  You can then examine console.log to see the 
                      //  result of your tests.

function onExit() {}  // The engine calls this function when you tell 
                      //  it to quit().  It is meant for clean-up, but 
                      //  you can leave it blank.  You don't strictly 
                      //  *need* this function, but without it, 
                      //  your console.log file will end up with a warning 
                      //  about there not being an onExit() function.

So, when I want to test basic stuff that doesn't require a GUI or rendering of any sort, I use this as my main.cs:

setLogMode(2);

echo("start test -- defintions");

function testMe() 
{
   echo("testMe() got called");
}


echo("start test -- execution");

testMe();

echo("end test");


quit();

function onExit() {}

Examing console.log then reveals whether the tests work.

Anyway, just a general tip on testing. This let's you use a stripped-down, bare-minimum script file, but you can still see the results of your code. Guess I got a little long-winded for such a basic thing though, sorry. :)
#11
07/20/2004 (9:28 am)
In addition to what Josh said, I use the Super Simple Torque Demo for testing pure script (with console support).

I has the advantage of keeping mostly everything in the bare minimum set of scripts. This is NOT ideal for doing anything with graphics, just for testing script ideas.

Another quick note: If you use error instead of echo, the output will be in red (easier to see your begin/end echos).

-ner
#12
07/20/2004 (3:43 pm)
Hey all...thanks alot for all the help. I think the crux of my problem was just my attempt to define a totally new class even though this is not directly supported in Torque script and also appears to be unnecessary. ;)

When I'm learning new syntax...I like to play around with it...even if it's just for the exercise. My goal here was to create a simple...stand alone object and link a datablock to it. But as I've been told underived objects cannot directly be created. So this explains a ton about my problem.

Since learning this...I am having more success working with SimDatablock and SimObject...thanks again for all the assistance!

--RB
#13
07/20/2004 (8:51 pm)
Great Ron, glad you're getting there. This is an important note on datablocks and object creation in TorqueScript, and our upcoming new scripting chapter covers it. Glad you got it figured out even without them at this point. :)

Also, I'll second what Dan said, his Super Simple Torque Demo is really useful. Dan, thanks a ton for making that thing, don't know if I've told you that before. It's very useful.
#14
07/20/2004 (9:13 pm)
Thanks Josh - keep in mind it was written by me and I make a lot of typos (in general). If you ever notice something wrong (assumptions or just plane bad facts), let me know and I'll update it.

-ner