feat: play a set online with friends, hosted from a link and kept in lockstep - #169
Merged
Merged
Conversation
r4mbo7
force-pushed
the
issue-147-online-coop
branch
from
October 5, 2026 09:19
4b2ae96 to
8ffb15f
Compare
This was referenced Oct 5, 2026
…bby from the local one
r4mbo7
force-pushed
the
issue-147-online-coop
branch
from
October 5, 2026 11:18
4a7d5cf to
d9bc58a
Compare
12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #147
Ce que fait la PR
src/app/online.ts: salon en ligne (créer, rejoindre par code ou#rejoindre=CODE), transport PeerJS, choix hôte ou invité, sources de lockstep, relance par l'hôte, fermeture propre, mesure de l'aller-retour (getStats). Les avisdesync,hostLeft,connectionLostpassent parshowNotice.src/app/game.ts: points d'entrée et boucle seulement. Quandsource.nextrend null, le pas s'arrête (steprendfalse,loop.tsfige l'interpolation à 1 et ne doit pas le temps attendu) ; au-delà du tampon (GUEST_BUFFER_TICKS), jusqu'à 2 pas de rattrapage par image.nextn'est appelé qu'une fois par tentative de pas. En ligne : la pause n'arrête pas le set (personnage immobile), l'onglet caché ne met pas en pause, caméra sur son joueur.src/app/pause.ts: texte optionnel (« Le set continue », R19).src/app/toast.ts: « X a quitté le set » quand un invité part.feedback/report.ts, test ajouté).window.ozoboom(?dev=fast) :online(rôle,pending,roundTripMs,connectMs),hash,forceVersion.src/net/peerjs.ts:PeerTransport.roundTripMs()(type local, pas un contrat partagé). Sim, lockstep et salon desrc/net/inchangés.onPlayTogetherouvre le salon en ligne tant que la coop locale (app : coop locale, une partie à plusieurs sur un écran #146, PR feat: play local co-op, two to four players on one screen from a lobby #168) n'a pas son salon local ;onGoOnlineest branché pour la suite.Preuves
pnpm checkvert (1516 tests).CI=1 E2E_PORT=4317 E2E_PEER_PORT=9317 pnpm exec playwright test --project chromium --workers 2: 75 verts ; un test (smoke, mode calme) a perdu son navigateur (« session closed ») sous charge puis passe seul.e2e/online.spec.ts: deux pages, courtier local, création, rejoindre par lien, piège posé par l'invité reçu des deux côtés, set?dev=fastjoué jusqu'au bout,hashStateet tick identiques ; version différente refusée (« Recharge la page ») ; fermeture de la page de l'hôte, avis chez l'invité ; solo sanspeerjs(aucune réponse JS ne contient la bibliothèque tant qu'aucun salon n'est ouvert, elle se charge à la création du premier).Limites
pagehiden'a rien signalé à l'invité en 60 s. Fermer un onglet envoiebye(pagehide). Pas de chien de garde ajouté : un hôte en onglet caché arrête aussi le set.byedeclose()serait pris pour un départ).Pour Constantin (#149) : deux machines, deux réseaux
?dev=fastexposewindow.ozoboom.online(aller-retour,pending) ; sinon « Ton avis » donne le rôle et l'aller-retour.Pour #146
game.tsgardesource,localPlayer,onlineMatchen variables locales. Dès que #168 fusionne, rebase surmatch.ts(createMatchavec la source de lockstep,focus: { kind: 'player', playerId }).