A collaborative web application (virtual office) presented as a 16-bit RPG video game https://workadventu.re
  • TypeScript 78.7%
  • Svelte 19.1%
  • HTML 0.7%
  • JavaScript 0.5%
  • CSS 0.5%
  • Other 0.3%
Find a file
yannisdia a50ab561d2 fix(zones): bound the number of zones a viewport can subscribe to
Production reports a RangeError in RoomManager.cleanupAllZones:

    RangeError: Too many elements passed to Promise.all

V8 stores the remaining-elements counter of Promise.all on a 21 bits
field, so it throws above 2^21 elements. In other words a single
listenRoom stream had accumulated more than 2 million subscribed zones.
The crash is only the visible symptom: long before throwing, such a room
had already blown up the memory of both the pusher and the back.

Nothing bounded the chain going from the client viewport to the zone
subscriptions: ViewportMessage is an int32 coming from the browser, and
the only validation was `left > right || top > bottom`. A client
announcing a viewport of 1 000 000 x 1 000 000 pixels generates ~9.7
million zones, freezing the pusher in the subscription loop.

Three layers:

- PositionDispatcher crops any viewport covering more than 1600 zones
  around its center, before looping (it is the loop itself that freezes
  the pusher). Cropping rather than rejecting, because a player fully
  dezoomed on a very large map can legitimately go above the limit: they
  keep seeing the players at the center of their view instead of being
  frozen on their previous zones. Viewports with inverted or non finite
  coordinates are still ignored.
- RoomManager refuses more than 50 000 subscribed zones per listenRoom
  stream, as a safety net if the pusher misbehaves, and reports it once.
- cleanupAllZones no longer uses Promise.all: removals are synchronous
  once the room is resolved, so SocketManager.removeZoneListeners
  removes them in bulk, resolving the room and attempting the room
  cleanup only once. Clearing the map also makes cleanupAllZones
  idempotent: it is called from the "cancelled", "close" and "error"
  handlers, which may all fire for a single disconnection.
2026-08-11 17:20:38 +02:00
.claude Adding a "translate" skill 2026-01-27 18:09:05 +01:00
.codex/skills/translate Adding the ability to configure the megaphone notification sound 2026-02-13 12:25:03 +01:00
.github feat(ci): add a "full-trace" label to opt into DOM snapshots 2026-08-11 16:06:59 +02:00
.husky fix(play front): load fonts and boyscout 2026-05-11 17:53:43 +02:00
.vscode Merging develop in refonte-main 2024-11-20 10:44:08 +01:00
back fix(zones): bound the number of zones a viewport can subscribe to 2026-08-11 17:20:38 +02:00
benchmark Migrate to svelte 5 and bump all libs (#6157) 2026-06-08 15:50:08 +02:00
cd Setting up a map-storage deployed in multi-domain mode in CD 2023-01-26 15:07:22 +01:00
contrib fix(self-hosting): use OPENID_WOKA_NAME_POLICY in Docker setup 2026-08-11 09:10:35 +02:00
desktop build(deps): bump form-data from 4.0.0 to 4.0.6 in /desktop/electron 2026-06-16 11:55:27 +02:00
docs fix(self-hosting): use OPENID_WOKA_NAME_POLICY in Docker setup 2026-08-11 09:10:35 +02:00
libs feat(shared-utils): report LockByKey callback failures and require observability hooks 2026-07-10 14:37:56 +02:00
map-storage chore(deps): bump shell-quote and concurrently 2026-08-10 15:43:31 +02:00
maps Migrate to svelte 5 and bump all libs (#6157) 2026-06-08 15:50:08 +02:00
messages chore(deps): bump tar from 7.5.16 to 7.5.22 in /messages 2026-08-10 15:43:54 +02:00
patches fix(tilemap): decode GPU layer data at full precision 2026-08-10 11:05:31 +02:00
play fix(zones): bound the number of zones a viewport can subscribe to 2026-08-11 17:20:38 +02:00
synapse feat(chat): add pending file attachments with preview before send (#5819) 2026-03-06 15:10:37 +01:00
tests feat(ci): add a "full-trace" label to opt into DOM snapshots 2026-08-11 16:06:59 +02:00
uploader build(deps-dev): bump form-data from 4.0.5 to 4.0.6 2026-06-17 21:35:23 +02:00
.dockerignore Migrating to PNPM (#2900) 2022-12-21 12:58:25 +01:00
.env.template fix(self-hosting): use OPENID_WOKA_NAME_POLICY in Docker setup 2026-08-11 09:10:35 +02:00
.gitignore Add Korean (ko-KR) translation (#5367) 2025-11-20 15:01:48 +01:00
AGENTS.md Updating AGENTS.md with Codex advices and Yannis Cursor file 2026-06-25 10:36:59 +02:00
CHANGELOG.md Revert change to CHANGELOG.md 2022-10-17 21:15:12 +02:00
CLAUDE.md Adding CLAUDE.md files 2026-06-26 12:02:22 +02:00
CONTRIBUTING.md Standardize npm lint commands: rename 'fix' to 'lint-fix' and separate lint/lint-fix commands 2025-08-18 17:58:31 +02:00
docker-compose-no-oidc.yaml Merge OIDC into main docker-compose and create no-oidc override 2025-08-18 17:40:59 +02:00
docker-compose.e2e.yml Implement a reconnection mechanism for dirty front disconnection (#6029) 2026-05-14 00:27:36 +02:00
docker-compose.livekit.yaml fix: Make livekit recording lifecycle webhook-driven (#6006) 2026-04-24 15:32:04 +02:00
docker-compose.no-synapse.yaml Updating self-hosting doc with Matrix 2024-09-17 11:23:23 +02:00
docker-compose.rustfs.yaml Migrating from Minio to Rustfs (#5702) 2026-02-18 17:04:32 +01:00
docker-compose.single-domain.yaml chore(dev): remove VITE_URL and PiP layout test dev harness 2026-07-10 14:38:39 +02:00
docker-compose.yaml fix(self-hosting): use OPENID_WOKA_NAME_POLICY in Docker setup 2026-08-11 09:10:35 +02:00
egress-config.yaml [Recording] wip : livekit recording with egress 2025-04-28 17:01:10 +02:00
livekit-config.yaml Fixing the flicker when coming back to a tab 2025-10-03 16:47:19 +02:00
npm-install.sh Revert "Prefer offline install" (#5854) 2026-03-13 15:43:49 +01:00
package-lock.json chore(deps): bump undici 2026-08-10 16:53:47 +02:00
package.json fix(ci): make patch-package resilient in scoped workspace installs 2026-07-14 14:20:28 +02:00
README-MAP.png WOrking on UI play 2023-10-08 09:59:06 +02:00
README.md Merge OIDC into main docker-compose and create no-oidc override 2025-08-18 17:40:59 +02:00
SECURITY.md Create SECURITY.md 2021-06-23 15:26:17 +02:00
UPGRADE.md feat: Move TURN credentials management from back to pusher (#5361) 2025-11-20 15:46:55 +01:00
Vagrantfile.template Update vagrant template 2020-12-16 16:39:34 +01:00
wait-proto.sh Implement Healthchecks on Docker Compose Files (#3206) 2023-04-27 21:53:52 +02:00

Discord Awesome

WorkAdventure office image

WorkAdventure

WorkAdventure is a platform that allows you to design fully customizable collaborative virtual worlds (metaverse).

With your own avatar, you can interact spontaneously with your colleagues, clients, partners (using a video-chat system, triggered when you approach someone). Imagine all types of immersive experiences (recruitments, onboarding, trainings, digital workplace, internal/external events) on desktop, mobile or tablet.

The little plus? The platform is GDPR and open source!

See more features for your virtual office!

Pricing for our SaaS version!

Workadventure live demo example Workadventure Website

Support our team!

Discord Logo X Social Logo LinkedIn Logo

Stats repo

Community resources

  1. Want to build your own map, check out our map building documentation
  2. Check out resources developed by the WorkAdventure community at awesome-workadventure

Setting up a production environment

We support 2 ways to set up a production environment:

  • using Docker Compose
  • or using a Helm chart for Kubernetes

Please check the Setting up a production environment guide for more information.

Note

WorkAdventure also provides a hosted version of the application. Using the hosted version is the easiest way to get started and helps us to keep the project alive.

Setting up a development environment

Note

These installation instructions are for local development only. They will not work on remote servers as local environments do not have HTTPS certificates.

Install Docker and clone this repository.

Warning

If you are using Windows, make sure the End-Of-Line character is not modified by the cloning process by setting the core.autocrlf setting to false: git config --global core.autocrlf false

Run:

cp .env.template .env
docker-compose up

The environment will start with the OIDC mock server enabled by default.

You should now be able to browse to http://play.workadventure.localhost/ and see the application. You can view the Traefik dashboard at http://traefik.workadventure.localhost

(Test user is "User1" and password is "pwd")

If you want to disable the OIDC mock server (for anonymous access), you can run:

$ docker-compose -f docker-compose.yaml -f docker-compose-no-oidc.yaml up

Note: on some OSes, you will need to add this line to your /etc/hosts file:

/etc/hosts

127.0.0.1 oidc.workadventure.localhost redis.workadventure.localhost play.workadventure.localhost traefik.workadventure.localhost matrix.workadventure.localhost extra.workadventure.localhost icon.workadventure.localhost map-storage.workadventure.localhost uploader.workadventure.localhost maps.workadventure.localhost api.workadventure.localhost front.workadventure.localhost

Troubleshooting

See our troubleshooting guide.