This is an Odin + Raylib game template that combines hot reloading capabilities with a comprehensive entity system. The template features a flexible entity-component architecture, collision detection with spatial partitioning, animation system, and hot reloading for rapid game development.
Supported platforms: Windows, macOS, Linux and web.
Note
These instructions use Linux/macOS terminology. If you are on Windows, then replace these words:
sh->batbin->exeso->dll(Windows),dylib(mac)
- Run
./build_hot_reload.shto creategame_hot_reload.bin(located at the root of the project) andgame.so(located inbuild/hot_reload). Note: It expects odin compiler to be part of your PATH environment variable. - Run
./game_hot_reload.bin, leave it running. - The game will start with a player (corgi sprite) that you can move with arrow keys, and 10 bouncing balls. The player can destroy balls by colliding with them.
- Make changes to the gameplay code in
source/game.odinor entity behavior insource/entity_setup.odin. For example, change the background color or modify player movement speed. - Run
./build_hot_reload.shagain, it will recompilegame.so. - The running
./game_hot_reload.binwill see thatgame.sochanged and reload it automatically, preserving the current game state.
Note: ./build_hot_reload.sh does not rebuild game_hot_reload.bin if it's already running. It only recompiles the game shared library for hot reloading.
./test.shThis runs all tests in the tests/ directory, validating entity creation, destruction, collision detection, and other core systems.
The template includes uses the Mega Struct architecture. The idea is that there is only 'Entities' all entities use the same struct and even thought it might seem wasteful, it's ok because your game probably isn't that huge anyways. If you really need a lighter weight entity you can just create the seperate struct later.
- Creation:
entity_create(kind)creates a new entity with automatic setup - Update: Entities are updated each frame through the update table
- Collision: Collision detection runs after all entity updates
- Drawing: Entities are drawn in z-index order
- Destruction:
entity_destroy(entity)removes entities and frees their slots
// Define a new entity kind
EntityKind :: enum {
PLAYER,
ENEMY,
// ... other kinds
}
// Register entity procedures
load_entity_functions :: proc() {
g.entity_setup_table = [EntityKind.COUNT]EntitySetupProc {
EntityKind.PLAYER = player_setup,
EntityKind.BALL = ball_setup,
}
g.entity_update_table = [EntityKind.COUNT]EntityUpdateProc {
EntityKind.PLAYER = player_update,
EntityKind.BALL = ball_update,
}
g.entity_collide_table = [EntityKind.COUNT]EntityCollideProc {
EntityKind.PLAYER = player_collide,
EntityKind.BALL = ball_collide,
}
g.entity_draw_table = [EntityKind.COUNT]EntityDrawProc {
EntityKind.PLAYER = player_draw,
EntityKind.BALL = ball_draw,
}
}
// Implement entity behavior
player_setup :: proc(player: ^Entity) {
player.pos = {0, 0}
player.animation = init_player_animation()
player.collider = init_collider(player^, width=30, height=20, layer={.PLAYER}, mask={.WORLD})
}Run ./build_release.sh to create a release build in build/release. That executable does not have the hot reloading stuff, since you probably do not want that in the released version of your game. This means that the release version does not use game.so, instead it imports the source folder as a normal Odin package.
./build_debug.sh is like ./build_release.sh but makes a debuggable executable, in case you need to debug your non-hot-reload executable.
./build_web.sh builds a release web executable (no hot reloading!).
- Emscripten. Download and install somewhere on your computer. Follow the instructions here: https://emscripten.org/docs/getting_started/downloads.html (follow the stuff under "Installation instructions using the emsdk (recommended)").
- Recent Odin compiler: This uses Raylib binding changes that were done on January 1, 2025.
- Point
EMSCRIPTEN_SDK_DIRinbuild_web.shto where you installed emscripten. - Run
./build_web.sh. - Web game is in the
build/webfolder.
Note
./build_web.sh is for Linux / macOS, build_web.bat is for Windows.
Warning
You can't run build/web/index.html directly due to "CORS policy" javascript errors. You can work around that by running a small python web server:
- Go to
build/webin a console. - Run
python -m http.server - Go to
localhost:8000in your browser.
For those who don't have python: Emscripten comes with it. See the python folder in your emscripten installation directory.
Build a desktop executable using ./build_desktop.sh. It will end up in the build/desktop folder.
There's a wrapper for read_entire_file and write_entire_file from core:os that can files from assets directory, even on web. See source/utils.odin
See the README of the Odin + Raylib on the web repository for troubleshooting steps.
You can put assets such as textures, sounds and music in the assets folder. That folder will be copied when a release build is created and also integrated into the web build.
The hot reload build doesn't do any copying, because the hot reload executable lives in the root of the repository, alongside the assets folder.
Inside the asset_workbench directory there is a lua script which is a plugin that allows you to automatically export the selected layer in aseprite into this project
The template works nicely together with Karl Zylinski's atlas builder. The atlas builder can build an atlas texture from a folder of png or aseprite files. Using an atlas can drastically reduce the number of draw calls your game uses. There's an example in that repository on how to set it up. The atlas generation step can easily be integrated into the build scripts such as ./build_hot_reload.sh
=> ./build_hot_reload.sh
Building game.so
./build_hot_reload.sh: line 37: 744324 Segmentation fault (core dumped) odin build source -extra-linker-flags:"$EXTRA_LINKER_FLAGS" -define:RAYLIB_SHARED=true -build-mode:dll -out:$OUT_DIR/game_tmp$DLL_EXT -strict-style -vet -debugThis template combines two excellent open-source projects:
-
Hot Reload System: Based on Karl Zylinski's Odin + Raylib + Hot Reload template. The hot reloading system allows you to reload gameplay code while the game is running, enabling rapid iteration during development.
-
Entity System: Adapted from baldgg/blueprint, providing a flexible entity-component architecture with collision detection, animation system, and spatial partitioning.
See The Legend of Tuna repository for an example project that also uses Box2D: https://github.com/karl-zylinski/the-legend-of-tuna
Karl Zylinski used this kind of hot reloading while developing his game CAT & ONION.