Skip to content

D2VP Vanilla+QoL-0.0.8-R144

Choose a tag to compare

@VTSTech VTSTech released this 09 Nov 10:42
· 27 commits to main since this release
image image image image

D2VP Vanilla+QoL — Release Notes: R139 → R144

R139 — On-screen build tag

Self-ID Vanilla+0.0.8-R139 · 2026-11-09 · no issue · no ini key

The title screen and the in-game automap overlay used to show the retail version
line ("v 1.14d"); both now show the fork build tag — D2VP-R139 — so the exe
identifies itself at a glance, in game and in every screenshot.

  • Added: fork build tag on the title screen and the automap overlay, replacing
    the retail "v 1.14d" line.
  • Under the hood: one define (Redivivus/d2_boot.h D2VP_ROUND) feeds the title
    screen, the automap line and the d2boot.log self-ID — every future round bumps a
    single line, and tag + self-ID can never drift apart.

Field: visible in daily play from the day it shipped; no behavior change of any
kind. Display-only round.


R140 — Ctrl+Click stash transfer

Self-ID Vanilla+0.0.8-R140 · 2026-11-09 · no issue · owner ask:
"Can we make Ctrl+Click put/remove items from Stash when Stash is open?"

With the stash open, Ctrl+Click now moves an item in one click — inventory →
stash or stash → inventory — no dragging. D2R parity for the one Ctrl behavior
retail 1.14d never finished: retail wired Ctrl+Click to sell-in-shop only, and with
no shop open the branch was a dead click (a lock, no packet, no cursor — the item
stayed put).

  • Added: Ctrl+Click transfer both directions with the stash open, including the
    Shared tab (the shared pages ride the same stash buffer, so nothing extra was
    needed). A full target plays the retail "won't fit" refuse sound.
  • How it works: the click sends the same 0x19 pick + 0x18 place packet pair a
    fast manual drag puts on the wire, with the free-cell finder the cube path uses.
    (The first cut sent the 0x18 place alone and the server refused it silently —
    its handler requires the item to be on the cursor, which is the 0x19's job. The
    gem's "ding" played while the item stayed; that build never left the field pass.)
  • Untouched on purpose: Ctrl+Click in an open shop still sells, belt items, the
    cube panel and the trade panel keep their retail behavior.
  • Config: [features] ctrl_click_xfer (default 0, like every feature) + the
    Vanilla+ Options page's Ctrl Click Transfer row. Off = the retail dead click,
    byte for byte.

Field: verified in both directions on the shared and retail pages the same day.
Field ask: SMOKE §R items 57–59.


R141 — Ctrl+Click: the vacated-slot fix

Self-ID Vanilla+0.0.8-R141 · 2026-11-09 ·
issue #35 — closed · field catch on R140

"The items move, but the slot they once occupied becomes unusable." The R140
build sent the pick and the place back to back, and both echoes drained in one
packet batch — a sequence no retail flow produces (a manual drag settles the pick
on the hand frames before any place arrives). The source container's client-side
grid entry went stale and the emptied slot refused every later placement.

  • Fixed: the place packet is parked and released one full frame later — the
    exact packet timing of a fast manual drag. The emptied slot accepts placements
    again, both directions, and the transfer still completes.
  • Edge case kept retail-shaped: closing the stash panel inside that one-frame
    window leaves the item on the cursor — the same interrupted-drag state retail
    produces, player-recoverable.

Field: verified 2026-11-09 ("R141 confirmed"), issue closed the same day.
Standing regression check: SMOKE §R item 60 (drag onto the just-vacated slot,
immediately after the click).


R142 — Unlock FPS

Self-ID Vanilla+0.0.8-R142 · 2026-11-09 · published release · no issue · owner ask

The presentation-FPS unlock. With the gate on, the game presents at ~60 FPS while
the simulation keeps the exact retail 25 Hz cadence
— ticks, movement, animations
and timers are byte-exact retail. The immediate wins: a 60 Hz cursor, smooth
hover/tooltip/target-highlight/Alt-label updates, and up to ~40 ms less
input-to-photon latency on clicks.

  • Added: the draw moves onto a 60 Hz present pacer in the client frame loop
    (skip-never-queue — a slow GPU re-anchors instead of queueing), the message-pump
    idle sleep paces to the same deadline, and D2GFX_EndScene's anti-spin budget
    drops 5 → 1 ms under the gate. Vsync behavior untouched.
  • The proof is in the log: while the gate is on, d2boot.log carries a
    presents/ticks-per-second pair every 5 s, e.g.
    presents 312 in 5021 ms (~62/s), client ticks 125 (~24/s) - sim stays 25 Hz.
    The tick number staying at ~25/s is the game-speed-unchanged proof — count,
    don't eyeball.
  • Rejected on purpose: retail's own GAMETYPE_SINGLEPLAYER_UNCAPPED QA path —
    it speeds the server, i.e. actual game speed, which is exactly what this
    feature must not do.
  • Config: [features] unlock_fps (default 0, like every feature) + the Options
    page's Unlock FPS row. Mid-session flips take effect within ~2 s (the ini hot
    read), no restart: off → back to 25, on → back to 60.

Field: SMOKE §S-61 confirmed on the published build — presents 292/300/299 per
~5 s window against client ticks 125/126/125, and the retail /fps overlay reads
60 in game; the mid-session menu flip is green both ways. Field ask: SMOKE §S
items 62–64. Sub-tick interpolation (world motion at 60) is the deliberate
follow-on — R143 below.


R143 / R143.1 / R143.2 — Sub-tick interpolation

Self-ID Vanilla+0.0.8-R143 (the d2boot mark reads
+ sub-tick interp (two-sample) from R143.1 on) · 2026-11-09 · no issue · plan Phase 2

With Unlock FPS on, the world scroll and everything world-anchored — floor,
monsters, missiles, items — now glide between game ticks at the present rate

instead of stepping at 25 Hz. Your character keeps its exact retail screen position
(D2's camera follows 1:1, so the world glides, not the character); shadows and
auras stay glued; animations still advance on ticks. The glide is applied at draw
time only and nothing is written back to the simulation — the d2boot tick count
stays ~25/s, byte-exact.

  • R143 shipped the feature with a velocity-prediction alpha (pos + velocity × α). A prediction is never exact, so every tick boundary snapped by its own error
    — the owner's field report: "the interpolation is jittery, looks better at 0."
  • R143.1 replaced the prediction with interpolation between two real position
    samples
    taken at each client world update — continuous at every tick boundary
    by construction. Still kicked in the field: "still looks jittery at 1, looks
    better at 0."
  • R143.2 found the delivery, not the math: the snapshot ran after the draw
    (so tick+present frames sawtoothed a full tick at every boundary), the sprite
    world-offset delta sat dead behind a shake early-return (shadows, overlays and
    the mouse world-pick stayed tick-locked against the gliding camera), and the
    player-sprite cancel double-added in perspective mode. All three fixed; a sandbox
    loop-order harness reproduces the reported 18 px backward kick on the old wiring
    and shows a monotone, kick-free glide on the new — 10/10 green.
  • Teleports and level changes snap instantly (by design — a glide across a
    loading boundary would look wrong). Known minor, only visible frame-stepping a
    recording: the automap arrow and the player's overhead label keep tick-snapped
    positions.
  • Config: [features] unlock_fps_interp, default 1 (ini-only through R143 —
    the Options row arrives in R144). 0 restores the R142 step-cadence look,
    hot-read within ~2 s.

Field: the R143.2 glide was field-accepted 2026-11-09 — "Ok, I think it looks
good now."
The d2boot tick-count and boundary sub-checks stay open under SMOKE
items 65/62.


R144 — Two-column Options page + the FPS Interpolation row

Self-ID Vanilla+0.0.8-R144 · 2026-11-09 · no issue · owner ask:
"Is unlock_fps_interp on the Vanilla+ Options Panel? … Can we make the panel two
column instead of one?"

unlock_fps_interp had been ini-only by design through R143 — and the one-column
Options page had grown to eleven rows (497 px), too tall to fit at 640x480 and too
long to see at a glance. R144 answers both halves.

  • Changed: the Vanilla+ Options page is now two columns of six rows (labels
    left, On/Off right-aligned per column, per-column hover highlight and mouse
    hit-testing — the same y is two rows now, one per column; Previous Menu
    full-width below). The box is 337 px again and fits every video stop whole,
    640x480 included.
  • Added: the FPS Interpolation row (twelfth row, directly under Unlock
    FPS) — the interp knob leaves ini-only. It rides the same write bridge as every
    row: flip → ini write → the 2 s cache flush, no restart.
  • The row shows the gate's truth: the interp gate reads a missing ini key as
    On (the intended look), and old inis never get keys backfilled — so the row uses
    a per-key read default instead of a generic Off display. On a pre-R143 ini
    without the key it correctly reads On, and the first click writes a real 0
    instead of a silent no-op.
  • Config: no new key — [features] unlock_fps_interp (default 1) is unchanged;
    it just gained its row. Ini template wording updated (the interp block no longer
    says "no Options row").

Field: the owner's R144 field screenshot (now the README gallery's panel shot)
shows the two-column page in game at 1920x1080 with both new rows On and the
console reading the R144 self-ID at FPS 60 — a visual pass. The behavioral field
check (SMOKE item 66: per-column hover/click, the 480p fit, the pre-R143-ini
display, both flip directions) remains open.


Upgrading across the arc (R138 → R144)

  • Extract the new build over the previous install — saves, realm logins and
    d2vp.ini carry over untouched. No save-format changes anywhere in the arc.
  • New ini keys since R138 (all under [features], all hot-read within ~2 s):
    ctrl_click_xfer=0 (R140), unlock_fps=0 (R142), unlock_fps_interp=1 (R143).
    A missing file auto-creates the documented all-defaults template; existing files
    are never backfilled — flip the new Options rows once to persist them.
  • Default-off charter holds with one deliberate exception: unlock_fps_interp
    ships On. It is a presentation-only look (the sim stays byte-exact 25 Hz with or
    without it), it rides the unlock_fps gate, and 0 restores the step-cadence
    look at any time, in game.
  • With no d2vp.ini at all, the game behaves exactly like retail 1.14d.

Still open after R144

  • Field asks (SMOKE §S): item 62 (stopwatch sim identity — attack + fixed walk,
    gate Off vs On), item 63 (the 60 Hz feel + the NOVSYNC spot-check), item 64's
    remaining half (Esc-pause / loading-screen / cutscene boundary walk) and item 66's
    behavioral remainder (per-column hover/click, 480p fit, pre-R143-ini display, both
    flip directions).
  • Known issues (unchanged by this arc): the Refilling Shrine XP buff
    (#25) and the intermittent
    attribute-point crash (#18) —
    triage pending; see the README's Known-issues section.