Two people, one plaza¶
A plaza with one person proves little. This part puts two people in it from one browser on one machine, then tries to break it.
Be two people at once¶
Two GitHub accounts and a GitHub app are both optional. Create .dev-identities at the
project root, listing the people you want to be:
and start synqt dev with the picker:
Open http://127.0.0.1:8080/synqt/dev/identity. Tick this tab only beside Alice and
choose her. Open the same page in a second tab and do the same for Bob. Each tab now holds
its own session, so the two tabs are two people. Each name is the part of the address
before the @, and each color comes from the identity, so a person keeps the same color
every time you start.
Put the tabs side by side, walk in one, and watch the walker move in the other.

The picture shows this example under synqt dev --identity-picker in headless Chromium,
from Alice's tab, with Bob signed in from a second tab.
synqt dev adds .dev-identities to .gitignore the first time it reads it, and no
build contains the picker. Developing locally explains each
helper and why none can reach a deployed system.
Try it, then think¶
Question
The edge owns where everybody stands. Open the browser console in Alice's tab and ask for a sprint:
Then walk Alice straight at Bob and keep walking. Predict what happens in each case, in Alice's tab and in Bob's.
Solution
walk(1000, 0, 0) walks. The edge reads forward as how hard the key pushes and caps it at
a full push, so a thousand becomes one, and Alice moves at 3.5 m/s like anyone holding W.
Only the edge sets a position, so the browser has none to forge: the rows that say where Alice is
belong to the edge, and a model flows only from owner to consumers.
Walking into Bob stops Alice at Bob. In Alice's tab the physics stops her first, because
Bob is a kinematic body her CharacterController cannot pass through. The edge stops her at
the same place, two radii from Bob's center, and Bob's tab shows that. If Bob moved in the
tenth of a second before Alice's prediction knew, the edge's answer wins and Alice's
walker moves to it.
Collisions push nobody. The edge moves each walker out of the others and leaves the others alone, so a walker who stands still stays put.
Important
The sign-in is enforced twice, and only the second time counts. The overlay that says
"Sign in to walk in the plaza" is a courtesy. The connect point's scope: user is the
barrier: a visitor who has not signed in never acquires the point, so it has no
Server.walk to call and no Server.walkers to read.
tests/plaza runs these
three checks against the example's own web/edge/Edge.qml: a console walk stays at walking
speed, two walkers never get closer than two radii however one walks at the other, and a
session without user never acquires the plaza.
What you learned¶
- A client can draw with Qt Quick 3D and simulate with Qt Quick 3D Physics.
synqt buildlinks both because the QML imports them and lists them inTHIRD-PARTY-LICENSES, andsynqt doctorchecks that the kits have them. Both are GPLv3, which matters for a desktop build. - Qt Quick 3D Physics runs in a browser with
numThreads: 0, on either WebAssembly kit. - The edge can own positions in a 3D world without the physics engine, because what it decides is flat: where a walker is on the ground, and whether that spot is free.
- Prediction and authority agree when both describe the same world: the same walls, pillars, radius and speed, and the same way a heading turns forward.
- People you know only from snapshots are kinematic bodies, moved to where interpolation says they were, so your own physics collides with them.
- A 2D label in a 3D scene faces the camera when it turns by the camera's heading minus the walker's.
- A model the owner republishes every step reaches the browser as rows first and values after, so a client reads a row only once its values are there.
.dev-identitiesand this tab only turn one browser into as many people as you need.
Where to go next¶
- Jump. A
CharacterControllerfalls under its owngravity, so a jump is a brief upwardmovement. The edge would need a height and a vertical speed per walker: the step from a flat world to a real one, and a good test of how much physics the edge must mirror. - Remember where people were. Add a relational entity, as in the Hall of Fame, store each walker's last position when they leave, and put them back there when they return.
- Send only what each person can see. Here everybody receives everybody, which is fine for a square and wasteful for a city. The multiplayer game makes the edge per caller and sends each player only what is near them.
- Build it for the desktop. Add
desktopto the client'stargets, and the same QML runs as a native app against the same edge. See desktop clients. - Read Qt's
CharacterController example
for crouching, sprinting, triggers and teleporters. Each changes how a walker moves, so
the edge's rules in
web/edge/Edge.qmllearn it too, or the edge refuses what the prediction allowed.