Skip to main content

Defines

Reusable state and behaviour composed into classes or other defines.

Declaring and composing defines

composition.sar
define Position {
    var x int64 = 0
    var y int64 = 0

    func move(change_x int64, change_y int64) {
        x = x + change_x
        y = y + change_y
    }
}

define Motion [Position] {
    var speed int64 = 5
}

class Entity [
    Motion as MainMotion {
        speed = 10
    }
] {
    var name string = "Unknown"
}

func main() {
    local var entity Entity = Entity.new(
        name: "Player"
        main_motion.position.x: 20
    )
    entity.main_motion.position.move(5, 2)
    print(entity.main_motion.position.x)
}

A define can contain variable and constant fields, methods, and other composed defines. A class lists its defines between square brackets after the class name. Each composed define becomes a namespaced component of every class instance.

Component namespaces and aliases

Without an alias, the define name is converted to snake case: Positionbecomes position. Use as Alias to select a different namespace; MainMotion becomesmain_motion. Nested compositions form nested member paths.

Composition configuration

An optional block after a composed define changes its field defaults for that composition. Construction may override class fields and composed fields using complete dotted paths. Configuration and constructor values must match the field type, and each path may appear only once.

Define methods

A define method directly accesses its own fields and methods. It accesses a composed define through that define's namespace. Class methods likewise access composed defines through their namespaces.