It's been a little while! I've been busy with work and trying to find a new apartment, but I have managed to find some time to hack away at this game. If you don't know, Visitor is a game I'm building. This post is a general update, along with some notes on getting NPC's and their dialogue into the game.
I gave myself a deadline until the end of March to build this game. For the most part, I will probably move on to other projects that I want to do, but come back to this one when I feel inspired or need a shift. I feel like I'm getting closer to being done, but I still have a ways to go. So, what's left?
I have a lot of dialogue to write. I've probably written seven or eight interactions with characters that can occur through the three parts of the game. Dialog gets written in org-mode on emacs, then gets put into Godot using Dialogic. Dialogic is a ui-driven plugin, which means that I'm dragging and dropping characters, text bubbles, questions, and if/end conditions to build the dialogue. Since I'm not using a data-driven approach I have to do some manual work, which is fine. Under the hood, Dialogic does use JSON, so it's very well possible to build my own scripts that would convert say, a spreadsheet of dialog into Dialogic, but it would take longer than manually inputting the scripts at this point.
All in all, Dialogic is very nice! It took minimal fiddling out of the box to get it installed and working. Super impressive! Kudos to the developers :).
I struggled with getting NPC's to spawn generatively. The NPC's only have one piece of state so far (how many times they have interacted with the player).
First, I tried using the "Starfield" system (described in Visitor 2 - Sky Generation) in which each "coordinate piece of sky" would be responsible for an NPC, just as they are currently responsible for spawning pieces of light to be absorbed. This worked at first, but I later realized that the NPC's need to live independently of the starfield they happen to be spawned in. This is because the starfields are continuously destroyed and recreated to create a "treadmill-generation". In my first attempt, any time a starfield was removed with
queue_free would mean that the NPC would also be removed (and their state lost).
So, after a refactor, I decided that whenever a starfield was created, it would pull an NPC out of a global queue held in a singleton, and be placed randomly based on the starfield's position. So long as that NPC is "in-play" we cannot spawn it again, but future starfields can spawn the next NPC in the queue.
So far this works with the two NPC's I've created and their respective dialogue scripts. I've got seven or eight more NPC's dialogue's written, so if all goes well they will happily spawn into place.
I'm still running into a bug where periodically the sky/starfields are not generating at boot. It seems that if I wait before pushing the "start game" button, they are more likely to appear, but this isn't always the case. I'll try debugging this by printing when the generation is done the first time to see if it's just taking a long time computationally, and if that doesn't help, I'll dive into the weeds to see what else might be happening.
Most of the coming work will just be grunt work of getting dialogue into the game and testing. After that, it's onto writing the music, and maybe, maybe, if I have the energy, wrangling people to do voice recordings for NPC's (a la Hollow knight).
General Game Dev thoughts
I've had a scattering of thoughts about game development from this experience:
- Technically - try and make things stand alone. It has taken me a while to grasp how Godot scenes should live and work in relationship with other scenes / singletons. This happened in the last game I tried to build, but I would end up only really being able to run the parent "Game" scene to test things. I'm wondering if it should be the case that scenes should be able to stand alone a bit more. I imagine that might help reduce a certain amount of bugs.
- Building a game takes long time. So, try and find a part of it that you can get particularly excited about. I don't think it's wise to expect that every part will maintain the original "thrill of starting" throughout; rather, I've found that the grinding parts need to have accompanying thrilling parts to keep me motivated to the end (I mean, the project isn't done, so I'm just hypothesizing at this point.)
- Test compilation on physical devices / your target platform as soon as possible. Nothing gets you discouraged like working hard to get everything running locally and then testing on your phone only to find it looks all squishy and out of sorts.
- An important one: know your limitations. Yes, I could sit around and wish for the ability to make a more aesthetically pleasing or expansive game, but I don't have the artistic skills or external help for that (yet). For now, what I'm making is what I can do. I'm more confident than I have been in the past that this is the most important thing to help me finish this game.
That's all I've got for now. I'm looking forward to the next post, as I think it'll be a bit more exciting once the characters are in place and I can start thinking about how I want to do the music.
Thanks for reading!