8.4.614-stable Switch to dev

Many Worlds

A GreyCat server holds one graph: the main world. A server can also hold any number of other worlds. A world is a named branch of the graph. A task that runs in a world reads the graph as the world sees it and commits to the world only. Main never sees what the world writes.

                      main  (the real system: live data)
                        │
       ┌────────────────┼────────────────┬──────────────────┐
       │                │                │                  │
   scenario-a       scenario-b       scenario-c        tenant-a   
   (overlay)        (overlay)        (snapshot)        (standalone)
   writes the       writes another   frozen copy of    its own graph,
   predicted        future           main at t0        nothing shared
   future

Worlds share the storage of the server. A world shares every block it has in common with its base, so a world costs only what it writes. An overlay world is created instantly, whatever the size of the graph. One server can run a hundred worlds side by side, with the same workers, the same memory budget and the same API.

What worlds are for

Namespaces. Several graphs run concurrently in one server. Each stakeholder, customer or team works in its own world, isolated from the others, while the server, its workers and its storage are shared. See Namespaces.

Simulation. This is what worlds were mostly designed for. A world is a change scenario: it holds alternative values for many nodes, and above all new points in nodeTime series, the predicted future of the system. You run your functions inside the world to compute a conditional future: what happens if the vessel sails at 8 knots instead of 11? See Simulation.

Sharing results. A world outlives the task that filled it. You keep it, give other users access to it, and they call your API in that world to read the scenario as if it were real. See Namespaces.

Search. Worlds can be the base of a search engine. An algorithm, a genetic algorithm for instance, forks one world per candidate, evaluates them all in parallel, keeps the worlds on the Pareto front and removes the others. See Scenario Search.

Whatever the use, one question always comes back: what did this world change? GreyCat answers it natively with WorldChangesReader and WorldDiffReader, which list the changes of a world against its base, node by node and key by key. See World Diff.

The pages of this section

Page What it covers
Basics The World API, the three modes, how to run code in a world, limits
Namespaces Isolating stakeholders, the worlds a user may use, sharing a world
Simulation Writing a predicted future in a world and evaluating it
World Diff Listing what a world changed, comparing scenarios, drift against reality
Scenario Search Parallel evaluation of many worlds, genetic search, Pareto front

The running example

The pages of this section share one small model, a fishing vessel whose speed and fuel consumption are time series:

type Vessel {
    name: String;
    /// knots
    speed: nodeTime<float>;
    /// litres per hour
    fuel_rate: nodeTime<float>;
    config: node<EngineConfig>;
}

type EngineConfig {
    mode: String;
    max_rpm: int;
}

var vessels: nodeIndex<String, Vessel>;

fn seed() {
    var start = time::parse("2026-10-26T06:00:00Z", null);
    var v = Vessel {
        name: "trawler",
        speed: nodeTime<float> {},
        fuel_rate: nodeTime<float> {},
        config: node<EngineConfig> { EngineConfig { mode: "diesel", max_rpm: 1500 } },
    };
    for (var h = 0; h < 6; h++) {
        v.speed.setAt(start + h * 1hour, 10.0);
        v.fuel_rate.setAt(start + h * 1hour, 300.0);
    }
    vessels.set(v.name, v);
}

Main holds what really happened: six hours of measurements, from 06:00 to 11:00. The worlds hold what could happen next.

World, WorldChangesReader and WorldDiffReader are in the runtime module of std.