Skip to content

Release Archive

codingncaffeine edited this page Jul 10, 2026 · 1 revision

Release Archive

SiegeFX's versioning was reset at the first playable alpha (v0.0.1). The earlier tags (v0.7.0v0.15.0) tracked internal engine milestones — parsers, VMs, subsystems — and their numbers climbed far faster than the project's playable maturity. Since nothing had an install base yet, those releases were removed and the scheme restarted at 0.0.1, which now tracks progress toward 1.0 = a complete, playable Farmhouse → Castle Ehb campaign.

The release notes from the retired milestone tags are preserved below for the historical record. (Tags v0.10.0v0.15.0 were tag-only markers with no published notes.)


v0.7.0 — Skeletal animation milestone (2026-04-24)

First tagged release. SiegeFX is a clean-room Dungeon Siege 1 reimplementation in C#/.NET 8. This milestone closes Phases 0-7 of a 9-phase plan — everything through a visibly-animated rigged character.

Rendering

  • Skeletal animation — rigged ASP + PRS clip viewer, per-corner 4-bone GPU skinning, looped playback. Walks the goblin.
  • Continuous world streaming — regions stitched via intra-region door graphs and editor/stitch_helper.gas cross-region pairs. World.dsmap: 81/81 regions placed, 0 unresolved.
  • Textured terrain.sno subsets with per-surface albedo from .dsmap tanks.
  • Textured meshes.asp static meshes, .raw albedo with pre-baked mip chain respected.

Asset Pipeline

  • Tank reader.dsres / .dsmap, zlib round-trip clean. 9187 files fuzzed across Logic/Objects/Terrain tanks, 0 failures.
  • RAW textures — BGRA→RGBA decode, full on-disc mipmap chain, hand-rolled PNG encoder.
  • GAS parser — DS1 hierarchical config format; tolerates authoring typos. Fuzz-clean across every shipped .gas.
  • PRS animation — bone name map, KLST key lists, normalized-time sampling.
  • ASP rigged — BMSH/BONH/RPOS/WCRN; cached inverse-bind matrices.

Viewer Modes

Launch via dotnet run --project src/SiegeFX.Runtime -- <args>:

  • <mesh.asp|mesh.sno> [texture.raw|tank.dsres] — single asset
  • --region <map-tank> <terrain-tank> <region-path>
  • --world <map-tank> <terrain-tank> [root-region]
  • --anim <rigged.asp> <clip.prs> [texture.raw]

Controls: RMB + WASD to fly, Shift to sprint, Esc to quit.

CLI (siegefx)

  • tank info|list|extract
  • asp info, raw info|decode, gas info|dump|fuzz
  • region info|layout|layout-diag|fuzz, world layout
  • prs info|sample|fuzz, anim fuzz

Requirements

Original Dungeon Siege game data (e.g., a GOG install) for Logic.dsres, Objects.dsres, Terrain.dsres, World.dsmap. No copyrighted assets ship with this release.


v0.8.0 — Skrit scripting runtime (2026-04-24)

Shipped DS1 scripts now drive real behavior inside SiegeFX. The Skrit VM is complete (lex / parse / bind / compile / interpret) and the viewer can hand an actor's animation decisions off to a shipped .skrit file.

Skrit VM (Phase 8)

  • Lexer — 364 shipped skrits (Logic + Objects), 0 lex failures on all of them.
  • Parser — recursive descent with 14 precedence levels; shipped-quirk tolerance (inline state triggers, declarative transitions with if guards and = { body } edge-fire blocks, bare-name functions, unbalanced-paren tolerance, ** exponent, commented-out parameter names, multi-declarator int a$, b$ = 0).
  • Binder — two-pass symbol table covering properties, fields, functions, states, and the host-API extern catalogue. Surfaces 154 real bugs in GPG's shipped scripts as informational diagnostics without aborting the pipeline.
  • Compiler + VM — stack-based bytecode with tagged-union values, ~35 opcodes, short-circuit via Dup + JumpIf, synthetic @__init__ chunk for property initialisers, case-insensitive keyword dispatch.
  • Runtime — per-actor SkritInstance with deferred SetState, one-shot chore scheduler at 20 Hz (DS1's authoritative scripted-systems rate), event/trigger resolution across state-local and top-level scopes.
  • Host bridgeActorHostBridge captures owner.blender.* activity through tag-string dispatch so undefined identifiers can't silently answer Math.RandomInt. ANIMEVENT_* bitmask constants synthesised on demand.

Tools

  • siegefx skrit tokens | parse | bind | compile | run | tick | fuzz <file.skrit> — full pipeline on the CLI, including a tick driver that runs shipped scripts against the runtime.

Viewer (Phase 9a)

  • SiegeFX.Runtime --skrit-anim <rigged.asp> <file.skrit> <clip0.prs> [clip1.prs ...] [--texture <raw>] — hand the viewer a rigged mesh, a shipped skrit, and a set of PRS clips; the skrit's OnStartChore$ handler decides which clip plays via owner.blender.AddAnimToBlendGroup.

Verified against shipped content

  • basic_walk.skrit: dispatches OpenBlendGroup / AddAnimToBlendGroup(0,1) / CloseBlendGroup / SetBlendGroupWeight(0,1) through the host bridge.
  • simple_loop.skrit: Startup$ -> Looper$ state transition via deferred SetState, OnEnterState$ fires the next state's blender calls.

v0.9.0 — Phase 10: actors (2026-04-24)

Phase 10 — actor pipeline

  • Template store with specializes-chain inheritance; resolves 3W_goblin_grunt back through 3W_base_goblin → actor_evil → actor, merging [aspect] / [common] / [chore_dictionary] blocks along the way.
  • Region actor loader reads per-region actor instances from objects/regular/actor.gas and hands them off as (scid, template, position) tuples.
  • ActorSpawner stands up per-region shared SkritRuntime + WorldMessageBus and drives each actor through its archetype's startup state.
  • WorldMessageBus routes PostWorldMessage broadcasts (toScid==0) and targeted sends to registered skrit instances on drain.
  • Viewer --play-region: loads terrain + 181 actors in fh_r1, runs the skrit VM at 20 Hz, renders per-actor skinned meshes with identity-bone fallback for archetypes whose PRS clips aren't parsed yet.

Composition fix

  • RegionLayout / WorldLayout matrix composition had the operands reversed relative to row-vector convention — regions were collapsing to a near-identity cluster at the anchor ("the world clumps at origin" since Phase 6b). New order matches OpenSiege SiegeNodeMesh::connect exactly. Post-fix World.dsmap places 81/81 regions spanning (-1954, -304, -947)(400, 28, 924) across 53,453 snodes.

Tooling

  • siegefx templates show <tank> <name> / templates list --prefix=… --tag=…
  • siegefx region actors <map-tank> <region-path>
  • siegefx region spawn <map-tank> <logic-tank> <objects-tank> <region-path> [--broadcast=EVENT]

Clone this wiki locally