Repository navigation
EN Create Phone On The Lan
Français · How-to · Published, partly reviewed by a person · Applies from: 4.1.2
A game is made for a phone held in landscape. This page starts the development server so that a phone on the same Wi-Fi opens the game you are writing, with the reloads as you edit, and says what stays protected while it does.
Audience, context, and the statuses of what this page rests on
Audience: author · Context: engine repository, created project
The game you are editing, open on your phone at http://<your machine's address>:5173/, reloading each time you save
a file. The Studio and the placement editor stay reachable from the phone too, but only with a one-session token the
command prints.
-
Engine repository:
npm run dev:lan(andnpm run studio:lanfor the Studio). It exists since 3.0.0; since 4.1.2 the Studio's write routes also check theHostthe browser sends (below). -
Created project (made by
npx @quest-n-click/create <folder>orquest-n-click create <folder>): there is nodev:lanscript. Itsdevpasses extra options to Vite, sonpm run dev -- --hostserves the game on the network. That mode gives no token: the phone plays, but the Studio and the placement editor refuse every write that does not come from this machine (see Limits).
- The game runs on your machine:
npm run devopens it athttp://localhost:5173/(The working loop). - The phone and the machine are on the same network, and the network lets two devices talk to each other (a guest Wi-Fi or a public hotspot often does not).
- Your machine's firewall lets incoming connections reach Node on port 5173.
On your machine, in a terminal open in the engine repository (or in the created project, for its own command). Nothing runs on the phone: it only opens a URL.
-
Start the development server on the network.
# in the engine repository, on your machine npm run dev:lan# in a created project, on your machine npm run dev -- --hostdev:lanfirst points@gameat the current game (GAME=<id>, else the game last selected, elsepackage.json→config.game), then starts Vite listening on every interface (--host 0.0.0.0). Before Vite's own lines it prints a banner:LAN write access is protected by this one-session token: <token> Studio: http://192.168.1.20:5173/__studio/?token=<token> Layout editor: http://192.168.1.20:5173/?edit=<room>&token=<token>The address is your machine's first IPv4 address on the network. Vite then lists its own
Network:URLs.
- On the phone, open
http://<that address>:5173/and turn the phone to landscape.
- Play what you just wrote. In the lamp of Your first game, tap the lamp with Use: the line shows, the prop changes, and the save remembers it when you reload. That is the loop: write a rule, place it, check, play.
- Optional: to edit from another device, open the Studio or Layout editor URL of the banner, with its
?token=. The first request with the token sets anHttpOnly,SameSite=Strictcookie, so the next pages need no token in the URL. To start the Studio itself on the network, runnpm run studio:laninstead of step 1 (engine repository): it opens the Studio's URL with the token.
Limit ·
dev-server-no-offlineThe development server is not the built game: the phone tests the rules, the placement, the text and the touch, not the installation as an app, the offline mode or the cache. Test those on a build served over HTTPS (Build and release a game, Sub-path, cache and service worker).
- Without
dev:lan/studio:lan, Vite listens on127.0.0.1only (vite.config.ts): no other device reaches it. - In LAN mode, every file-writing route of the Studio (the Studio's API, the placement editor's save) asks for the
token: in the
x-web-scumm-tokenheader, in?token=, or in the cookie. Without it:401 Studio token required. The token is new at each start, unlessWEB_SCUMM_STUDIO_TOKENis set (environment variables). - In every mode, those routes answer only to this machine's names (
localhost,127.0.0.1,[::1]) and, in LAN mode, to the addressesdev:lanprinted. Any otherHostgets403 the Studio answers its own names only, so a page that rebinds a name to your port cannot write. A write whoseOriginis another site gets403 cross-origin Studio request refused. - In a created project with
npm run dev -- --host, no LAN address is on that list and no token exists: the phone plays the game, and any write through the Studio or the placement editor from the phone is refused with a 403. Edit on the machine itself.
Guarantee ·
lan-writes-need-token· referenced · executed on47dccf1b4b15· scope reviewed In LAN mode, the Studio answers 401 to a request without the token, and 403 to a write whoseOriginis another site even with the token. The test runs the guard on a local HTTP server; it does not start Vite.
Limit ·
lan-trusted-networkThe token protects writes, not reading: anyone on the same network can open and play the game while the server runs. Use it on a network you trust, and stop the server (Ctrl+C) when you are done.
The phone shows the title screen, then the game in landscape. Save a room file on the machine: the phone reloads with the change. In the Studio opened from the banner's URL, a save goes through (no 401).
| Symptom | Cause | Fix |
|---|---|---|
| The phone's browser waits, then says the site cannot be reached | The phone is on another network, the Wi-Fi isolates its clients, or the firewall blocks port 5173 | Put both on the same Wi-Fi, allow Node through the firewall (macOS asks at the first start), or try another network |
It works on the machine (localhost) but not on the phone |
npm run dev was started, not npm run dev:lan: Vite listens on 127.0.0.1 only |
Stop it and start npm run dev:lan (created project: npm run dev -- --host) |
401 Studio token required when saving from the phone |
The Studio or editor page was opened without the banner's ?token=
|
Open the banner's URL; the token changes at each start of the server |
403 the Studio answers its own names only … |
The page was opened under a name that is not this machine's or the printed address (a .local name, another interface's address), or in a created project with --host
|
Open the exact address of the banner; in a created project, edit on the machine |
✖ games/<id>/index.ts not found (GAME=<id>) |
GAME names a game that does not exist |
Check ls games, or unset GAME
|
| Port 5173 in use, Vite picks another port | Another dev server runs | Stop it, or open the port Vite prints; the banner's URLs say 5173 whatever Vite chose |
dev:lan itself writes nothing but the .cache/game link to the current game. What the phone saves (the game's
progress) stays in the phone's browser storage. A write made through the Studio or the editor changes the game's files
on the machine, as on localhost.
Stop the server with Ctrl+C: the token dies with it, and npm run dev goes back to listening on 127.0.0.1 only.
-
tools/serve.tsandtools/serve-args.ts: whatdev:lanandstudio:lanstart, the token and the banner. -
tools/studio/security.ts: the token, the names and the origin checked on each write. -
vite.config.ts:server.host,127.0.0.1unlessWEB_SCUMM_LAN=1. - Your first game, The working loop, Local and LAN security.
- Next: DSL reference for every field, Classic mechanics for famous mechanics written with them, The local Studio for the tool, Working with an AI for a whole game from the first idea to the release.
Generated publication · publication générée — current documentation · documentation courante: quest'n'click 4.5.4 r2, documentation revision · révision de la documentation 63112c877c587cc4fad16b25a3400408db2c36bd.
Latest documentation · dernière documentation: https://quest-n-click.cleverapps.io/docs · https://quest-n-click.cleverapps.io/fr/docs; earlier versions · versions précédentes: each release's quest-n-click-docs-<version>.tar.gz · l'archive quest-n-click-docs-<version>.tar.gz de chaque release, https://github.com/Quest-n-Click/quest-n-click/releases
An edit made in this wiki is overwritten at the next publication · une modification faite dans ce wiki est écrasée à la publication suivante.
Edit the source · Modifier la source · Report an error · Signaler une erreur
Index (6)
Start (6)
Play (9)
Install (18)
- Requirements
- Install from the release archive
- Install from npm
- Install from the repository to work on the engine
- doctor: checking your machine
- Image toolchain
- Audio toolchain: ffmpeg, fluidsynth, Furnace, uv
- Upgrade
- Upgrade notes: 4.5
- Upgrade notes: 4.4
- Upgrade notes: 4.3
- Upgrade notes: 4.2
- Upgrade notes: 4.1
- Upgrade notes: v3
- Upgrade notes: v2 to v3
- Coming from web-scumm
- Package reference
- Install troubleshooting
Create a game (55)
- Your first game
- Layout of a created project and of the engine repository
- The working loop
- Content principles and the identity contract
- Rooms
- Geometry: placement, walk zones, masks, layers, camera
- Something is visible but unreachable
- Reactions
- Game commands
- Conditions
- Flags, variables and events: which to use
- Custom code
- Characters
- Items and inventory
- World map
- Dialogues
- Scripts and events
- Moving characters: patrols and walks
- Exits
- Chapters and objectives
- State and saves: persistent or temporary, renaming an id, migrations
- Staging: wide rooms and animations
- The stage: lights, particles, floors
- Skin and fonts
- Title and credits
- Heroes: several characters and hero choice
- Built-in minigames
- A custom minigame
- Translations
- Music in stems
- Sound effects
- Voices: per language and per hero
- Images: prompts, cutting sheets, transparency, scale
- Asset provenance
- The storyboard, source of truth
- Puzzle design
- Classic mechanics
- Review pages
- DSL reference
- Checking your game
- What the solver proves
- Solver options
- Playtests
- Remix
- Speedrun for authors
- The sealed ending
- Production template
- Example games
- Working with an AI
- Build and release a game
- Publish on GitHub Pages
- The static game on Clever Cloud
- Other static hosts
- Sub-path, cache and service worker, incomplete deploys, going back
- Testing on a phone over the LAN
Local Studio (24)
- The local Studio: overview and launch
- Edit a room
- Placement and stage
- Preview, apply, undo
- Storyboard
- Assets and cutting
- Check: validator, solver, critical path, heat, health, coverage
- Before and after captures
- Semantic diff
- Play and replay a session
- Rule explainer
- Language and objectives
- Voices and the heroes × languages matrix
- Map
- Notes
- Remix in the Studio
- Music
- The Assistant: bring your own key
- Demo mode and studio-apply
- Local and LAN security
- Studio API
- Local MCP: setting up each client
- MCP tools
- Studio troubleshooting
Team Studio (21)
- What runs where
- Concepts: revision, transaction, span, lease, preview, build
- Starting as an invited dev
- Working together day to day
- Roles and actions: the full matrix
- Invitations
- Managing members
- Write refused on the hosted Studio: stale base revision (409)
- Write refused on the hosted Studio: span locked (423)
- Recovering after a lost lease, a disconnection or a stale preview
- Comments
- Map and semantic diff
- Publishing builds
- Remote MCP
- The game in Git
- Upgrading the engine of a hosted game
- Hosted assets
- The server's command line
- Health and metrics routes
- Trying it locally with compose.yml
- Known limits
Clever Cloud (23)
- Clever Cloud: overview, cost and prerequisites
- Apps and add-ons
- Domains and TLS
- Keycloak
- Generic OIDC and GitLab
- Configuration
- First deployment
- Backups
- RPO and RTO
- Restore the Studio on a fresh installation
- Redeploys
- Upgrading the server and checking state after a migration
- Limits of going back
- Monitoring
- Security
- Rotating keys
- Recovering admin access
- Changing domain or OIDC provider
- Worker, PostgreSQL or Cellar down
- Exporting the game and leaving the installation
- Retention
- Clever Cloud troubleshooting
- Costs and teardown
Reality Bridge and connectors (16)
- The Reality Bridge: what it is
- Quick start
- Guarantees
- Install and run the Bridge
- Backup and restore
- Several tenants
- Signals and the manifest
- The Bridge's command line
- Connectors overview
- Email connector
- Telnet connector
- SSH connector
- Open Badges connector
- The connector SDK
- Security: Biscuit and signatures
- Bridge and connector troubleshooting
Contribute (25)
- Welcome
- Developer setup
- The dev loop
- Before a pull request
- Conventions
- Writing documentation
- Architecture
- Code tour
- Import boundaries
- Which tests run when
- Mutation testing
- The coverage ratchet
- The quality baseline
- CI explained
- Field passes
- Benchmarks
- Releasing
- npm packages
- Decisions and ADRs
- Governance
- Bot pull requests
- Contributing with AI agents
- Security policy
- Code of conduct
- Licences and credits