Field Data Types

Jump to: navigation, search


Data Types should not be confused with Archetypes. An archetype is a descriptor for a class, which is a collection of different fields.

Data Types are the descriptors for individual fields. Data Types are also used to declare variables.


Datatypes are used in the CLI, and in HeroScript. Some respective datatypes are not entirely consistent. Please see below for more information.


Data Types

TODO: Add description of the FSGUID and RawData data types.

CLI HeroScript equivalent Description
NONE -- For more information, see the NONE section below.
ARRAY ARRAY Maintains a fixed length group of values of a given type. This is like LIST but much more efficient -- it specifies exactly how many elements it has to be ahead of time (and this cannot change). The default values will be the default for whatever type is contained within the array.
HeroScript syntax: groovy as array[5] of string
loop i from 1 to groovy.sizeX
-- ASSOCIATION A complex datatype which can only be used to declare variables, and not field types. An association has three sub data elements, which are accessed as though they were subfields: source, associationtype, and target, all of which are set to NULL when a variable is created. Possible values for the Associationtype data element are defined in the DOM. For more information, see Associations.
BOOLEAN BOOLEAN Logical field which can be set to "true" or "false". The default is false.
CUBIC CUBIC Maintains a fixed sized three-dimensional group of a given type. This is like a TABLE, but with three dimensions. The default value will be the default for whatever type is contained within the group.
CLI Syntax: cubic 4 5 6 of string.
HeroScript syntax: x as cubic[4,5,6] of string
ENUM ENUM A field of this type will contain a value that references one constant on an enumerated list of constants (called, interestingly enough, the "enumerator list"). The default value is the first value of the enumeration, if it has values. Otherwise it is an invalid value. Please see the section on Enumeration for more info.
FLOAT FLOAT This is a standard 32-bit floating point value, such as 0.0, 2.6, 3.2037. Leading zeroes are not required. The default value is 0.0
GUICONTROL -- For defining GUIXML elements.
CLASS <classname> CLASS <classname> This is a field which contains a class (and thus that class's fields). In this way it is possible to have any arbitrary complex nested structure in various classes. For more information, please see the section below on subclasses. Default is the default of all the individual subfields
ID ID This field stores a numerical identifier which corresponds to some sort of definition, node or prototype, etc. Although it is an integer value, it can be a very large one (UINT - unsigned 64-bit integer) so it is necessary to use fields/variables of type ID for all Global Unique Identifiers (GUID), as an integer will not do. The default value is 0.
INTEGER INTEGER A signed 64-bit integer which can be positive or negative. The default value is 0.
LIST OF <typename> LIST OF <typename> Please see the section on List Information. Defaults to an empty list.
LOOKUPLIST LOOKUPLIST A key/pair list. Please see the section on List Information. Defaults to an empty list.
NODEREF NODEREF Declares a pointer to a node. Note that if a class is not specified, a WHERE will be needed if it is desired to access fields on the node. Defaults to no reference (NONE)
NODEREF OF CLASS <classname> NODEREF OF CLASS <classname> Declares a noderef of a specific class, which makes it easier to access its fields. Important: A NODEREF type is a pointer to a node in the GOM, so setting a variable of type NODEREF is just changing what it points to - not creating a node or copying its values. Defaults to an invalid reference (NONE)
SCRIPTREF SCRIPTREF References a script. It can be set to a script name such as fallScript or test_four. Defaults to an invalid reference (NONE)
STRING STRING An unlimited-length string value, such as "this is a string" or "27" or "Michelangelo". To determine its current length via HeroScript, check <string>.length. Defaults to an empty string ("")
TABLE TABLE Maintains a fixed sized two-dimensional group of a given type. Defaults to the default value of whatever type is contained within the table.
CLI Syntax: table 4 5 of integer.
HeroScript syntax: x as table[4,5] of integer
Date Time Date Time A type used to display or track the current date/time
Time Interval TimeInterval A literal time interval is of the form HH:MM:SS.SSS where HH is the hours, MM the minutes, and SS.SSS is the seconds (the fractional part is optional).
TIMER TIMER A collection of different types. Please see the TIMER section for more information.
VECTOR3 VECTOR3 Has fields: x, y, and z. Can be added/subtracted to other vectors, or multiplied/divided by a float. Operations affect all fields. Default is (0,0,0).
Syntax: q as vector3. See Vector Functions

Memory Footprints

In HeroEngine, each datatype is a "Union" type. The normal scalar types all use the same amount of memory. Complex types use more. If given a choice between using a simple data type or a complex one, it is more efficient to use a simple type.


Note: To convert an integer to a float, simply set it.

f as float
f = 1
f = 0.3
f = .2    // Note that a leading zero is not required

There are many other options for Auto Conversion.

The NONE Data Type

There is a special keyword NONE which is used for dealing with ScriptRef and NodeRef variables:

Adding classes to nodes

There are different ways of either defining the class that a node is, or of adding additional fields to that node.

It is also worth noting that while adding a class to a node will increase the number of fields available to that node, it will not add field *data* to that node. Adding the class is simply adding more locations in which data can later be stored.

If multiple classes are added to a node, and any of the classes have the same field names, then the node will only have *one* instance of that field. If it has never had the field before, the field is added with a NULL value. If it already had the field, and a new class is added which has the same field name, there is no change to that field's data on the existing node. The only difference will be that the node will then gain access to the other fields on that class which it didn't have yet.

Subfields -- Creating fields which are classes

Sometimes it may be desired to have a node which is of 1 or more classes, which also has access to other classes and fields, without being of those classes. Or, it might be desired to have a complex nesting structure where one node has many different possible types of data that it needs to keep separate, such as to have many different damage fields which are capable of storing different data even though they're on the same node. The way this is accomplished is via subfields -- adding fields to the node which are of type class, and thereby allowing access to those classes' fields, without affecting the data in the node's other fields.

In this way you could have any arbitrary complex nested structure in a class. For example, create a field definition:

: cfd "field_which_is_class", class "that_class_name"

Define a class which uses that field

: ccd <classholder>, asset; "field_which_is_class"

Add that created class to a node.

: mnac <node id>; <classholder>

And then it is possible to modify the node's subfields which were based on that class:

: MN <node id>; field_which_is_class.field_in_that_class_name=<value>

For a more specific example, there might be a noderef which is a pointer to a node of a nine-headed hydra. Each head can be in a different location, doing something different, and taking different amounts of damage. There are of course many different ways to accomplish this, but for the purpose of this example, one way might be create a class hydra and as part of that class, create a field which was an array of class hydrahead. The hydrahead class would have its own fields such as damage and location. In this way, each of the nine heads would have its own field data.

: cfd heads, array 9 of class hydrahead     // Create the "heads" field definition
: mcdaf hydra, heads                        // Modify the "hydra" class to add the "heads" array
: cnfc hydra                                // Create node ID #2, from class "hydra"

Then to access the subfields, the dot (.) connector would be used:

: mn 2; heads[1].damage=3
: mn 2; heads[2].damage=27
: mn 2; heads[4].location=(1, 3, 5)

This technique could be further extended, with subfields being defined to be of type class and having their own subfields, ad infinitum:

: mn 342; orc.arm.left.hand.damage=.5

VECTOR3 Example

Create a variable of type VECTOR3 and set its fields

// the old way
v as vector3
v.x = 1.0
v.y = 2.0
v.z = 3.0
// or as of version 1.23
var v2 = (1.0, 2.0, 3.0)

would produce an output of:

 (1.0, 2.0, 3.0)


printV3(v * v.y)

would result in:

(2.0, 4.0, 6.0)

(v*v) would result in an error. Vectors can only be multiplied or divided by floats, and can only be added or subtracted by other vectors.

Lookuplist Examples

  ll as lookupList by string of integer
  ll["test"] = 3
  if (ll has "test") 
    // list uses remove <list> at <offset>
    remove ll entry "test"     // or:    remove "test" from ll

  l2 as lookuplist indexed by enum Tolkien of string
  l2[frodo] = "hmm"
  l2[bilbo] = "dork"
  remove frodo from l2
  if (l2 has frodo) 

Example field dataypes

See also

Personal tools