MiniJamLab: Building Scenes

Armen - Jul 31 - - Dev Community

It's been a little while since I wrote an update on what's going on with MiniJamLab, so here are a few things I want to share.

Where's the editor?

Conceptually, the way the engine works is similar to engines like Godot and Unity. We compose a scene from components/nodes and attach scripts to them to define behaviors. But where, then, is the editor? How do we go about "composing" anything, if we lack a "composer" tool? Well, that's a great question! Currently, I'm afraid you're stuck writing JSON files to define a scene. Luckily, the JSON file isn't overly complex - For example, this is the TypeScript interface that defines a base node component:

interface NodeData {
  is: string;
  name: string;
  script?: string;
  angle?: number;
  group?: string;
  position?: {
    x: number;
    y: number;
  },
  scale?: {
    x: number;
    y: number;
  },
  size?: {
    width: number;
    height: number;
  },
  opacity?: number;
  fill?: string;
  children?: NodeData[]
}
Enter fullscreen mode Exit fullscreen mode

If you have no intention of displaying anything, this is all you need. Create a component, then add child-components, and so on.

A quick high level overview of the allowed properties:

is

"is" defines what kind of node we are serializing. The base component is just "Node", but we also have others like "Sprite", "TileMap", and some UI nodes like "Text" and "Button", as well as non-display nodes like "Audio" and "SimpleCollider".

name

For many nodes, you'll want to be able to look them up and manipulate them from a script. In order to find them, we must name them - Note that the engine does not guarantee unique names, so keep that in mind!

script (optional)

Well we can't just sit there and do nothing - the "script" property allows us to attach a script file, for which we use the excellent MiniScript language

angle (optional)

For nodes that can be displayed (Sprite, TileMap), this allows us to rotate the node. This property may be moved out of the base node in the future.

group (optional)

Like name, this helps us identify what node we're dealing with - this is particularly useful when dealing with collisions. If we collide with a node in the "enemies" group, we may want to take damage now. If we are are colliding with a node in the "ladders" group, we could enable vertical movement controls. These group names are user-defined, so don't be afraid to get creative!

position, scale, size (optional)

Most nodes, even some that can't be displayed like the base node, will benefit from having at least a position set. That's because its children will be positioned relative to this, which allows things like easy attachments (weapons, tools), or relative movement (like parallax and particle effects)
Scale is useful for example to scale up pixel art, and size will help define a bounding box for collision. Note that for Sprite nodes, the size can be derived from the image, but if it is given, and smaller than the image, it allows us to treat the image as a spritesheet. Defining animations on a Sprite node is a topic for another day, however.

opacity (optional, default=1.0)

Again for nodes that can be displayed, this will allow us to add some transparency - note that here too, the value applies to this node's children as well.

fill (optional)

The "fill" property may mean slightly different things depending on what kind of node we set it on. On a base node with position and size, we are telling the engine to draw a rectangle with the given color. On a Text node, we are setting the fill color for the text.

children (optional)

This one is a bit magical, as hinted at before: nodes defined as children will be drawn after their parent, relative to their parent's position, and inherit the parent's opacity. Hiding the parent will also hide all of its children.

Seriously though... an editor?

While I hope the above sparks the imagination, I bet it also looks a little daunting if you're thinking about even mildly complex scenes. There is no editor. Will there be one? Well, maybe. I can't see any merit in trying to build an editor like Godot, instead, as much as possible, I want to leverage available tools. For example, the TileMap node imports maps from the excellent TileD map editor - and includes support for collision data and item spawns, and indeed should in the future support embedded animated tiles, and parallax layers. In a way, that's most of your Editor needs taken care of. I also don't see a need to provide a code editor for the engine - there are so many options better than anything I could give you: vscode/codium, VIM, or even EMACS for the masochists among us. Use what makes you happy.

Unfortunately that does leave a few gaps:

  • Composing individual components
  • Creating UI layouts

Open source tools are notoriously bad at marketing themselves, so perhaps solutions for these exist that I simply haven't come across yet. Perhaps in the end, I'll create a small editor to compose Sprite components and UI layouts. First, however, I'd like to actually have a functioning demo game running on this Mini Jam Lab of mine.

Final thoughts

JSON is a practical format because it is widely supported, many tools exist to create and manipulate these files. However, it's not great for humans to read and write. Other options exist, but sacrifice heavily on tooling. Perhaps another, better way exists to serialize a scene - if anyone has a suggestion I'd love to hear it!

. . .
Terabox Video Player