What's in
the Engine

A C++ engine with a Python API, a PBR renderer, Bullet physics, HTML/CSS user interfaces, networking, and exports to the desktop, the web, Android and the Wii — plus Studio, the launcher and acronmanager to build and ship with.

Python 3.14 + C++ PBR Rendering Bullet Physics RmlUi Interfaces Desktop · Web · Android · Wii

One Project, Four Kinds of Target

A finished game ships as a program of its own — players install nothing else. A Python game is frozen with build_apps from the engine wheel of each platform; a C++ game is compiled against a prebuilt Acron SDK. acronmanager dist does either.

▣

Windows, macOS, Linux

Engine wheels for 64-bit Windows, macOS 11+ on Apple silicon and 64-bit Linux; one machine can build for all three. Prebuilt desktop C++ SDKs with a CMake package (find_package(Acron)). The engine also builds for Windows on ARM64.

◎

The Web

Export a game as a static site: WebAssembly, WebGL 2 (WebGL 1 as a fallback) and Web Audio. Python games run on a prebuilt CPython web runtime; C++ games use the web SDK and content packs. Host it anywhere that serves files.

▯

Android

arm64-v8a, Android 7.0 (API 24) and later, OpenGL ES 3 and OpenAL Soft. Python games build an app bundle (.aab) and a signed APK; C++ games a signed APK. Full-screen immersive mode, rotation, the Back button, and multi-touch.

◇

Nintendo Wii (homebrew)

C++ games run on the Wii from the Homebrew Channel or in Dolphin: a GX hardware renderer, ASND audio, Wii Remotes with Nunchuk, Classic Controller and IR pointer, GameCube pads, up to four players and rumble. Built with devkitPro.

⬡

App Icons & Store Art

Give the game one picture in [tool.acron.app]; acronmanager assets makes every platform's icons — Android adaptive icons, web icons, desktop icons — and the store art.

⇌

CI for Games

acronmanager ci init writes a GitHub or Gitea Actions workflow that builds every target on each release; ci check keeps it valid and up to date.

PBR, Shaders and Splats

Physically based rendering comes from acron.simplepbr, the engine's PBR pipeline, with the scene graph, shader system and render-to-texture of a mature C++ core underneath.

  • Metal-roughness PBR — normal, emission and occlusion maps; all light types; MSAA; fog; hardware skinning
  • Image-based lighting — acron.hdri turns an HDR or EXR panorama into an environment map, live or pre-converted at build time
  • Tone mapping & grading — filmic tonemapping, exposure, and a colour lookup table
  • Shadows — shadow maps for directional lights and spotlights
  • Custom GLSL — your own shaders, with a GLSL ES path for the web and Android
  • Gaussian splats — render .sog and 3DGS .ply scans with spherical harmonics, anti-aliasing and a native back-to-front sorter (desktop, OpenGL 4.1)
  • Display pipes — OpenGL by default; a Vulkan display pipe ships with the engine as an opt-in
pbr_scene.py
from direct.showbase.ShowBase import ShowBase
from acron.core import DirectionalLight
from acron import hdri, simplepbr

base = ShowBase()
simplepbr.init(
    env_map=hdri.load_env('assets/sky.hdr'),
    use_normal_maps=True,
    msaa_samples=4,
)

# glTF loads directly; its PBR materials come along
sword = base.loader.load_model('assets/sword.glb')
sword.reparent_to(base.render)

sun = DirectionalLight('sun')
sun.set_color((1.0, 0.95, 0.85, 1))
sun.set_shadow_caster(True, 2048, 2048)
sun_np = base.render.attach_new_node(sun)
sun_np.set_hpr(30, -50, 0)
base.render.set_light(sun_np)

base.run()
player.py
from direct.showbase.ShowBase import ShowBase
from acron.world import PhysicsWorld, static_box, layer_bit
from acron.fixed_loop import GameLoop
from acron.character_body import CharacterBody3D
from acron.input_map import InputMap

LEVEL, PLAYER = layer_bit(1), layer_bit(2)

base = ShowBase()
physics = PhysicsWorld()   # a BulletWorld, stepped exactly
inputs = InputMap(base, edges={'jump': ['space']})
loop = GameLoop(physics, base.task_mgr,
                base.task_mgr.globalClock, input_map=inputs)
static_box(physics, base.render, 'floor',
           (30, 30, 0.5), (0, 0, -0.5), mask=LEVEL)

class Player(CharacterBody3D):
    def _physics_process(self, dt):   # 60 Hz
        self.velocity += self.get_gravity() * dt
        if inputs.is_action_just_pressed('jump') \
                and self.is_on_floor():
            self.velocity.z = 5.0
        self.move_and_slide(dt)

player = Player(physics, collide_mask=LEVEL, body_mask=PLAYER)
player.np.reparent_to(base.render)
loop.register(player)
loop.start()
base.run()

Bullet, Plus the Parts Games Need

The Bullet physics engine is built in, with ODE and a lightweight built-in collision system beside it. The acron Python layer adds the game mechanisms that sit on top.

  • Bullet — rigid, soft and kinematic bodies, constraints, vehicles, ray and sweep tests
  • Character movers — CharacterBody3D and CharacterBody2D: collide-and-slide with floor, wall and ceiling state, slopes and floor snapping
  • Fixed-step loop — GameLoop runs game logic at a fixed rate and gives the render-interpolation factor that removes camera jitter
  • World conventions — PhysicsWorld extends Bullet's world with exact stepping, layer bits and hits that resolve back to game objects
  • Spring arm & camera shake — a collision-aware camera boom and trauma-based shake
  • Ragdolls — a fast Verlet ragdoll solver for characters that fall and come to rest
  • ODE & built-in collisions — for simple queries and projects that don't need Bullet

HTML/CSS Interfaces, Any Input

Menus and HUDs are written as documents and style sheets with RmlUi, built into the engine. The same document takes a mouse, a keyboard, a touch screen or a gamepad.

  • RmlUi — RML documents and RCSS styles, data binding, events, and the RmlUi debugger
  • Touch & gamepad navigation — taps click, drags scroll with inertia; a gamepad moves focus and presses buttons
  • On-screen gamepad — TouchGamepad, a themable gamepad on the touch screen that reads like any other device
  • HUD instruments — acron.hud draws what CSS can't: minimaps, compass tapes, dials
  • Input map — named actions over keys and pads, edge detection, rebinding at run time
  • Gamepads — dead zones, trigger normalisation and seat adoption on reconnect
  • DirectGUI & text — the engine's own widget set, with TTF/OTF fonts through FreeType and HarfBuzz
menu.py
from acron.core import load_prc_file_data, InputDevice
load_prc_file_data('', 'framebuffer-stencil true')

from direct.showbase.ShowBase import ShowBase
from acron.rmlui import RmlRegion, RmlInputHandler

base = ShowBase()

# Mouse, keyboard and touch reach RmlUi here
handler = RmlInputHandler()
base.mouseWatcher.attach_new_node(handler)

region = RmlRegion.make('main-ui', base.win)
region.set_input_handler(handler)

# Gamepad navigation is opt-in
pads = base.devices.get_devices(InputDevice.DeviceClass.gamepad)
for pad in pads:
    handler.add_gamepad(pad)

context = region.get_context()
context.load_font_face('fonts/Lato-Regular.ttf')
menu = context.load_document('ui/menu.rml')
menu.show()

base.run()

From Packets to Shared Objects

Three levels to choose from, all part of the engine: reliable UDP sessions with ENet, raw TCP and UDP datagrams, and Distributed Objects for state that is replicated to every interested client.

⇌

ENet

Connections over UDP with reliable or unreliable delivery per packet, several channels, fragmentation and bandwidth throttling. ENet is compiled in; messages are the engine's own datagrams.

⬛

Distributed Objects

Declare networked classes and fields in a .dc file; the repositories create copies on interested clients and route field updates to your methods. Zones, owner views and smoothed movement included.

🔌

Datagrams

A connection manager, readers and writers for TCP streams and UDP, for when you want to design the protocol yourself.

More on Multiplayer

Python, C++, Blueprints

Write the game in Python 3.14, in C++, or both. The launcher sets projects up, acronmanager builds and ships them, and Acron Studio is the IDE.

🐍

Python API

The engine's C++ API is bound for Python 3.14, as the acron package. Your game is ordinary Python: any library you can import is available. Type stubs are published for editors and type checkers.

⚙

C++ SDKs

Prebuilt SDKs for the desktop, the web, Android and the Wii: headers, libraries, a CMake package and a starter game. You never compile the engine itself.

🔀

Blueprints

Visual scripting in Studio: events, typed pins, variables, functions, structs and enums. Graphs compile to readable Python committed to your project — and can be ejected to plain Python at any time.

▤

Acron Studio

The IDE for Acron projects: the Blueprint editor, a script runner that starts the game from the editor, an assistant panel with a coding agent, language-server support, git, a terminal, and CMake and debugger integration for C++.

▶

Launcher

Sign in, create or clone a project, pick the engine version, and open it in Studio or run it. Build, test, distribute, export for the web or Android, and make icons from one project page.

⌘

acronmanager

The project CLI behind the launcher: build, run, test, dist (with --web, --android, --wii), assets, ci and update, driven by pyproject.toml.

acronmanager — terminal
# Convert assets/ (.blend, .gltf, .hdr, ...)
# into .built_assets/, only what changed
$ acronmanager build

# Run it, test it
$ acronmanager run
$ acronmanager test

# Ship it
$ acronmanager dist             # desktop
$ acronmanager dist --web       # dist/<name>-web.zip
$ acronmanager dist --android   # dist/<name>-<version>.apk
$ acronmanager dist --wii       # C++ games

# Icons and store art for every platform
$ acronmanager assets

From the DCC Tool to the Build

Models come in as glTF or straight from Blender, and are converted to the engine's binary format as part of the build.

  • glTF 2.0 & GLB — loaded directly by acron.gltf, with PBR materials, skins, animations and punctual lights
  • blend2bam — Blender scenes to BAM, via glTF
  • BAM & EGG — the engine's binary and text formats; egg2bam, multify archives and the pview viewer
  • HDR environments — panoramas to environment maps with acron.hdri
  • Gaussian splats — SOG v2 bundles and 3DGS .ply files
  • Build streams — acronmanager's converter plugins run on every build and skip unchanged files
  • Textures & audio — PNG, JPEG and more; WAV, OGG Vorbis and others for sound

Characters, Tweens and Sound

Skeletal animation and intervals from the engine, blend spaces and root motion from the acron layer, and 3D sound through OpenAL Soft.

🦴

Skeletal Animation

Animated actors from glTF or BAM, blending between clips, per-part control, and joints exposed for attaching props.

🔀

Blend Spaces & Root Motion

BlendSpace2D, a cross-fading transition state machine, and a root-motion sampler that reads a clip's authored motion per cycle.

✨

Intervals & Keyframes

Lerp intervals, sequences and parallels for scripted motion, and keyframe tracks with cubic-bezier sampling.

🔊

3D Audio

Positional sound with OpenAL Soft, a sound bank with caching and pitch variation, and voice-limited one-shot players.

🎵

Acoustic Zones

acron.audiospace crossfades baked wet and dry stems as the listener moves between zones; acron.dsp synthesises and caches baked audio offline.

❄

Particles

The engine's particle system, plus CPU emitters in the acron layer for 3D effects and pooled 2D particles.

Bring a Godot Game Across

The acron layer grew out of porting shipped Godot games — a third-person shooter, a racing game and a 2D platformer. Ported code stays close to the GDScript it came from: move_and_slide, is_action_just_pressed, signal.emit.

🗂

Godot Format Readers

acron.gdformat reads .tscn and .tres files, res:// paths, materials, tile sets, sprite frames, AnimationPlayer tracks, particle emitters and the input actions of project.godot.

▦

2D Tier

A pixel-space 2D stage, tile maps with exact collision, sprites and animated sprites, areas, a 2D character mover, a camera with limits and smoothing, and parallax layers.

⇄

Conventions Done Once

Y-up to Z-up conversion, Godot transforms, per-instance signals, timers on the fixed step, and Godot's mover defaults — each in one place, with tests.

Profile, Budget, Prove

Game logic in Python, the heavy lifting in C++. The engine's profiler shows where a frame goes, and the acron layer has tools to hold a frame budget and to test games without a window.

  • PStats — the engine's profiler: per-frame CPU and GPU time by collector, including your own
  • Frame governor — caps total framebuffer pixels and trades resolution for frame time
  • Scene-graph tools — flattening, hardware instancing and hierarchical culling
  • Threaded pipeline — app, cull and draw stages can run on separate threads
  • Asynchronous loading — load models in the background without stalling the frame
  • Headless testing — acron.testing drives the real engine offscreen with a fixed clock, compares frames and injects clicks
  • Determinism — integer-hashed noise and a seeded RNG that give the same world on every machine
profiling.py
from acron.core import PStatClient, PStatCollector

# Connect to a running PStats server
PStatClient.connect()

# Time your own code next to the engine's
pathfind = PStatCollector('App:AI:pathfind')

def think(task):
    pathfind.start()
    path = navigator.find_path(start, goal)
    pathfind.stop()
    return task.cont

# Merge a static scene into fewer nodes, once
level.flatten_strong()

Ready to Build?

Create an Acron account, install the launcher, and start a project.