David William Karagory

Mostly Ducks & Technology

Trey Simulators 4's Terrain Format


Introducktion

Eendgine isn't just a mediocre 3D game engine that's named after the Dutch word for duck. Eendgine is the means by which the long awaited Trey Simulator 4 will be delivered unto the world. Naturally, I need a system for building Trey's world atop Eendgine. This post will be explaining that system.

Inspiration

Back when I was in grade school I remember my brother talking about a game, or perhaps just an idea for a game, that was Terraria like but used PNG files as save files. I always thought that was a cool idea, and liked how it would make "modding" or "hacking" a game more approachable. In my case I'm not so worried about Trey Simulator 4 being modable, but I am interested in reducing the amount of tooling and overhead I will need to program myself. By leveraging the power of PNGs, GIMP, and pixel coordinates, I can avoid making a proper level editor entirely.

Asthetically the inspiration for my terrain format is largely inspired by the games Runescape 2 and Pokemon Soul Silver. A PNG based format naturally lends itself to a tiled world, like Runescape 2 was and OSRS is. Also like Runescape 2, I'm going for a 2.5D experience where the environment is aesthetically 3D, but functionally 2D. Like Soul Silver, I want the environment to have entities that are a mixture of always facing planes and 3D objects.

Format

The terrain format is comprised of 3 PNG images and 1 JSON file.

  1. A height map, which is a monochromatic PNG. Black is the lowest a tile can be specified and white is the highest. A height map of a grassy terrain with a lake
  2. A collision map, which is a monochromatic PNG where black pixels are collision boxes. All other shades of gray are not treated as collision. A collision map of a grassy terrain where the lake, border, and trees are black pixels
  3. A texture map, which is a full color PNG. This doesn't have to conform to the dimensions of the previous two maps. A texture map of a grassy terrain where the border is bright pink to indicate transparency
  4. A list of each type of entity used, their pixel coordinates, and their properties in a JSON file. This means that objects can be placed on a terrain by hand, and without programming.
  "Boards": [
    {
      "position": [9, 5, 9],
      "scale": [5.0, 10.0],
      "pace": 1.0,
      "rotation": 0.0,
      "path": "terrain/grassy/boards/tree"
    },
    {
      "position": [19, 5, 9],
      "scale": [5.0, 10.0],
      "pace": 1.1,
      "rotation": 0.0,
      "path": "terrain/grassy/boards/tree"
    },
    {
      "position": [9, 5, 16],
      "scale": [5.0, 10.0],
      "rotation": 0.0,
      "pace": 0.9,
      "path": "terrain/grassy/boards/tree"
    },
    {
      "position": [14, 5, 7],
      "scale": [5.0, 10.0],
      "pace": 1.02,
      "rotation": 0.0,
      "path": "terrain/grassy/boards/tree"
    },
...

In place of developing a bespoke level editor, this format lets me use GIMP as a level editor. I can develop all of the maps in GIMP, and then determine the desired coordinates of an entity using GIMP before writing those pixel coordinates in the JSON file. In fact that's exactly what I did to create my grassy test map!

A pixelated duck standing on a grassy terrain

There are still more entity features that need to be added as well as entirely new entities such as teleporters. None the less, this terrain format is already quite useful.

Moving Forward

While there is much more code to be written. It's really about time that I work on some assets. I've already begun making Trey!