How I hand rubbed an indie game from scratch
2025-01-02Every gamer has a dream of making their own **game**. After much effort, I successfully created an indie game and released it on Steam on January 1st, 2025. This article serves both as a **commemoration** of this process and leaves behind some **thoughts and reflections** on the topic of **game development**. If it can help others avoid some pitfalls, that would be even better. I will present the entire game development and publishing process chronologically. The article is quite long, so thank you for your patience in reading. ## Origins 2019 I'm someone born in the 80s, part of the generation that grew up with video games in the 90s. During my school years, I went through a period of being addicted to games, playing Romance of the Three Kingdoms and Civilization series late into the night.
Read the full notes
My father couldn't stand it anymore and said to me: "**What's so great about being good at playing games? If you're capable, make one yourself**". I was young then and didn't have the ability to make a game, but perhaps due to that youthful defiance, I kept these words in my heart. Later when I started working, like most corporate workers, I was exhausted every day like a dog, just wanting to lie down and rest when I got home, not even having the interest to turn on the computer to play a game. In late 2018, the indie game **Chinese Parents** became popular on Steam. I happened to play this game and recommended it to my friends. Then in spring 2019, one night when I was frustrated with overtime work, with work piling up like a mountain, I glanced at my colleague **Hu Dapang** who was trying to sneak away after just a bit of overtime. I said: "Keep me company with overtime, after I finish this bit of work, we'll play **Dark Moon Invasion**", and Hu Dapang agreed. Dark Moon Invasion was a popular DOTA2 map at the time. We had never cleared it before, but that night, we reached our historical best record - the second to last level. Then before dawn, Hu Dapang said: ``` "Overtime work actually has a certain probability of sudden death" ``` I said: ``` "Why don't we make a game, let's call it **Chinese Overtime**" ``` Hu Dapang agreed, and then we brainstormed this **special** game together. At that time, Hu Dapang didn't know that he would become the **prototype of the main character**. So in May 2019, I initialized the Git repository for this game project. ## A Newbie's Attack Although I knew nothing about making games, I was aware of many game engines like RPG Maker, Cocos2d, Unity, and Unreal Engine 3. At the time, I really didn't have the heart to invest time in learning these engines. So I thought, could I make this game with my existing tech stack? I decided to make a DEMO first using frontend (Vue) + Electron. The DEMO came out quickly, and it looked something like this: After clicking "New Game", a few dialogues appear, just that simple. In my naivety, I realized I needed to create a game script engine system, but as a DEMO, I hadn't added the script engine yet. Everything seemed to be going smoothly, and then I started calculating what else I needed to complete this game. Obviously, I needed 2D art resources to express character portraits and scenes, and I needed sound effects and background music. I decided to start with the simplest things - sound effects and background music. There were many free-to-use sound effects online, and for background music, I chose to purchase directly from AudioJungle, spending around 800 RMB in total. Then came the art resources. I found an artist on Taobao to draw illustrations. At the time, I thought it was a good plan to develop the game while outputting art resources according to the plan. I commissioned the artist at a price of 200 RMB per illustration, and we quickly finalized and output the basic UI graphics. When outputting scenes and character illustrations, both the artist and I paid a considerable price. At that time, outputting one illustration required the following processes: 1. I would describe in text the desired scene/character features, as detailed as possible, with example images 2. The artist would create the line art 3. The artist and I would finalize the line art, making adjustments if it deviated from my vision 4. The artist would refine the line art and add colors 5. The artist would optimize and adjust the final product based on my feedback At first I didn't realize it, but later I found out that the cost of producing one illustration this way was just too expensive! At that time we made some illustrations like these: Then I realized this problem - I simply didn't have enough resources to get these art assets I wanted, so after spending 8,700 RMB, I chose to archive this project and stop continuing. Neither the time cost nor the monetary cost was something I could bear at that time. ## Dawn's Light Several years passed this way, and I would occasionally think about this game project with deep regret, because I was never someone who liked to leave things unfinished. But in middle age, I also learned to accept many objective realities. The turning point came in 2022 when Stable Diffusion emerged out of nowhere, and in December of the same year, ChatGPT officially launched. I quickly realized that perhaps now I had a chance to complete **Chinese Overtime**. After studying SD for a long time, I was convinced that even though the images it generated had various flaws, it was my only way to obtain 2D art resources at a low cost. So I decided to restart the **Chinese Overtime** project. The first thing I did after restarting was to create a roadmap table. This is what the table looked like after the game was finally completed: I decided to strictly follow this table and immediately began working on the game mechanics design. When designing the gameplay, I considered my limited energy, so I set the game's mechanics to be particularly simple, thinking that the gameplay's shortcomings could be supplemented with rich storylines. The game type was determined to be an **SLG simulation management** game. For indie games, storylines actually represent a huge workload, but I didn't have this awareness at the time. I tried to create a prototype using Adobe XD, which I had learned for less than a week. Here are some extracted prototype images: This prototype was rough, but its greatest value was displaying the game in my mind in image form, and I knew that these settings in the prototype wouldn't have particularly big changes later. ## Times Have Changed, Sir I still needed to thoroughly solve the art resource problem, so I specifically bought a computer. Due to limited budget, I used a 4060Ti graphics card. Then I started trying to use SD for AI image generation. The biggest problem I encountered in this process was how to maintain consistency in character/scene style. After trying many methods, I finally adopted the approach of prefixing style descriptions in the prompts. At first, I would write the image prompts in Chinese, then use DeepL to translate them to English, and finally generate images in SD. But this method had a drawback - it required very high-quality prompts, and writing prompts wasn't an easy task. Then I thought of a solution: let ChatGPT help me write SD prompts. After Claude came out, I switched from ChatGPT to Claude. The prompts written by AI were very detailed, and SD could better understand them, but there was still one problem - it couldn't generate subtle variations of the same scene or character. For example, it was difficult to generate an image of a person in a different pose without changing their clothes and hairstyle. Even when I used ControlNet for constraints, the new images always had subtle differences in clothing or hairstyle, making it impossible to maintain consistency. So I simply gave up on diversifying character poses and used just one image per character until the grand finale. This made things much simpler. After solving the art resource problem, I started developing a simple game engine from scratch. Though I call it an engine, the most core part was just one thing - the game event script engine, because the entire game was **event-driven**. I quickly built the event script system. I divided event scripts into two parts: event conditions and event content, and wrote them both into a SQLite database. The SQLite database is actually just a file, which is simple and easy to manage. Event conditions mainly included character attributes and time/prerequisite tasks, etc., stored in a separate table. Event content was slightly more complex. I designed its basic syntax based on Markdown, and it ultimately looked like this: ``` 1. Dialogue Yui Aragaki: I brought **Rimi-chan** with me today. 2. Scene Switch $ /* Hide UI */ + /* Direct Switch */ <> /*Empty scene, delay event execution 1s*/ 3. Define Branch # Trust Stranger Stranger: Hello, I am a stranger. 4. Option Jump Branch 1. Should you trust him?@Trust Stranger 2. Don't trust him!@Don't Trust Stranger 3. (Character.Luck > 80) ? I want to take a chance@Trust Stranger 5. Scene Load/Cancel NPC * NPC1 * NPC2 ~ NPC3 6. Jump Branch (Character.SuperiorSatisfaction Equal exploitation of labor is capital's primary human right. 8. Prompts + - 9. Attribute Modification (System.Character = Unlocked) (Character.SpiritLimit = $ + 100) (Character.BottomScrew = Activated@3Days) (Character.RestDay23Hour = Sleep*) /* * indicates locked card */ 10. Play Music {Calm1.mp3} ``` Then I implemented the entire game engine according to the event script syntax. At the time, to learn something new, I abandoned Vue which I had used in the first DEMO and switched to React instead. I actually knew nothing about React, but with the help of Github Copilot, I quickly got the hang of it. The entire game engine took about 6 months, and then I used this engine to make another DEMO version to test if the event script engine could run correctly. Fortunately, it really could run. ## The Real Resistance Then I excitedly started writing the game outline, including the game background outline and playable character outline. At the time, I planned to have four playable characters: Hu Tuba (Stubborn Leek), Xiao Wangrong (Middle-aged Tragedy), Sun Xili (Small Goal), and Zhao Hao (Procrastinator's Dream). The fourth character, Zhao Hao, was actually designed based on myself as the prototype. After writing the outline, I started writing companion novels for each character's script according to the original plan. After writing tens of thousands of words for the first character Hu Tuba's companion novel, I suddenly felt that I couldn't finish this. When humans don't get immediate feedback for their efforts, they tend to become extremely lazy. I was the same way, constantly wavering between "I've bitten off more than I can chew with the novel" and "I'll squeeze in some time to write more." The progress was extremely slow. Later one day I really couldn't take it anymore, and I thought, is this novel really necessary? I'm making a game, not writing a novel. So I simply removed the entire novel system from the game, and after removing it, I felt completely relieved, and the game development progress advanced rapidly. ## Completion and Perfection After writing story scripts for a while, I started slacking off again, because I truly wasn't enjoying making the game. Making games is completely different from playing games. Making games is not only very difficult, but you also can't get the kind of pleasure you get from playing games. Basically, you can't get any positive feedback until the game is delivered for testing. Then while making the overtime game, I started **slacking off**. This went on for a long time, until I couldn't stand it myself. I opened my phone and wrote down these paragraphs: ``` Chinese Overtime has taken two years from last year to this year and still isn't complete. Need to reflect and summarize, find ways to speed up development progress. ## Reasons 1. Inertia People always tend to do easy things, things that are easy to get a sense of achievement from, so lots of free time was spent watching videos and playing games 2. Difficulty entering flow state Can't focus completely during development, and don't enjoy the game development process. Creating feels completely different from playing games, can't get real-time motivation 3. No sense of urgency, no plan The whole thing has no time node pressure, now there's plenty of time, and no financial pressure either, so can't efficiently push tasks forward ## Solutions 1. Lengthen the path to those simple dopamine-getting activities Like deleting games, limiting usage time of apps like TikTok, free up fragmented time, make focused time longer 2. Set deadlines and task plans Review this plan every day and firmly push forward according to the planned time and workload, try to break down big tasks into small tasks as much as possible 3. Make the creation process more interesting Make the process of creating game scripts simpler and more fun, even doing game development like playing a game, or playing while making 4. Put making games in the important and urgent quadrant Give up pursuit of some quality and details, especially in generating scene images and character images and other resources, set making games as currently the most important thing that needs to be completed quickly, give up expectations for sales volume, just focus on the one thing of "completing it", even if it leads to poor player reviews due to being too rough, at least this thing I "completed", maybe it has flaws, maybe it's not fun at all, but "completing it" is very meaningful to me 5. Use the power of collaboration, bring in others to participate, use more spatial power to execute tasks 6. Keep the roadmap table open, remind myself at any time, update the roadmap according to progress, estimate good work periods ``` This way the game's development progress advanced rapidly again, but when I approached the last segment of the main storyline in Hu Tuba's game outline, I fell into anxiety again. Just thinking that even after finishing this, there were still 3 game characters to do, I felt awful all over, feeling it could never be completed. Then I complained to Hu Dapang, saying making games is so hard, and Hu Dapang said, then just make it simpler, just get it done first. I thought about it, how could I speed up the overall progress? Why not just reduce the number of playable characters? Then I just deleted all three characters except Hu Tuba. With this, the progress bar sprinted forward, directly reaching 90%. Then I started rushing work, with completing the main storyline as the only goal. I had planned many branch storylines originally, but if I didn't want to do them, then I wouldn't. This way the main body of the game was quickly completed. ## AI Music When setting background music for the game, I was initially still using the music resource pack I bought a few years ago. Later I thought, times have changed, why not use AI to generate game background music? Said and done, I registered and bought a Suno membership, spending $10, then generated instrumental pure music as the game's background music. Later I thought, why not put a vocal theme song in the game's main menu interface? I thought this idea was great, and simple, because the cost was low, as Suno happened to also support generating songs with vocals. So I started writing lyrics. At first I wanted Claude to help me write lyrics that rhymed, but the AI-generated lyrics didn't meet my expectations. So I decided to write a song myself, named **"Destined Worker"**. When I used Suno to generate the song, an unexpected issue arose - the Chinese vocals generated by Suno were always unclear in parts, and some words would strangely use Cantonese pronunciation (I suspect Suno used many Cantonese songs for training). No matter how I adjusted it, it didn't work. I even tried using pinyin with tone marks as lyrics in Suno to generate, but it still didn't work. Then I thought, the foreign moon isn't rounder, do we have similar AI music websites in China? Hey, I really found one, it was China's **Haimian Music** (ByteDance system). I pasted the same lyrics into Haimian Music, and in less than 5 minutes I got rock music with clear pronunciation. Although the music generated by Haimian Music wasn't as sonically rich and detailed as Suno's, it won in having clear pronunciation, making people want to keep listening. If you want to listen, you can open this TikTok link to hear it: https://v.douyin.com/iyMKtt8p/ ## Multi-language Translation The last thing to do was multi-language translation. Since I had used the i18n library from the start, this work mainly involved translating i18n strings. I provided several languages for the game: Simplified Chinese, Traditional Chinese, English, and Japanese. I tried using Claude to translate JSON strings, and after a series of attempts, I got good results using the following prompt: ``` The following are some game i18n dialogue texts, please translate their values into English, don't modify the keys, the translated content needs to be suitable for all age groups, please complete the translation in one go, please make sure to complete the translation in one go, please preserve the ** marks or other escapable marks in the text, output content should be JSON, output in inline code format ``` But manually calling Claude to translate was too much work, so I thought about whether I could call Claude's API? But I got stuck at the payment step, not having a suitable foreign card for payment, as my domestic Visa card couldn't pay for Claude's fees. After some searching, I found rapi's Claude API service. Actually, this service provider just forwarded Claude's API service (don't know if this violates Claude API's TOS), but the good thing was that rapi's payment channels were good, accepting domestic Visa card payments. After getting the API sorted out, I directly wrote a Python script with Copilot's help to batch use my researched prompt to translate i18n texts. This script would also automatically check if any i18n keys were missed after translation. Then the translation work was completed simply and easily, taking less than half a day in total. ## Android Port At this point I actually wanted to release a beta version and give the game to my friends to play. But when I expressed this intention, they all said that sitting in front of a computer to play games was too luxurious, asking if there was a mobile version? Okay, although I didn't plan to release a mobile version, I decided to port an Android version. Then I learned to use **Cordova** and built an APK package. Running it on the phone resulted in a white screen. Thinking about it, that makes sense - porting work isn't as simple as just packaging an APK. I needed to modify all places involving file reading to call Android APIs instead. So I redesigned the Files library, treating PC and Android differently, and had everything in the game involving files use this Files library. After two days of tinkering, the game could finally run on phones. ## Friend Circle Beta Testing I excitedly posted a message about game beta testing in my friend circle. I sent it to Hu Dapang first thing, but Hu Dapang said it showed a white screen. My expression at that time was: ???????????? My first reaction was: **It works fine on my machine** Upon asking, I learned that his phone was Android 11, so it must be some compatibility issues, as Android 11's WebView wasn't as advanced as later Android versions. I spent another two days solving this compatibility issue by debugging an Android 11 virtual machine. Hu Dapang began testing the game very rigorously, right up until the moment I clicked the game release button. He was still tirelessly testing the game, playing through storylines he had already played many times. Here again I want to express my thanks thanks thanks thanks thanks thanks thanks thanks thanks thanks to Hu Dapang! During the game testing, new bugs were constantly discovered, but fixing bugs didn't make me feel pain, so the whole process went smoothly. ## Is This Enough? With the game at this stage, I felt it was about done, but I wrote down another paragraph: ``` From a player's perspective, how do you judge if a game is fun? I think the most important thing is whether you experience joy in the game. Game players are actually a particularly easy group to please, they will laugh out loud at some clever designs in the game, and also feel happy when seeing some small novel things. And game players are empathetic, they have especially strong immersion in games, when you please them in the game, they know it clearly in their hearts and really enjoy it. As designers, our games are poor imitations and magnifications of the real world, setting up some things that are rare or even completely impossible in the real world. When designing games, we need to cater to the audience's seeking, adding corresponding mechanisms to satisfy players' psychological needs, these mechanisms can be in the following forms: 1. Unique special events, usually unfolding in the form of game main storylines or branch storylines 2. Loop events based on random processes and results, just like fishing, you never know what you'll catch today 3. Any game settings that form contrast with the real world, the harder something is to get in reality, the easier it is to get in games, so even joy beans will have people who like to save them 4. Rare events that can form contrast and immersion with the real world, during gameplay players don't specifically expect any one thing, but are always expecting good things 5. Players need slight setbacks, human nature is such that things too easily obtained won't be cherished, so when players violate mechanisms set by designers in some aspect, they will receive numerical or other punishments in the game ``` Based on these reflections, I did some completion of parts of the game's storylines, especially the romance events, because I found Hu Dapang was particularly obsessed with building good relationships with beautiful women. This way, the waiting time for release was also fully utilized. ## Final Testing and Live Streaming As the release date drew closer, while "Fat Hu" was still testing frantically, I decided to record a gameplay video to loop-stream on Steam. After reviewing the Steamworks documentation, I learned that Steam allows recorded broadcasts as long as you clearly indicate it's a replay on the page. During my first attempt at recording the gameplay video, I discovered an unforgivable bug in the later stages - companies in the game might not pay the player their salary on payday! I had to rush to fix this bug, and in doing so, I discovered that this fix actually resolved several other potential underlying issues in the game. This was actually a positive development - finding bugs now is much better than having players discover them. As a low-budget narrative-focused indie game, I know players won't give me a second chance. If bugs prevent them from properly experiencing the main storyline, while they might not request a refund, they certainly won't be interested in launching the game again. I then started recording the gameplay video for the second time. This attempt went very smoothly. After recording, I used OBS to stream the gameplay video to Steam as a loop broadcast. Soon after, my Steam store page showed that I was live streaming. ## Steam Release Launch At midnight on January 1st, 2025, I finally clicked the release button for the game. Everything came to a conclusion. Perhaps it wasn't perfect, but I had realized a dream. Despite the significant effort involved, in that final moment, I felt deeply proud. The game received its first positive review on launch day - truly, people who play games are wonderful! ## The Final Words Typically, after release, unless there are bugs to fix, the journey of making an indie game should come to an end. However, I felt I should document these experiences as a reference for future developers and as an opportunity for self-reflection. So I wrote this piece in my spare moments. There are surely oversights or errors, and I welcome any corrections from fellow developers. Finally, I wish everyone the best in pursuing what they love to do!





