We were looking for web multiplayer games for working remotely, some friends like to play Beat Saber for exercise, and some wanted to play Beat Saber but didn't have a VR headset.

What it does

Yeet Saber is a web based multiplayer game that uses phone orientation/rotation data and websockets to enable playing Beat Saber with your phone as the controller for hitting blocks. Also, you can create and join rooms with a room ID to play the same Beat Saber song as your friends and see their scores, and upload official Beat Saber maps to play. This would be beneficial for de-stressing and taking breaks when working remotely, and getting some stretching and exercise.

How we built it

We obtained the device orientation using the deviceorientation event. Then, we forwarded this to our backend server.

Our backend was written in Node.js. It acts as a proxy between people's device controllers and their desktop browsers. It also allows people in rooms to see each other's scores and states. It sends controller orientation data to the desktop it was paired with.

The desktop page then uses Three.js to display 3D blocks. It also allows room hosts to upload Beat Saber maps so that everyone can play on the same map at the same time.

Challenges we ran into

We have never used DeviceOrientationEvents before and don't have that much experience with quaternion 3D rotations, so we spent a long time figuring out what the quaternions from the phone's orientation represent in terms of the x/y/z rotation of the blocks in game. We could only get the relative orientation of the phone and not the absolute position in 3D space, so we couldn't create all Beat Saber features like obstacles.

We had to account for the fact that, for example, when you point the top of your phone to the left, there are multiple orientations which should all count as "rotating left" (screen facing up, down, toward you, away from you). Additionally, it turns out that the compass heading the DeviceOrientation events return are not consistent and drifts. Therefore, we had to make our calculations insensitive to the phone's compass heading.

Hit detection was also fairly difficult, but we solved it by computing the cross product of the current rotation vector (where the top of the phone is pointing) and the previous animation frame's rotation vector to obtain the angular velocity. We then took this velocity and computed the dot product with each block's expected angular velocity. If these 2 vectors line up, it represents a hit.

Another challenge is recording the demo since streaming and video call platforms have a lot of latency but we wanted to show the multiplayer features.

Accomplishments that we're proud of

We got more experience with 3D rendering in Three.JS and networking with websockets. Also, we actually got some code done despite having to work remotely and with only 2 people.

What we learned

Too many console.logs will crash Chrome Chrome and modern browsers do a lot of things to prevent spam (such as preventing autoplay of media)

What's next for YeetSaber

More lights and colours of blocks, just like the light effects of Beat Saber Improved rotation detection, with possibly position tracking with the help of AR systems.

Share this project: