Skip to content

Conversation

@Ragudos
Copy link
Contributor

@Ragudos Ragudos commented Sep 11, 2023


title: #716 | [TASK]: Refactor Multiplayer & Typing Logic

Discord Username: @aaronragudos

What type of PR is this? (select all that apply)

  • [x ] 🍕 Feature
  • [ x] 🐛 Bug Fix
  • [ x] 🚧 Breaking Change
  • [ x] 🧑‍💻 Code Refactor
  • 📝 Documentation Update

Description

Large refactor of the race logic of the game. Namely:

  • Typing Logic
  • Result Page
  • Multiplayer (Rooms)

First, I made the logic for typing, instead of handleKeyDowns, to listen to onChange. This is simpler, in my opinion, since we won't be doing slices, and such, as much as possible. Refactored the typing logic to be reusable as well using useReducer, and added some optimizations (useMemo, useCallback, and memo). Second, I added a button in practice to get a new snippet if a user wanted to.

Third, I finished the prototype for the room multiplayer functionality using the new typing logic. Lastly, I refactored the websocket server to separate the memory/state handling and the logic for the game (checking for status, etc.). I also made it clear about what a function does (well, not all of them, could do with more abstraction, but it's good for now).

Take note: The current rooms implementation does not do any call to the database except for when getting a snippet (getRandomSnippet).

The client will only connect to the socket if a user want to play multiplayer. I added autoConnect: false to the socket config.

Securities:

  • No one can join a room if:
  1. The room is full (specified by the constant of MAX_PARTICIPANTS)
  2. The room is ongoing, or is finished. The room's state must be === "waiting"
  3. The room does not exist
  • If a room only has one user and that user disconnects, the room will be removed. A user is considered disconnected if:
  1. They refresh the page.
  2. They navigate out of the room
  3. They enter a full room, or get errors while in a room.
  • There is a notification catcher that wraps the layout of the folder "rooms" to handle socket disconnections for:
  1. Errors
  2. Room Full
  3. Server Full (MAX_ROOMS), this is to prevent users, if they wanted, to keep creating rooms.
  4. And others.
  • A user who's logged in cannot connect to the socket again. They must be disconnected.

  • The socket uses middleware to initialize a user (displayName, displayImage, userID).

  • If a user is not logged in, the provided socket.id is used instead.

  • If a room is not "waiting" and is either on "countdown", or "running" states and a user leaves, the server will check if there is one player remaining (for example, two users will play and one leaves). If there is only one player left, then the room will go back to "waiting" state no matter what.

  • If a room owner leaves the room, the next room owner will be the player that came after the room owner.

  • When a race is finished, a room owner can restart the game.

  • We can add displayNames when joining a room using searchqueries. If there is no displayName provided, we use either:

  1. Logged in user's displayName
  2. A random username (which is constant right now)

Possible features:

  • Add a videolike replay just like in results page during multiplayer to see where each user is on a snippet
  • Add a functionality to change a snippet while waiting on a lobby.

Related Tickets & Documents

QA Instructions, Screenshots, Recordings

TESTS TAKEN ON:

  • Google Chrome
  • Brave

How can you test the changes?

For typing changes (on practice):

  1. Go to Practice Race

  2. Try to choose a language that does not exist in your local database. A message like "Uh oh", should show.

  3. Now, try to choose a language that exists.

  4. Click on the snippet, a focus indicator should then pop up (outline) on the black rectanlge.

  5. The snippet should not overflow and should break into new lines.

  6. As you type, the progress bar should track the changes and the row line tracker (the number on the side) should track the current line you are in. The row line tracker will based on whether you have typed a new Enter (⏎) character.

  7. The timer should be running at this point.

  8. Try clicking Reset.

  9. This should reset your progress and time.

  10. Now type something again and click Get New Snippet.

  11. A loading indicator "Getting Snippets..." should replace the text on the button and the whole black rectangle should be disabled (buttons, textarea, etc.).

  12. Try finishing a race.

  13. The result page should:
    a. use sessionStorage
    b . Display the words you typed for each timestamp (for example, on the first timestamp, you would have "c", then on the next, it will be "co", and on another, "coo", etc.).
    c. The graph should be displayed and on each hover of the timestamp, the snippet displayed below should follow (highlight) the latest character type.
    d. Not have topten and history tabs
    e. Should have a replay
    f. Be able to play again with the snippet you used.

  14. The replay should:
    a. Play on pressing play button.
    b. Stop when pressing pause
    c. Restart and pause when pressing rotating arrow button
    d. Stop playing and is paused when the replay finishes.
    e. Play from the top upon playing the play button when the replay has finsihed.
    f. Should follow how you typed everything on the snippet.

For multiplayer:

  1. Go to /race.
  2. Click Go Now!
  3. You should be at /race/rooms
  4. Try creating a room
  5. If you aren't logged in, you should have a random username (like, ImTheBestTyper123) and a fallback image.
  6. There should be toasts that notify you of:
    a. Room is being created
    b. Room has been created, then the room should show up.
  7. You should be at /race/rooms/[roomID]
  8. Try refreshing the page
  9. You should be kicked out since this room would be deleted, saying (roomID not found). This is because there's only one player in the room.
  10. Try creating a new one (Should be the same process).
  11. Now, try joining that room while logged in on the other tab.
  12. You should not be allowed to connect and a toast should pop up saying that you are already connected.
  13. Now, try joining that room on a tab where you aren't logged in. You should be able to join.
  14. First, of cousrse, you should be able to use a displayName you desire.
  15. On the currently connected clients, there should be a notification (a toast should pop up) about the name of the user that joined and the visuals updated.
  16. Okay, now try pressing backspace or leaving the current page (/race/rooms/[roomID]).
  17. You should see that the client that left the page left the room and this should be notified to the currently connected clients and update the visuals.
  18. Join the room again
  19. On the client that's the owner of the room, try leaving. The new owner should be the other client that just joined.
  20. Join again.
  21. Try to start the race.
  22. There should be a countdown that happens.
  23. Try leaving on one of the clients.
  24. The game should revert back to "waiting" since only one client would be connected.
  25. Join again
  26. Click start or play
  27. After the countdown, the snippet should show up along with the progress tracker of all connected clients. The timer should have started, but right now, it's a bit buggy where it will start once a connected client type (try playing around with it to see what I mean).
  28. As you type on one client, that client's progress should be updated live to all clients.
  29. The client with the most progress should have its progress tracker on top (It's sorted).
  30. When a client finishes while the others are not yet finished, you should see on a finished client a live representation of the average of all the timestamps of all the clients.
  31. Before the race finishes (It will only be considered as finish if every client's progress is the MAX, which is 100) , try leaving the room.
  32. The race should revert back to "waiting"
  33. Try to redo everything and finish.
  34. A table should show the details of every client.
  35. Now, try leaving on one client. The connected client should still see the table displayed.
  36. Try rejoining on the client that just left. They should be notified by a toast that the game has just finished.
  37. Try playing again.
  38. Rejoin.
  39. Redo everything.

https://discord.com/channels/663478877355507769/1126627632461643797/1150827943749226647

UI accessibility concerns?

Added/updated tests?

  • 👍 yes
  • 🙅 no, because they aren't needed
  • 🙋 no, because I need help
    Not sure, I will be adding an updated documentation tomorrow though.

[optional] Are there any post deployment tasks we need to perform?

[optional] What gif best describes this PR or how it makes you feel?

@Ragudos
Copy link
Contributor Author

Ragudos commented Sep 11, 2023

Note:

This has a not that important (just affects the timeTaken variable, which should be equal from the moment the race starts to when everyone finishes), bug, which is that sometimes, the timer will not start on component load. If checked, we can see a useEffect for that.

@Ragudos
Copy link
Contributor Author

Ragudos commented Sep 12, 2023

Updated the README file for the server and fixed some memory handling error on running game state when all users disconnect.

@webdevcody
Copy link
Owner

too much code to review, but I trust it's good, remind me to merge when conflict fixed

@Ragudos
Copy link
Contributor Author

Ragudos commented Sep 20, 2023

Noted! Does the conflict happen because it's a recent merge and I did something with it?

Welp, I will be going back to the code racer and refactor my refactor again to make it much cleaner once I finish my hackathon submission. Thanks!

@Ragudos Ragudos closed this Sep 21, 2023
@Ragudos Ragudos force-pushed the refactor-multiplayer branch from 3f80b6c to 361b123 Compare September 21, 2023 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TASK]: Refactor Multiplayer & Typing Logic

2 participants