Textboxes and Weddings

Textboxes and Weddings

Hello! Welcome back!

The last blog post was on July 17, so we have 8 weeks of life to catch up on. Here is what the time spent working on the game looked like over the 8 weeks. This view also demonstrates the two mini-eras (chunks) that happened over the 8 weeks. GD Hours in the chart below is game dev hours - time working on the game.

 
 

Work Chunk

The first five weeks that this blog post spans were pretty standard weeks spent at home, doing my usual stuff. As such, I did set aside some hours to work on making this video game.

Reviewing my game dev journal, I’d say that these notes roughly describe the flow of the five weeks:

 
 

In the first week that this update covers, I was looking for a new direction to move in. There’s a lot of options, but I opted to start building the system that will manage dialogue and text boxes in the game.

This started with some poking around. I watched a bunch of Youtube videos about making a dialogue system in godot. I read a bunch of reddit posts, read a blog post, and installed two different dialogue management plug-ins that I read about people using.

The two plug-ins I tried are called Dialogic, and Dialogue Manager. First, I tried Dialogic, which is the more robust of the tools. With pretty minimal effort, I was able to get a text box to pop up whenever I hit the action button near an item that could be investigated.

I’ve seen some samples of games that use Dialogic to great effect and have amazing looking results. Obviously it can be done, but I just didn’t love using an external plug in. It was unsettling, for example, to look at the actual code the plugin uses for the dialogue boxes and remember that I have no CLUE what any of it actually does. Nor did I have enough coding skill to be able to read through the code that makes up the plug in, and piece together how it worked.

This then led to me trying to create a dialogue system from scratch, which I subsequently got frustrated with and sort of failed to accomplish, initially. I wasn’t just failing to do it, though. It was more like I was failing to figure out HOW to figure out how to make a dialogue system. I kept finding different tutorials and different personal stories of how to do it, but the google fragments didn’t coalesce into anything.

This then led to me trying the second dialogue plugin - Dialogue Manager. This one is smaller scale than Dialogic, which is why I tried it out. There’s way fewer features than Dialogic has, and therefore less code to understand if you want to look into it yourself. It felt like the middle option, given that making a system from scratch was daunting once I got up close and personal with it.

But, similar to with the first plugin, I installed it, read some documentation, got it to work fairly quickly, and then felt the same unsettling feeling about depending on this outside source that I don’t intimately understand.

This is around the time I got demotivated in week 2. There wasn’t an easy and satisfying way to get a dialogue system going. The plugins worked, but weren’t satisfying me, but I also wasn’t skilled enough to code one entirely from scratch. By the start of week 3, I decided that my next best path forward was to try and focus on improving my programming and just inching toward building one myself.

This started with watching and taking notes on a godot programming focused series on Youtube. After that, I started finding my footing in the project more. If you’re interested, the playlist I took to was Godot Basic Tutorial Series posted by the Godot Tutorials Youtube account.

https://www.youtube.com/playlist?list=PLJ690cxlZTgIsmdEhFufnB7O6KWoMS8M6

The thing I found most helpful about this series is that the creator and teacher put a TON of emphasis on getting good at reading the official Godot API documentation:

https://docs.godotengine.org/en/stable/classes/index.html

I appreciate that this may not sound like particularly insightful advice. “To learn how to use this tool, check the instruction manual,” is essentially what the advice is. From where I was coming from though, this was actually a very, very valuable thing to have instilled in me over and over again.

What I had been doing was googling, reading godot message boards, watching Youtube tutorials, and all other manner of listening to other people try to explain highly technical things to me. Well, the API documentation does this better than people do, I now realize. During this time period, I made it a new practice that I should always start my any research I do by reading any pages in the API docs that I suspect will connect to what I’m doing. This tweak got me out of the mire of random googling, and greatly accelerated the rate I was improving at the programming. I’m sure message boards and other community forums will be valuable in the future, but the foundation-building I’m doing by reading page after page of the API docs is the thing that really got me unstuck.

Anyway, this process continued and led to the highly-productive Week 4 of this mini-era where I worked ~20 hours. Much of it was finishing the Youtube course I had started, and then it transitioned into reading lots and lots of the class definitions and other reference material from the API docs. I estimate that I read over 100 pages of material over the course of the week. It was a heads-down study moment. I got a lot better at programming in this time, and toward the end of it, I was ready to actually go back and start trying to program the dialogue system from scratch again. This led to the Git Detour (or branch) of 2023.

The Git Detour (or Branch) of 2023

After the committed programming learning time, I returned to the project with a fresh set of eyes, ready to revamp my effort to code a dialogue system from scratch.

The first thing I did was to totally remove the dialogue management plugins I had previously installed, as I felt much more confident in my ability and desire to do this myself at this point (late week 4). Unfortunately, after I un-installed one of my dialogue plugins, I continued getting errors within the application interface that godot was looking for the dialogue plugin I had been using, but couldn’t find it.

Thus I embarked on a road of research that led to me finding out that errors like these are common when you remove plugins, because often the plugin will change some of the base godot files so that those files are aware of the plugin, but then if you remove the plugin, those base godot files do not revert back. I was unable to fix this issue. Really, this is further evidence that I am not interested in using community-generated plugins to help make this game. I can feel the sting of the added dependency to the plugin, and it’s not as bad as the sting of reading the boring API documentation.

This issue is also something that you’d need version control to best remedy…which I did not have in place. I back up my project, but I’m just saving entire updated versions to the cloud. I don’t have a catalog of old versions I can go back to…I only have the most recent one. Using version control instead of just backing up the whole project is the solution people use to tackle issues like this, I found out.

Since I didn’t have version control, I had to restart my project, re-import everything, copy paste all my code over, and a host of other manual efforts to migrate the project, and thus clean up the old plugin errors.

Now, in the back of my head somewhere, I’ve always known that I ‘should’ be using git and doing real version control on this project. It’s a very easy thing to procrastinate, though. This avoidable incident was the straw that broke the camel’s back for me - I think especially coming off of the learning mindset I was in during the preceding weeks. I decided to finally suck it up and figure out how to do git commands and be more legit about backing my work up.

One of the tough things about implementing git with a godot project, is that godot projects make up an infinitesimally small % of things using git. Git is like, real enterprise programmer stuff. Because of this, I found the greatest challenge to be finding git instructions that would actually be able to meet me where I was at with programming as a whole. This playlist helped me get my project setup tremendously:

https://www.youtube.com/playlist?list=PLCBLMvLIundB2axawTUWHySTeAD-bCfyg

So anyway, long story short, I now have this project backed up on GitLab (an open source version of what GitHub is), and I have version control working. There’s still a whole world of how - like how, strategically - to use git to version control most effectively that I remain a complete beginner at, but I made some progress and I’m happy about that.

What has been coded so far?

After the diversion into git, I spent the rest of my work time trying to build stuff. The dialogue management is obviously what put me down all these rabbit holes in the first place, but once I got back into the project I started with a lighter project: implementing a working way to change the scene.

scene switching

The reason scene switching jumped to the top of my todo list at this point (late week 4 into week 5) is that the way I visualized doing it shared a lot of similarities with the way I visualized programming the text system, but scene switching is a bit simpler. This was kind of the warm up to the bigger dialogue management project.

And by scene switching, I mean let’s say the character is in room 1 and then walks into a door and now the game loads for a second and now we’re looking at the player standing in room 2. The process of switching the active ‘scene’ from room 1 to room 2 is what I’m calling scene switching here. The term scene is used by godot. In GameMaker Studio, this would be called switching rooms, which is probably why I still refer to scenes that are a setting you can walk around in as a ‘room’. Anyway.

I think this summarizes the logic put in place to accomplish this…these are the three new objects:

  • There is now a box covering the player’s body called the Exit Finder (in godot, it is the class Area2d). As the player moves, it will follow them and always be located directly on top / overlaying the player.

    • In godot, you can program collision boxes to be on different “layers”. For example, my game has a collision layer. Anything you can bump into has a collision box on this layer.

    • In order to make sure the main character’s new Exit Finder only looks for exits, I created a new layer called the Exit Layer. The only things that will exist on this layer are the Exit Finder, and the things it looks for

  • What does the Exit Finder look for? I created an object called the Exit Area. In godot, it is also the class Area2d.

    • When the player stands on this spot, we want the game to change scenes. So for example, if we have a door in the game, we would put an exit area somewhere the player has to walk over as they pass through the door.

    • This object doesn’t do much on its own - it’s really just a container of information. The Exit Area is storing what the new scene is that we want to load. So for example, if we’re in a room that has six exits, there will be six different instances of the Exit Area object, and each one will be manually coded to contain whatever destination we want those exits to lead to.

  • There is now a singleton or autoload called Global.

    • Part of what I thought about and learned about while doing the recent deep dive into programming is how to smartly structure this game. Up until this point of this game’s development, every object in the game is something tangible. As in, I made the main character. We can see him and move him. I made a wall object. It is a wall. I made a table. It is a table. Everything was self-contained.

    • Global is the game’s first behind-the-scenes object. It will always be running. GLOBAL IS WATCHING YOU! But really, Global exists to help do stuff that it doesn’t really make sense for anyone else to do. Changing scenes is an example of a job I have in store for Global.

Those are our three important and newly created objects - Exit Finder (attached to the player), Exit Area (put this wherever you want) and Global (behind-the-scenes person). With this setup, a player walking through a door where we, the developer, have placed an Exit Area triggers the following chain of events:

  • The Exit Finder and Exit Area collide

    • When two areas collide, you can have each party choose to do something. Each party can also easily access any info the other party has. In this case, Exit Area does nothing, while Exit Finder grabs the destination that Exit Area was storing, and sends it to Global.

    • Global receives the message and takes the scene we had been looking at (whatever room the main character was in) and replaces it with the new scene that the Exit Finder specified.

You can see this working in the video below. In the video, I have made the Exit Finder visible - you’ll see it as a blue rectangle over the main character (in the actual game, the Exit Finder would be in the same place, it would just be invisible).

I walk to the left and eventually come across a spot on the floor that is another blue rectangle. This also would be invisible in the actual game, but this is the Exit Area. Once we run into it, the scene switches to a new environment. Obviously a real scene-switch in-game would have more context and details to it - this just demonstrates that the programmed system works.

 
 

intro to dialogue

With the scene switching behind me, I wanted to use the same sort of concept to begin implementing dialogue and other messages in the game. Here are our newly created objects that are involved:

  • Actionable Finder

    • Designed to work just like the Exit Finder. Scanning its own layer called the Actionable Layer. One slight difference is that while the Exit Finder was overlaid directly on top of the main character, the Actionable Finder is programmed to be a few pixels in front of whichever direction the main character is facing.

      • For example, let’s say we’re trying to examine a treasure chest. That chest is going to be in front of whatever direction we’re walking, so we can’t look on top of ourselves like the Exit Finder did.

  • Actionable Area

    • Works just like the Exit Area, except instead of storing a destination, it needs to store whatever text we want to display.

    • Unlike the Exit Area, there is going to be way too much dialogue in the game to store this information physically inside the objects themselves. Even if you built a pretty large game, telling each Exit Area where to point to isn’t a huge deal. Managing all the dialogue in an RPG on the other hand is an undertaking.

  • Dialogue JSON file

    • The bullet point above led to the creation of a JSON file that is outside of godot. A JSON file is a text file where the data you enter are pairs, like FirstName : John. The catch is that the second element of the pair can be an array, and an array can hold an array, so really this thing can hold a diverse collection of things

    • The way I have it designed right now you can picture as two columns of a spreadsheet. Column 1 is DialogueKey and column 2 is a string of text. Similar to how the Exit Area pointed toward new scenes to load during scene switching, the Actionable Area will store a DialogueKey that can be looked up in the JSON file

    • Whatever we have in column 2 of the file then gets printed on screen.

    • Note: while it’s putting the carriage in front of the horse to the nth degree, it’s also true that using this JSON approach makes translating your game to other languages a lot simpler, since it centralizes the text.

  • TextBox

    • This is a new object that serves as the literal textbox that you will see on screen.

    • Responsible for printing the dialogue line by line and listening for user inputs to advance text.

    • This is a work in progress and I bet will become responsible for more things over time - we’ll see

  • Dialogue Player

    • Similar to the Global object created in the scene switching example, the Dialogue Player is a behind-the-scenes helper that will always be running

    • Responsible for storing the JSON file’s data within the game. Then responsible for fielding requests for information from the file

    • Does this need to be its own object, or are these tasks that Global could take on? Really I don’t know - it’s a work in progress.

In the video below I have made the Actionable Finder that appears in front of the player visible, as well as the Actionable Area that is sitting over the SNES - the old video game console sitting on the rug. You can see that when the areas collide, there isn’t instant action like there is with the scene switching strategy. First the user has to press the action button - this then results in a text box appearing at the bottom of the screen that lists a description of the object we examined (a SNES).

When the textbox appears you’ll notice that it needs to become more intelligent and wrap the text and other stuff, but it’s a start. You’ll also notice that a little picture of the main character appears next to the text box - this is a space I’m reserving for character portraits. Finally, you’ll notice that we’re able to walk around without closing the text box first - these are the things I’ll be working on next!

 
 

Wedding Chunk

That brings us up to the present in the game making. The next three weeks make up the wedding chunk of recent history, where no game dev was done:

 
 

Over the span of these three weeks I had jury duty one day, I attended a wedding in Brooklyn over the span of 4 days and attended another wedding in Wyoming which was a 5 day excursion. All of this ended on Tuesday of the third week, so I took the rest of that week off for wedding recovery.

wedding one - brookly New york

Another recent event that is tied to this wedding update is that since the last blog post Erika and I bought a car. It’s a pre-owned Honda HR-V. Cool?

Anyway me, Erika, another couple AND Podo (my dog) all drove to Brooklyn for this wedding in that new car. We bought Podo a harness and doggie seatbelt setup which he did really well with. Once we got to Brooklyn, Podo was totally shocked that the NYC dogs just go to the bathroom on the sidewalk. I could see the lack of green areas visibly confusing him. That’s the big city, bud.

As far as I can tell this is the only picture that we took while in Brooklyn - this was us attending the wedding event the night before the wedding.

 
 

wedding two - jackson wyoming

We got more photos of Wyoming for some reason. We had a pretty packed trip - we flew in early Thursday morning and flew out Monday morning. Friday morning a bunch of wedding people went on a calm raft ride down the Snake River. Check it out!

 
 

Saturday was the wedding - here’s me and Erika.

 
 

Probably my favorite detail of the wedding - after the ceremony, but before the reception (the cocktail hour in-between period) this wedding hired three people who worked for a local nature conservancy place to give an educational chat about some of their birds! There were two hawks and one barn owl - I have provided pictures of all three because this was important. I had a tiny intimate wedding, so I didn’t go this route, but if you’re going to spend big on a wedding, I recommend allocating resources to bird exhibitions.

Sunday Erika and I did basically our only solo activity of the trip and went horseback riding. My horse was named Goliath, and Erika’s Fleabag (Flea for short).

 
 

the latest with baking

With all of the time spent away from home recently (and another wedding to attend in October), I’ve put the sourdough starter creation on hold. I’ve still been baking though - here’s a collection of recent bake photos. Two photos are a pumpkin cake with cream cheese frosting that I made in celebration of Erika’s birthday. One pic is a cheesecake that I made because I haven’t made cheesecake in a long time. There’s also a yellow cake slice with chocolate frosting that I made for no particular reason. Finally, there was also a good looking pizza.

That’s it! Thanks for reading and talk to you later.

All aboard the signal bus!

All aboard the signal bus!

An injury, and reviewing the first half of 2023

An injury, and reviewing the first half of 2023