Subchapter 178.12
assets/gameBase-template-repo.mdMarkdown10 KBView on GitHub
A feature-rich, opinionated starter template for 2D game projects built with Haxe and the Heaps game engine. Created and maintained by Sebastien Benard (deepnight), the lead developer behind Dead Cells. GameBase provides a production-tested foundation with entity management, level integration via LDtk, rendering pipeline, and a game loop architecture – all designed to let developers skip boilerplate and jump straight into game-specific logic.
Repository: github.com/deepnight/gameBase (opens in a new tab) Author: Sebastien Benard / deepnight (opens in a new tab) Technology: Haxe + Heaps (HashLink or JS targets) Level editor integration: LDtk (opens in a new tab)
GameBase exists to solve the “blank project” problem. Instead of setting up rendering, entity systems, camera controls, debug overlays, and level loading from scratch, developers clone this repository and begin implementing game-specific mechanics immediately. It reflects patterns refined through commercial game development, particularly from the development of Dead Cells.
Key benefits:
gameBase/
src/
game/
App.hx -- Application entry point and initialization
Game.hx -- Main game process, holds level and entities
Entity.hx -- Base entity class with grid coords, velocity, animation
Level.hx -- Level loading and collision map from LDtk
Camera.hx -- Camera follow, shake, zoom, clamping
Fx.hx -- Visual effects (particles, flashes, etc.)
Types.hx -- Enums, typedefs, and constants
en/
Hero.hx -- Player entity (example implementation)
Mob.hx -- Enemy entity (example implementation)
import.hx -- Global imports (available everywhere)
res/
atlas/ -- Sprite sheets and texture atlases
levels/ -- LDtk level project files
fonts/ -- Bitmap fonts
.ldtk -- LDtk project file (root)
build.hxml -- Haxe compiler configuration
Makefile -- Build/run shortcuts
README.mdThe main application class that extends dn.Process. Handles:
class App extends dn.Process {
public static var ME : App;
override function init() {
ME = this;
// Initialize rendering, controller, assets
new Game();
}
}Manages the active game session:
LevelEntity instances (via a global linked list)class Game extends dn.Process {
public var level : Level;
public var hero : en.Hero;
public var fx : Fx;
public var camera : Camera;
public function new() {
super(App.ME);
level = new Level();
fx = new Fx();
camera = new Camera();
hero = new en.Hero();
}
}The core entity class featuring:
cx, cy (integer cell coordinates) plus xr, yr (sub-cell ratio 0.0 to 1.0) for smooth sub-pixel movementdx, dy (velocity) with configurable frictX, frictYh2d.Anim or dn.heaps.HSpriteupdate(), fixedUpdate(), postUpdate(), dispose()hasCollision(cx, cy) check against the level collision mapclass Entity {
// Grid position
public var cx : Int = 0; // Cell X
public var cy : Int = 0; // Cell Y
public var xr : Float = 0.5; // X ratio within cell (0..1)
public var yr : Float = 1.0; // Y ratio within cell (0..1)
// Velocity
public var dx : Float = 0;
public var dy : Float = 0;
// Pixel position (computed)
public var attachX(get,never) : Float;
inline function get_attachX() return (cx + xr) * Const.GRID;
public var attachY(get,never) : Float;
inline function get_attachY() return (cy + yr) * Const.GRID;
// Physics step
public function fixedUpdate() {
xr += dx;
dx *= frictX;
// X collision
if (xr > 1) { cx++; xr--; }
if (xr < 0) { cx--; xr++; }
yr += dy;
dy *= frictY;
// Y collision
if (yr > 1) { cy++; yr--; }
if (yr < 0) { cy--; yr++; }
}
}Loads and manages level data from LDtk project files:
hasCollision(cx, cy))class Level {
var data : ldtk.Level;
var collisions : Map<Int, Bool>;
public function new(ldtkLevel) {
data = ldtkLevel;
// Parse IntGrid layer for collision marks
for (cy in 0...data.l_Collisions.cHei)
for (cx in 0...data.l_Collisions.cWid)
if (data.l_Collisions.getInt(cx, cy) == 1)
collisions.set(coordId(cx, cy), true);
}
public inline function hasCollision(cx:Int, cy:Int) : Bool {
return collisions.exists(coordId(cx, cy));
}
}Provides:
Particle and visual effect management:
A cross-platform, high-level programming language that compiles to multiple targets:
A high-performance, cross-platform 2D/3D game engine:
h2d.Object hierarchyA modern, open-source 2D level editor created by Sebastien Benard:
# Clone the repository
git clone https://github.com/deepnight/gameBase.git my-game
cd my-game
# Install Haxe dependencies
haxelib install heaps
haxelib install deepnightLibs
haxelib install ldtk-haxe-api
# Build and run (HashLink target)
haxe build.hxml
hl bin/client.hl
# Or use the Makefile (if available)
make runsrc/game/ package declarations and project references to match your game.build.hxml – Adjust the main class, output path, and target as needed..ldtk file, define your layers and entities, and export.src/game/en/ extending Entity.| Target | Command | Output | Use Case |
|---|---|---|---|
| HashLink | haxe build.hxml | bin/client.hl | Development, desktop release |
| JavaScript | haxe build.js.hxml | bin/client.js | Web/browser builds |
| DirectX/OpenGL | Via HL native | Native executable | Production desktop release |
GameBase includes built-in debug tooling:
GameBase uses a fixed-timestep game loop pattern:
Each frame:
1. preUpdate() -- Input polling, pre-frame logic
2. fixedUpdate() -- Physics, movement, collisions (fixed timestep)
- May run 0-N times per frame to catch up
3. update() -- General per-frame logic
4. postUpdate() -- Sprite position sync, camera update, rendering prepThis ensures physics behavior is consistent regardless of frame rate, while rendering and visual updates remain smooth.
Constructor --> init() --> [game loop: fixedUpdate/update/postUpdate] --> dispose()