Ledger v3 · C# · Godot 4.7 Get started
The author's guide

What changed for an author

One line for each change to a form, a refusal or the host surface an author meets, dated, newest last. The first lines say where it starts: the kernel's master at f1ef4fe.

  • 2026-10-25: the start. ledger check, ledger play (with --journal LINE), ledger forms [FORM] with a meaning line for each form; a game's own plays list a line with no source as a warning.
  • 2026-10-25: the host: LedgerSession<TSpace> over any ISpace (LedgerSession over the plane); Quicksave.Write and Read, the head naming the game (GAME quicksave 2), a broken file refused as a FormatException with nothing replaced; IReloadable (Needs, Rebind(World, ReloadReport)) and LedgerSession.Reload between two ticks.
  • 2026-10-25: Godot: the adapter and the addon come from the kernel's godot\, through Ledger.Godot.targets; WorldHost.Begin watches the content and reloads it into the running world, its report as Godot warnings.
  • 2026-10-25: checks: ledger check reports every error a catalog has, a definition naming a failed one as depending on it (L0401); ledger check --json and ledger play --json, one JSON object a line with a stable id, the line as written and a fix where one is known; a failing play step quotes its statement, and a play step's own error reads as words at its line. The editor's dock lists every error, and a reload refused names the first and how many more.
  • 2026-10-25: words: ledger rewrite carries the four old words still loading with a warning into today's: a filter's to becomes of (Damage of holder) and its from becomes by, blocks' except becomes unless, and lose's from becomes on.
  • 2026-10-26: words: the four old words are refused, each at the word with an id (L0109 to L0112) and the kept word as its fix; ledger rewrite still carries old content into today's.
  • 2026-10-26: the host: ILedgerSession, the face every LedgerSession<TSpace> has, which WorldHost and LedgerCapture take, so a game over its own space has Begin, the watcher, Reload and the editor's channel; ITellsPlaces, which a space implements to tell where its actors stand, and Quicksave.Write over any such space; a reload restores into the space the world runs over; Mover(actor, fromX, fromY) tells where a mover came from, the same way in every session.
  • 2026-10-26: Godot: a game's build takes a Release kernel, whatever configuration Godot builds the game in.
  • 2026-10-26: recordings: a recording goes on across a reload in segments, each keeping the files its catalog was loaded from (Catalog.Sources) and its starting save, so it replays whatever the files hold since and holds each reload; Recording.Segments, SaveOf, ContentOf and FirstOf; its text names format 2, and one written before reads as one segment and replays against the catalog given; ReplayRefusal.OtherContent is gone for SegmentContent, a segment whose content doesn't load, named with the loader's words.
  • 2026-10-26: the host: World.Get and MaxOf refuse a read of an actor that is gone, in words, where they answered 0; a game skips a body whose id names no number now before it reads it.
  • 2026-10-26: the tools: ledger new is a command of ledger (tools\Ledger.Tool), writing the kernel's own template (templates\godot\) on the checkout it was built in unless --kernel names another, and refusing a folder inside the kernel's repository, whose content the game's runner would take for its own; the game's CLAUDE.md names this guide in the kernel's checkout. ledger forms --write writes forms.md, every form with an example, which the kernel's gate holds to the language; traps.md lists what the language can't say yet. The template's F8 note no longer says a reload ends the recording: only a quickload does.
  • 2026-10-26: the guide: each trap in traps.md names its witness, a play in witnesses\ the kernel's tests run, or says why it has none. Four entries left it or changed, being no longer so: a play expects one event before another (expect event A before event B); a forecast reaches a chance inside a rule; a play reads where a request moved an actor (expect ACTOR at X Y); and a tags line under from TEMPLATE replaces the template's tags, not adds to them. moments.md says a flight that pierces flies on after a report; ledger forms prints its meanings as forms.md does, with no word of how the kernel was built, and a filter's to and from are refused there as they are at load.
  • 2026-10-26: refusals: a name not found as one kind says the kind it has and the word that takes each ("no effect named Strike: Strike is an ability; an archetype grants an ability ..."), in content and in a play; a word out of place (L0106) says where it goes ("it goes before 'with'"), that the form takes no such word ("cost POOL F [upfront] takes no 'on'"), or that the form takes its lines in a block, and an expected word (L0107) or an actor name says when the form takes the word found nowhere.
  • 2026-10-26: refusals: a name not found that is near a declared one says it, of the kind looked for first ("no ability named Firebal; did you mean Fireball?"), or of another with its kind ("did you mean Burning, an effect?"); every statement of an effect, an ability or an archetype in error is said, not the first alone, and an error that follows from another stays out (the checks of the whole definition after a statement failed, and a definition's errors after an extend or a replace of it failed); the kind words' example names the name found ("Health is a pool; gain and lose change a pool (gain Health 10 on holder) ..."); and a rule whose having asks a content event for a tag no raise of it writes is warned of (traps.md).
  • 2026-10-26: refusals: every step in error in one body is said, an ability's, a rule's, and a step after a clause in error; what follows from another stays out: a block whose head is in error isn't read into, a step saying a name a failed let or as would have given isn't said, and an ability's steps aren't read past its target, takes, radius, phase or with in error, since they read what it gives.
  • 2026-10-26: refusals: a did-you-mean in a rule's event filter ("no event or tag named Dide; did you mean Died?"), for a modifier's misspelled stat ("an effect can't say 'MaxHelth'; did you mean MaxHealth?"), and at each other name looked up: a property, a command, a fact, a pile, a curve, a table, a stream, a stage, a category, an effect's var, an actor's root ("no actor named holdr; did you mean holder?"), and the host's lookups by name.
  • 2026-10-26: refusals: the kind words' example of the kind looked for names the catalog's own first name of it ("an archetype grants an ability (grants Strike)"), or is left out where the catalog has none.
  • 2026-10-26: Godot: the presentation kit (LedgerKit, Viewer, PoolBar, CastBar, AbilityBar, AbilityTooltip, Cues, Cue and CueMap), showing one side only what it may be told; ledger new's game uses it, its ability bar listing what the content grants, and its S key gone to the bar (host.md).
  • 2026-10-26: forms: create … at PLACE stands each made actor at a point or where an actor stands, read at the step (create Cloud at target; create Gold at holder under a death rule lays it where the foe fell). The game's space stands it as its Create is raised (ISpaceCommands.Stand, which a recording keeps and a preview puts back), and the world tells it placed before its start rules run; where the space can't stand it, it stands nowhere and a fault says so. in and at together are refused. traps.md's "Making at a place" keeps only an effect's var holding a point.
  • 2026-10-26: forms: fact(FACT, ACTOR, PLACE) asks a fact of an actor and a point where target or event.target holds one (requires fact(Sight, holder, target) > 0 on an ability that targets a point), through ISpacePlaces.Fact, 0 where a space has no answer; a recording keeps it, and a play sets one with fact Sight h 5 0. traps.md's "A sight check on a point" closed, and its witness went.
  • 2026-10-26: forms: cost POOL F on holder.LINK is paid by the actor a link of the holder names (a side's bank): its line priced on that actor's pool through its rules (before Cost Ore of holder), refused CannotAfford on that pool or NoPool naming none where the link is unset, and paid as a change of its pool, while a rule hearing what the caster sends (by holder) prices it too. Any other actor is refused at load, and so is an auto granted one; a beat's cost is its holder's. traps.md's "A cost paid by another actor" closed, and its witness went.
  • 2026-10-27: the environment: the one-Godot check looks by the program's whole name (tasklist //fo csv //nh), so it finds a Godot started through a link, as godotenv's godot.exe is, and passes over godot-ai.exe; the kernel's godot\checks\games.sh looks the same way, and the page says how to learn your own Godot's name.
  • 2026-10-27: the environment: seeing the game, its frames written by Godot's --write-movie with a fixed frame rate into a folder outside the game's, and read as images.
  • 2026-10-27: the environment: a build refused in obj\, or failed with no error, while other builds run on the machine is built again with --disable-build-servers.
  • 2026-10-27: the kit: godot\notes\kit.md lists each node's exported properties, PoolBar.Fill (a bar's colour) among them.
  • 2026-10-27: tools: ledger forms and ledger forms FORM work in a kernel shipped without its census, as a game's is, printing what they print in the kernel's checkout: forms.md gives each entry's use (Used:), which they read there.
  • 2026-10-27: forms: each example in forms.md is from what a game's author has: the content (never its census), the guide, the template or the kit; a form no shipped content uses takes one from a witness in guide\ledger-author\witnesses\forms\, a catalog and its plays, each play passing.
  • 2026-10-27: the state a game keeps: WorldOptions.Seat declares it, typed (Seat, its parts One, List and Keyed, their fields a whole with its range, a Num, a flag, an actor by number, a place or a stream's state; the game's, or each side's), and the world saves it (ledger-save 4), restores it checked whole, hashes it, rewinds it, records each write (recording format 3) and tells a side its own (PartsAs); the game's code writes it between moments (Write, WriteNum, WritePlace, WriteStream, AddRow, KeyRow, RemoveRow, ClearRows) and reads it (ReadWhole, ReadNum, ReadFlag, ReadActor, ReadPlace, ReadStream, Rows, RowOf). A save of another declaration is refused PartChanged, naming the part. CheckAs, PriceAs, PreviewAs, ForecastAs and ChoicesAs take the side asked as; a read of a stream's state in a view is refused. A field's range holds 0, which a record holds until written (a key's may not), and a part has a field. Needs names a pool and a link. The template keeps its state in the seat, and its quicksave has no game part of its own.
  • 2026-10-28: the cookbook by mechanic: content\cookbook\mechanics\ holds 37 recipes, each a .ledger and its .play lifted from one of the lab's six games and cut to its mechanic (a burn, a windup, a channel, a stun, an aura, a turret's priority, a turn's start, overwatch, a deck, a team's bank, a reload and more), each loading alone, its numbers sourced and its play passing in the gate. content\cookbook\README.md indexes them by mechanic, with the forms each uses and its source, lists what was left out and why, and the concept pairs ported from v2 below. SKILL.md sends an author there before forms.md; content\v2\README.md says what v2's ported games are.
  • 2026-10-28: deaths in one moment: holders whose dies clauses hear one blast fall in their Depleteds' order, each destroy at once where nothing in the catalog hears its event and as that event's after phase ends where something does, the same on every path the kernel takes; before, a rule naming no kind but a change's tag (after Damage of holder) made the gate's full path hold an unheard death until its after phase. A channel's caster destroyed by an order or by another's destroy ends its channel Stopped Gone with the destroyer's source, so an effect that ends on Stopped by source stays; ends on Stopped of source ends however the caster goes.
  • 2026-10-28: the wake: in a frame's Placed, an auto waiting for a target wakes only for a mover its clause's side can take, and the movers' own look only where a body of another side stands within their reach; elsewhere every sleeper wakes as before, since a host's space may answer moves it hasn't told yet. Nothing a game sees changes; a crowd pays for what its autos can take (a thousand foes round one hero: the bench's Placed 0.25 ms from 1.84). A recording begun now names asks-53; one naming asks-9 still replays, its world waking as it did then.
  • 2026-10-28: the host: a frame that puts, tells and steps (Mover, TellMovers, Tick) has its tick wake an auto only for a body its clause can take, by side and by the tags its having and unless name, as a Placed does; a frame stepped without telling keeps the old wake, as does a space whose distances move with no body moving (host.md, "Put, tell, step"). A save writes wait-reach where a restore would otherwise ask the space at another reach; a save without it restores as before. Nothing a game sees changes. A recording begun now names asks-54; one naming asks-9 still replays, and one naming asks-53 is refused.
  • 2026-10-28: checks: ledger check warns where an effect only items give reads source.STAT and an item giving it has no such stat (no base, pool, default, or modifier in an effect it holds), "... and an item's gift has the item as its source", naming the taker's word: holder in the gift, credit in what its aura puts on others (traps.md).
  • 2026-10-28: the host: World.Get on a pile's name answers how many items it holds, as content reads holder.Offers; host.md, "What a host calls on the world", lists the members a host calls by what it does, the plane's Push and what StateHash holds (a restored world hashes apart from its source though their saves agree).
  • 2026-10-28: the template: roundtrip's broken quicksaves misname the seat's first part and cut the world's length, which every game's quicksave has, so a game's own seat needn't rewrite them; run's comment says what the hash holds.
  • 2026-10-28: the guide: traps.md gives an item's gift's source, a request in an effect being its holder's, and by source against of source on a Stopped, each with its witness; forms.md's source, credit, request, command and "Play files" say the same, and the cone recipe names command Push.
  • 2026-10-28: flights: a piercing flight keeps the actors it has flown on past, and a report naming one again is refused AlreadyMet (a refusal at the enum's end), nothing run, so a game reports every overlap and keeps no list. Its phase line writes them as met 14,22 after pierced N, and an old save's line restores to a flight that remembers none; World.Met(flight, list) reads them. The trap "A pierce that remembers whom" is answered, its witness turned; forms.md's pierces, host.md and the pierce recipe say the same.
  • 2026-10-28: values and lifetimes: strongest CATEGORY keeps the term that moves its stat furthest, an add's or a percent's furthest from 0 and a factor's from 1 by ratio, the larger of two as strong, where it kept the largest: of two slows the stronger holds, and terms that all move a stat up keep what they kept. A category holding two kinds of term is refused at load. A lifetime counted in turns or events ends End.Expired as it runs out, at its counter or set to 0 by a handle or World.Reschedule, its expire running before its end rules, as for time; End.Spent is what is used up, an each ... removes taking the last stacks or signed stacks summing to 0. ledger check warns where an effect's own end rule names End.Spent and nothing can spend it. The traps "strongest on a slow" and "A lifetime counted in events" are answered, their witnesses turned; forms.md's modifier, categories, lasts, expire and End tags say the same, and the smoke recipe's cloud ends by expire. A recording begun now still names asks-54, and one made before replays on this kernel: where its world ran a count out heard by an expire or an end rule naming a reason, or read a category whose kept term the weighing changes, it replays to another final save, told as a different final save. So does one made before 56 that ends with a flight mid-pierce: its final save is one word apart (met), told as a different final save, not by the word.
  • 2026-10-29: draws: all ... at random draws its order, as N random draws its first N: with no up to, n - 1 picks for n found, from the stream using names, else the acting actor's own, each journaled as a pick; so does all items in PILE at random. It kept the order found before, so a recording made before whose content says it replays its orders to other draws, told as a different final save: record it again.
  • 2026-10-29: what a settled value follows: a pool's bound and drift, a clock's rate and an unsampled aura's reach read one list, their holder's own values, another actor's through a link of its holder's, a global link or its source, one step, and a count of a query finding actors by side, tags and presence. Now loading: aura Chilled on all enemies within holder.Reach of holder (reworked as the Reach moves), base MaxHealth 10 + 5 * count(all allies having Brute) (its count worked out as the moment ends; inside a moment the bound reads the count as the last settle left it, and what else it reads as any bound does, so apply Fortify then gain Health 20 gains against the bound Fortify raised), and base TimeRate holder.owner.Frost. What reads more stays refused, a count by place among it (base TimeRate 1 + count(all enemies within 3 of holder), which loaded before: a lane space moves its walkers with no mark), a bound's and a rate's words ending "... and a count of a query finding actors by side, tags and presence", an aura's "one reading more than its holder's values, another's through a link and counts by side, tags and presence is sampled, every D". A recording reading what now loads couldn't be made before.
  • 2026-10-29: the host: World.Having(effectOrTag, list), every live actor carrying a tag or holding an effect, in the order of their numbers and allocating nothing once warm, so a host lists the bodies content made with no walk of its own; host.md names Find, LinkOf and an order through an item's grant (Abilities' Source and Grant, Order.Grant), and says how worlds run on many threads from one catalog.
  • 2026-10-29: Godot: the kit's pool bar and a pool reading's Says print the value and the max whole, rounded half away from zero (680 / 810), the reading's Value and Max exact; KitStat reads a stat as the viewer sees it. A presenter matching a bar's old text (679.56525/810) reads the whole one now.
  • 2026-10-29: ledger new --turns: whose turn it is is content's, a Match actor's Turn, passed by its Turns rule as a side's order resolves; a walk on a turn is the content's Walk, a channel of a second. The game's C# keeps no Turn, Settling or Walking in its seat and reads the match's Turn. A game made before keeps its own until its author moves it.
  • 2026-10-30: the host: a rollback in place. LedgerSession.KeepSnapshots(capacity), then Take() each frame and RollBack(tick) on a wrong guess, put the same world back as it stood at that frame, hashing as it did, its journal and recording cut back with it and its order hook kept, allocating nothing once sized; Snapshots does the same for a world with no session. A rollback host keeps its space on a spare Plane (CopyTo, CopyFrom) and its own buffers beside it; host.md, "A rollback host", says how. A game that restored a text save each rollback goes on working.
  • 2026-10-30: checks: ledger check warns where a rule or a block asks an ability's event (an Activate, a Commit, a Pulse, a Finished, a Contact, a Stopped, a Resolved) or an effect's (an Apply, a Remove) having tags no ability, or no effect, carries all of: having asks for every tag it names and unless refuses any, so the rule never runs. Write a rule for each tag, or give them a tag they share and ask for that; forms.md says so in each form taking them, and traps.md has the trap. A world does nothing new.
  • 2026-10-30: the host: Catalog.Times(name, list) gives an ability's or an effect's times as content gives them, its template filled in, and each effect it applies with its duration, in ticks, none where a time reads the world; a host's frames or stun table reads it, not the content's text (host.md, "What a host calls on the world").
  • 2026-10-30: the guide: host.md names Raise, SetGlobal, Report's parts and an order's Grant, Toward and With, each with its signature, and where Api.cs doesn't reach (Order.cs, Seat.cs, World.Seat.cs); state.md gives the seat's reads and writes with their signatures; visibility.md, state.md and host.md agree that what a game keeps in the seat is the world's and what it keeps outside is its own, and that a world rolled back in place hashes as its frame while one restored from text hashes apart. Nothing a host already calls changes.
  • 2026-10-30: the guide: host.md names every public builder of an Order, each with its signature, by what it does, so an order's parts need no read of Order.cs; World.Remaining (an effect's time left, in ticks) and World.ArchetypeOf; DefTime's fields with their types, Ticks a long?; and Num's scale, a millionth, with Nums.Quantize for an engine's float rounded once. Its line on Api.cs says what that file holds, and where the world's, the session's and an order's members are, by file. Nothing a host calls changes.
  • 2026-10-30: the guide: an effect an order applies between ticks counts its time from the tick that ran last, where the clock stands, so its lasts 1t ends as the next tick runs, before the game's read; the same effect applied inside a tick is read once. moments.md says so, and traps.md has the trap with its witness: a one-tick impulse the game reads has no lasts, and is taken off by a Remove as it is read. A world does nothing new.
  • 2026-10-30: the guide: host.md, "When the engine moves the bodies": the engine's edges raised as events and kept as effects, a position rounded once to Num, what a quickload makes again beyond the bodies' floats, and which headless verbs need the engine. The template's headless tool says in its usage, and a new game's CLAUDE.md in its line on the tool, that run, record, roundtrip and perf move nothing where the engine moves the bodies, and go to the game's own arguments under godot --headless.
  • 2026-10-30: checks: ledger pipeline CATALOG POOL prints the rules a change to the pool meets, in the order it meets them: each stage a heading, then the rules at no stage, then the after rules; each rule with its line as written, its file and line, what its steps do to the change (an absorb and the pool it spends, a scale, a cap, a prevent, a conversion) and the archetypes holding its effect from their start, or what applies it. At the end, an archetype holding the pool that lacks a layer is flagged where a designer would act: it keeps the pool the layer spends or reads, or most of the archetypes with its very tags hold the layer. A deal or a heal is heard only on the damage pool, or a pool a redirect sends it to. It is the loader's same-stage analysis shown, not a second account.
  • 2026-10-30: Godot: the dock's Pipeline tab shows the same lines for a pool picked from the catalog's, each rule a button to its line, drawn again on each save; in a running game it narrows to the inspector's picked actor, the rules its effects hold now, each when true or false as it stands, or "reads the hit" where it reads the change.
  • 2026-10-30: the host: World.PipelineNow(actor, pool, rules) gives a pool's pipeline narrowed to an actor as it stands, as HeldRules (Effect, Line, Now): each rule its effects hold now that hears a change to it, its when read as an order key is read, nothing moving. The lines themselves are Ledger.Checks', the tool's and the dock's one source.
  • 2026-10-30: the cookbook: two recipes held by no game before, from the owner's ask: gate, a shield gate, a hit that breaks the shield spending none of itself on Health (absorb into Shield, then at most 0); and rate, a layer's rate by damage type, electricity counting double on a shield and not on Health (absorb up to holder.Shield / 2 as NAME, then lose Shield NAME * 2). Both with today's forms.
  • 2026-10-31: the host: a side's view (SideView): Read what a side may be told, by its labels (Name for the setup's actors, Withhold for what only the side's own are told), Ledger.Host's ViewBytes (Encode, EncodeDiff, Decode) for the wire, Write a client's world to hold it and Hold to count what it doesn't, Answer an order and LabelOf what it met; WorldOptions.Views keeps who made each actor (a made line in its save) and a written pool's told maximum (host.md, "A predicting client"). Words: an ability's cooldown is the effect ABILITY.cooldown, read by Remaining and written by Apply with Lasting.Ticks; a flight's costs are written under its ability and paid as it is loosed (ledger forms flies); Num's operators, root and absolute value, and the signatures of Having, FlightOf, Check, Create and LinkOf, are in host.md.
  • 2026-10-31: the kit: the ability bar takes a game's own settings on its Reading, each unset as before: its rows (Abilities, Source, Only; a row's Source by number where the side sees it), its keys (Keys, a key's name or none; KitAbility.Key is now a name, "1" by default), a target from the game's aim (Aim, a KitAim), and what an ability takes (Fill; one unfilled says "takes P, not given" and gives nothing). LedgerKit.Hand(order, row) hands the game each order whole with its row, before Give; AbilityBar.Buttons = false draws nothing and the game presses a row where it draws it (Press). The host: Catalog.Takes(ability, list), the properties an ability takes. The kit's check: --kit-press=* presses every row once (host.md, "The presentation kit").
  • 2026-10-31: tools: ledger play --why LINE ACTOR[.VALUE] CATALOG|PATH plays the play at that line and prints, at its end, the value's receipt (a stat's base, terms with their effects, the strongest of each category and the sums; a pool's anchor, drift, bounds, bands and next crossing), then the actor's changes the journal holds, newest first, each with its line items (its effect, verb, portion, amount, before and after). ledger names CATALOG NAME: where a name is defined and every line that names it. ledger pipeline CATALOG POOL --hit [TYPE] AMOUNT ARCHETYPE: the hit dealt to a fresh actor of the archetype, each rule that met it at its stage and what it left, read from its line items, then what it raised and the actor's pools after. The host: LineItemView.Rule, the rule whose step made a line item (OWNER:LINE, as a journal row's Rule).
  • 2026-10-31: Godot: the inspector's picked pool or stat opens its receipt, each effect in it a button to its line, and its changes list opens each change's line items, the text ledger play --why prints; the dock's declared names open their definition and list their uses; content files complete the forms' words and the catalog's names as they are typed (ctrl+space anywhere); the Pipeline tab takes a hit's type, amount and archetype, in a running game on the picked actor on a copy of the game's world. The capture answers why, changes and lines (channel.md).
  • 2026-11-01: forms: stat NAME by type gives a stat for each type the portions lines declare, each with the stat's options, named Resist.Fire wherever a stat is named (a play's expect d.Resist.Fire = 0.5 too). A base or a modifier on the stat alone (Resist + 0.25) gives every member that term, one on a parent type's member (Resist.Elemental) each child's. A content declaring no portions, or naming a member of no declared type, is refused as it loads.
  • 2026-11-01: forms: in a scale (or a convert's share), a stat by type read bare (scale 1 - holder.Resist) reads the member for each portion the scale acts on, so one rule is a resistance to every type; a change in no portions reads the stat as a member with no base reads it (its default, held at its bounds). Read bare anywhere else (a when, a let, an add, an after rule, a modifier), it is refused as content loads, naming the member to read or the scale to move it into.
  • 2026-11-01: the cookbook's backbone (backbone.ledger) is the default way to write a build's affixes and resistances: an affix a modifier on a stat by type, one rule a stage reading it.
  • 2026-11-01: tools: ledger pipeline --hit gives a scale's factor beside its line item (x 0.5); ledger names on a member lists each line reaching it, by the stat's name alone or an actor's read too, and on the stat alone its line and members.
  • 2026-11-01: tools: ledger why WHO PATH..., the batch's why: each play a run, read as it goes, and over all of them for an actor a play names or an archetype, what it dealt and took (by ability or effect, by whose archetype, by type), what killed it, its casts (by order, rule or auto, their tags and refusals), what healed it (its pools' drift among it), how long each effect held it with its most stacks, and its stats' terms by the actor that gives each, an item for its gift (StatTerm.Source). A game's headless batch reads each run into Ledger.Checks' WhyRuns and adds them; on many threads it wants the server collector (DOTNET_gcServer=1, or <ServerGarbageCollection>). ledger names on a stat by type exits 0.
  • 2026-11-01: Godot: the dock's Run tab, the inspector's picked actor's why since the game began, or since Again, each ability and effect a button to its line; the capture's ledger:run.
  • 2026-11-01: checks: a rule asking a change for a tag no change can carry (after Damage of holder having Hit, where Hit is only an ability's tag) loads with a warning naming the tag and tags Hit carried; a change carries its steps' tags, its portions' types, the tags declared carried, for a cost its ability's own, and for a host's deal any tag it names.
  • 2026-11-01: a trial, not a rule: ledger play --none-reads-default reads a stat through no actor (a grant's source on a change no grant made) as its declared default, where it reads 0; off, nothing moves.
  • 2026-11-01: a stat read through no actor (a grant's source on a change no grant made, an actor gone) gives its declared default, as a read through an actor without the stat does, where it gave 0; a pool still gives 0. ledger play --none-reads-default is gone with it. A guard by a stat that declares a default above 0 no longer tells a grant from none: guard by a stat that declares no default.
  • 2026-11-01: tools: WhyRuns.View(WHO) and View(world, number) give the batch's why as numbers by key (a WhyView: dealt and taken by ability, archetype and type, WhyKiller, WhyCasts, WhyHeal, WhyHeld, WhyStat with each WhyTerm), and Lines is that view printed, so a batch reads its numbers without parsing the words.
  • 2026-11-01: tools: WhyRuns.Naming names each actor as the why first meets it, given a WhyMet (its number, archetype, maker and maker's name), so an actor gone by a run's end is named; End's named is asked as before and taken over it where it gives a name.
  • 2026-11-01: tools: a stat's term reads its giver by the name the caller gives it (RingPower add 3 from a), so terms from a hero made again sum as one; a giver with no name reads as before (from #2 Ring). ledger why names each giver a play names.
  • 2026-11-02: forms: many definitions from one. template NAME(PARAMS) with no kind holds whole definitions, and from NAME writes them once for each line under it, its values the parameters' in order; NAME... is a list (the rest of the line, and the use's own lines), a line naming one written once a value, {NAME} a value inside a word, and TERM OP ... a term once a value, joined by the operator. Written out as the file is read, so the catalog is the one its definitions written out load to; an error names the use that wrote it.
  • 2026-11-02: forms: falls at no POOL [raising EVENT], an effect clause: the death that keeps its actor. As dies does, the holder raises the event credited to its killer, then falls where it stood, its pools as they stood, its activations ended Stopped Gone. The catalog writing it gets a tag and an effect of its own, both Fallen: a query or a target clause naming no Fallen passes the fallen over, so no unless Dead is written; one naming having Fallen finds it. The fallen acts not at all (an order refused Blocked by Fallen, a target refused BadTarget, "unless Fallen"), its every rules, auras given and mirrors stop, and it hears only what names it. Refused at load: one effect, or one archetype's effects, both dying and falling at one pool; a catalog falling at two pools; a catalog that falls declaring a tag or effect Fallen; apply, remove, aura or has naming Fallen.
  • 2026-11-02: forms: prevents death, an effect clause: a change that would leave its holder's pool at its least, where a dies or falls the holder holds hears that pool, lands one above it, and the effect ends Spent. It meets the hit after every before rule, so it needs no order; a set passes it; the first put on acts; a hit on a pool at its least already, or on the fallen, lands and leaves it. The change's line item names it, verb prevents death.
  • 2026-11-02: forms: revive TARGETS [at F], a step: each fallen target's fall comes off and it is back in play, its pool set to F (held one above its least) or to its maximum. A target not fallen is left as it is, a refusal row BadTarget "not fallen". The cookbook's fallen recipe has the three together.
  • 2026-11-02: forms: a cast's time. remaining(ACTOR) and elapsed(ACTOR), the running cast's time left and run on its clock, 0 with none; phases slot all (beside clock STAT or alone), the slot holding every ability an order or an auto asks for, and off cast, an ability's clause letting one through it; pushed back D [at most N] by FILTER [when F] under a windup, the cast stepped back by a hit; a channel's every read from a formula at each beat, with self.beats, the beats it has landed. Refusals: off cast where the slot holds only phases, or on an ability whose windup, channel or charge-up holds it; pushed back under a channel, a charge-up or a flight, twice, or by a formula; phases saying nothing. The cookbook's casting recipe has the four.
  • 2026-11-02: the host: catalog.Times gives a channel's every blocks after its length, none for a formula.
  • 2026-11-02: forms: windup D said before flies, as charge up to D is: the windup is any windup (the slot, broken by, pushed back, a haste, remaining), and its commit looses the flight; Running says windup, then flight. charged is refused where a windup leads. The pair's refusal names both: "but a windup or a charge-up said first may loose a flight". flies ARCHETYPE at F [up to D]: a flight at a speed, its time the distance as it is loosed over F, its arrival its hit, a reflect timing it again back; past its cap, or with no distance, it flies as before. Refusals: a constant speed of none or less, pierces or bounces with a speed, a draw in F. The cookbook's bolt recipe has them.
  • 2026-11-02: the host: host.md says how a flight is read, W.Running(W.FlightOf(projectile), ...), since W.Running(actor, ...) reads an actor's slot and answers false of a projectile, and how a game draws a flight at a speed at its elapsed share.
  • 2026-11-02: refusals: a fallen caster's order refused Blocked by its fall names the fall's time left, as every other block does, so a play's act ... expect refused Blocked on the fallen holds.
  • 2026-11-02: forms: a channel's every may name its own clock, every D [clock world | clock STAT], apart from its length's: channel 6s clock world with every 1s clock CastSpeed lasts 6 s of the world's time, ends Finished, and beats faster under a haste. channel D clock K keeps its beats on K. A channel's every blocks all name one clock or none does, and clock on an effect's every is refused.
  • 2026-11-02: the host: for a channel whose beats name their own clock, Running's Elapsed, Length, TicksLeft and Rate, and remaining(ACTOR) and elapsed(ACTOR), are its length's clock's, and TicksToBeat its beats'.
  • 2026-11-02: tools: a cast's receipt. ledger play --why LINE ACTOR.ABILITY CATALOG|PATH plays the play a tick at a time and prints each activation of the ability the actor began, newest first: its Activate, its phase's length on its clock and that clock's line, each stretch at each rate with the stat's terms and the row at each change, each push and beat, a flight's speed and time, its end, and that it adds up to what its clock ran. A word left over beside a path (--why 50 c CastSpeed PATH) is refused naming the --why form, where it was refused as mixing catalogs and paths, and so is one beside a catalog's name (--why 50 c CastSpeed raid), where it was taken as a second catalog.
  • 2026-11-02: the host: Ledger.Checks' CastReceipt, read after each tick as WhyRuns is, gives that receipt as numbers by key (CastView, its CastMoments) and in words (Lines); a play's EachTick feeds a reader after each tick something is due at. In the editor, the inspector's why answers an ability of the picked actor as it does a stat.
  • 2026-11-02: the host: a running cast's tags by its id, World.HasTag(ActivationId, string) and World.Tags(ActivationId, List<string>), its ability's then its carried ones.
  • 2026-11-02: the host: a game's Needs names an event it raises and a stat it reads (Catalog.HasEvent, Catalog.HasStat), a reload dropping one refused by name where it threw; another kind's throw names the eight.
  • 2026-11-02: checks: ledger play over several play files plays on past one that doesn't load, saying why, the count line adding 1 file not loaded, and exits 1.
  • 2026-11-02: the host: DefTime.Clock, the clock each time Catalog.Times gives runs on, a stat by name or world.
  • 2026-11-03: the host: a quickload keeps the recording. LedgerSession.RestoreSpace is the space a quickload reads over (the recording's keeper while one is on), and Replace opens the recording's next segment at the restored world (Recording.Restored), the stretch the load abandoned kept before it; a world restored over another space is refused before anything moves (World.RunsOver). A text with a restore is format 4, its segment segment K restored; every other is written as before. StartRecording after a quickload refuses, begun once; the template's quickload keeps the recording, and its roundtrip replays one across.
  • 2026-11-03: forms: an effect says holds TAGS until turn|EVENT [raising EVENT] and holds its holder's orders of those tags until its turn, each answering done with Outcome.Held, and going off as given, checked and paid then; one dropped is refused Dropped (replaced by a new order, cancelled, its holder fell, its hold ended). The word ordered(ACTOR [, PROP]) reads a held order's property. The host: World.HeldOrders and HeldOrdersAs list them as HeldOrderRows, and Order.Cancel drops one by its id. A world whose content says no holds is as before.
  • 2026-11-03: forms: a query's key reads a formula, by highest F or lowest F, it each actor found, then between keys (by highest ordered(it, Priority) then highest it.Speed), so no stat is kept to be a key; a key naming a value alone reads as before, and one that draws is refused. ledger play --why LINE ACTOR.POOL adds each place a sorted for each set, with the actor ahead and the first key that told them apart (Quick 80 > 70); the host: World.ReadSortKeys reads a sort's keys of an actor, and SortReceipt keeps the view.
  • 2026-11-03: the host: WorldOptions.Sorts keeps what each sort read as it sorted (World.Sorts), never saved, hashed, journaled or told, and ledger play --why LINE ACTOR.POOL reads each place a sort set, changed or kept, with the keys as it sorted them: a place left as it was is named, and a key reading its event or a distance is read.
  • 2026-11-03: the host: World.Ordered(actor, prop) reads a held order's property as content's ordered does, and OrderedAs(sees, side, actor, prop) as a side sees the world, a foe's properties its side's (null).
  • 2026-11-03: checks: ledger why reads a rise in a pool damage doesn't land on as raised (raised Place: 19), and the why's view keeps it as Raised; a rise in damage's pool reads healed as before.
  • 2026-11-04: Godot: the kit's readings (KitJournal, KitRow, KitCueRules, Viewer, the widgets' readings, LedgerPreview and CatalogShape) are a library of their own, godot\Ledger.Godot.Kit\, their names as they were. A game's Godot build takes it through the targets with no change to its project; a rules library or headless tool that linked the files by path from godot\Ledger.Godot\ references the library's project instead. The targets remove the copies an older kernel left of the moved files in a game's Ledger.Godot\.
  • 2026-11-04: Godot: the kit over a rollback. KitJournal.Cut says a rollback's cut its read met, and each KitRow its entry's Number; KitCues keeps each cue played by its frame, tag, actor and order, as far back as Reach (KitCues.ReachOf(session), the ring's snapshots), taking back one the frames played again don't find and begun told its Age one they find first. Cues keeps its scenes so (Reach, Keeping, TakenBackCount), freeing one taken back, and tells a scene its age through ICueScene.Cued(row, tag, at, age), which by default calls Cued(row, tag, at). A world that never rolls back plays as before; Cues.Says adds "N taken back" only where one was.
  • 2026-11-05: an unsampled aura's reach of its holder's own values (within holder.Reach of holder, or a stat that follows only the holder's values) costs what a number's does at a birth or a death: a radius aura by side and tags about its holder is reworked there only where its reach counts, directly or through a stat, or reads another actor's values across. So a host that walks its bodies and tells them in one Placed has such an aura meet a body moved untold at that Placed, as a number's reach always did, not at a birth or a death between. A recording made before whose content writes such a reach and whose host moved bodies untold across a birth or a death may replay to another final save, told as a different final save.
  • 2026-11-05: Godot: a cue may name the row's ability and a tag its actor carries, beside its tag and kind: a Cue's Ability and Having, and Cues.Bind(tag, scene, kind, at, ability, having) (KitCueRules.Bind alike), each empty for any and a condition as the kind is, so a cue not met leaves its tag's ancestor to be tried. The having is read as the kit's viewer sees the world as it reads the row: an actor unseen or gone carries nothing. KitCueRules.Played(row, into, viewer) reads havings; Played(row, into) meets none. Cues warns of an ability or a having the content doesn't declare. A cue naming neither plays as before, and the matching no longer allocates.
  • 2026-11-06: the host: helpers for a game's own space code, none of them the world's: SpaceOver, which a game's own space derives from in place of forwarding to a PlaneSpace; PlaneSpace.Put(session, actor, x, y[, fromX, fromY]), clamped and its mover named; Quicksave.Loaded.PutBack(plane); Steer.Toward and Steer.Diagonal, a step by the plane's distance rounded once; Trig.Cos, Sin and Direction of whole degrees from one table; and Found, a collector. The plane: Plane.Nearest, the nearest placed actor within a radius among those an IPlaneFilter admits, allocating nothing. The template's GameSpace and walk use them.

From ledger-v3's guide/ledger-author/changes.md, last changed 2026-11-06.