A complete game engine.
Kept compact.

A small, batteries-included C library for 2D and 3D graphics, physics, spatial audio, input and assets. Built for simple, enjoyable development of apps and games - link one library, or start with Lua.

One codebase

Cross-platform. By default.
Fully native. By design.

Made with Natiny, running here

Built as one system

The engine handles the machinery.
You keep the game.

2D and 3D, one API

Primitives, text, sprites and glTF models go through the same calls. 2D piles into one batch until the texture or the material changes.

One shader source

One NSL file becomes Vulkan, D3D12, Metal, OpenGL, GLES or WebGPU at load time - uniform blocks and skinning included.

Instancing, same shader

Mark a material instanced and 500 copies of a mesh cost one draw call per part. render.tag picks what to draw.

Animation in layers

A layer is one clip with a weight and a bone mask. Clips cross-fade while both keep running; the pose is built once a tick.

One transform hierarchy

Models, rigid bodies, cameras and sounds are one entity system. Parent them once; movement stays in sync.

3D physics included

Rigid bodies, mesh colliders, impulses and raycasts, on Box3D. A rendered mesh can become its own collider.

Interfaces that fit the screen

Rows, columns, grids and free layout in a tree of rectangles. One call lays it out, routes the pointer and draws it.

Audio that belongs in the scene

Sources are entities, feeding a third-order ambisonic mix with binaural HRTF output for headphones.

The rest is already there

Windows, input, fonts and asynchronous loading. Assets come off a stack of mounted folders, so a mod replaces a file.

Small surface area

An actual window. An actual frame.
No project ceremony.

main.lua
local natiny = require("natiny")

natiny.backend.init()
local window = natiny.window.create("Hello, Natiny!", 800, 600)

natiny.backend.loop(function()
    natiny.window.bind(window, function()
        natiny.render.clear(0.90, 0.92, 0.96)
        natiny.render.set_color(0.776, 0.871, 0.376, 1)
        natiny.render.clear(0.07, 0.09, 0.13)
        natiny.render.set_color(0.66, 0.76, 0.22, 1)
        natiny.render.circle(400, 300, 80)
    end)
end)
Hello, Natiny!

Use it your way

Native at the boundary.
Lua when iteration matters.

C SDK

Plain C API

Link libnatiny into your executable, or load the shared library beside it, from C, C++, Rust, Zig, Go, or any toolchain that speaks C. The API stays explicit and the engine stays behind it.

Native API reference
Official runtime

Lua wrapper

The same engine through a direct Lua interface. Fast startup, short edit-run cycles, and no second-class scripting layer.

Start with Lua

Natiny 0.14.0

It is early. It already works.
Complete where it matters.

Still growing - see what we are building next.

Download Natiny