DEV Community

Cover image for Now this is how you create video games
Luis Bastidas
Luis Bastidas

Posted on • Edited on

Now this is how you create video games

I started creating an educational video game about numeric sets with Godot Engine.

Numeric sets video game showcase

The idea is this: the more specific the set you place the number in, the more points you get.

Adding some references

I wanted to show memes when the player placed special numbers such as 67, 69, or 87, which have certain meanings in this cultural context.

  • 7: The most likely number to appear when you roll two dice and sum their results.
  • 67: Viral absurd meme.
  • 87: Five Nights at Freddy's lore key date (1987).
  • Many more.

The problem? I was doing it manually. It was something like this:

  1. Convert the video into separate frames.

  2. Copy the frames into the project folder.

  3. Put all the frames inside an animation named after the special number.

  4. Optionally put the audio of the meme in another folder and the file must be named after the special number.

So as you can see, this workflow was inefficient, especially because I had to repeat myself a lot and programming is about avoiding these bottlenecks. But even worse, all the animations were inside a single SpriteFrames resource which severely affects performance.

Solution

Fixing the workflow

Instead of having frames and audio in different folders, I made a special folder in the project where all the subfolders must follow a specific schema:

/multimedia/special_numbers_animations/
└─ <animation_name>
   ├─ frames (optional folder)
   ├─ audio.ogg (optional)
   ├─ image.{png, jpg} (mandatory if there is no frames folder)
   └─ meta.json - I save the URL sources of the content here.
Enter fullscreen mode Exit fullscreen mode

Now instead of having to specify the special number every time, the special number itself determines which animation will play.

const SPECIAL_NUMBERS : Dictionary = {

    308: { # Breaking Bad Reference
        "folder": "waltuh", # This is the <animation_name> folder of the code above.
        "volume_db": 0.0,
        "message": "waltuh" # This is the message which display the green label you can see in the GIFs
    },

    69: {
        "folder":"ts_you",
        "message": "you freak..."
    },

    64: {
        "folder": "homer64",
        "message": "PEAK!",
        "fps":30.0,
        "duration": 187.0 / 30.0
    },

    67: {
        "folder": "six_seven",
        "message": "ABSOLUTE\nSIX-SEVEN! +{score}"
    },

    57: {
        "folder": "peruan_caine",
        "volume_db": -10.0,
        "fps": 6.0,
        "message": "AMAZING! +{score}"
    },

    7: {
        "folder":"miners",
        "message": "gambling, gambling\ngambling, gambling"
    },

    6: {
        "folder":"gta_vi",
        "message": "son...",
    }
}
Enter fullscreen mode Exit fullscreen mode

Performance optimization

As we have all the animations in different folders, the code only loads the animations that will be played when the number is placed.

if valid_set:

    var _reward = SpecialNumbers.get_reward(number, depth)

    feedback_label.set_color("#00ad00")
    feedback_label.prompt(_reward.text)

    if _reward.is_special:
        special_anims.show_animation(number)

    score += _reward.score
Enter fullscreen mode Exit fullscreen mode

However, loading and releasing animation data every single time can be counterproductive if we want high performance, so I implemented a cache system.

func _load(number):
    var _cached = _loaded_animations.get(number)

    if _cached != null:
        return _cached

    # (A lot of code loading the animation like frames, image and audio here).

    var _loaded = LoadedAnimation.new()

    _loaded.image = _image
    _loaded.frames = _frames
    _loaded.audio = _audio
    _loaded.number_info = _special_number_data
    _loaded.audio_player = _audio_player

    _loaded_animations[number] = _loaded
    return _loaded
Enter fullscreen mode Exit fullscreen mode

Memes system working

Now we have a scalable and easy memes system!

This is an important concept to understand. I used to think you just make the game, but it’s not like that at all. At least if you don’t want your code to become Undertale’s cousin. Before creating the game, you must build workflows that optimize creation itself, so you can modify anything in the future with minimal effort.

Just remeber

If adding content hurts, your pipeline is wrong.

Top comments (0)