Game Assets: To Script or Not to Script? GPT Changes Everything!

posted in: Devlog | 2

This past weekend I used Google Bard to save me a little time updating some game assets (I wanted to try out Bard’s new PaLM 2 model first, but I tried Bing AI and ChatGPT as well). I’d estimate it saved me a few hours in total. Not a big deal. But the bigger deal is I really feel this is a new way of working. It feels like a little like pair programming, but with an AI instead of a human, and we take turns at the keyboard. The result is my internal threshold of when to script has significantly changed.

The Problem

In creating the reboot of ChipWits (a game about robot coding), we first assumed floor tiles were okay as small 1×1 2D planes:

Floor panel before game assets update
Flat floor panel

We made all of our floor tile textures accordingly, as simple squares:

Game assets: texture for floor panel
Texture for floor panel

Usually this is okay because a room is fully surrounded by walls, so you never see the side of a floor panel. Then, we decided to do a mission on the exterior of a space station. Now, the sides of the floor tiles are visible, so they need some height.

Scene before game assets update
Preview of flat tiles in space, side perspective

Updating the Game Assets

First, I updated the Blender model to extrude the 2D plane and add some height:

Floor panel game assets with depth in Blender
Adding height to the tile mesh, in Blender

But now, the sides of the floor panels need texture. So the next job was to change the texture map. At first I considered adding ~32 pixels to the bottom of the texture map, but that would make it a NPOT texture, so instead I decided to resize the texture to be smaller vertically and then add the texture for the sides of the floor panel to the bottom of the texture map:

New texture game assets for floor panel
New Texture for floor panel

It’s a trivial change. Easy enough in GIMP, but now I realized I had to do the same thing for the normal maps, height maps, and ambient occlusion maps, and then I have to do that for all of our tile textures. In total that’s well over 100 images! Time to write a script.

To Script or Not to Script?

We all make that tradeoff every now and then… You know the one. Do I suffer through updating these game assets by hand, one at a time, or do I take the time to write a script to automate the process? I always feel lazy when I decide to do it by hand. Playing it out in my head, it goes something like this:

Me: I should really script this. The results will be more accurate and I’ll save myself all that tedious clicking and typing.

Me: Yeah, but I don’t remember the details of how to use that library. So first I have to go research this and that. Then I have to write the script. Then I have to test it and iterate until it works. It will take forever. I should just roll up my sleeves and do it by hand.

Me: Ugh, fine. But I’m going to regret this.

<two hours later>

Me: Now look what I’ve done. I done it all by hand but I forgot one little detail and I have to start all over again. Next time, I’ll just script it from the beginning.

— Me, debating with myself about whether or not to script something

Enter Generative Pre-Trained Transformers (GPTs)

My experience this past weekend has significantly changed my internal threshold about when to script something. This time, instead of giving in to my lazy self, I opened up Google Bard and asked it to write the script for me. Its first attempt was not bad!

Bard output

The script it gave me had several fairly obvious bugs:

  1. It is using float instead of int for some parameters
  2. The fill logic should be (pixel[0], pixel[1], pixel[2]) instead of (pixel, pixel, pixel)
  3. The fill logic needs a 4-tuple for the target box size instead of just the (y0, height) tuple

I won’t bore you with the full chat session, but after 3 more prompts, Bard was able to fix these bugs, and the resulting script worked great! Now I just have to touch up the specific textures where the height will be visible.

Furthermore, I was able to ask Bard to modify the script to apply the logic to an entire folder of .png images so I wouldn’t need to script that part of the automation, either.

How about Bing AI / ChatGPT?

I tried the same prompt in Bing AI and it took a bit longer to generate a response but it got it right on the first shot:

Bing AI output

The resulting code is less efficient because the fill logic relies on python nested loops instead of the vector-optimized paste. But at this scale it really doesn’t matter.

Conclusion

Here’s the new floor tile, with the texture applied:

Floor panel with height

And here’s the new scene (now we will need to add floor panels below all walls!):

gpt-after
Tiles with height

It’s subtle, but an important update to the game, and would have taken many hours without scripting.

In general, I’ve found it interesting to compare Bard and ChatGPT. My impression is that Bard is still lagging in accuracy for these types of coding prompts, but it is much faster which makes it more conversational meaning I can riff and iterate on ideas faster. I also like the ability to edit my previous prompt and see 2 other draft responses. For now, I’ll be using both. But the important thing is I’m much more likely to script my game asset updates thanks to GPT.

Discussion

Have you used GPT to automate some of your game asset creation? Have you experienced a similar shift in productivity and internal automation threshold? Add your comments below!

2 Responses

  1. Doug Sharp

    Cool! AI can amplify our intelligence and give us more time. IAbout a third of the time I use ChatGPT for things I used to google.
    The only time I used ChatGPT to write code was as a silliness. I prompter it, “write a maximally suboptimal sort routine in python and explain it” It chose the Bogosort and warned, “Beware, if you give it a long list, it could theoretically take until the heat death of the universe to finish sorting.”
    Nice way of making our space station. Can’t wait to see it!

  2. Doug Sharp

    FYI: Here’s the “maximally suboptimal” sort code it created:

    import random

    def is_sorted(data):
    return all(data[i] <= data[i+1] for i in range(len(data) – 1))

    def bogosort(data):
    while not is_sorted(data):
    random.shuffle(data)
    return data