Skip to main content
Version: 🚧 Alpha 🚧

Class Definition and Instantiation

Declaring a Class​

A class block defines a pure data/logic type — not an agent, no population, no reflex.

class point2d {

/** Horizontal coordinate. Defaults to 0.0. */
float x <- 0.0;

/** Vertical coordinate. Defaults to 0.0. */
float y <- 0.0;

/**
* Returns the Euclidean distance from this point to another point.
* Returns a float.
*/
float distance_to(point2d other) {
return sqrt((x - other.x) ^ 2 + (y - other.y) ^ 2);
}

/**
* Returns a human-readable representation like "(3.0, 4.0)".
* Returns a string.
*/
string to_string() {
return "(" + x + ", " + y + ")";
}
}

Key Points​

  • The class keyword introduces a new object type.
  • Attributes are declared exactly like species variables, with optional default values (<- 0.0).
  • Actions are declared like species actions but operate on the object instance (this).
  • The built-in root class object is the implicit parent of every class that does not declare an explicit parent.

Instantiating Objects​

The constructor syntax is a call to the class name with attributes as facets:

point2d p1 <- point2d(x: 3.0, y: 4.0);
// p1.x = 3.0, p1.y = 4.0

point2d p2 <- point2d(x: 6.0);
// p2.x = 6.0, p2.y = 0.0 (y keeps its default)

point2d origin <- point2d();
// origin.x = 0.0, origin.y = 0.0 (both use defaults)

Only the listed attributes are overridden — the rest keep their defaults.

Accessing Object Members​

Use the dot operator:

write p1.to_string(); // call action: (3.0, 4.0)
write p1.x; // read attribute: 3.0
p1.x <- 5.0; // write attribute
write p1.to_string(); // (5.0, 4.0)

Objects Are Values​

Objects are ordinary GAML values: they can be stored in variables, put in lists, passed as arguments, and returned from actions.

list<point2d> pts <- [
point2d(x: 1.0, y: 0.0),
point2d(x: 2.0, y: 0.0),
point2d(x: 4.0, y: 0.0),
point2d(x: 7.0, y: 0.0)
];

// Iterate over the list
loop p in: pts {
write p.to_string();
}

Nil Objects​

An uninitialized object variable is nil:

point2d maybe_nil;
if maybe_nil != nil {
write maybe_nil.to_string();
} else {
write "maybe_nil is nil — need to instantiate it.";
}

Object Composition​

Objects of one class can be attributes of another class:

class segment2d {

string label <- "seg";
point2d start <- point2d();
point2d end_pt <- point2d();
rgb color <- #gray;

float length() {
return start.distance_to(end_pt);
}
}

A segment2d has point2d objects as attributes — demonstrating that object composition works naturally in GAML.

Example: Full Model​

model ClassDefinitionAndInstantiation

class point2d {
float x <- 0.0;
float y <- 0.0;

float distance_to(point2d other) {
return sqrt((x - other.x) ^ 2 + (y - other.y) ^ 2);
}

string to_string() {
return "(" + x + ", " + y + ")";
}
}

global {
init {
// Constructor with all attributes
point2d p1 <- point2d(x: 3.0, y: 4.0);
write "p1 = " + p1.to_string(); // (3.0, 4.0)

// Constructor with partial attributes
point2d p2 <- point2d(x: 6.0);
write "p2 = " + p2.to_string(); // (6.0, 0.0)

// Distance between points
write "distance(p1, p2) = " + (p1.distance_to(p2) with_precision 3);

// Objects in a list
list<point2d> pts <- [ point2d(x:1.0,y:0.0), point2d(x:7.0,y:0.0) ];
write "First point: " + pts[0].to_string();
}
}

experiment Class_Definition_and_Instantiation title: "Class Definition and Instantiation" type: gui {}