World travel

Usage guide of travel.worlds: destinations backed by engine scenes, shuttles, costs, timed trips, locked destinations, a state parked per world, settings and defaults, service methods, verbs, hooks (travel.depart, travel.unlock, travel.open), events.

Source: module-kits:kits/travel_worlds/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs travel-worldsMCP tool: gripforge_docs { "topic": "travel-worlds" }

Travel between worlds (travel.worlds) #

What it is for #

travel.worlds lets one game hold several worlds (planets, islands, dimensions) and the trip between them. A destination is a document of the destinations collection: a scene of the engine with an entry, a name, a cost in items, a travel time and an opening condition. A shuttle is any entity carrying the component travel.shuttle; using it opens the travel screen. A trip takes the cost, lasts its seconds while the game goes on, then sends the player to the destination scene through the scenes of game.engine. Each world keeps its own state: what stood in the world left is set aside and put back when the player returns.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "travel.worlds" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "travel.worlds",
                              config: { "carry": ["companion"], "reach": 6 } }

It requires game.engine. Declare the scenes (with their entries) in the scenes collection, then the destinations:

{ "destinations": [
  { "id": "earth", "name": "Earth", "scene": "earth" },
  { "id": "moon", "name": "Moon", "scene": "moon", "seconds": 0.1,
    "cost": [{ "item": "fuel", "count": 2 }] },
  { "id": "mars", "name": "Mars", "scene": "mars", "unlocked": false }
] }

First example #

<!-- test: kits/game_engine/host/tests/travel_worlds.rs::a_trip_changes_the_world_and_parks_what_stood_there --> With earth as the start scene, moon reachable and mars locked, calling the service travel.worlds:

travel("mars")   ->  { ok: false, reason: "locked" }
travel("moon")   ->  { ok: true }
travel("earth")  ->  { ok: false, reason: "busy" }     a trip is under way
(the trip ends)  ->  current() is "moon"; a crate left on earth is parked
(back on earth)  ->  the crate is there again, visited("moon") is true

The parked entities are part of the saved game.

Settings and defaults #

SettingTypeDefaultMeaning
shuttleLabelstringBoard {name}Prompt of a shuttle; {name} is its label.
shuttleNamestringShuttleLabel of a shuttle that has none.
reachnumber4The screen opened from a shuttle closes when the player walks further than this, metres (1 to 30).
scopedlist of strings["world.stages", "world.biomes", "life.ecosystem", "resource.nodes"]Capabilities whose service keeps a state per world (scope(id)); told the live world on arrival, in this order.
parkbooleantrueEverything that stood in the world left (but the player, the engine instances and the carried tags) is set aside and put back on return. Off: it stays where it is in every world.
carrylist of strings[]Tags of entities that travel with the player (a companion, a vehicle); never parked.

A destination has id, name, scene (required), and description, entry (default: the first entry of the scene), world (default: its own id; two destinations with the same world are two landing sites of one world, with one state and one park), cost (a list of { item, count }, taken when the trip starts), seconds (default 0: at once), unlocked (false: locked until unlock_destination), opensWhen (a trigger condition such as { "type": "stage_reached", "stage": "orbit" }; the destination stays locked until it holds, then stays open) and order (position in the screen).

Service methods #

Service travel.worlds:

  • destinations(): each destination with open, current, affordable, missing, visited and world.
  • current() and world(): the destination and the world the player is in.
  • travel(id, opts?): answers { ok: true } or { ok: false, reason, missing? }; passing { free: true } skips the cost.
  • trip(): { to, left, total } while a trip is under way, else null.
  • unlock(id) and visited(id).
  • open(shuttle?), close(), isOpen(), shuttle(): the travel screen.
  • placeShuttle(at, yaw?, label?): place a shuttle entity from a script and answer its id.

Verbs, variables, events, hooks #

  • Actions travel_to { destination } (no shuttle, no cost; the travel time still applies) and unlock_destination { destination }.
  • Conditions in_world { destination } and world_visited { destination }.
  • Variables: travel.world, travel.trip, travel.left, travel.open.
  • Events: travel.departed { from, to, seconds }, travel.arrived { from, to, first } (also at the start of the game, and when a script loads the scene of another destination), travel.failed { to, reason }, travel.unlocked { destination }, travel.opened { shuttle }, travel.closed.
  • Failure reasons: unknown, locked, cost, here, busy, scene, or the reason of the tap that cancelled it (default refused).
  • Hook travel.depart { from, to, seconds, free }: mutable seconds and free, cancellable. Asked after the checks and before the cost is checked and taken (a faster ship, a free first trip, a storm that grounds the shuttle).
  • Hook travel.unlock { destination, by } (by is call or condition): cancellable; it stays locked.
  • Hook travel.open { shuttle }: cancellable; the screen stays closed and travel.failed carries an empty to and the reason (default closed).
{ "id": "free_first_trip", "hook": "travel.depart", "match": { "to": "moon" }, "set": { "free": true } }

Hooks and modding #

shuttleLabel, shuttleName, reach, carry and the destinations collection are moddable: a mod adds a destination as a document, or taps the three hooks.

Engines #

The rules run on the web and in the native player. The travel screen is an ui.webui fragment shared by the page and the engines; the arrival uses the scenes of game.engine.

When it does not do what you expect #

  • travel answers scene: the engine could not enter the scene of the destination; check the scenes collection and the entry.
  • cost: the bag lacks items; missing lists them.
  • here: the player is already in that world.
  • A destination never opens: its opensWhen does not hold yet. It is checked when the screen opens, on every arrival and when a trip is asked.
  • Things reappear in the wrong world: the entity carries a tag listed in carry, or park is off.

Limits #

One trip at a time. Per-world state is kept for the scoped capabilities and for what parking sets aside.

Versions #

Kit version 1.1.1; first release in 1.0.0; the hooks and the moddable settings and destinations in 1.1.0.