Getting Started With Gaem: A Practical Guide
Gaem is a lightweight game prototyping and deployment tool that has been circulating in the indie dev space for a few years now. It's not the most polished thing out there, but it does what it says it does, and some people find it useful for rapid iteration. I've used it on and off over the past several months for some small internal prototypes, and I want to walk through how it actually works in practice rather than just repeating what the docs say. At its core, Gaem is a framework that lets you define game logic in a config-driven way and then compile it into a runnable build for web or desktop. You write in a hybrid syntax that mixes JSON-style declarations with JavaScript for the actual runtime logic. That sounds weird until you try it. The idea is that you can swap out assets, tweak stats, and recompile without touching the core codebase. It's aimed at people who want to spin up a playable version in an afternoon rather than spending weeks building a proper engine setup. There's no official central repository, which is worth noting. You typically find it through community mirrors or GitHub forks. The original project moved around a bit and there are several active variants now. Make sure you're pulling from the right one because they don't all share the same API surface. The most commonly used fork at this point is the one maintained under the gaem-core namespace, and that's the version this guide assumes you're working with.
Installation and Setup
You'll need Node.js installed. Version 18 or later works fine. I'm running on 20 myself and haven't had issues. Clone the repo to wherever you keep your dev projects, then run npm install from the root directory. It pulls down a decent number of dependencies but the whole thing installs in under two minutes on a normal connection. After installation, initialize a new project by running gaem init in your project folder. This creates a config.json file and a basic directory structure with folders for assets, scenes, and scripts. The config file is where most of your time will go. Every game object, scene transition, and input binding goes through there. One thing the docs don't mention clearly: you should set the rendering backend before you do anything else. In your config, under the renderer key, pick either canvas or WebGL depending on what you need. Canvas is faster to prototype with because it handles more of the edge cases automatically. WebGL gives you better performance once you actually ship but requires more careful setup for shaders and texture handling. If you pick the wrong one and realize too late, you have to redo a lot of your asset pipeline. I made that mistake on a project last month and lost about half a day moving things around.
Building Your First Scene
Let me walk through a simple scene. Say you want a basic platformer test with a player character, a few platforms, and gravity. Create a file in your scenes folder called test_platform.json and reference it from your main config. Here's the structure. You define a scene object with layers, then objects within those layers. Each object has a type, position, dimensions, and behavior properties. For the player, you'd set the type to character and then define the behavior as a script that handles input and physics. The physics system in Gaem is not sophisticated. It's AABB collision with a simple gravity constant. That's fine for prototyping and surprisingly sufficient for a lot of things, but if you need precise platformer feel—like coyote time or jump buffering—you're going to have to write that yourself in the behavior script. The behavior scripts are just plain JavaScript functions that receive an event loop. You get update, input, and collision callbacks. It's not event-driven in the traditional sense. Everything runs on a fixed timestep which is actually good for determinism but can feel clunky when you're used to frame-based game loops. You can adjust the timestep in the config, but going below 33 milliseconds starts to show instability in the collision system.
I ran into a specific issue recently where my player character would occasionally pass through thin platforms. The problem was that the objects were thinner than the movement delta between frames. Even at 60fps with a normal movement speed, the player could skip over a one-pixel platform. The fix wasn't to lower the timestep—that actually made it worse in some cases. The real workaround was to enable continuous collision detection in the config by setting CCD to true on the player object. That slows things down a bit but it completely eliminates the tunneling problem. It took me about an hour to figure out because the documentation for CCD just says "available" without explaining the performance tradeoff.
Compiling and Running
When you're ready to test, run gaem build from the project root. This compiles everything into a single output folder. There's a built-in server you can start with gaem serve, which spins up a local HTTP server on port 8080 by default. Point your browser there and you should see your scene loading. For a standalone build, use gaem build --standalone. This bundles everything into an Electron wrapper on desktop or a self-contained HTML file for web. The standalone build is roughly 40 megabytes because of the Electron dependency, which is annoying if you're trying to keep things small. The HTML-only build is only about 800 kilobytes for a minimal project. One limitation you should know about: the standalone build process doesn't handle asset path resolution well. If you reference images using absolute paths in your config, they'll break in the standalone output. Always use relative paths from the scene file. I learned this the hard way when my standalone build had no textures for three hours before I realized the paths were all wrong.
Common Pitfalls and What the Docs Skip
Asset loading is synchronous by default. That means if you load a large sprite sheet, your game freezes until it finishes. You can make it asynchronous by deferring the load, but the API for that isn't obvious. You have to set asyncLoad to true in your asset config and then handle the ready state in your scene script. Without this, projects with more than a handful of assets will feel sluggish on first load. Input handling is another area where things don't work the way you'd expect. Gaem uses a raw input poll system, not an event system. You check for key states inside your update callback rather than subscribing to keydown events. This works fine for most things but makes it difficult to implement combo inputs or timing-sensitive mechanics. You end up writing a lot of state machines in your behavior scripts just to track whether a sequence of keys happened in the right order. The audio system is equally basic. You can play sounds and music but there's no mixing, no volume automation, and no positional audio. If you need multiple sounds playing at once, they'll clip against each other. I got around this by routing everything through a simple gain node in a custom audio script, but that's not something the framework provides out of the box.
When to Use Gaem and When Not To
Gaem is useful when you need to test a game mechanic quickly without setting up a full engine. It's also decent for making browser-based mini-games or jam entries where the scope is small. What it's not good for is anything that needs precise physics, complex animations, or multi-platform deployment. If you're building something that will actually ship and needs to feel good, you're better off using Godot or even Unity. Gaem is a prototyping tool, not a production tool. I've seen people try to push it past its limits and it always ends badly. The collision system breaks down with fast-moving objects. The animation system is purely frame-based with no skeletal support. Networking doesn't exist at all. If any of those are requirements for your project, move on to something else. For what it is, Gaem gets the job done. It's not elegant but it's functional, and the community around it is small but active enough that you can usually find answers if you dig through the issues and pull requests. Just go in with realistic expectations and you won't be disappointed.