Developing my own tools

Developing my own tools
Did you know Vincent Price had a cooking show? Also cookbooks. One of my heroes right there.

So godot allows you to build your own tools in the engine, with the engine and it's kinda brilliant. Like you could build a sprite editor into the game engine or even into the game itself, see; PixelORama.

So I have been building tools into the game engine that for us could be used for development and testing of games and be used across multiple games with small modifications. Keeping all the item data and recipe data as a database stored in JSON, then reading that JSON back in on load, saving, reloading, hot reloading when you save by having a versioning system on each piece of the data. This means I could cache most of the stuff in ram and only overwrite it when I absolutely have to. This will allow us to test the game assets while the game is running.

We could add an item to a store or in this case an item to a resource processing building or spawn a new kind of vegetation to grow a new kind of fruit from within the game itself, using the tools. I think I have unlocked the next level of knowledge in game development. I wonder what the next level after this will be like? Hmm... Well, only one way to find out.

Anyway, here's how it works...

I built a UI around the management of some JSON files, basically. I could port this to SQL, maybe include a SQLite database? These tools could be used for mods later, I have considered that when developing them... hopefully my logic is not weird and the UI comes across as straight forward, I have never been too good at UI... always tell myself "I'll fix it later." With that in mind, I have created this UI within the engine itself and all the code is built into the engine and can be run from inside the game.

The UI in Godot's editor.

So, godot has a tabbed interface and a container hierarchy in the UI that makes it function just like nodes in a scene, it is just nodes in a scene. You can avoid redrawing the UI more than once with signals and it's really quite intuitive once you get your head around it. You could build Godot inside itself, of this I am certain.

They make everything they use for the editor itself in the UI components, because DRY. I really appreciate the thought they put into the design and that makes me feel like I should think at least as much as that about mine. I do have to fix some things in my sprites because I was testing 32x32 item icons and I decided keeping everything 16x16 for ease of development and (hopefully clever) use of 2 frame animations a la tamagotchi or many gameboy-gba games.

Editing Resources – I have spent more time building the UI than making assets the past few weeks.

It will test every entry before it can be sent to the DB manager and saved into the resource database to be used in the game. This should prevent someone from saving something that could potentially break the database and then the hot-swapping code in the game.

Something that could break the database.

It tests to make sure there's a sprite, that the sprite LOADS into the game, that the category exists, that there is a name and description, that there isn't already a similar entry, and a few other things... I spent a lot of time writing tests and sanitizing user input.

Now because of the design methodology Godot uses, I can detach any part of this UI and run it on it's own.

This allows me to put the parts of the UI in anything I want. I could include them with the game as creation tools for mods.

Alright so I have to finish implementing the Edit Recipe and Delete Recipe code, but I plan to do that later today, I just figured I would spend the time I am waking up and drinking my tea some constructive work documenting the experience I had with the UI tools in Godot.

So let's say I want to add a new recipe to the database... Oat flour, for instance off the top of my head. I don't yet have a category for grains.

No grains! What is this fly by night bullshit!?

So I click the + next to category and I get a popup to add one.

Time to remedy the lack of grains.

So I can add a new category. It will check and make sure the category doesn't exist before trying to create one, or you could overwrite that category with and empty one and that would not be bueno if you had 50 hours of work in that category.

I took a lot of blows to the head as a younger man, I forgot how to spell grains apparently.

This wont overwrite the honey category.  Your Clover Honey is safe.

Still safe, see. No fatfingering or brain short-circuiting the database to death.
G-R-A-I-N. That spells flibblebum.
There we go.

So now I have grain, but I feel like oatmeal should be a cereal, not a grain. I've changed how I want to categorize it.

I can just add cereal grain.

Ah, it feels good to give into my pedantry sometimes.

So now I can add my Oats.

Click on the sprite selector to open a sprite selector dialog.

No oats here?

It opens a file select dialog inside the Database Sprites folder, you select the sprite, which in this case there is not one... so I will have to make a quick one.

Get in there, you. Fix it.
Oi, where you at?

Refresh and there it is, didn't restart the game, just refreshed.

Wait, that's not honey!

And now I can enter my details about it. It's a tier one resource, it is a cereal grain, it has a description.

The description can be as complex as you want, as long as the in game UI it will be displayed to the player through makes it readable.

Hehehe... yoink!

You could have a paragraph or a page if you want. You could even use BBCode formatting if you wanted. The UI in game can parse it. You can sanitize out the BBcode and then use the same text in a tooltip that shows when you hover over the item sprite in game.


Now I didn't implement the color changing on the Add Resource UI as I started doing that after. I will implement it before the end of next week.

But if the tests all pass it will make an entry to the database. Thinking about it I should make a clear form button as well.

Anyway on Confirming I will have (assuming it passed the tests) commited the Oats to the resource database.

It not here.

Of course I could have it auto refresh and I might still do it that way but for now I have a Refresh button to make it easier for me to debug.

There you are, you sneaky bastard! Hiding at the bottom.

The edit resource tab could sorted by name alpha-numerically or any by any property. I will be adding filters to the top probably by the end of the week.

Yeah, that checks out.

So now I have Oats, I want to make them into Oatmeal through a Mill building I will add to the game, I can make the recipe here and now in the DB tool and load it to the Mill. This way any time I change the database the mill will get the new data (if I needed to change my description to fit it into the tooltip better, for instance). Realtime updates makes it easier to test stuff.

Why don't I just use the whole damn article? WHY NOT JUST LINK IT!? (I could actually)

The text entry for the description does scroll so it's capable of dealing with a lot of text. I may make it a popup with a WYSIWYG editor if I need to later on, but this serves current purposes.

Now the player will be smarter. I'm such a nice person. Ho ho ho ho... (dammit)

It will always test before saving, the test function HAS to return true for save to ever fire. Save calls Test, if all tests pass THEN save is called.

Refresh to be sure it saved.

Yes. The player will have to know the WHOLE HISTORY OF OATS! BWAHAHAHAHAHAHA!

All saved.

On second thought, let's not overload the player with information. Tis a silly practice.
This might work.

Or maybe I want it to be really short and concise.

Insult the player, surely they will enjoy being insulted!

Or maybe some joke falls flat so you gotta quickly change crap.

That was a lot of angry e-mails from them mothers... >_>

Or if you want to be nicer to the player let them know what it could be used for, hint at mechanics with the description and then introduce a mill later.

Sensible, concise. I hate it. =[

Make sure it saved.


Now I move on to the recipe adding. Oh and you wont accidentally delete unless you are really unlucky or out of it.

After the hell I went to with these oats they ain't going nowhere!

Also every other panel is lighter to help visually delineate them, I found without it the information felt like it all ran together.

Now then. I need to make oatmeal... so I need to add the oatmeal Item.

The Add Recipe UI expects you already created the resource you are making a recipe for... because why would you need it any other way?  The database uses references to make sure it's all redundant (the resources must exist to be part of a recipe). It has built in tests as well, so our resource DB is being tested whenever we edit it and will output errors and suggestions on how to correct them.

First off, need some oatmeal in the Resource DB.

Alright, whatever. It has to have a face now.

If you somehow don't have a sprite edit will let you set one to fix it.



It will watch you eat it. =|

Of course, there's the test output for our database saying all is well.

That's not an X! (I was using that to make sure resources with no sprite would load an X image.)

I should have left the honey broken, oh well. Moving on.

That tin looks suspiciously like wood, sir. If I didn't know any better I would think you were trying to dupe me.
Debug output goes here, it would tell you what failed and offer ideas as to what might be the problem.

Test code that would generate output of things that fail.


I even have notes that I need to rewrite some of my tests once I get the databases fully set up. I used a lot of TDD in this, writing tests first and then making them pass. It's pretty good actually, I see why a lot of people bang on about it.

So now I want to add my recipe.

Oatmeal, please.

I'll have to add a building.

So does the smith smash the oats or does the sawmill saw them?
O.G. Grinder.
You chop the oats good.

The tooltips are here in case something doesn't make sense.


Then I set up ingredients. Say I want 2 pounds of oatmeal to produce one pound of flour. The denominations are incidental, but it's pretty easy to think of things as being in parts, so one part X produces two parts Y or visa versa in this case.

You got one for the price of 2! Suck it player!

The system also allows for byproducts, so say we wanted oat hulls as a byproduct and the player had to deal with them or make them into something else... as the warehouses have limited inventory.

For now we'll test and make sure our Oatmeal recipe will work and does not already exist. Again Test is always called before a commit so you can't submit bad data.

Green means go.

Now let's say I decided I wanted them oat hulls. I will quickly sprite them up, add them into the DB and I can set up a byproduct to be produced by the processing of the resources.

Oat hulls or someone dropped a real nasty one.
What the hell am I gonna do with oat hulls anyway?

Now I can commit the recipe to the DB, since it passes all the tests.

Well, I got that going for me which is nice.
Seems to be in order, nobody wants fake_shit.

And it's in the Database, you can see it in the Edit Recipes tab.

It's looking at me...
Oh no ya don't.

And if I need to edit it (currently working on this) it will open this panel:

Yep, that tasted purple.

And that's where I am at. I got some bugs to fix, I got some features to implement (like finishing the edit UI's code) and some sorting algorithms to write for the filters but the DB and all the tools to interact with it are available to this toolset and to the game itself, so both can use the same lookup functions in the DB.

The tools are attached to the DB itself as nodes at runtime and are essentially an API for the DB.

Haha! It only took me a week to realize I should just attach the tools to the DB and make it an API.

So now this has gone on for over 2,300 words and I need to get to coding this last panel. I intend to have this tool done by the end of next week hopefully... at least this iteration of it.

Here's how I have been organizing my thoughts to design all these things.

Notebooks are important.

Anyway, off I go.