Attention


Introduction

Attention is a project I submitted for NUS Hack & Roll 2023, with my teammates Jonathan, Brandon and Nathaniel. I mainly worked on the frontend which was done in Flutter. Despite the numerous bugs that made it to the presentation, luck was on our side during our pitch for the Most Entertaining Hack prize. Check out our devpost submission here. In this blog post, I will recall some of my takeaways and also the obstacles I faced.

Advent of AI

I was one of 2 guys working on the frontend in my team. However, when it came to designing the UI, it was all on me. Unfortunately, like most developers, I suck at digital art. At first, the plan was to use squares as player avatars, and while simplicity is often your best friend if you suck at UI, surely I can do better than that…

I spent a few minutes scouring the internet for simple sprites that I could just use. But this proved more challenging than I thought. The size of the characters were no bigger than an icon, so most humanoid sprites were too small since they were much taller than they were wide. Furthermore, I couldn’t pick anything too iconic either, if not the game would simply look like a cheap ripoff. Ideally it look simple as well. Having too many colors could work against us, making the characters look far too out of place within the simple 2D maze.

After some scrolling with poor results, I decided to try my luck with AI. This was the time ChatGPT was growing in hype which reminded me of another OpenAI product: Dall-E.

With some trial and error using words like “game”, “pixel-art”, “sprites”, “2D”, “8-bit”, I was able to generate some decent looking results. This gave me some hope, but none of these were really usable.

First Few Sprites

Apart from the reasons already mentioned, there was an additional restriction now that I was using AI: directions. If the sprite generated was facing a particular direction, it was practically useless since DALL-E wasn’t yet advanced enough to iterate and produce the same sprite but facing other directions. More specifically, I needed a symmetric sprite not just one that is front-facing. I did try using prompts like “animation frames” to hopefully produce something usable but this only made it worse.

prompt1

With some inspiration from the generated sprites, I then thought about generating “ghosts” to fit the shape, color and simplicity criteria.

prompt2

Now those criteria could be decently met. I just needed to try find one that fits the symmetry criteria. After looking at enough ghosts, I came to realize they kinda look like slimes. I also adjusted the prompts to include shapes such as “circular”. Eventually, I got these set of results.

prompt3

With some photoshop, we settled on the following sprites to represent player and enemy sprites.

sprites

The Javascript Bug Magnet

I strongly advocated for the use of Javascript as opposed to Typescript to avoid having to deal with tedious type definitions during the hackathon. Back then, my familiarity with Typescript wasn’t at the level where I could resolve compilation errors without spamming any. Furthermore, CAPSLOCK was developed without Typescript as well, and we didn’t face many issues that would be resolved using Typescript. So this time trade-off didn’t make sense.

This was an oversight on my part. One key difference in this project was that our frontend used flutter. While communication was done using socket.io on both ends, the language difference let many more bugs slip right by. Loosely-typed Javascript would just parse the data serailized with some flutter library with no issues.

While these errors aren’t super hard to resolve, we were constantly misled. Bugs that were introduced much earlier only surfaced after newer features made it obvious. Logically, we assumed it was the new feature causing the bug which wasted tons of our time. I remember we took almost the whole afternoon/evening to resolve 1 bug regarding maze shrinking, a crucial aspect of our game. And 12 hours later, there was another bug that keep us up all dawn. I wasn’t sure if this was also due to some spelling error, since it was solved when I was sleeping (we resorted to rotational sleep to tackle this issue).