Missing features
An inventory of what Kerosene does not have yet, in four parts: what the code reveals that the docs did not admit, what the docs already admit, what is absent by subsystem, and what the mainstream engines have that is worth borrowing – and what is not. Read it as a candidate roadmap, not a bug list: several of these are deliberate design choices (a flat entity list, a closed shader set) and several are simply unstarted. The last section puts an order on it.
For which of these absences actually matter – and which genres the engine is
shaped to serve – see positioning.md. Everything here is
weighed against that document’s answer: a movement shooter or an immersive
sim first, geometry-heavy and animation-light.
1. What the code says that the docs did not
These were found by reading the tree rather than the README, and each is either a correctness gap or a thing whose absence undercuts a claim made elsewhere in these docs.
The view is not interpolated between ticks.Fixed: the host readsEngine::interpolation_alpha()and takes the view angles from the latest input rather than the last tick.No continuous integration.Fixed:.github/workflows/ci.ymlrunsfmt --check,clippy -D warningsand the tests on Linux, and builds on Windows and macOS.No panic hook, no crash log.Fixed:kerosene_console::install_crash_handlerwritescrash.logbeside the binary with the panic, a backtrace and the last 64 log lines.- No demo recording. The most conspicuous Source feature not here, and
the one the architecture most obviously supports: the tick is fixed, the
simulation runs headless, and input arrives as an
InputStateper tick. Recording those is nearly free and buys replays, ghosts for the time-trial genre, bug reports that reproduce, and a regression harness for the movement solver. The determinism claim inpositioning.mdis unproven until something replays. No game-state serialization at all.Fixed: saved games are JSON throughserde, level changes carry state across, and saves mirror to the store’s cloud. See Saving and level changes.volumeis the only sound convar an options screen could set. There is no separate music or effects volume.Fixed: the tools’ egui host is nowkerosene-uiis not a UI toolkit.kerosene-toolui, andkerosene-uiis the game UI (section 8).- Chisel is a fifth of the codebase in one crate. About twenty-eight
thousand lines now that the GPU viewport has landed in it (as
gpu/); the renderer, the geometry (brush_edit,shapes,faces) and the egui layer would split cleanly.
2. Already acknowledged
These come straight from the README’s known-limits section and are kept here for completeness.
- Networking. The simulation runs headless (the hard part is done), but there is no client/server wire protocol, no snapshot, no prediction, and no replication.
Skeletal animation.Playback exists: Forge imports skinned glTF with its clips, the renderer skins on the GPU, andprop_dynamicplays, switches and crossfades clips. See section 5 for what is not there.- Chisel 3D view.
Software-rasterised.It renders on the GPU now, with props drawn as their models and entity helpers (section 19). Still no lighting or shadow preview: the view is flat-shaded. - Texture block compression.
.ktexis uncompressed; no BCn. The README’s reason – a bad encoder is worse than none – no longer holds:intel_tex_2andtexpressoare pure-Rust BC7 encoders that are good enough. Mipmaps at runtime.Fixed: the whole chain is uploaded.Texture dimensions in the BSP.Fixed: Cleave reads each material’s compiled texture (from the project found next to the map, or--content) and writes its real size, warning by name for any it cannot find. Maps compiled before this carry the old 512 and want a recompile.- Audio. Stereo only. Falloff, panning, occlusion, air absorption and a per-room reverb the compiler measures exist; doppler does not.
3. Rendering and visuals
- Dynamic/real-time lighting and shadows.
light_dynamic(point or spot, switchable, movable) and a flashlight are drawn live on top of the bake, with clustered shading for up to 32 lights and shadow maps for the nearest shadow casters. What is left: no dynamic sun or cascaded shadows (the sun is baked whole), no light cookies or IES profiles, no volumetrics, and the 512² shadow maps are fixed-size rather than a convar. - Post-processing. The scene is HDR (
Rgba16Float) and tone-mapped once per frame (mat_tonemap: ACES by default, Reinhard, or none) with a livemat_exposure. Still no bloom, SSAO, color grading, auto-exposure or motion blur; the HDR target is what each of those needs first. Anti-aliasing.Fixed:r_msaa(4x by default) on the HDR target, resolved before tone-mapping. No TAA or FXAA.- PBR material model. Materials are a small closed set
(
lit/unlit/sky/water/ui). They carry colour, normal, roughness, emissive, occlusion and metalness maps, plus$metalnessand$roughnessfactorscalars, shaded with GGX / Smith / Schlick. What is left: no parallax, no per-material shader customization, and diffuse lighting is still direction-free, so normal maps on the world are lit by a fixed notional direction rather than the real one – radiosity normal mapping in Radiance is the fix. - Level of detail. No LOD for models or geometry.
Decals / projected textures.Mesh decals: cut from the world’s triangles when placed, lit by the lightmap under them and by dynamic lights, frominfodecal, thedecalcommand, scripts and the stock weapons (see Game UI). Not on moving brushes or props, and a section streamed in after a decal was placed does not get it.- Particles / VFX. None. Muzzle flash, sparks, dust.
- Reflections.
env_cubemapprobes, baked by Radiance and reflected by every smooth or metal surface (nearest visible probe, blurred by roughness). No parallax correction, no SSR, no planar reflections. - Dynamic sky / weather / time-of-day. Sky is a static skybox; sun and sky lighting are baked.
GPU instancing.Fixed:prop_staticmodels draw instanced, one call per model mesh however many copies there are. (They were not drawn at all before, and did not collide; now they do both.)Debug labels.Fixed: labelled passes and pipelines, and debug groups around the world, brush models, props and debug lines.
4. Physics and simulation
- Rigid-body dynamics.
kerosene-physicsis the player movement solver plusPhysicsWorld, which wraps Box3D (viabox3d-rust) and is wired into the engine: world brushes become static hulls,detailjoins them, and moving brush entities (doors, shutters) become static bodies that follow their entity’s pose, so a closed door blocks a thrown prop.prop_physicsentities get dynamic box bodies (from their model bounds) whose object properties –mass,friction,elasticity,pickable– decide how heavy, grippy, bouncy and grabbable each one is, and aprop_dynamic_spawnerdrops them on demand (inheriting those properties). The player is in the simulation too, as a kinematic body, so props bounce off them rather than through them, and walking into one shoves it: how far is a contest between a fixedphys_player_push_forceand the prop’s ownmass, so a crate slides and a safe does not. The use key is a pick-up tool: aim at a prop and press use to carry it, press use again to set it down, or attack to throw it atphys_launch_speedplus whatever the player was already doing. A carried prop is steered toward the hold point rather than placed at it – driven by impulses under ceilings on speed, acceleration and turn (phys_hold_speed,phys_hold_accel,phys_hold_spin,phys_hold_spin_accel), braking early enough to arrive rather than overshoot – so it stays an ordinary body in the simulation: it turns to face the player as they turn, shoves what it can move, and hangs back short of the hold point when it meets what it cannot, rather than being driven through it..kmdlmodels render at their simulated pose, andphys_debugdraws the collision boxes. What is not there: convex-hull props (see the callout below – the solver does hulls, props do not use them), joints, per-surface-material friction, a launch-beams gravity gun, turning a prop while carrying it (Source’s use-plus-mouselook), and any sound or effect when a prop hits something. - Ragdoll / skeletal physics. None. Box3D has joints, but no skeleton attachment.
- Vehicles / wheeled physics. None. Box3D has wheel joints, but no vehicle controller.
- Cloth / soft body / fluid simulation. Water is a volume flag, not simulated. Props fall through water rather than floating.
- Projectiles / ballistics. No projectile physics. The stock weapons are hitscan: they trace, mark walls and shove props.
Generalized physics queries.Mostly fixed:Engine::trace,trace_rayandtrace_viewsweep a ray or a box against the world, the moving brushes and every prop’s body, and say which entity they hit (TraceHit::entity). Still missing: overlap and radius queries (“what is within 200 units”), and traces against a turned prop’s real box rather than the world box around it.- Determinism is asserted, not audited.
rayonis on the compile side today, but nothing guards the simulation path against it, or against aHashMapiteration order reaching gameplay. The demo replay in section 1 is the test that would catch it.
5. Animation and characters
Skeletal animation playback.Fixed forprop_dynamic: clips play, loop or hold, and crossfade on change. Still missing: a viewmodel – the weapon in front of the camera, the first thing a shooter needs from this – and animation events (a footstep sound on frame 12).- Animation state machines (the Animator equivalent). None: two-clip crossfades only.
- Morph targets / blend shapes. None.
- Inverse kinematics (foot placement, look-at). None.
- Animation retargeting. None.
- Third-person character. Only a first-person controller, which is otherwise solid: walk/run/jump/air-strafe, duck, swim, ladders, noclip, step-up, health/fall-damage/respawn.
6. AI and navigation
- NPC entities. No
npc_*classes;tools/npcclipexists as a material but nothing is an NPC. - Pathfinding.
NavGraphlinks walkable faces that share a stretch of edge (T-junctions included, which a compiled floor is full of) and A*-searches it for waypoints. The engine loads each map’s.kwalkwith it, andEngine::find_pathandEngine::navare how a game asks. There is still no smoothing into a funnel, no flow fields, and no NPC entity to steer along the result. - Behavior trees / state machines / perception. No AI decision-making and no sight or hearing queries.
- Crowd / group movement. None.
- Dynamic navigation. The static walkmap cannot reflect a door that is currently open or closed.
7. Audio
Occlusion / reverbFixed: Resonance measures every room at compile time and the mixer has a reverb that reads it; walls muffle, and a sound with no way through is silent. Seeaudio.md.- Doppler. A sound moving past you does not bend in pitch.
- 3D spatialization. No HRTF, no surround.
- Audio effects / mixing buses. The mixer is voices into a stereo buffer with one reverb bus. No EQ, compression, ducking, or effects graph – and no volume convars for an options screen to drive.
- Streaming audio. Sounds are decoded whole; no streaming for long ambience or music.
- Footstep/impact effects.
$surfacepropnow parses into aSurfaceProperty, and the engine traces to resolve it and emits stride-timed footstep sounds (footstep/<surface>/n) named off it. Impact effects are still not emitted – neither the player’s own landings nor a physics prop striking a wall makes a sound, though the solver reports every one of those collisions – and no footstep sound files ship, so a game without its own has silent steps (quietly: a game with no footsteps has made a choice). - Procedural audio. None.
8. UI and HUD
In-game HUD / menus.kerosene-ui: XML layouts, CSS styles and Rhai scripts, with bindings to published game state, hot reload, a stock HUD, damage overlay, pause menu with options, and world panels. See Game UI. Still missing: a main menu before any map is loaded, and dialogue boxes.- The attribution screen. The licence exception requires every game to
show “Built with Kerosene” when it starts. The engine should draw that
itself, so a game meets the condition by default and a fork inherits it;
today each game draws it in
Game::ui. Gameplay UI toolkit.See above. What is left: scrolling containers, grid layout, and text shaping beyond kerning (no ligatures or right-to-left scripts).- Localization. No string tables or translation. Cheap now, painful to retrofit.
Runtime text/font renderingfor gameplay: a glyph atlas over ab_glyph, with@font-facefor a game’s own fonts.
9. Input
- Gamepad / joystick support. Keyboard and mouse only.
gilrsis the pure-Rust answer; Steam Input replaces it on Steam and adds glyphs. - Input actions.
bindmaps keys to commands, and a game’s own held+actionsare per-tick state (engine.input.action_held("zoom")); the bindings are onEngine, withkeys_forfor a rebinding screen to show. There is still no layer that lets a gamepad and a keyboard both drive+attack, and no stock rebinding screen. Bindable keys.Fixed: arrows, the numpad, punctuation, the editing keys, mouse 4 and 5, and the wheel (mwheelup,mwheeldown), under Source’s names.- Touch / mobile input. None.
10. Gameplay systems (beyond the FPS sandbox)
- Weapons and combat. A stub exists (
kerosene_game::weapons): three hitscan weapons with ammo, reload, spread and recoil, and a dash on a cooldown. A shot marks walls and shoves props; nothing takes damage, and there are no projectiles, viewmodels or firing sounds. - Damage model. Only player fall damage. No damage types, armor, enemy
health, or hit reactions, and no
OnDamagedoutput on entities. - Inventory / items / pickups. None.
- Objectives / quests / missions. None.
- Dialogue system. None.
Save/load.Fixed:save,load, F5 and F9,logic_autosavecheckpoints. See Saving and level changes.Persistent game flow.Fixed:trigger_changelevelandchangelevelcarry the player’s health and the game’s own state (throughGame::saveandGame::load) into the next map, lined up by aninfo_landmark.- Difficulty / game settings. None.
- Entity classes. The set is enough for the demo level and thin for a
real one. Missing from Source’s glue, roughly in the order a mapper hits
them:
movelinear,tracktrainandpath_track,logic_case,logic_compare,math_remap,filter_activator_nameand_class,env_fade,env_shake,trigger_gravity,point_viewcontrol,env_sprite,game_ui. None of these are hard; each is a class inkerosene-gameand a row in the schema – or in a game’s own crate, since a game registers classes through theGametrait without touching the engine. A game’s class with amodelis drawn and collided with when it says how (ClassDef::model(ModelRole::Physics)); until this audit only the three stockprop_*names were.
11. Content and asset pipeline
- Prefabs / instances. Brushes are authored per map; there is no way to
include one
.kmapin another. This is not a scene-graph feature – Hammer had instances too – and past a handful of maps the brush workflow does not manage without it. - Scene graph. Deliberately a flat entity list (a design choice, listed here for comparison with Unity/Unreal).
- Material editor.
.kmatis hand-written KeyValues; no visual material graph. - Shader graph / custom shaders. The shader set is closed.
- Animation import in Forge. glTF (skins and animations) is in. No FBX, no morph targets, no animated scale, and only a model’s first skin.
- Model LOD generation. None.
- Terrain tooling. Brushes only; no heightmap terrain or terrain editor.
Level streaming / world partition.Sections: a visgroup marked as streamed is loaded and unloaded around the player by potential visibility (seearchitecture.md). Still one.kbspper map, compiled and lit as one; not an open world.- Visibility control for the mapper.
tools/hintandtools/skipsteer Cleave’s splits, but there is noareaportaland no occluder, so a door cannot close off what is behind it. - Runtime asset hot-reload. Game UI reloads by itself (
ui_hotreload), and scripts and sound tables on command (script_reload,snd_restart). Materials, textures, models and the map do not, nothing watches files for the scripts and sounds, and Chisel-to-engine iteration is F9, which is a full restart. Project templates.Fixed:kerosene-tools newmakes a game crate (aGamewith a class of its own, its toolset binary,cargo play,cargo toolsandcargo ship, a project file and a starter map), or with--content-onlya mod. The engine’s base content means either runs before it has any art of its own.- Per-target build settings.
.kprojnames a content tree and a start map, and the window title comes from the game’sLaunchOptions. An icon, default convars and a start map per configuration belong there too, along with named ship targets (Godot’s export presets) for Kiln.kiln --ship --target <triple>builds for another platform, but there are no presets.
12. Networking and multiplayer
- Client/server protocol (acknowledged). No connection, snapshot, RPC, or entity replication.
- Prediction and interpolation. None between machines. On one machine the view is interpolated between ticks (section 1).
- Dedicated-server story.
--headlessexists, but there is no network stack to serve. If the engine goes Steam-first, Steam Datagram Relay is the pragmatic transport rather than a hand-written one.
13. Platform and distribution
- Windows/macOS support. CI compiles the workspace on Windows and macOS, but runs the tests and plays a new game only on Linux. Nobody has yet played one there by hand.
- Mobile / console. None.
- Crash reporting. A panic hook writes
crash.log(section 1); there are no minidumps for native crashes and nothing that phones home.sentrycovers both; Breakpad minidumps beside the log are the no-service option. - Installer / auto-updater. None.
For a game,build-content.shis a shell script.cargo playandcargo shipare the build, and they run anywhere Cargo does. The script only builds this repository’s base content and the base vault.
14. Integrations
-
SteamworksIn, as the opt-insteamfeature (see Steam). It covers:- init and the relaunch through Steam
- the overlay, which pauses the game
- achievements (with progress), stats and leaderboards
- rich presence, DLC checks and the cloud file API
- Workshop items mounted as VFS layers, with
kerosene-tools workshop uploadfor putting a.vaultup
All of it is reachable from entity I/O (
logic_achievement,logic_stat,logic_leaderboard,logic_richpresence,logic_platform), from Rhai (theplatformobject, aliassteam) and from game code.kiln --ship --steaminstalls Valve’s redistributable with an rpath and writes the SteamPipe scripts.Still missing:
- Steam Input
- lobbies and Steam Datagram Relay
- leaderboard downloads
- Workshop browsing in-game
- uploading from Chisel rather than the command line
-
A platform traitkerosene-platform’sBackend: Steam is one implementation and the offline stand-in another, and no game code names either. GOG Galaxy and Epic Online Services are not written. -
Discord rich presence (
discord-rich-presence). Trivial. -
Crash reporting (section 13).
-
itch.io as a Kiln ship target, via butler.
15. Kerosene-specific tooling gaps (editor and compilers)
Chisel:
- 3D lighting preview (acknowledged). Baked lighting is not visible until compile and run.
VisGroups.Fixed: a VisGroups tab with nested user groups and automatic ones, quick-hide, groups, and object colours.Autosave and recovery.Fixed:arena.kmap~every minute, offered back when it is newer than the map.- Recent files. None.
Cordon.Fixed: a box that limits what is shown and what Cleave compiles, sealed by its own walls.Carve.Fixed, along with hollow and a clip tool.- Instances / prefabs (section 11) and a prefab library in the browser.
Entity report.Fixed: filterable, and it marks outputs aimed at nothing.- Check for problems. Leak detection exists, the entity report finds dangling I/O, and “Check for problems” lists every problem in the output panel – broken wires included, by the same check the Outputs tab’s lights make. It does not yet look for a missing texture, and its lines do not lead to what they name.
Undo history panel.Fixed:Edit → History....- Vertex/edge editing.
None.Brushes have it: the select tool’s vertex, edge and face modes, with drag in the flat views, extrude and merge, refusing any edit that would make a brush concave. Meshes still do not: Chisel draws, picks, moves, resizes, duplicates and deletes them, but a mesh is shaped by converting a brush, or by hand in the.kmap. No bevel yet, for either. - Texture painting. No brush-based texture painting or blending.
- Walkmap visualization. The rule-tint view exists, but there is no in-editor preview of the compiled walkmap faces versus what Cleave will actually emit.
Multi-entity editing.Fixed: the Object tab and the properties window edit every selected entity, brush or face together, with a key they disagree on marked and left alone until typed over.- Play-in-editor. F9 launches the engine. Launching it as a child with a socket and syncing the camera back would be most of what Unity’s play button is worth.
- Automated level testing. No way to script or assert level logic in-editor beyond Rhai.
The compilers and Kiln:
- Incremental builds key on mtimes. Kiln now skips every stage’s
current outputs (maps also record whether they were built fast or full),
but by file time, which breaks on CI and after a git checkout; content
hashes do not. A
--watchmode and a build cache follow from having them. - Independent stages run in sequence. Textures, models and sounds do not depend on each other.
- No lint.
kerosene-tools lint: materials naming textures that do not exist, sounds a map fires that.ksnddoes not define, outputs aimed at names no entity has. The editor’s “check for problems” and this should be one function. - No map diff. The formats are text, which is the point; a semantic
.kmapdiff – this brush moved, that output was added – is something no mainstream engine can offer a team using git, and it is a small program.
The engine as a tool:
- No profiler. Nothing is instrumented.
r_speedsreports counts; a frame timeline is what finds the hitch.puffindraws in egui and drops straight into the console overlay;tracy-clientis the other answer. stat-style overlays.r_speedsandphys_statsexist; fps, memory, audio voices and physics bodies should be the same kind of thing.Hosted docs.docs.rs builds the published crate’s. Seven of the ten stable crates now refuse an undocumented public item (section 18).
16. Found in the September 2026 audit
A sweep of the runtime and the tools for what the sections above did not
already list. Nothing in the tree is marked TODO, FIXME or todo!();
these are gaps found by reading.
Fixed in the same pass:
Pausing did not pause.The pause menu, the console and the Steam overlay only showed a layer; the world ran underneath.sv_pause_on_menu(on by default) now stops the ticks, and apausecommand does it whatever is open.No focus handling.Out of focus, the game pauses andsnd_mute_losefocussilences it; minimised, it stops drawing.The window was always called “Kerosene”.The title and desktop app id are the game’s own, fromLaunchOptions.A failed start said nothing.A native error box when the renderer cannot start, and when a windowed game crashes.
The runtime:
Console.History is kept, Tab completes maps, saves, sounds, classes and convars, and there aremaps,revertandhost_writeconfig.config.cfgis still written only on a clean quit unless asked.Debug commands.god,buddha,notarget,give,kill,ent_fire,ent_create,ent_remove,ent_info,setpos,getpos,setang,restartandhost_timescaleare in; see the console. Still nor_wireframe,host_framerate, orent_textdrawn in the world (ent_infoprints to the console).- Video.
Fullscreen,are in. Still no render scale, texture-quality or anisotropy settings, and no UI text scale.-w/-h/-fullscreen, a clampedcl_fov,screenshot - Feel. Ducking snaps the view; no head bob, view roll, landing punch
or step smoothing; crouch-jumping does not tuck the feet; no underwater
tint, fog or muffling; no drowning, though
WaterLevel::Eyesis there to drive it. - Rendering. The worldspawn docs describe fog, and nothing implements it. The sky is one equirectangular texture: no cubemap or 3D skybox.
- Audio. No music system (playlists, crossfades), no
env_soundscape, no subtitles or closed captions, no per-sound priority, and animated props make no sound.Doors and buttonsdo now:noise_move,noise_stopandnoise_locked,door/moveby default. - Movers and entities. A door does not push, stop on or crush a
blocking player and has no
OnBlocked; a player on a moving platform is not carried; noparentname; nodoor_rotating,point_template/env_entity_maker,point_teleport,trigger_look/trigger_proximity,game_textorsky_camera. - Scripting. No traces, spawning, or entity angles and velocity in the
Rhai bindings.
Random numbersare in:rand,rand_range,rand_intandpick, seeded per map. A map that fails to load leaves a blank world.Its reason is on the main menu.
The tools:
- Chisel. Cut, copy and paste work (in the editor, not through the system
clipboard); go-to by id or name and nine camera bookmarks (not saved with
the map) are in. No texture-lock toggle, though
Solid::translate_world_lockedexists; no find and replace. The layout, helper mode, shading and fly speed are remembered now (chisel.layout); the grid is not, and there is no Preferences dialog, keymap file, or light theme. Undo keeps a whole copy of the map per step. - Validation.
Nothing checks that a connection’s input exists on its target’s class.Fixed: every connection has a light, green, yellow or red, with the reason (section 19). There is no sound key type, so sound keys have no picker. - The output panel
cannot be searched, filtered or copiedcan now; its lines still do not lead to what they name. - Other tools. Timbre, Alchemy and Loupe have no undo. Alchemy reads PNG,
JPEG and TGA only: no EXR or HDR for skies. Radiance has no named quality
presets.
No: there is one now.kerosene-tools doctor - The texture stage writes the developer textures into every project’s
art/andmaterials/, although the engine’s base content already has them, because the compilers read tool and sky materials from the project’s own tree. A new game’s.gitignoreleaves them out; the fix is for the compilers to read the base content too.
18. Found in the second September 2026 audit
A second sweep, from the game’s side this time: what a game crate built on
kerosene reaches for and does not find. Struck through is what was fixed
in the same pass; the rest is open.
The game API:
Traces never said what they hit.Engine::trace,trace_rayandtrace_viewreturn aTraceHitwith the entity it hit – a door, a prop – as well as where and which way the surface faced.Only three class names could have a model.Drawing, animating and colliding a model were keyed toprop_static,prop_physicsandprop_dynamic. A class now says so itself:ClassDef::model(ModelRole::Physics).No camera control.view_punch,screen_shake,set_fov_override,set_view_angles, andset_camerawith aCameraOverridefor a cutscene or a death camera. The stock weapons kick.A game could not read its own held actions.+zoomran as a command once a frame;engine.input.action_held("zoom")is per-tick state now.The bindings belonged to the window.They areEngine::input, so a rebinding screen can read and change them, andbindworks headless.Death was always an instant respawn.Game::player_damageddecides how much a hit takes andGame::player_diedcan take the death over, leaving the player dead untilEngine::respawn_player. Maximum health is the game’s to set.Missing lifecycle hooks.frame(every frame, paused or not),player_spawned,can_save,map_unloadingandshutdown.No debug drawing for a game.debug_line,debug_boxanddebug_point, for a number of seconds, underr_debugdraw. Still no text in the world.No seeded random numbers.Engine::rng, seeded by the map and kept in saves;rand,rand_range,rand_intandpickfor scripts. The stock weapons’ spread still has a generator of its own.Spawning took a class name and nothing else.Engine::spawn_entity(class, &[(key, value)])reads keyvalues the way the map loader does, then runs the spawn handler.The walkmap was never loaded.See section 6.- Class handlers are bare
fnpointers. They cannot capture settings or reach the game’s state; everything goes through a string-keyedHostRequest. No touch or damage callbacks on a class.ClassDef::on_touchandon_damage, withEngine::damage_entity. Still no use or collision callback.Triggers only notice the player.Spawnflag 8 adds physics props. An NPC, when there is one, is still to come.- Error types differ by crate.
platformanduireturnResult<_, String>, the engine mixes that withanyhow, the rest use typed errors. Unifying them is a breaking change, so it wants doing before1.0.0.
Rendering:
On the world, an alpha-tested surface is cut out, a translucent one is blended back to front after everything solid, and$alphatest,$translucentand$nocullwere parsed and ignored.$noculldraws both sides. On models the alpha test works, but a translucent model blends where it is drawn, among the solid ones and unsorted, and a two-sided model is still culled. Umbra and Radiance still treat a translucent brush as solid – it blocks visibility and casts a full shadow – unless it isdetail.- No sprites, billboards or beams. Particles need them first.
- No render-to-texture or second camera. Security monitors, mirrors,
scopes and
sky_cameraall wait on it. - No model attachments or hitboxes. No muzzle point, no held item, no headshot.
No brightness or vsync at runtime.mat_gammaandr_vsync, both in the stock options menu and both applied at once.No loading screen.One is drawn for the frame before a load. The load itself still runs on the main thread, so a very long one still holds the window on that picture.
Audio:
Pausing did not pause the sound.A paused game holds every sound in the world where it is; the interface’s clicks play on.- No random variants or pitch in
.ksnd. One file per sound; footsteps get variety by naming (footstep/<surface>/n). - A playing voice cannot be changed. No volume, pitch or fade on a handle, so no crossfade and no door loop that fades out.
- No device choice or hot-plug. The default output always; a device
that goes away needs
snd_restart.
Platform and saves:
Saves and settings went beside the executable.They go to the player’s own directory (~/.local/share/<game>,%APPDATA%\<game>,~/Library/Application Support/<game>), and old saves in the content tree are still found.--portablekeeps them in the content tree.crash.logis still written beside the executable.- No local mods folder or
-gameflag. Workshop items mount; a folder of loose mods does not. - No save migration. A newer save is refused and an older one loads as
it is; nothing lets a game upgrade its own
Game::savedata. No save thumbnails. No save or load menu.The pause menu saves and loads, and the main menu loads.
Entities:
- Missing classes.
are in, withbreakable,wall_toggle,point_hurt,item_*pickups,game_end,player_speedmodpoint_teleport. Still missing:physbox,env_spark,env_explosion, and fog and water controllers. - Thin common inputs.
Kill,AddOutputandFireUser1to4work on everything;SetParentdoes not, andEnable/Disableare each class’s own rather than universal.
The tools:
It clears only a directory it made.cargo xtask bundle --outemptied whatever it was given.It exits 0.cargo xtask helpfailed.The published README’s links were broken.The bundle points them at GitHub.Both fixed; the bump also moves the changelog’s comparison links.scripts/install-desktop.shstopped on a missing icon, andbump-version.sh’s changelog step needed GNU sed.No way to clean.kerosene-tools clean,kiln --clean.Mistakes on the command line were guessed at.An unknown command gets “did you mean”, and Chisel refuses a flag it does not know.A game called Kerosene isnewcould make a game that depends on itself, and made no repository, CI or test.kerosene-game;newrunsgit initand writes a CI workflow,.gitattributes,rust-versionand a test of the pickup class.Four copies of “is this output up to date”.One,kerosene_vfs::up_to_date.“Check for problems” showed one.It lists them all in the output panel.Chisel and Kiln each build the compilers’ arguments.One list,kerosene_vfs::toolchain::MapStages.- No shell completions. The top-level command line is hand-rolled, so clap cannot generate them.
- The generated game has no licence. Choosing one is the author’s, but
newcould ask. No--watch.kiln --watchandplay --watch; the game reloads a rebuilt map undermap_autoreload.
Code health:
The stable crates’ public items were half undocumented.math,physics,script,vfs,game,consoleandplatformare documented and warn on anything new that is not.entity(about 160 items),ui(about 280) andengine(about 150) are not yet, so the lint is off for them.Broken links in the crates’ own docs.Every crate’s rustdoc builds with warnings as errors.- Big files.
engine.rs’s console commands are in their own module now;kerosene-render/src/gpu.rsis still 3,200 lines.
19. The editor overhaul (September 2026)
Chisel was reworked towards Source 2’s Hammer: a GPU 3D view, a layout of toolbar, per-tool options bar, outliner and docked asset browser, hover cards, schema-declared entity helpers, a Hammer-style Outputs/Inputs pair with validation, and vertex/edge/face editing on brushes. See Tools. What doing it turned up:
- Handles move only in the flat views. A corner can be picked in 3D but not dragged there; the move gizmo still moves whole objects.
- No marquee for handles. Corners are picked one click at a time (with shift); dragging a box around several is not there yet.
- No bevel, no edge split, no face split. Extrude and merge are the only operations beyond moving; a face with a new edge across it needs the clip tool.
- Helpers are drawn, not edited. A spot light’s cone cannot be dragged wider, a sound’s sphere cannot be dragged bigger; the keys are typed.
- Models are static in the editor. An animated
prop_dynamicshows its rest pose, and a model’s skin or body group is not previewed. infodecalandpoint_worldpaneldraw an outline, not the decal’s material or the panel’s layout.- The hover card has no material swatch, only the name.
- The software rasteriser is kept for tests and thumbnails. It no longer draws models or helpers, so a toolset without a GPU callback path shows less than one with it.
17. What the mainstream engines have, and whether it matters
positioning.md argues against chasing Unity, and this document agrees.
But some of what they have is small and worth having, and it is worth being
explicit about which is which.
Worth borrowing:
Project templatesand anewcommand: done,kerosene-tools new.- Play-in-editor, in the child-process form above.
- Input action maps with a rebinding screen.
- Localization string tables.
- Build settings per platform, and named export presets.
- Prefabs, as Hammer instances rather than as a scene graph.
- A profiler in the editor.
- Unreal’s
statcommands, as overlays.
Deliberately not:
- A scene graph, a shader graph, a material graph.
- Heightmap terrain.
- Open-world streaming. Sections of one map stream; a world of many maps does not.
- A garbage-collected scripting runtime. Rhai is small on purpose.
- Character tooling: animation state machines, IK, retargeting, until a game in a genre that needs them exists.
Three gaps worth calling out
- The walkmap has a consumer now. The engine loads each map’s
.kwalk,NavGraphlinks its faces (across T-junctions, which it used to miss, leaving a real floor with no links at all) andEngine::find_pathanswers with waypoints;Engine::debug_linecan draw them. What is missing is the NPC that walks them. - The solver already does convex hulls; props do not use them.
PhysicsWorldexposesadd_dynamic_hull, and world brushes anddetailgo in as static hulls, so the hull path is real and running. Butprop_physicsbodies are built from the model’s bounding box (add_dynamic_box_material), so a barrel collides as a crate. Nothing callsadd_dynamic_hull. Closing this is wiring a hull out of.kmdlgeometry, not new physics. $surfacepropis driven at runtime. Traces now report the texinfo they hit, the engine resolves that to a material and its$surfaceprop, and footsteps emit from it. The remaining gap is the other side of the coin – impact effects – and the sound assets themselves, which are content rather than code.
An order
Weighed against positioning.md: the shortest path to a shipped movement
shooter or immersive sim, cheapest first.
Interpolation, MSAA, runtime mipmaps, texdata dimensions.Done.CI.Done:fmt,clippy, the layering check and the tests on Linux, a build on Windows and macOS, and a new game made and played.- Demo record and playback. Proves determinism, becomes the movement solver’s regression fixture, and is the ghost system for genre 3.
A game UI layer and save/load.Done, with a main menu, a loading screen and save and load pages.- Chisel: instances. VisGroups and autosave are in; this is what remains of making the second real map editable.
- Weapons and damage. Hitscan, ammo,
OnDamaged, decals for the holes. Steam, Workshop first.Done, as thesteamfeature.- Impact sounds. The physics sandbox sounding like one; the room it happens in already rings.
Everything after that – animation, NPCs, networking – is in the sections above and is not smaller for being later.