A world is visited by people, but content never names a player. Players, their identity, the avatars fetched for them, authentication, payment and messaging are outside the content (Outside the content). What an avatar is made of, and which of its pieces are content, is on Avatars. What the content sees is beings: parts that act. A visitor drives a being; a villager's mind drives another; both perform the same named actions, and the world answers them with events. Where a visitor's act meets the content, three layers meet: the physical input (a key, a tap), which is the browser's; the named action, which is the contract; and the content's response.

Beings

A being is a part that acts. Each step of the world it is given actions (walk ahead, turn, run, jump, hail), and the engines move its body accordingly. A lantern is placed; a being moves itself. Who chooses its actions is a separate question: for a visitor's avatar it is the visitor, for a villager a mind, for a puppet world logic, and for the stand-in on the beach, nobody until a visitor takes her over.

part villager
  field who  : person
  part body: who
    being(self)                                 // a being: it acts each step; no visitor may take it over

part beach
  part standIn: people.averageWoman
    being(self, possessable: true)              // idle until someone takes it over

A handle on a being

Content must still say "the nearest visitor", "whoever asked", "the one who threw it", key a field by them and range over them. It does so with a handle on a being: an id for a body in the world, not a path, which content may compare, use as a key and measure distances from.

on(action(ask, q, to: g, by: v), ...)                        // v: the being that acted
field asked: Table[being, bool] = false, mutable: true, lives: both   // a field keyed by being
npcbehave.follow(nearest(visitors), keep: 6 m)               // a relation over visitors' beings

nearest(visitors) is whichever visitor-driven being is nearest at this step, without naming any visitor. me is the being driven by the visitor at this machine: on each visitor's machine it is that visitor's being, so a value worked out from it, such as occupied(post, by: me), is each visitor's own and lives on their machine (lives: client; Physics: areas). It names no one: it is a relation, as nearest(visitors) is. A being is not a player: the same person could be a villager in one world and a visitor's avatar in another, because what a being is (its who) and what drives it are separate fields.

What a being handle reads

A handle reads the being's state, as fields. The ones content may read:

WrittenTypeWhat it is
v.feet, v.placeplacewhere its feet stand, on the ground; v.place is the same place
v.nametextthe name it is known by
v.heightmetershow tall its figure is
v.whopersona figure of its height and colors, which is enough to make a copy of it (the looking-glass's reflection). Reading more of a visitor's look stays open (Avatars)
v.chestplacethe middle of its chest, 0.7 of its height above its feet; a spell's range is measured to it
v.eyesposewhere its eyes are and which way they look; a plain walker's eyes are 1.7 m up
v.rotationrotationthe way it faces, about up
v.speedspeed (m/s)how fast it moves along its heading, signed: negative backing up. In the air it is the speed it left the ground with (a walker's gait is told 0)
v.verticalSpeedspeed (m/s)how fast it rises (negative falling); a fall faster than 5 m/s sends it limp
v.modeenumwhat it is doing: walking (on its feet, in the air or not), limp (a ragdoll, falling or lying), gettingUp or seated (Physics: the ragdoll)
v.standingbooltrue while v.mode == walking: false while it is limp, lying, getting up or seated
v.activebooltrue for a being with a body of its own (a figure that walks, jumps and is drawn); false for a plain walker, which is only eyes
v.healthfraction1 whole. A hard landing costs it (Physics: landing); a fall faster than 5 m/s sends the being limp whatever its health, and an emptied health only decides where it gets up (Physics: the ragdoll)
v.groundedboolwhether its feet are on something
v.onPlatformboolwhether it stands on a platform that carries it (the balloon's basket)
v.isPropbooltrue for a thing that is moved but does not act (a ball, a pin); a gate's when: may ask it of whatever tries to cross

A handle is typed by what it stands for: a field that holds a guard is field guard: ?guard, the design's name, and the checker knows it has the guard's fields; it is not a bare being. A bare being is for what any being has, the fields above.

Actions: verbs with typed values and targets

An action is a named verb a being may perform, with a typed value it carries and the kind of thing it is aimed at. It is a message whose sender is a being. In an event it is a trigger:

on(action(name, value, to: target, by: v), ...)
on(action(ask, q, to: g, by: v), ...)          // carries a question; aimed at a guard; by being v
on(action(hail, by: self), ...)                // carries nothing; a being's own hail

The handler receives the value, the part or place addressed, and the being that acted. None of these is a key: the content never sees keys, only actions.

Declaring an action

A world may declare its own actions, with these fields:

action(ask,
       carries: (q: question),               // name and typed value
       to: guard,                            // what it needs as a target
       range: 4 m,                           // range, checked again on the server
       offered: offered(ask, by: target),    // availability
       kind: once,                           // once, or held (a value every step, as walk)
       suggestKey: 1 ..= 4)                  // the world's own actions only: a digit, a letter in quotes ("B") or a function key (F2)

action(walk, carries: (ahead: number, turn: number, run: bool), kind: held)   // illustration
action(nextWeather, kind: once, suggestKey: "T")           // carries nothing and needs no target: both left out

action(zap, carries: (eye: place), to: being, range: 25 m, kind: once, suggestKey: F2,
       offered: v.standing && v.active && target.standing && target.active)   // a spell on a being
FieldMeaning
What it carriesA typed record with units and ranges, as fields have: walk carries (ahead: number, turn: number), each between -1 and 1, ask carries (q: question). carries: may be left out when the action carries nothing: nextWeather, a key that cycles the weather, is just pressed.
TargetOne of: self (hail, drink-me), a part (a seat, a lever, a docking port), a being (zap, jab), or a place, given as a point or as a ray the engine follows (paint, a fireball). to: ray carries the ray from the visitor's eye along where they look, a start and a direction, for the handler to follow as it needs: the bowl hands it to throw, which aims where it first meets the ground or a solid within 60 m (Physics: throwing a body). It may be narrowed by type: to: part is seat. to: may be left out when the action needs no target.
RangeHow far the target may be, range:. The server checks it, measured from the eye to the target's chest (t.chest). The browser aims inside it: its lock-on reaches 22 m, to the surface of a 0.35 m sphere round the chest, 3 m inside the zap's range: 25 m.
The eyeAn action may carry eye:, a place the browser fills from the camera, so that range and a clear line are worked out from where the person is looking from, not from the being's head. The server believes it only within 5 m of the being's head (0.936 of its height up); beyond that it uses the head.
AvailabilityWhen the action is offered: sit only near a free seat, stand only while seated, ask only after the guard has offered it, bowl only while the visitor stands and has a body (offered: v.standing && v.active, v the being that would act). offered: may read target as well as v: the zap is offered only on a target that is standing and drawn. It drives the browser's hints and its action menu; the server refuses an action that is not available.
Once or heldMost actions happen once; walking is a value every step.

Three tiers

TierExamplesWho defines itWhat a world may do
Reservedleave, portal home, menu, mute, blockthe browserNothing: never remove, rebind or intercept them, and never receive them.
Standardwalk, run, jump, use, sit, hailthe browser's environmentAdopt any, and write its own response. The response to walk, run, turn and jump is built in, needs no line from the world, and is the same on the server and in the visitor's predicting browser (Physics: the walking response). A hail may be a wave in one world and a bow in another, but the name and what it carries do not change, so a person's habits carry from world to world.
The world's ownask, zap, paint; dock and thrust in space; drink-me in a dreamlandthe worldEverything: name, value, target, range, availability, suggested keys.

A space world would declare thrust along three axes and turning about three, with no jump and no run; the keys could be the same as walking's, since walk and thrust are never available together.

Input mapping

The three layers:

LayerWhat it is
1. Physical inputA key, a stick, a gesture, a panel. The browser's, or a future overlay's. Out of the content's scope.
2. A named actionWhat the being means to do. A world may define these, as it uses vocabulary names. Examples: walk (ahead, turn, run), jump, sit, hail; ask, carrying a question, aimed at a guard.
3. The content's responseAn event, a library behavior, a subscription. For example, a gait turns walk and jump into motion and a pose; on(action(hail, ...)) is a wave and a smile; a hall's handler answers ask.

The proposals for the browser's side of the seam:

Offering an action

offer(ask, to: h) makes a world's own action available to one being, after a hail (proposed; actions.html). How the browser shows it, a panel, four buttons, a spoken menu, is the browser's. The content says what may be asked; the browser decides how to ask it.

Speech is an act

A speaker (an NPC, a door, a radio, a player, a narrator) computes its words as a pure value, then performs the act say(g, words, to: v) at a moment. It puts the words nowhere. How speech appears is the world's: the world has a rule that answers every speech act and manifests it as its designer chose:

on(spoke(speaker, words, to: v), ...)         // the world's rule for every speech act

In what it shows, you names the being the visitor drives, whose picture this is, and a bubble is shown with show(element, for: d) (overlays.html). A bubble layout anchored above the speaker, a subtitle, speech from text, a chat-log line, several at once, or nothing out of earshot or through a wall: each is a way the world may show it (overlays.html). Only the act crosses the network; each visitor's machine manifests it, and the visitor's own preferences (captions, translation) may apply on top. A visitor's own speech is the same act: a player is one of the speakers.

on(action(ask, q, to: g, by: v), {             // the guards' riddle
  if within(v, g, 4 m) {
    if asked[v] {
      say(g, "You have had your question.", to: v);
    } else {
      set(asked[v], true);
      say(g, answer(g, q), to: v);
    }
  }
})

to: v names the addressee, not the audience. A guard's line is addressed to the asker, and everyone near sees it: the act goes to every visitor's machine, the plate over the guard's head shows it to all, and the asker's panel takes the line as its answer because the panel acts only for its own visitor (on(spoke(g, line, to: you), ...)). So others learn by watching that a guard refuses a second question. say(g, words, voice: 118 Hz) overrides the speaker's own voice for that one line, so a speaker whose lines differ in pitch (the Worm's) gives each its own. A line of speech carries its words; the engine may compress lines on the wire, which content never sees.

What it means

Authority

The server holds the truth and may refuse at every stage:

Nothing a visitor can forge

Values that decide what a being may do or what a villager thinks of it live on the server, written by logic that runs there, kept there or shown only to their own visitor. A browser that claimed a better standing would have nothing to send it to.

How it connects

Open questions

← Package behaviors | Contents | Avatars →