May 6, 2021 | Dukus | 7 Comments
Do you ever get the feeling that work on your video game is coming along to slowly? It seems I've spent the last month slogging through issues and bugs that come up as I make progress toward a cohesive game. Why isn't that object drawing it's selection when selected? Why did that animation just hiccup? Why is no one picking up rocks that are close to trees? Why is the there still a random crash while background loading!? (I already 'fixed' that once.) But that's okay - it's good to fix bugs when encountered rather than let them slide. Despite code refactors and bug fixes, it feels like I'm coming up to a critical mass of systems and the game will come together into something.... soon... I feel like I just have more done, but maybe not? When I started Banished I had nothing, and spent 10 months working before I had the game in a playable form. This time around I've been extending the game engine, and laying foundation for something that's better to work with, and will hopefully be just as fun. On a totally different note, I had a pretty amazing experience with source control that I haven't had before. That sounds silly to type. But having access to all the revisions of code I've written in the last 10 years is pretty amazing. First, some background. I've had a desire to move some code into data. The situation is how villagers will interact with objects. It comes down to a simple list of actions. Walk to some location, play an animation, add something to inventory, create this other object, play a sound, spawn an effect, etc. For each thing in the world that can be used, this needs to be defined in some way. In the last game, there were just a specific set of these written for specific categories of objects, but in general they were shared heavily. But this time around I want the option of more variety. If I want sparks to fly when hitting a certain type of rock with a hammer, which might start a nearby tree on fire, I don't want to have to write specific C++ code for that. If the rock is huge and you need explosives to break it up before using it, I don't want to have to specifically write that in the game code either. So instead, what I want is the engine to provide the simple actions, CreateEntity, AddInventory, WalkTo, PlayAnimation, etc. And per object in the world, I wanted to be able to chain them together to allow unique behaviors. I could have built it with my existing serialization system, (which looks something like JSON) but it would have looked ugly and verbose, been hard to use, and difficult to debug. And so I recovered my scripting code that I deleted over a year ago from source control. I'm pretty sure this is the first time I've brought code back such a large amount of code that I deleted and found it useful in another manner. Amazing! And I started hacking it up. Mostly by simplifying and removing lots of features. And in two days, I had a functioning script system that could tie the actions together and use simple stack variables. And it has a debugger! Two days! Yay! For a simple interact where a character is idling, it looks like this: To extend the script, all I have to do is write a simple C++ class that exposes the action and its parameters. The script compiler uses the C++ class and its serialization function to properly parse and use the action. It's not the fanciest thing or the easiest thing to read, but it's functional and gets me where I'm going. (Is it bad that I feel like I'm writing assembly code but the instructions are more than 3 letters long and the registers are named nicely?) It's a nice step toward being able to make new objects in the game without having them hard coded. It's a nice feeling to delete all the C++ code that was previously used to setup actions. It was far more verbose as it had to include a lot of error checking, and fetching of commonly used data. What's also nice about the format of the script, is there is a new parser for reading objects from text. Since each line represents the data in a C++ class, I can shorten what I type depending on the object. Normally an item that is stored in inventory might look like this: But with this new parsing format it can be shortened to a terse line like this: Granted the former format allows for fields to be omitted and be in any order, while the latter requires all fields in a specific order. I have a few places in data where this would be more readable and friendly so I'll change them when editing the data gets frustrating. With a simple change of adding the name of the field back in, like so: I'll be able to omit unneeded fields and supply them in any order. I think my user interface data will benefit from it, and it should take very little work to turn the mess of UI layout I have now into something more friendly. Maybe. I'm always having these idea that end up being slightly more work than I think. But that's for later. Anyway, Thanks, source control system.Plan idleInteract
{
Sequence()
{
// load values for where we are going
// @self is the villager
// @interact is the object being used
LoadInteractIndex(@interact0, @int0)
LoadInteractTransform(@self, @interact0, @int0, @transform0)
LoadInteractAnimation(@self, @interact0, "IdleInteract", @animation0)
// walk to and idle
WalkTo(@self, @transform0)
TurnTo(@self, @transform0)
PlayAnimation(@self, @animation0, Length, 0.0)
// finished using this interact, someone else can have a turn
Interact(@self, @interact0, @int0)
}
}
Item granite
{
Category _category = "Stone";
int32 _volume = 2;
LocalizedText _name = "granite@StringTable.rsc:objects";
}
Item("Stone", 2, "granite@StringTable.rsc:objects");
ImageElement(_sprite = "Cancel@UISprites.rsc", _color = 0xFFFF00FF);
I love that you are so passionate and involved in your projects. That's the reason why your games turn out so well. Looking forward to what this game turns out to be and ready to buy the alpha so that I can share feedback from the starting phases! 🙂
I'm excited for anything you produce. Banished is a game I keep going back to. You love what you do and it shows.
I love these updates as it reminds me why I love Banished so much. Banished is one of my favorite games and I look forward to anything you put out in the future.
Properly controlling the source code is crucial. I look forward to smoother progress going forward!
Thank you for writing of your developer experience. As a developer myself I am quite interested to read stuff like this. Yes, source control is a great thing. Have you already tried a git-bisect [1]? It is a great tool to find code that introduced a certain bug (presuming you are using Git as your VCS.)
[1] https://git-scm.com/docs/git-bisect
Glad you are still enjoying your coding experiences. We await with baited breath for your "mess of UI layout I have now into something more friendly", so we can enjoy it on our screens.
I don't understand how coding works but I will say this. I purchased Banished when it first came out and still enjoy playing. Never experienced any glitch. I did purchase "Life is Feudal" and found it to be an almost 100% copy of Banished with different graphics.