Story-driven world building
Control is easily one of my favourite games of all time. I love its world-building, and the aesthetic throughout - from the brutal architecture in-game, to the clean UI.
The game enhances its story experience through its collectibles - each one that you pick up tells a short story, whether it's a member of the fictional world writing a message to a work colleague, or a case file documenting mysterious items under inspection by the games secret agency: the "FBC" (Federal Bureau of Control).
I wanted to try and build something that someone could go through and read through all of them. There's a Fandom Wikia that collated these documents, but I wanted to create something that felt more like the game itself - trying to capture the feel of the UI, and how the documents/information is presented in Control.
Stacking up
I knew I'd need a CMS to store the data, so I opted to go back to use Contentful, after feeling pretty good about it when I used it for the build of Becky's portfolio. I had to create several data models, one for each of the in-game document types - and populate them (there were 265 files in total...) Luckily it didn't take too long, and I managed to get through that in a (long) afternoon - with welcome distractions coming from the several Euros games throughout the day.
Gatsby was my final pick for the build of the site again - but it wasn't my first. I was originally going to try and build the site in Nuxt.js, to try and support some more learning around Vue.js, but I missed how Gatsby handled things, images/GraphQL especially, and switched back after building the basic structure of the HTML/components.
The site uses GraphQL to do a couple requests to Contentful (individual pages, and the "sidebar" list for each document type), and then builds the pages/routes based on the content returned. I really like how easy Gatsby makes this process - I just request the "slug" field from Contentful in my GraphQL query, and then use that to generate the page, all pretty painlessly.
Plus, Gatsby helps me get straight 100s in Google Lighthouse scores, so I love it for that. The fireworks that appear in the inspector window make all the devving worth it!
Creating a feel... and sidebars
I wanted to recreate the look of Control, so I did some "research"... which kind of just ending up as a playthrough of the game and the DLC (which I hadn't played before!) - side-point, but Alan Wake 2 when?... 👀
Anyway... I wanted to capture the look of the documents screen for sure, which has a sidebar on the left containing a list of the documents, divided into sub-categories, and the document on the right presented with additional information.
The sidebar provided to be surprisingly tricky, not only in terms of CSS - through fixed heights, CSS and overflows, but also through getting the required data from GraphQL in as few requests as possible. I spent quite a while trying to get the sidebar/main document area to feel good together, it was feeling pretty nasty for a while - having multiple scrollbars on the screen, silly overflows, janky scrolling. Plus the most annoying problem of all, which required a lot of faff - stopping the sidebar from scrolling back to the top when you picked a new document in the sidebar (which is horrible when you can have 100+ documents in the sidebar, and you're near the bottom!)
This one felt like a deal-breaker if I couldn't find a way around, as it'd be a horrible user experience. Basically on route change, all of the components were unmounting/remounting, causing the sidebar to jump back to the top again. I was confused as to why this was the case as I'd just finished a massive project at work which used Nuxt.js, and that didn't re-render everything when it didn't need to. Turns out v1 Gatsby persisted its layouts components, but as of v2, layouts are inside the page, so they do - causing everything to re-render. I had to do a bit of work to go back to the v1 format, but feel like I learnt some important things about how Gatsby comes together from this rabbit-hole.
I really enjoyed this project, it was the first one I'd done outside of work in quite a while - so was really rewarding in that way, and feels like a good showcase of my ability to recreate a front-end from an existing design - with some personal creative choices.