Cruise.jl, a game engine kernel with a powerful plugin system to allows you to build games or full game engines without too much overhead. It's closer to Linux philosophy, the same way everyone can build his own OS using the Linux kernel, anyone can build his own engine using Cruise.
Stable release:
julia> ] add CruiseDevelopment version:
julia> ] add https://github.com/Gesee-y/Cruise.jl-
Secure and flexible plugin system: Built around a DAG (Direct Acyclic Graph), it allows you to extend Cruise, share your own plugin and collaborate without too much hassle. Each system of the plugin have his own inteface to safely interact with his dependencies.
-
Optimal system scheduling: Through topological sort, Cruise ensure your systems are executed in the most efficient way.
-
Game logics as first class citizens: Your customs systems have as much power as the core ones
-
Assets Loading and Management: Cruise can load a wide variety of files (Images, sounds and soon meshes) and manage/reuse them during the game lifecycle.
-
Complete and optimized math library
-
JIT compiled: Which means you can dynamically add code to your program while it's running, allowing you to do hot reloading or live coding.
-
Event System: Cruise provides you 2 event system, a lightweight synchronous one that can be use for simple cases, and a complex one leveraging the full powers of reactive programming such as merging, filtering, delays, throttling, etc.
-
Temporary storage: To easily share data among your systems, it also support TTL (Time To Live) for data and provides events and serialization support
-
Multiple clear interfaces: ECS, SceneTree, Rendering , windowing and events. All clear and set for you to overload with bunch of premade implementations available.
-
Make your own structure: Cruise doesn't enforce any architecture, build your game as you feel
-
Build your own engine: Since Cruise is just a minimal core, you can just choose the set of plugins (or build your own) that perfectly match your use case.
These modules are included into Cruise when you add it with the package manager
-
GDMathLib.jl: The mathematics toolbox. It contains game-dev functions (lerp, slerp, etc.), stack-allocated structures for optimized performance, vector and quaternion manipulation, optimized matrix operations, boxes and circles, an extensible coordinate system, colors, and more.
-
EventNotifiers.jl: A reactive module. It allows you to create events with a Godot-like syntax (
@Notifyer MY_EVENT(x::Int)) and manipulate them by modifying their states in an OpenGL-like manner. Features include easy traceability, support for synchronous and asynchronous callbacks, parent–child relationships, state serialization/deserialization, and more. -
AssetCrates.jl: An asset loader and manager. It offers an easy-to-extend interface to load any type of file and manage their lifecycle. Hot reloading is in progress.
-
Outdoors.jl: A backend-agnostic window manager. Based on a microkernel architecture, it offers a clear interface to define window and event management backends. Backends can be obtained via external packages.
-
Horizons.jl: A backend-agnostic rendering engine. Based on command buffers, you just need to define your own commands or use the existing ones and create new actions for them to build your own rendering backend. Backend can be obtained via external packages.
-
Cruise.jl: The package itself offers several tools and utilities, such as a plugin system to add your own plugins and manage their lifecycle in the game loop, a
@gameloopmacro. Provides utilities like temporary storage and more.
Should be added when needed into Cruise. They don't depend on the game lifecycle
-
Arceus.jl: A decision-making system based on
traits and relying on bitboards. It's designed to get the behavior corresponding to a given combination of traits in less than 20 ns (for the slowest backend; the fastest one can reach 2–3 ns), avoiding endless branching. -
ReAnimation.jl: An animation system built with a layered architecture where low-level structures compose into high-level ones (from simple keyframes to multi-track players). This offers tons of interpolations and easing with an easy-to-extend structure, animation frames, async/parallel animation, bindings (to bind a mutable object to an animation), animation players, tracks, and soon blend trees, animation graphs, and more.
-
WavesFlow.jl: An audio engine. It offers audio streaming, effects, audio groups and buses, mixing, and soon spatial audio.
-
NodeTree.jl: Tree manipulation to create
SceneTrees and any parent–child relationship.
-
Interactions.jl: A 2D/3D physics engine. It supports particles, collision detection, forces, contact resolution, integration using a Verlet integrator, constraints, and more.
-
ReactiveECS.jl: A modular and high-performance reactive ECS. It's based on a reactive pipeline where systems register to a given query, and at each tick, the manager dispatches data to the systems. Using a database-like storage system plus partitioning, this ECS can deliver industry-grade performance (even the fastest ECS on some operations) while offering extreme flexibility with system chaining, runtime system injection (even in chains), and
HierarchicalLockfor manual but granular concurrency safety.
using Cruise
using Cruise.ODPlugin, Cruise.HZPlugin
using SDLOutdoors
using SDLHorizons
using AssetCrates
# We create a new app
app = CruiseApp()
merge_plugin!(app, ODPLUGIN)
merge_plugin!(app, HZPLUGIN)
manager = CrateManager() # The resources manager
# Here we are assigning the global resources manager
AssetCrates.getmanager() = manager
# Initialise SDL style window with a SDL renderer
win = CreateWindow(SDLStyle, "Example", 640, 480)
backend = InitBackend(SDLRender, GetStyle(win).window, 640, 480)
# We import our resource as an ImageCrate
img = @crate "docs|example|assets|001.png"::ImageCrate
# Then we define our bindings
@InputMap UP("UP", "W")
@InputMap LEFT("LEFT", "A")
@InputMap DOWN("DOWN", "S")
@InputMap RIGHT("RIGHT", "D")
# We create a new renderable object
texture = Texture(backend, img)
pos = Vec2f(0,0)
@gamelogic pos_update begin
pos.x += IsKeyPressed(instance(win), RIGHT) - IsKeyPressed(instance(win), LEFT)
pos.y += IsKeyPressed(instance(win), DOWN) - IsKeyPressed(instance(win), UP)
end
# Our game loop. It update events and render for us. Once the window will be closed, it will stop.
@gameloop begin
LOOP_VAR = LOOP_VAR_REF[]
DrawTexture2D(backend, texture, Rect2Df(pos...,1,1)
println(LOOP_VAR.delta_seconds) # LOOP_VAR contain the internal data of our loop
endCore Cruise's modules and plugins are self-contained, meaning they use their own interfaces to implement their functionality. This allows any contributor to do the same and stay aligned with the engine's design. Whether you're fixing bugs, writing documentation, or improving performance, you're welcome to contribute.
- Choose the module you want to improve.
- Fork, hack, PR. Simple.
Cruise is released under the MIT License. See LICENSE for details.