Relation

A relation is an object that defines adjacencies between different kinds of objects and specifies operations that apply when objects are connected (related) or disconnected (unrelated). Relations set the rules governing how objects interact within the universe.

Relations are created from a special set called the Set of Relations, managed by the OOPS contract, which is a key component of the protocol. All relations follow the Kind of Relation, which outlines the essential elements a relation object must include.

While it's unclear if original relations existed at the protocol's inception, new relations emerge when users register them.

Relations are typically included in the rel_spec field of kind objects. By listing a relation in its rel_spec, a kind declares that the relation’s rules apply to all objects of that kind.

ID

Emergent relations are assigned IDs by the OOPS contract upon registration:

#![allow(unused)]
fn main() {
ID_EMERGENT_RELS_BEGIN = 17;
}

State Meta

When a relation is registered with the OOPS contract, its metadata is initialized as follows:

#![allow(unused)]
fn main() {
meta.flags = 0;
meta.rev = 1;
meta.kind_rev = latest_kind_rev();
meta.set_rev = latest_set_rev();
meta.kind_id = ID_KIND_OF_RELATION;
meta.set_id = ID_SET_OF_RELATION;
}

State Elements

A relation object, as defined by the Kind of Relation, consists of the following elements:

ElementNameTypeDescription
elems[0]ruleBytes32Defines how the object's properties change when related/unrelated.
elems[1]descBytes32Hash of the JSON material containing information about the relation.
elems[2]adj_spec_0Bytes32Specifies the adjacencies for the relation object.
elems[3]adj_spec_1Bytes32Specifies the adjacencies for the relation object.
elems[4]adj_spec_2Bytes32Specifies the adjacencies for the relation object.
elems[5]adj_spec_3Bytes32Specifies the adjacencies for the relation object.

The rule and adj_spec_i elements cannot be changed after they are set.

rule

The rule field encodes a mini-contract that defines preconditions and postconditions for relate and unrelate operations. This contract specifies ownership, position, and other properties when objects are connected or disconnected.

#![allow(unused)]
fn main() {
pub struct MiniRelationContract {
    relate_precond_operator: is_dep_owner,
    relate_precond_owner: is_dest_owner,
    relate_precond_pos: is_void,
    relate_precond_time: is_any,
    owner_on_form: dest_owner | dep_owner | nobody | vault_under_nobody | vault_under_dest_owner | vault_under_dep_owner,
    pos_on_form: dest_pos | dep_pos | void,
    owner_on_term: dest_owner | dep_owner | nobody,
    pos_on_term: dest_pos | dep_pos | void,
}
}

Each field of the MiniRelationContract is encoded into a Bytes32, ensuring compactness.

desc

The desc field is a material hash, where the preimage is stored on the Previous Chain. This description material is not directly referenced on universe chains but is often used for generating assets for the relation object.

adj_spec_i

The adj_spec_i fields define the adjacency rules for the relation, specifying the kinds of objects that can be connected and the limitations of these connections. Each adjacency specification is encoded in compact form for storage efficiency.

Operations

Operations available for relation objects are as follows:

OperationModifiesSupported
transferownerYes
updatemeta.rev, elems[1]Yes
upgrademeta.rev, meta.kind_rev, meta.set_revYes
touchmeta.revYes
relate/unrelaten/aNo
moven/aNo
enter/leaven/aNo
jump/dropn/aNo