# CatCaster Team-02 ###### tags: `Semester2` ## Opdeling 1) DOCUMENTATIE - [ ] auteurs toevoegen aan elke file (maartje) - [ ] credit geven aan herbruikte code (maartje) You can reuse code from the first semester as you see fit and you can then give credit to the contributors of that code from the first semester as well (by looking at git commits). However mark this in a separate line as “Based on … from semester 1 by {authors}”. - [ ] 2) ENKEL SCHERM - [ ] gameplay - respawn 3) MULTI SCREEN - [ ] QR codes uit foto halen (serverside) - [ ] locaties van 4) CONTROLLER: - [x] nummer WebRTC berichten[Jonathan] - screen: - [x] maak graphics functie die parameters van websocket accepteren om planeten, portalen en lijnen te tekenen (Karam) 5) MULTISCREEN: - [ ] cat switch protocol VARIA: - [x] maak 'Getting started' voor noobs zoals assistent zei - [ ] Respawn kat (random over verschillende clients) - [ ] Testing? - [ ] Achtergrondkleur controller = kleur kat - [ ] Deploy on Cloud - zie Toledo - [x] About page listing copyright and used library licenses LANGETERMIJN (halen we waarschijnlijk niet meer) - [ ] resize screen - [ ] clean shutoff van games - [ ] new cat design ## Flow(s) (stappen in chronologische volgorde) Start server. The server now waits for screens and controllers to connect. Start screens: for each screen: * open browser and connect to catcasterteam2/screen/ * server answers to screen with an ID and a QR code * screen displays the QR on a way that allows to extract size information When all screens are connected to the server, the first controller may join: * first controller scans one of the QR codes * hij kan dan kiezen tussen "single screen game" en "multi screen game" (we assume further multi screen) * hij maakt een foto van alle screens die zullen meedoen aan deze game * hij stuurt de foto naar de server en dan wacht When server gets the picture: * bepaal de ligging van alle QR codes * bepaal dan de ligging en de grootte van alle schermen (bepaal ook welke schermen zullen meedoen aan deze game) * kies aantal en ligging van planeten per scherm * kies portalen * stuur informatie naar schermen * spawn first controller (random planet, give the controller an ID) * make webRTC connection between controller and all screens * stuur info naar controller (de controller moet weten met wie hij vervolgens moet communiceren) When the screens receive the "world layout": * teken planeten en portalen * teken de verbindingen Now the game has begun. When a new controller joins: * give the controller an ID * make webRTC connections to all screens * spawn on random planet The server has nothing more to do. ... behalve respawn when a cat dies Connection between screens and controllers: * the screen S a controller C is on receives "moves" from C: schuiven of teleporteren * the screen script moet die informatie verwerken en nieuwe ligging op schijf of al dan niet teleportatie bepalen * indien geen teleportatie of teleportatie naar planeet op S: S toont nieuwe ligging kat op zelfde schijf * indien teleportatie naar andere screen: - send new screen info to controller - send new controller info to other screen ---> ??? hoe gaan we info van scherm naar scherm sturen? via the server? via de controller? rechtstreeks? ## Functional requirements We received several (broad) requirements from the management team: - [ ] [M1] No GDPR statements. That means: no cookies, no user accounts, ... - [ ] [M2] Limit the number of external libraries and keep track of their licenses. There should be an "about" item which lists all used external libraries in a correct way. Also include your own copyright license... - [ ] [M3] The game should feel smooth when played. (There are examples of using smartphones as controllers for games in a browser...) - [ ] [M4] The whole setup should work on all modern browsers and smartphones. Our technical team also came up with some further requirements. Let us first define some terms: - **Server**: this is the server where our node server process runs. We serve our website from here. This is also where we keep track of registered "clients". Our server keeps websocket connections with the clients. There is only one server. - **Client**: is either a "screen" or a "controller". - **Screen**: this is a web browser which makes available its view port to be used for showing the game. Note that one computer could have multiple browser windows and hence multiple "screens", which might be on the same physical display or on different displays. Multiple computers can register multiple "screens" at the same time. We assume that different "screens" do not overlap. - **Controller**: this is a smartphone which is used to control a cat in the game. We make use of the gyroscope to move in a certain direction and we make use of the accelerometer to jump through a wormhole. The idea is to have one or more browsers (possibly from multiple computers) connect to the server and allow their browser window to be used as a screen for the game. (Note: the lab computers could be used for this... but then keep in mind that the peer-to-peer connection to a controller will involve some hops. More hops means less responsive movement. Try to take this into account, i.e., be aware of this.) We now list some requirements from our technical team: Client-server: - [x] [CS1] Clients load the game in a web browser. - [x] [CS2] The URL for a screen ends in `/screen/`. - [x] [CS3] (The URL for a controller ends in `/controller/`. (You probably do not need this.)) - [x] [CS4] Each client gets an `id` generated by the server. - [x] [CS5] The `id` is a hexadecimal string (like the hashes from git) and the server guarantees that the first 8 characters (alternatively 4) can be used as a short and unique version of the `id`. - [x] [CS6] As soon as a client knows its `id` it will reload the page and add the `id` as a GET parameter. (The technical team thought this would help if anything goes astray, then the user can just reload the page and at least we have retained our `id`. They think that things can get implemented in such a way that connections are automatically restored and there is minimal disruption in the game.) - [x] [CS7] If the GET parameter is already present then the server does not generate a new `id`. - [x] [CS8] Each client establishes a websocket connection to the server. - [x] [CS9] The client sends its `id` over the websocket connection by a message `{ id: "..." }` as a kind of "helo" (note that this is not a typo, this spelling is actually used in the SMTP protocol). - [x] [CS10] The server closes connections for unknown `id`'s. - [x] [CS11] We are currently not protecting against hijacking of `id`'s. - [x] [CS12] If the websocket connection disconnects then the client tries to open it again. After a number of tries it gives up and displays an error message "Cannot connect to server.". This error message should be clearly displayed. - [ ] [CS13] The server purges a record of a client when the websocket has been closed/lost for longer than 10 minutes (of course this number is a configuration variable somewhere). Screen-controller-server: - [x] [S1] A screen can be in two states: free or game. - [x] [S2] When a screen is in free mode it displays a QR code which contains the URL of the server with `/screen/{short-id}` at the end, where the `{short-id}` is the 8 (or 4) character short id for this screen. (Note that you could type in this URL manually and it should also work...) - [x] [S3] When a screen is in free mode and a controller scanning this QR code goes to that URL (by using the builtin functionality of the smartphone), then a menu will be presented on the smartphone: - Play on single screen - Detect multi-screen - ... (other possible options) - [x] [S4] The option "Play on single screen" will let the controller play the CatCaster game on the single screen. - [ ] [S5] The option "Detect multi-screen" is explained further and lets the controller take a picture of the multiple screens and identify its physical setup (from a specific point of view; note that the physical setup is different from different points of view!). - [x] [S6] When the screen is in game mode then scanning the QR code will let another controller join the game. - [ ] [S7] In free mode the QR code is placed in such a way on the "screen" that it is possible to identify their physical position from a picture of multiple "screens", possibly on different physical displays. This analysis can either be done on the controller device (smartphone) or on the server. - [x] [S8] In game mode the QR code is placed somewhere out of the way such that the game can take up most of the "screen" size. - [x] [S9] Note that a screen will be instructed by the server to change mode (through the websocket connection): `{ mode: "free" | "CatCaster" }`. (Note that we say "CatCaster" instead of "game"...) Detecting the multi-screen setup (from a specific point of view; since this needs to be similar for all players, this might mean that one needs to be some minimal distance away from the screens): - [ ] [D1] The controller (aka smartphone) takes a picture of all of the screens from a specific point of view. (The point of view is important, other players cannot be too far off this point of view as then the straight line connections between the screens will not be correct anymore.) - [ ] [D2] In the "Detect multi-screen" mode the controller can upload this picture to the server. (Alternatively the analysis can be done on the smartphone.) - [ ] [D3] Analysis of the picture consists of scanning for all screen QR codes in the picture. - [ ] [D4] The position of the QR code on each screen should reveal the size and position of the screen in the picture. (E.g. put the QR code horizontally and vertically centered and take note of the relative height and width w.r.t. the screen size.) - [ ] [D5] We are assuming all screens to be placed under a normal viewing angle. (So no funny perspective is going on.) - [ ] [D6] Relevant information is passed by the screen to the server on each resize of the browser window (and on each connect or reconnect of the websocket). - [ ] [D7] When joining screens into a multi-screen only screens in the free state will be considered. - [ ] [D8] The screens then receive a list of their neighbors and establish WebRTC data connections to all of their neighbors. - [ ] [D9] The connected screens draw lines from the centers of the screens to their neighboring screens. (You can do this by a Voronoi diagram.) - [ ] [D10] These connection lines stay visible in the background also when the CatCaster game is on. - [ ] [D11] The lines disappear when the multi-screen is deleted. - [ ] [D12] The lines connecting the different screens should look equal in thickness on the different physical displays. - [ ] [D13] Scanning a QR code on one of the connected screens adds a menu item "Play on multi-screen" and also "Delete multi-screen". Technical and debug information on a screen (always visible): - [x] [I1] A screen will have a designated area where technical information is shown. - [x] [I2] It shows the short id of the screen. - [x] [I3] It shows the state the screen is in ("free" or "CatCaster" (game)). - [x] [I4] It shows the connection status with the server (websocket). (Also show when the screen is trying to reconnect...) - [ ] [I5] It shows the connection status with all other screens in a multi-screen (WebRTC data). The other screens are identified by their short id. - [x] [I6] It shows the connection status with all connected controllers (WebRTC data) to this screen. The controllers are identified by their short id. - [ ] [I7] If the screen is part of a multi-screen then the picture which was used to detect the screens is shown in small. (This will allow a user to go stand at the correct point of view.) CatCaster: - [x] [CC1] When a controller selects "Play on single screen" or "Play on multi-screen" the CatCaster game starts on all the screens involved. - [x] [CC2] When a controller scans a QR code of a screen in game mode it will join the running game (this could be a multi-screen game). - [x] [CC3] When a controller joins a game it establishes WebRTC data channels to the screens involved. We use the websocket to the server as our signaling channel to set up the WebRTC connection. - [ ] [CC4] The cat is spawned at a random planet (of a random screen in multi-screen mode), similar to when a cat died and is re-spawned (see further). - [x] [CC5] The `id` of the controller should be visible somewhere on or above the cat. - [x] [CC6] Cats should be distinguishable, e.g., by different colors. - [x] [CC7] When a screen starts the CatCaster game it generates between one and three planets. (To make it interesting a single screen game should probably generate three planets.) - [x] [CC8] A planet is a disk of which the center is fixed but the distribution of weight/cats will make the disk tilt in that direction. - [x] [CC9] Cats which do not try to move in a certain direction will slide. - [ ] [CC10] Cats which slide off a disk die and re-spawn on a random planet. (The player should be able to recognize its cat. To give the player more time this could be animated, and during this re-spawning period the cat cannot slide off its new planet.) - [x] [CC11] The planets/disks can be very simply represented by an oval. - [x] [CC12] The portals are situated where the straight lines from the center of the different disks connect to their neighbors (Voronoi). - [x] [CC13] Portals can be simply marked by marking an arc on the disk. - [x] [CC14] If a cat is close enough to a portal (on the edge of the disk) then shaking the controller in the direction of the other planet will cast the cat from one planet to the other. (The shaking does not necessarily need to be in the right direction.) - [ ] [CC15] There is a lot of choice in tuning parameters, these should all be in a separate configuration file (or at least in a designated place). - [x] [CC16] A controller sends the orientation data directly to the screen where its cat is on using the WebRTC connection to the particular screen. - [x] [CC17] A screen determines the positions of all the cats on that screen. - [ ] [CC18] If a cat switches screens then the old screen passes the cat onto the new screen and informs the controller to send data to the new screen. - [x] [CC19] The WebRTC connection between the controller and the screens can be set into a UDP kind of mode by specifying `dataChannelOptions = { ordered: false, maxRetransmit: 0 }`. - [ ] [CC20] If necessary a timestamp/counter can be added to the packages such that the screen can ignore old packages must they arrive out of order. (The screen needs to store the previous value of the timestamp/counter to decide this. Do not compare the timestamp of the controller with the time of the screen.) - [ ] [CC21] We are assuming the number of screens and the number of controllers allows us to connect everything to everything. - [ ] [CC22] For debugging mode the CatCaster game should be playable on a single screen using the keyboard attached to the computer. This mode could e.g. by activated by pressing `x` after which a cat is spawned which can be controlled by the arrow keys and space bar. - [x] [CC23] Construct a formula to take into account the weight of the cats and how your planet tilts. (Think of easy unit tests.) - [x] [CC24] Construct a formula on how the sensor data from a controller is used to move a cat on a tilted planet. (Think of easy unit tests.) - [x] [CC25] Construct a formula to detect if a cat is close enough to a portal. Controller: - [x] [C1] A controller shows its `id` somewhere on the screen. - [x] [C2] Optionally the controller can have buttons to move the cat. - [ ] [C3] The controller shows the player the color of its cat (or whatever feature you use to distinguish different cats). - [ ] [C4] The controller shows the short id of the screen where its cat is supposed to be. You are allowed to make changes to the requirements. The functionality should be equivalent. E.g. you could opt for screens to be identified by a combination of two or three words instead of the short id if you have a good reason for that. Or you could decide to establish the WebRTC connection between the controller and the screen only at the time that your cat actually appears on that screen. Etc... In case of things not completely working as planned there are some mitigation strategies: - [ ] [B1] If the interaction between controller and screen is not fast enough then the cats can be replaced by turtles... - [ ] [B2] If detecting the physical setup of multiple screens turns out to be too hard then a (partial of full) manual procedure can be implemented. There are different options: - [ ] [B2.a] A predetermined setup of screens (i.e. a straight line). - [ ] [B2.b] Let the user mark the screens on the picture. (Either on the smartphone or on one of the computers which controls a screen.) - [ ] [B3] If detecting the size of the screens is too hard then a user can manually override. - [ ] [B4] If the Voronoi lines connecting the screens are too hard then a user can manually interact to draw and position connections.