Repository navigation
Releases: shadow-kernel/Vortex-Engine
Release list
Vortex Engine v3.4.17 — Claude play-tests your game, enemies fight back
Vortex Engine v3.4.17 — Claude play-tests your game, enemies fight back
Play-testing with Claude
- Claude presses the keys. The new
send_inputtool feeds keys, mouse buttons, mouse movement, the wheel and a UI cursor into your game during editor play, through the engine's own input layer. Your real cursor stays put, and it works while the editor is in the background. Claude can walk, aim, fire and click through a mission beat and check the result. (#457) - Claude reads and sets live game state.
get_script_state/set_script_stateread and write a running behaviour's fields, or a script class's statics such as the current mission beat or the player's credits. Writes are live only; Stop takes them back. (#457) read_console(since_id)returns only the lines that are new since the last call. (#457)- Player input scripts gain
scrollandcursor. Scripted Space, Return, Tab, arrow keys and left clicks now also reach game menus.
Saves you can test with
- Play-mode saves stay out of the shipped game's saves. New projects keep editor play-test slots in a sandbox the exported game never reads. Switch it under Project Settings ▸ General ▸ Play testing ▸ Saves; existing projects keep sharing the game's files until you switch. (#458)
- New
Save.Reload()andSave.Keys(). (#458) - Claude can seed a test state, for example "act 4, rank 3, 5,000 credits", with
get_save,set_save,reset_save,snapshot_saveandrestore_save. Every overwrite or delete keeps an automatic backup first. (#458) - Fixed: save values containing a backslash, such as Windows paths, came back mangled.
Navigation
- Large levels bake every tile. Navmesh tiles no longer lose their polygon budget as a level grows. A 1.5 km × 16 km valley used to drop 165 tiles; it now bakes completely, with up to 262,144 tiles per bake. (#517)
- Clear messages when a tile is too dense. They name the real remedies (a smaller Tile Size, a larger Max Edge Error, more Verts Per Polygon), and the bake lists every failed tile with its position. (#517)
.vnavfiles are version 2. Version 1 navmeshes still load, and they give the same paths as before. A corrupt navmesh file is refused instead of crashing the editor.
Templates: enemies fight back
- Enemies hurt you. Bot shots, zombie bites and the horror monster's catch now reach the player's health. Bots hit with both character controllers, and cover stops their shots. When your health runs out, "YOU DIED" fades in and you respawn at the start with full health and med-kits.
- The Range's bots hold their yard. They fight in an arena over the yard. The booths and the feature-tour stations stay quiet, and walking into the yard starts the fight. Shoot one from outside and the squad fires back for 8 seconds.
- Bots and the monster react mid-patrol instead of finishing their patrol leg first.
- H uses a med-kit and F1 shows the feature-tour help in every template. The HUD shows how many med-kits you carry.
- The TacticalShooter pause menu closes cleanly again.
Behaviour changes
- Player
--inputlooks turn 2–7 % less than before: a one-frame overshoot is gone.
Vortex Engine v3.4.16 — Characters and rays you can trust
Vortex Engine v3.4.16 — Characters and rays you can trust
Seven physics bugs reported by @patii132, which were the last open bugs he reported. Also fixed: loaded entities that all shared one engine id, and the template bots' blind spot.
Characters
- A character no longer collides with itself.
Physics.MoveCharacterignores the colliders of the moving entity and its children, so a guard with a solid hitbox stays on the floor and gets noOnCollisionEnteragainst itself. This works with both controllers.Physics.CanStandexcludes them too. (#417) - Characters leave when their entity does. Destroying, deactivating or ragdolling an entity removes its character capsule, including its Jolt character. The new
Physics.RemoveCharacter(id)does it by hand, and a laterMoveCharacterwith that id brings the capsule back. A Nav Agent whose body goes limp leaves the crowd, refusesSetDestinationandWarpwhile limp, and rejoins where it went down. (#407) - Inactive colliders take no part. A level part saved inactive, or anything under an inactive parent, no longer blocks characters, and switching it on adds it once. (#443)
- Ramps are ramps. Pitched and rolled box colliders keep their full rotation in the character world. A 10–30° ramp is walked up instead of acting as a wall at its foot or a ghost slab you walk under. (#498)
- A MeshCollider's own mesh collides. A MeshCollider that names its own collision mesh now blocks characters and managed raycasts, like its Jolt body and the navmesh already did. A collider that yields no shape says so once. (#500)
Rays and queries
- One rule on both physics paths.
- A ray that starts inside a convex collider passes it. A ray that starts exactly on a surface hits it.
- Meshes are hit from either side, and the hit normal faces the ray's origin.
- A surface exactly at the maximum distance counts.
- The managed and Jolt paths now give the same answers. (#418)
Physics.Raycast(…, ignoreEntity)skips the whole entity: its colliders, its ragdoll parts and its character capsule. An AI's line of sight no longer stops at its own collider. (#406)- Jolt character capsules report their entity, so a shot that hits a player moved by the "jolt" controller names the Player. (#406)
- New
Physics.OverlapPoint(point)returns the entities whose colliders contain a point. It works with and without Jolt. A point counts as inside a mesh only when the mesh closes around it, so an open roof or a cave shell contains nothing.
Entities
- Every loaded entity has its own engine id. Entities loaded from a scene file, and their duplicates, pastes and prefab instances, all used to share engine entity 0. Their transforms went to it, and deactivating one of them removed it from under the others.
- Delete, undo and closing a project take an entity's engine twin with them, and undo brings it back.
- A scene that isn't open stays out of the engine. Applying a prefab whose instances also live in a scene you never opened no longer activates that scene or applies its fog and exposure to your viewport.
Foliage.Find()returns an entity handle likeScene.Find. It used to return 0, meaning "none", for every foliage layer loaded with its scene.
Templates
- Template bots see the player. Their eye ray no longer stops at their own capsule, so they engage, take cover and shoot in the Range scenes. Their muzzle rays leave impacts and decals on walls. Their shots don't hurt the player yet: the player's health sits on its own entity. The next update moves it onto the Player.
- Mantling checks the whole standing capsule on top of a ledge and never climbs into a wall taller than a ledge.
Who owns a character
A characterId names an entity when it is the calling code's own EntityId. That code can be a behaviour, a behaviour-tree task, an entity's area handlers or its UI actions. The new overload Physics.MoveCharacter(feet, radius, height, move, characterId, ownerEntity) names the owner directly, for a manager script that moves several NPCs. A capsule keeps its owner when other code moves it later. Custom ids that belong to no entity stay anonymous.
Behaviour changes for script authors
- A manager script that moves NPCs by their ids should name the owner with the new overload. Otherwise an NPC whose own code never moved it is blocked by its own colliders.
- A ray that points away from a surface it starts on reports no hit.
Vortex Engine v3.4.15 — Every script runs, Stop leaves no trace
Vortex Engine v3.4.15 — Every script runs, Stop leaves no trace
Twenty-six bugs reported by @patii132 and two found on the way. They cover scripting, play mode, the Claude tools, audio, navigation, asset import and rendering.
Scripting
- Every script on an entity runs. Only the first Script component of an entity used to run; the rest were skipped without a word. Each one now gets its own behaviour, fields and lifecycle, and every callback reaches all of them. Disabled Script components stay off. Play start lists entities that run several scripts and warns about duplicates. (#408)
- Save reads the disk every session. A save file changed between play sessions is read again, and a new session never writes the last one's leftovers. (#452)
- UI units.
UI.Width,UI.Height,UI.MouseXandUI.MouseYare points in the editor and in the player. The newUI.Scalegives the pixels per point. All of them are valid inStart(). (#454) - NaN guard. A NaN or infinity written to a Transform or passed to
MoveCharacteris refused with a capped warning instead of reaching native code. (#455)
Play mode
- Stop leaves no trace. Stop now gives back exactly the scenes you had before Play, whatever changed them: the Claude tools, the Inspector, the hierarchy or scripts. (#423, #478, #479)
- Entities created, duplicated, placed or scattered while playing are removed. Re-parented entities return to their old place, in every loaded scene.
- Script field values and environment settings changed in play come back.
- Data files that play created for removed entities are deleted.
- Prefabs saved in play re-sync their instances.
- Undo and redo are the ones you had before Play.
- One Console line says what Stop did.
- No pause menu left behind. Gui screens and cached canvases are cleared when play stops and when a project closes, so one template's menu no longer overlays another game. (#477)
Application.Quit()in the editor stops play after the frame. Bone attachments no longer write their play pose into the edit scene. (#410)
Claude and MCP tools
- Scripts in subfolders. Every script tool finds a bare script name in any subfolder of
Assets/Scripts. An ambiguous name is refused with every candidate listed, and a misspelt one gets suggestions. (#456, #494) - Script fields.
get_entityshows a script's field values and which ones are overridden.set_component_propertiessets them, and in play the value reaches the running script, also while paused. (#405) - Honest results in play. Every change made while playing or paused says
runtime_only: true when Stop takes it back, false with the reason when it can't. The result keeps its edit-mode shape. Play-mode hints go intoplay_note. - project.vortex keeps your keys. A save merges into the file at the JSON level. The version, creation time,
$schemaand every key the editor doesn't know survive, and so do edits made to the file meanwhile. (#414) - The capture shows the right camera.
focus_cameraandcapture_viewport(focus)switch to the editor camera, and the capture names the camera that rendered. (#444) get_scripting_apiprints the doc summary of each API.
Audio and navigation
- One-shots reverberate. A 3D
Audio.PlayOneShotinside a Reverb Zone gets the zone's reverb, like an Audio Source. 2D one-shots stay dry, and both have areverbMixoverload. (#496) - Reverb Zones follow the hierarchy. A zone counts only while it is active in the hierarchy. Box zones turn and scale with their entity, and the gizmo shows the same shape. (#497)
- Audio Sources and Listeners follow the hierarchy too. A source under a deactivated parent is silent. The ears follow the first Audio Listener that is active, so switching camera rigs moves the listener with them.
- Fade in from silence. "Start at Volume 0, then fade in" now reaches its target. Other fades still multiply Volume, and a fade that can't be heard warns once. (#404)
- Stability AI works on macOS. Sound Studio's Stable Audio backends connect over TLS 1.3. The API key never appears on a command line. (#403)
- Tall levels keep their navmesh. Levels taller than 819 m bake completely, and the bake reports anything it cannot keep. (#451)
Asset import
- glTF alpha modes. MASK imports as a cut-out at the glTF cutoff and BLEND as alpha blend. A BLEND material that is fully opaque in practice imports opaque, so it keeps its shadows.
doubleSidedapplies to cut-outs and blended materials. (#441) - Colour-only materials stay colour-only. A glTF material without a colour map no longer picks up one of the model's images, which was often its normal map. (#453)
- KHR_texture_transform. Offset, rotation and scale are applied as the glTF spec defines them, so Sketchfab scans and tiled textures line up. (#470)
- Emission is imported. The glTF emissive colour and
KHR_materials_emissive_strengthreach the material, so a placed glTF glows. (#450) - Animation clips reload.
.vanimclips and skeletons reload when their file changes, and a missing clip is looked for again. (#419)
Rendering
- Up to six times more animated characters. All submeshes of a character share one bone palette per frame, so a character made of six meshes uses a sixth of the budget it used before. Over budget, visible and near characters keep their animation first, and the first-person arms always do. New script stats:
Rendering.BoneMatricesUsed,BoneMatricesCapacityandSkinnedBindPoseFallbacks. (#415) - Lights no longer pop. With more than 16 point or 8 spot lights in a scene, the ones that matter most are picked, and a light already chosen gets a keep bonus. A light the budget swaps out fades over half a second. A shadow map changes hands only after its old shadow has faded. A camera cut picks the new set at once.
engine_statsreports the bone and light budgets. (#416) - Two-sided back faces. The back of a two-sided material is lit on its own side, so glTF
doubleSidedcards, fences and cloth seen from behind are no longer lit inside out.
Behaviour changes for existing projects
- Scripts that were silently skipped now run, for example the Open World player's footprints, which now fade after 60 s. Disabled Script components stop running.
- The standalone player starts scripts in its first frame, so the window size is known in
Start(). - Undo after Stop no longer replays steps recorded while playing.
attach_scriptwhile paused starts the behaviour when play resumes.- FBX and OBJ models with colour-only materials that picked up an
*_albedoimage lying next to them now show their material colours. - Models re-import once (import cache version 5). Sidecar
.vmatfiles written by older imports keep their values until re-imported.
New smoke checks guard these fixes on Metal and on DirectX 12 in CI:
two-sided back faces,light budget,bone palette budgetandmcp play mode leaves no trace;audio play,sound studioandnavigation;- five glTF import checks.
Vortex Engine v3.4.14 — Glowing lit materials, sharper terrain
Vortex Engine v3.4.14 — Glowing lit materials, sharper terrain
Four rendering bugs reported by @patii132, and two more found on the way.
- Lit materials glow. A StandardPBR material with an Emissive colour and strength now glows on top of its shading: lit windows, neon, screens and lamp globes keep their highlights, fade into fog and feed the bloom. An emissive map multiplies the glow per texel. Metal, Vulkan and DirectX 12. Unlit materials keep glowing with their base colour × strength, and the Material Editor and the
set_material_propertiestool now say so. - The UV offset works. A material's Texture offset was saved but never applied. Every map now samples
uv × tiling + offset, live from the Material Editor, so one texture can serve as an atlas or be cut into strips. - Reflections turn with the sky. A sky set with
Sky.SetTexture(path, exposure, rotationDeg)turned the skybox but not its reflection. Metal, wet sand and lakes now mirror the sky you see, and a sky spun from a script needs no re-bake. - Sharper terrain layers. Layer maps larger than the terrain atlas are now area-filtered instead of sampled once per texel, so 4K ground textures no longer sparkle. The Open World sand is one of them. The new Layer Resolution setting (Auto, 512, 1024, 2048) chooses the atlas per terrain, and the console names every map it shrinks or enlarges a lot.
- DirectX 12 water shader fixed. It used a sampler it never declared, so the shader compiler rejected it.
- No crash without shadow maps. With
VORTEX_NO_SHADOWS=1, or on a device that cannot create shadow maps, the first frame crashed.
Three new smoke checks (lit emission, uv offset, sky reflection rotation) read the rendered picture on Metal and on DirectX 12 in CI.
Vortex Engine v3.4.13 — Clean edges with TAA
Vortex Engine v3.4.13 — Clean edges with TAA
Temporal anti-aliasing now does what its name says. Until now it only steadied the picture; edges still stair-stepped.
- Sub-pixel jitter: with Temporal AA on, the scene is drawn up to half a pixel off its centre, a new offset every frame over a cycle of eight. The resolve gathers those samples, so edges, thin palm fronds, lianas and grass blades come out smooth.
- A still camera stays crisp. This frame's colour is rebuilt at the pixel centre from its neighbours, weighted by where each sample really sits. The history is never resampled while nothing moves.
- Particles and decals follow the same offset, so they stay glued to the surfaces they sit on.
- Metal and Vulkan. DirectX 12 has no TAA pass yet and keeps FXAA.
VORTEX_NO_TAA_JITTER=1restores the previous TAA for comparisons.
Vortex Engine v3.4.12 — An overgrown cave with a shaft of light
Vortex Engine v3.4.12 — An overgrown cave with a shaft of light
The Open World cave, reworked after the first look: you see it from the oasis, it is overgrown, and its light has a mood.
- The cave sits at the foot of the escarpment, facing the oasis. Its rock arch opens at ground level, and a curtain of lianas hangs over it. Before, the entrance was hidden behind the hill's shoulder.
- Overgrown: ferns, grass and shrubs around the arch and on the cave floor near the mouth.
- A shaft of sunlight falls through the chamber's ceiling onto a fern garden, with drifting dust and a warm haze in the beam.
- A campfire burns at the far end with a flickering light (
FireFlicker.cs), and two patches of glowing moss light the dark stretches. - Plant inside caves: painted foliage lands on a mesh's real surface, not its box. The brush plants a cave's floor, a rock's top or the ground under an arch.
paint_foliagehasfrom_yto paint below a height. - Dark caves on Windows too: the world lighting cache now runs on DX12. Caves and hollows go dark there as on the Mac, and the sky no longer lights them through the rock.
- No checker pattern from the screen-space bounce anymore. Its rotations follow a 4×4 pattern that the blur averages exactly.
tools/cave-gen.pygenerates a shaft of light (--skylight), keeps the floor level into a wide mouth and closes the tunnel with a rock wall.VORTEX_GI_LOG=1prints what the world lighting cache does.
To bring the reworked cave into an existing Open World project, right-click the project in the Project Hub and choose Update from Template…. The cave and its lights are placed in the scene, so tick Scenes (replace existing). That replaces your copy of the scene; the dialog backs the project up first and lists every file before anything changes.
Vortex Engine v3.4.11 — Caves
Vortex Engine v3.4.11 — Caves
Caves you can walk into, under the terrain, with zones that know you are inside. The Open World template has one in the escarpment north of the oasis.
- A Mesh Collider on a model works. Put it on the model you placed (its root) and it collides with all the model's parts. An imported model keeps its meshes on child entities, so a collider on the root used to have no mesh, and you fell through the cave floor.
- Terrain skirts no longer cut through tunnels. The skirts that hide gaps between terrain detail levels hung down by a chunk's whole height range, 30 m and more under a hill. They showed as striped walls inside caves. Now they are only as deep as a real gap needs, and there is none next to a hole.
- Caves get dark inside. The world lighting cache treats a model with a non-convex Mesh Collider as a space you can walk into: its inside stays open and its walls block light. Imported models now block light at their real size; they were 1 m cubes in the cache before. Surfaces read only the probes on their open side, so a cave wall no longer picks up the sky above the hill.
- Deep in a cave it is dark. The screen-space bounce and the sky reflection now fade where the world cache sees no sky. The bounce used to light cave walls through the rock, as a checker pattern. In the open nothing changes.
- Shadows under the palms are complete. The sun's shadow cascades skip casters smaller than two shadow texels. Pebbles and grass used to fill the shared shadow budget, and up to 9,000 casters per frame were dropped, whole trees among them.
tools/cave-gen.pygenerates cave tunnels: winding, with chambers, a flat floor with its own material, and a rock shell around the mouth that hides the terrain hole's edge.--pointswrites the tunnel's path for placing it and fitting Areas.- Open World template: a 48 m cave with a rock arch, ferns and lianas at the mouth, and three Areas linked to
Assets/Areas/Cave.varea(tags cave, no-fly, dark;flightAllowed=false). create_areaandset_areaapply a linked.vareafile's values right away.
Vortex Engine v3.4.10 — Fire while aiming
Vortex Engine v3.4.10 — Fire while aiming
A patch for one input bug.
- A mouse button pressed while another one is held reaches the game now. In editor play, holding the right button (aim) and clicking the left one (fire) never set
LButton, so you could not shoot while aiming. A button released while another one stayed held also stayed down. The toolkit reports a second button as a pointer move, not a press, and the viewport ignored that. The viewport now routes those button changes like a normal press or release. - The exported game was not affected: it reads the mouse buttons straight from the operating system.
- A new smoke check holds the right button and presses and releases the left one, through the real event path on macOS and Windows.
Vortex Engine v3.4.9 — Areas (zones) and terrain holes
Vortex Engine v3.4.9 — Areas (zones)
Regions of the world with tags, properties and events — a cave, a no-fly zone, a village, a safe zone — as big as a level, nothing hard-coded.
- Area component: a box, a sphere or a vertical cylinder around its entity, moved, turned and scaled like any other (Create ▸ Area (Zone), Add Component ▸ World ▸ Area,
create_area). Tags ("cave", "no-fly") and free properties ("flightAllowed=false", "ambient=cave_drips") carry the meaning; the engine only tracks who is inside, every tick. - Events: every behaviour of an entity that enters, stays in or leaves an area gets
OnAreaEnter(AreaInfo),OnAreaStay(AreaInfo, dt)andOnAreaExit(AreaInfo); a manager subscribes toAreas.Entered/Areas.Exited.AreaInfohas the name, the tags,HasTag,Get/GetBool/GetFloatfor the properties, the priority and the position. - Queries:
Areas.IsInside(id, "cave"),Areas.Of(id)(highest priority first),Areas.Current(id),Areas.At(point),Areas.IsPointInside(point, tag),Areas.Find(nameOrTag),Areas.Track(id)for entities without scripts. .vareafiles: a reusable definition (shape, size, tags, properties, colour, priority) in plain JSON. The inspector's Save as… writes one intoAssets/Areasand links it; Load reads a linked file; many areas can share one. Tools:set_area,list_areas,areas_at,save_area_file.- The viewport draws every area's outline in its colour, the selected one bright; Draw in game shows it in play mode too.
- The Open World template ships a "Grove" box (tags grove, no-fly; flightAllowed=false) over the jungle corner, a "Lake dome" sphere,
Assets/Areas/Grove.vareaandZoneManager.cs, which logs every entry and exit and shows where a no-fly rule goes. - Holes in the terrain (the first half of caves): the Terrain Editor's new Hole tool (Sculpt tab; Shift fills a hole back) cuts the cells under the brush out of the terrain — the mesh at every LOD, the collision and the navmesh leave them out, the height query and the terrain raycast look through them, so a cave mesh placed under the terrain becomes the ground there. Saved in the
.vterrain(a flag bit, one byte per sample; older editors ignore it).sculpt_terraintakesop: "hole"and"fill".
Vortex Engine v3.4.8 — The standalone game plays again
Vortex Engine v3.4.8 — The standalone game plays again
Three bugs a standalone run of the Open World game ran into, and one in every project save.
- The pause menu stayed on the picture. ESC did close the menu, but the screen that shows it was only ticked while the menu was open — so after the close nothing hid the PAUSED overlay; it swallowed every click while the mouse was captured again underneath it. The menu's tick runs every frame now (template scripts; a project made from an older template gets the fix with a template update).
- The window jumped to twice its size on the first ESC. The menu applied the default 1920 × 1080 the first time it opened, although nobody had changed the resolution; and on macOS the host took those pixels as points, so a Retina display got a 3840 × 2160 px window. The applied values start from the current settings, and
set_resolutiondivides by the pixel density and clamps to the display. - The exported game was white. A shipped game imports its models from the in-memory asset pak, and a model's own textures — a glTF's images, as in the Open World's generated palms, ferns, lianas and bark — were loaded by path from the disk, where a shipped game has nothing: every one of them came up white and the whole oasis looked bleached. The native texture importer now asks the managed layer for any file the disk does not have, and the pak answers. Verified: an export of the Open World template, run with the player's input script, shows the textured grove again.
- The sky's underside at height. Flying high, the far dunes end at two kilometres and the picture's blurred ground showed through as a blue sea below the horizon. Below the horizon the sky is the haze now (which follows the sky's own horizon colour), blended in over the first few degrees — an endless hazy plain instead of water. The far terrain's distance patches come from an isotropic noise instead of the sand layer at a sixty-fold tiling, whose ripples became parallel bands seen from above.
- A black strip along the window's bottom edge appeared together with the window jump on ESC. That resize no longer happens; and after a resolution change the macOS host now lets the window manager settle the size and takes the drawable as it really is before the next frame.
- Saving the project reset its version (#471).
project.vortex'sversionwent back to 1.0.0 andcreatedAtto the save time on every save. Both are carried through and written back; verified with a 2.3.4 / 2023 manifest surviving a save. - Engine-side nothing else changed since v3.4.7 (the world radiance cache, TAA, sharpen, the far dunes, the haze that follows the sky).