# Buzzer A simple buzzer implementation using web technologies. ## Usage ### Preconditions You need a JDK, version 11 upwards. ### Build Until artifact storage is provided, start the service using `gradlew run` from within the project directory. Alternatively, you can create the artifact using `gradlew shadowJar`. The output will be written to `/build/libs/`. Then run it using `java -jar `. After it successfully launched, you have access to two clients. ### Player-Client All participants should call `http://:8888/` or `http://:8888/clients/player`. Now, they only need to enter their name on top, and they're set. To trigger the buzzer, they just need to push the large surface. After a short amount of time they will be notified whether they were the fastest players (button turns green) or not (it turns red). ### Game-Master-Client You can access this client from `http://:8888/clients/master/`. Your surface consists of three parts. After a game has started, and some player decided they want to do the turn, these have the following functions: * On top, there's a large surface showing you the fastest player if any. * Below, you will see the order of players who pushed the button within *500ms* after the fastest player (including the initial push). This information is included solely for transparency reasons and might be used to resolve obvious "Whoops, my beer tipped, and I accidentally activated the button!"-like situations to some extent. * A "reset"-button is located at the bottom. Clicking this will prepare the app for the next round. It will forget about all buttons pushed, and re-enable the buttons on the player's clients. ## Troubleshooting & Tips * Before starting the game, test that each of the player's client works properly, by letting each one put their button after each other, resetting after each turn. * If the players or clients can't connect to your game server, make sure it's not blocked by the firewall. The app requires access to port 8888 for tcp connections. * Make sure each player's clients are released after you reset the round. If this is not the case, wait a few seconds and try again (and also check the players network connection and power save settings). ## Technology This project contains a weird mixture of technologies that I wanted to play around with: * Currently, there is no check for uniqueness of player names, and the name is used as identifier (that's the simplest way to be consistent across reconnects). Make sure each player uses a different name! * The server-portion is based on the [ktor][ktor] framework, a rather lightweight, code-configured web servicing library. * The clients' HTML files are created on the fly using the domain specific HTML language provided by [kotlinx-html][kotlinxhtml]. * Javascript and data binding in the clients is achieved by embedding [alpine-js][alpinejs], in conjunction with a few extension functions to integrate it into kotlinx-html. * Client-side websockets are made resilient with [robust-websocket][robustws]. Honestly, it's a shame how much time you need to invest nowadays to find a plain JS utility library that can just be included without running it through a full `npm` build pipeline for even a small task like this… ## Roadmap * Configure startup (IP and port) * Keep history of previous rounds. * Ship utility JS libs as asset, don't rely on CDN and internet connectivity. [kotlinxhtml]: https://github.com/Kotlin/kotlinx.html [alpinejs]: https://alpinejs.dev [ktor]: https://ktor.io [robustws]: https://github.com/nathanboktae/robust-websocket