Skip to content

Releases: shadow-kernel/Vortex-Engine

Vortex Engine v3.4.17 — Claude play-tests your game, enemies fight back

Choose a tag to compare

@github-actions github-actions released this 15 Oct 13:49
efdab29

Vortex Engine v3.4.17 — Claude play-tests your game, enemies fight back

Play-testing with Claude

  • Claude presses the keys. The new send_input tool 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_state read 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 scroll and cursor. 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() and Save.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_save and restore_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)
  • .vnav files 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 --input looks turn 2–7 % less than before: a one-frame overshoot is gone.

Vortex Engine v3.4.16 — Characters and rays you can trust

Choose a tag to compare

@github-actions github-actions released this 15 Oct 06:10

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.MoveCharacter ignores the colliders of the moving entity and its children, so a guard with a solid hitbox stays on the floor and gets no OnCollisionEnter against itself. This works with both controllers. Physics.CanStand excludes 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 later MoveCharacter with that id brings the capsule back. A Nav Agent whose body goes limp leaves the crowd, refuses SetDestination and Warp while 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 like Scene.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

Choose a tag to compare

@github-actions github-actions released this 14 Oct 11:15

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.MouseX and UI.MouseY are points in the editor and in the player. The new UI.Scale gives the pixels per point. All of them are valid in Start(). (#454)
  • NaN guard. A NaN or infinity written to a Transform or passed to MoveCharacter is 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_entity shows a script's field values and which ones are overridden. set_component_properties sets 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 into play_note.
  • project.vortex keeps your keys. A save merges into the file at the JSON level. The version, creation time, $schema and 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_camera and capture_viewport(focus) switch to the editor camera, and the capture names the camera that rendered. (#444)
  • get_scripting_api prints the doc summary of each API.

Audio and navigation

  • One-shots reverberate. A 3D Audio.PlayOneShot inside a Reverb Zone gets the zone's reverb, like an Audio Source. 2D one-shots stay dry, and both have a reverbMix overload. (#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. doubleSided applies 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_strength reach the material, so a placed glTF glows. (#450)
  • Animation clips reload. .vanim clips 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, BoneMatricesCapacity and SkinnedBindPoseFallbacks. (#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_stats reports 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 doubleSided cards, 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_script while paused starts the behaviour when play resumes.
  • FBX and OBJ models with colour-only materials that picked up an *_albedo image lying next to them now show their material colours.
  • Models re-import once (import cache version 5). Sidecar .vmat files 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 budget and mcp play mode leaves no trace;
  • audio play, sound studio and navigation;
  • five glTF import checks.

Vortex Engine v3.4.14 — Glowing lit materials, sharper terrain

Choose a tag to compare

@github-actions github-actions released this 14 Oct 08:45

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_properties tool 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

Choose a tag to compare

@github-actions github-actions released this 13 Oct 09:27

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=1 restores the previous TAA for comparisons.

Vortex Engine v3.4.12 — An overgrown cave with a shaft of light

Choose a tag to compare

@github-actions github-actions released this 13 Oct 07:51

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_foliage has from_y to 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.py generates a shaft of light (--skylight), keeps the floor level into a wide mouth and closes the tunnel with a rock wall.
  • VORTEX_GI_LOG=1 prints 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

Choose a tag to compare

@github-actions github-actions released this 12 Oct 22:08

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.py generates 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. --points writes 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_area and set_area apply a linked .varea file's values right away.

Vortex Engine v3.4.10 — Fire while aiming

Choose a tag to compare

@github-actions github-actions released this 12 Oct 21:27

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

Choose a tag to compare

@github-actions github-actions released this 12 Oct 17:23

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) and OnAreaExit(AreaInfo); a manager subscribes to Areas.Entered / Areas.Exited. AreaInfo has the name, the tags, HasTag, Get / GetBool / GetFloat for 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.
  • .varea files: a reusable definition (shape, size, tags, properties, colour, priority) in plain JSON. The inspector's Save as… writes one into Assets/Areas and 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.varea and ZoneManager.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_terrain takes op: "hole" and "fill".

Vortex Engine v3.4.8 — The standalone game plays again

Choose a tag to compare

@github-actions github-actions released this 12 Oct 16:56

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_resolution divides 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's version went back to 1.0.0 and createdAt to 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).