Echoes of Eternity : A look behind the scenes with critique

I was introduced to my first game engine in high school, Unreal Engine 3 (originally released in 2006). I can remember setting up global elements like a central lighting system, configuring spawn points, creating pathing for players, and working on weapon design. I spent a good amount of time playing Unreal Tournament 3 on homegrown half-baked maps that I’d created against bots. During that same time, I was introduced to my first computer language; Python. As a scripting language, it’s become massively popular over the years and even now in my daily life I use it because it’s just easy. When I was first introduced, my goal was to build a space game using a Python package called Pygame. I completed the game but it was dead simple and basically followed a tutorial. Since that time, I’ve dabbled in many other engines, programs, apps, and languages. In the last few years, as we’ve seen the rapid adoption of Artificial Intelligence, an idea came to me to make another game with AI. A necessary part of building something is choosing tools. While researching tools in 2024 I came across a myriad of options; Godot and Unity seemed to rise to the top regarding 2D related games for an indie dev project. An idea occurred as I was looking at engines: “I should try to create an entire game with AI and a computer language from scratch”. Performant languages like C++, C#, Rust, and Java back popular engines each with their own strong suits and all sharing strong runtime performance. However, for nostalgia’s sake and wanting to better understand the capacity and use of AI, I was pulled towards Python and Pygame from “back in the day”. After some looking I found that Pygame (community edition or -ce) has received updates and worked well with the ModernGL (OpenGL) packages for GPU acceleration. Additionally, I found that Cython had also been maintained and can be used to build out specific math intensive portions of programs written in Python wrapped in C variations. I started a new Git repo and added the readme.txt. Chat GPT 3 was the market standard for LLM’s and coding. I went with that. The options we now see with AI are massive and the barrier to entry for custom self hosted models is minimal. This was different in early 2024 and I was still unaware to some degree.

The following section of this text is an overview of my interaction with AI during this game’s creation. At start, I described my game to Chat GPT and asked for an outline of what I would need. The original idea was a 3/4 view 2D RPG with tower defense elements and bullet-hell features. Chat GPT 3 was rough. I would get a set of requirements suggested to me, start to build them out and then realize something was missing. Back to GPT 3 I would go, and then after describing the problem, it would agree with me and suggest a new method of systems and structures to proceed. I repeated this process through 4 iterations of Echoes of Eternity. In all of those 4 cases, I reached a point where the structure had been so wrongly created that I knew it would be more work to rebuild each of them than to start fresh. I almost deviated from trusting AI to create a structure on a few occasions to rely on my own understanding but did resist. Onto the 5th version. At the start of this version I noted the failing points of the previous 4 versions and saved them to add to GPT’s memory. By this time I’d worked through using GPT 3, 3.5, 4, 4o, and was now on GPT 5; significant improvements. The availability of being able to start a project and save files for reference through the web app was significant. I could now reference previous work and the rate of good progress seemed to increase massively. At this 5th version, Chat GPT had a pretty fair idea that I needed a main controller, game state management, game scene management, orchestration management, world management, entity captures, assets, and a render system. The process of introducing next steps to GPT 5 went something like “hey reference the description I’ve provided you on the game I’m making, I’d like to work on xyz feature next.” It would generate code and I’d apply and test. Consistent variable strings and cleanly structured logic were the main challenges. I was committed to only guiding GPT and relying on it’s suggestions to proceed. When we got to building the render pipeline using ModernGL it choked. Certain features like describing a vertex and fragment shader just were not happening. I would describe many times over what I’d like and the simplicity I was shooting for, and all permutations of the code were present except the one where content displayed correctly on the screen. It would flip, invert, minimize, blackout, whiteout, and crash the game. I took some time to dig into the ModernGL and OpenGL documentation, watch some tutorials online, and with strong guidance we got through it. I had a working GPU accelerated game in progress. The next challenge was performance improvement – of course because we are using Python to make a real time game! Chat GPT was helpful navigating packaging Cython and building it out with command line tools. However, I would run into scenarios where I would rework and expand the Cython functions massively and hit a point of diminishing return on performance. Chat GPT would not suggest caching ever. I would suggest caching to improve asset retrieval and display and then it would agree and help me bake up a very immobile and fragile caching system. I would try to expand the cache to other objects as needed and it would break because I was asking too much of it. Chat GPT assured me we could rebuild and would suggest lively and creative options that failed in all cases. After a significant amount of guidance and provision of working examples, we got a cache system that would expand out to fit the game’s necessary assets. However, when I would introduce a new entity, say the Containers or Doors, it wouldn’t use the cache system. I would prompt to use the cache system and used every available memory allocation and project file I could to establish a grounding framework where it would be imperative to use the Cache system and 2 messages later it would provide solutions without the cache system. Another significant hurdle was generating many visual assets for backgrounds, foregrounds, parallax items, and projectiles in the same theme. AI is fantastic if you want to generate one or two images in a specific style; a style I will include that was originally learned from a real human who experienced pain, suffering, love, and joy to attain. However, if you generate a style and need to have 100 different assets follow it, you’re going to have a rough time. The way I solved this was by adopting a looser definition of style and using similar sets of prompting in the same chat memory. We got through it. This pivoting and many-prompt-input of interaction continued for the game state, constants definitions, game difficulty curation, input controlling, key bind assignment, audio system, camera system, animation system, world coordinate calculation, collision detection, story management, and packaging features. Through many repetions and prompts, we made our way to the version of the game as it sits. Total project time was 18 months from concept art and first commit to publication on Steam.

A note on the experience as a human: It feels odd to see commercials for AI that present a fairy godmother which solves one’s problems. While working in the capacity I’ve laid out above and with the intention to have AI handle the majority of the game creation in order to justify saying “It’s AI generated”, I became extremely frustrated. The tendency towards entropy and that 5% error rate of Models is what gets you in the end. It was notable how slowly I typed even at 60 to 80 WPM when GPT can generate code, images, and prose at speeds orders of magnitude above this. I felt that. Impression, amazement, and shock were my feelings associated with this. With modern English we have such variability and very loose requirements. We as humans are able to impressively interpret a set of words, sentences, and paragraphs with semantic awareness given many different orders, word choices, and lengths. A computer with a runtime environment that is built upon 1’s and 0’s does not have the same freedom currently. A variable defined and needed on line 30 and used again on line 3500 must be the same. That was the struggle of this project. Even axiomatic rules are not safe from a statistical model’s meddling.

A final thought: I acknowledge that the process I took was an odd use case for creating a 2D game in these times. There are certainly better ways to build a game and even better extensions and integrations but web based AI in Python is how this one went. I continue to use AI on a daily basis and dabble in the market’s options for which model is performing best and in what scenarios. I am aware of a divide between what is marketed and what a person must use in the trenches. I remain positive on the approach we are taking towards building new models and implementations and feel amazed to be alive in this time when so many people are working so incredibly hard to better and improve our world. I will echo Bjarne Stroustrup’s sentiment that we shouldn’t let AI make brake pads for cars just yet. I was reminded that I must pursue knowing who I am, what role I play, and what goal I’m aiming at while interacting with a language generating thing.