FGCombos

A web app and resource for optimizing competitive performance in fighting games.

Live demo
Screenshot of project

Project Purpose

I wanted to create a web application that can help players of fighting games improve their competitive performance, particularly by learning and optimizing their combos.

Users can view combos made by others or create ones of their own.

My personal goal was to further push myself by creating a more ambitious, full-stack application.

Tech Stack

I chose Svelte and SvelteKit for the frontend because I'm already comfortable with it. I wanted to challenge myself even in a familiar environment, so I wrote the code using the new Rune API with Svelte 5.

I created a PostgreSQL database using Supabase to store data. Supabase was a good fit as it also includes an authentication feature that tightly integrates with the database (much like Firebase).

I conducted E2E tests using Playwright.

Problems and Thought Process

One big issue I had to consider how to handle the same page depending on a user's status, like if they're signed in or not, or if they have certain permissions. For example, should there be distinct pages for viewing and editing the same combo, or should it be one page and one component with a toggle for viewing and editing?

There isn't an obvious answer as both come with tradeoffs. The tradeoff of the first approach is that it creates a less seamless experience, and makes sharing links harder. The tradeoff of the second approach is that it can potentially balloon the amount of code stuffed into one route, making it unmaintainable over time.

The most robust solution would be to have distinct routes for each, but give them the same URL. Middleware would resolve which route to serve depending on the user's permissions. However, this would require maintaining two distinct routes for mostly the same functionality, and also require time to resolve edge cases.

I prefer not overengineering, so before taking this approach, I identified how many pieces of functionality behaved differently between the view and edit modes. I found there was less deviance between the two than I expected, so putting the code for both modes in one route was a viable approach in this scenario.

Conclusion

Thanks to the lessons I learned from creating Plant Market, the development of this app went much more smoothly. However, this was the first time I've made a UI dynamic in consideration to user state, at least to this extent. It's a non-trivial task and requires some engineering thought.