Expand description
Kvas gameplay engine: scenes, physics, procedural geometry and hot-reloadable scripts.
§Start here
preludecontains the common script-facing types.scene::Sceneowns registered ECS components and environment settings.runtime::Runtimeruns the same simulation in the editor and the player.script::Scriptdefines gameplay callbacks;script::Ctxaccesses host state.assets::Assetsreads loose project assets or a packed game archive.
§Units and lifecycle
Positions and collider sizes use metres; time uses seconds; components::Transform
stores Euler angles in degrees, in Y-X-Z order. The world is right-handed with
+Y up and local -Z forward. Refresh cached world matrices with
hierarchy::update_globals after editing transforms outside the runtime.
§Native scripts
Host and script libraries must use identical engine sources, dependencies and
compiler. Rebuild scripts after changing the engine. Script callbacks share
host-owned built-in components through Ctx; creating custom ECS storage in
an unloadable library would leave dangling vtables after hot reload.
use kvas_engine::{prelude::*, scene::Scene, runtime::Runtime};
let mut scene = Scene::default();
let cube = scene.spawn("Spinning cube");
scene.world.insert(cube, MeshRenderer::default());
scene.world.insert(cube, Spin { speed: Vec3::new(0.0, 90.0, 0.0) });
let mut runtime = Runtime::new(scene, None);
runtime.tick(1.0 / 60.0);
assert!(runtime.scene.world.get::<Transform>(cube).unwrap().rotation.y > 0.0);Modules§
- animation
- Serializable transform keyframes with quaternion interpolation, scrubbing and runtime playback.
- assets
- Asset access. Everything reads through
Assets, so the editor (loose files) and a shipped game (single .pak) share the exact same loading code. - audio
- Sound: the
AudioSourcecomponent and theAudioBusthat scripts talk to. - canvas
- Immediate-mode game interface for scripts: every frame a script describes what is on screen
(panels, text in any font, images, buttons, sliders, toggles) and the shell paints it over the
game. Clicks and slider changes come back on the next frame, so menus are plain
ifs: - cloth
- Cloth simulation: Verlet particles joined by structural, shear and bend links.
Wind acts on each triangle by its area and orientation, so cloth billows and flaps.
Links snap when stretched past
tear, ground / sphere / box colliders make cloth drape and pile up. - components
- Built-in components. Every one is plain serde data plus an optional
fields()listing for the inspector. - decal
- Projected decals: a box that paints whatever surface lies inside it (any shape of geometry, no UVs needed). The box projects along its local -Y axis, so its +Y should point out of the surface; its X and Z scale give the size, its Y scale the depth it reaches.
- events
- Typed, bounded event queues for gameplay code.
- fx
- Per-scene shadow and post-processing settings. Plain data: the renderer reads them every
frame, scripts change them through
crate::script::Ctx(ctx.post(),ctx.shadows()). - gameplay
- Small built-in gameplay components usable from both the editor and native scripts.
- grass
- Procedural grass. The patch is split into square chunks; each chunk is one merged mesh with its
own bounds, so the renderer frustum-culls whole chunks. Wind animation and distance thinning
happen on the GPU in
builtin:grass; the meshes are built once. - gui
- Serializable screen/world UI components. Native shells paint them and publish button signals.
- guide
- Руководство по Rust API Kvas
- hierarchy
- Parent/child relations and world-space transforms.
- humanoid
- Procedural clips for humanoid rigs that come without animations:
Idle,Walk,Run,Talk,Wave,Sit,Wipe,Look. - ik
- Inverse kinematics on top of a playing clip, for humanoid rigs (
crate::humanoid): - input
- Frame input state, fed by whichever shell hosts the engine (editor or player). Besides raw keys it supports named actions (“Jump”) bound to keys / mouse buttons. Bindings come from the project settings and can be changed from scripts at run time.
- interaction
- Puzzle building blocks that need no code:
Switch(button, lever, pressure plate) andSlider(door, lift, gate). They talk through a sharedchannelname: a slider opens while any switch on its channel is active. Scripts press buttons withpress(). - material_
graph - Node-based materials. A material is a graph of small nodes (textures, colours, maths, noise,
gradients…) saved as a
.kmatfile;to_wgslturns it into a fragment shader that the renderer compiles like any other custom shader. Drop a.kmatfile on a model to use it. - material_
nodes - The second half of the node library: shader-graph outputs, vector / maths / colour / procedural
nodes, camera-effect nodes and the node help texts. See
crate::material_graph. - material_
nodes_ ext - The third part of the node library: light inputs, geometry masks, normal tools, advanced noises,
patterns, a colour ramp, blend modes and extra maths. See
crate::material_graph. - material_
nodes_ v4 - The fourth part of the node library: general “Math” / “Vector math” nodes with an operation
selector, Blender-style texture generators with several outputs, an image texture with its
own file, curves, mapping and colour tools. It also holds the table of extra outputs that any
node may have and the conversions a linked input can apply. See
crate::material_graph. - material_
presets - Built-in procedural materials. Every preset is an ordinary node graph (open it in the node editor
and change anything). The editor installs them into
assets/materials/library/of every project. - material_
presets_ v4 - Game-ready materials built only from general nodes (texture coordinates, noise, Voronoi,
bricks, maths, ramps, mixing and bump), so every step can be opened and changed in the node
editor. They go to the
Game Readyfolder of the material library; marble is built here too. - materials
- PBR material sets: finds the maps that belong to a model or texture by file name, and builds the texture keys the renderer understands.
- math
- Small scalar helpers for gameplay scripts: interpolation, smoothing and angles.
- mesh
- CPU-side mesh data: procedural primitives and OBJ / glTF importers.
- mesh_
deform - Vertex access and deformation for
EditableMesh: the building blocks for procedural animation, destruction, terrain tools and “squash and stretch” effects from scripts. - mesh_
edit - Editable static geometry, persisted in scenes and uploaded as versioned DynamicMesh data.
- mesh_uv
- UV unwrapping and normal smoothing for
EditableMesh: projections, UV transforms, flat shading and crease-angle smoothing. All methods work on local-space geometry and mark the mesh as changed. - meshmod
- Mesh modifiers: a Blender-style stack that reshapes an object’s mesh without touching the
source model. Add
MeshModifiersto an object with aShapeor a model and stack modifiers (Array, Mirror, Subdivide, Displace, Twist, Bend, Taper, Solidify) in any order. - modifiers
- Built-in behaviours you attach in the editor with no code. They run every frame in Play mode. (Spin, Bob, Pulse, Wobble, ColorCycle.) Scripts can add, remove and tweak them like any component.
- neural
- Small CPU supervised networks with portable JSON weights and a planar steering component. This is imitation/regression training, not reinforcement learning, navigation or NVIDIA inference.
- noise
- Procedural noise for scripts, shaders-on-the-CPU and generated textures.
- paint
- Texture painting: blend several surface textures with a painted mask, so dirt can be brushed along a road edge and fade into grass without a hard seam.
- params
- Typed script variables. Declare them once with
script_params!: they get defaults, show up as Inspector fields on the attached script, are saved in the scene and can be read or changed by other scripts (Ctx::var/Ctx::set_var). - particles
- Particle emitters: fire, smoke, sparks, rain, snow, magic dust.
- physics
- Rapier integration. ECS components are the source of truth: bodies, colliders and joints are created from them (also for entities spawned later), and dynamic results are written back.
- prelude
- Everything a script author needs.
- procedural
- Systems that build or simulate procedural geometry (cloth, voxel smoke and clouds, grass).
They write a
DynamicMeshthat the renderer uploads. - project
- Project layout on disk: project.json – name and start scene assets/ – scenes, models, textures, shaders (packed into game.pak on build) scripts/ – a Cargo crate (cdylib) with the game’s Rust scripts
- ragdoll
- Ragdolls for humanoid rigs: when
Ragdoll::activeturns on, the character’s body is rebuilt from physics capsules (pelvis, chest, head, upper arms, forearms, thighs, shins) joined by ball joints, starting exactly in the pose the clip was in and moving with the velocity it is given. The skeleton then follows the bodies every frame (hands and feet ride on their forearms and shins); turning it off removes the bodies and the clip takes over again. - random
- A tiny deterministic random generator for scripts (xorshift64*), so gameplay does not need
an external crate. Keep one
Rngin your script struct for a repeatable stream. - reflect
- Tiny reflection layer. A component (or script) lists its editable fields as
Fields; the editor draws them and the scene/script layer converts them to and from JSON. One mechanism, no per-type UI or serialization code. - registry
- Type-erased component table. The editor and scene loader work through this and
never name a concrete component, so adding a component = one
info::<T>()line. - runtime
- The game loop shared by the editor’s Play mode and the standalone player.
- scene
- Scene = ECS world + environment settings, saved as readable JSON.
- script
- Rust scripting. Scripts are ordinary Rust types compiled into a dynamic library next to the
project and hot-reloaded by the host. Host and library must be built by the same toolchain
from the same engine sources;
AbiInfois checked on load to catch a mismatch early. - script_
game - Game-wide services on
Ctx: the screen interface, saves and settings, files, cameras and asking the host to quit. - signals
- Bounded next-frame messages shared by native gameplay scripts.
- skeletal
- Skeletal animation: skinned models with bones and clips, played by the
Animatorcomponent. - sky
- Procedural atmosphere: time of day drives the sun/moon direction, light colour and ambient. The renderer draws the sky itself from the same settings, so light and sky always agree.
- spatial
- GPU-independent rays, axis-aligned bounds and conservative frustum queries.
- storage
- Files of a game on the player’s computer: save slots, persistent settings and a small file
system API. Everything lives under the game’s data folder (set by the host:
%APPDATA%/<game>for a built game,<project>/.kvas/datawhile playing in the editor), so a script cannot touch other files by accident.externalreads and writes anywhere, on purpose. - timer
- Deterministic gameplay timers driven explicitly by simulation deltas.
- tree
- Procedural trees. A
Treegrows a trunk with branches (tapered tubes) and clusters of leaf cards at the twigs. Bark and leaves are twoTransientchild meshes drawn with the built-inbuiltin:barkandbuiltin:foliageshaders: leaves are cut out in the shader and sway in the wind on the GPU, so the meshes are built only when a parameter changes. - tween
- Easing curves and script-free local-position animation.
- voxel
- Voxel effects built on one fast mesher: smoke that rises and swirls, and drifting clouds.
- water
- Voxel water: an animated water surface built from wave functions, drawn either as stacked voxel columns (blocky, Minecraft-like) or as a smooth semi-realistic sheet.
Macros§
- choice_
enum - Declares a serde enum that can be picked from a dropdown.
- fields
- Lists the Inspector fields of a hand-written script in one line.
Every listed field must implement
Param(numbers,bool,Vec3,String,Color, asset and entity references, enums withChoice, andLocalto hide a variable). - register_
scripts - Exports the scripts of a library crate:
register_scripts!(Spinner, Player); - script
- Declares a whole script in one block: the variables with their defaults (shown in the Inspector
and saved in the scene) and the callbacks. No
Default, nofields(), no boilerplate. - script_
params - Declares a script struct with typed, defaulted variables. Generates
Defaultandparams(), which a script returns fromfields():