feedback1 integrate: form fx survive the render engine's stale-event drop; hidden-tab backlog compacted and flushed when a finished battle is shown; same-field re-entry buffered
- render/interp.js isCosmeticEvent: an fx with a form is state, never dropped as stale nor shed from a full queue; a late one switches the model without its telegraph, its closing clip shortened (render/app.js) - battle/runner.js: a backlog past HELD_MAX keeps only the last status / skill toggle per unit; a battle that ended while the tab was hidden delivers its backlog and last snapshot when the tab is shown - screens/game.js: a new field meta for the field on screen buffers its frames until the view re-enters it - browser test stalls the main thread (blocking 1 s long tasks); Node tests drive the runner into the render buffer
This commit is contained in:
1 parent
88d419b095
commit
4e68100065
11 files changed
+259
-39
No files matched your search
@@ -16,7 +16,8 @@
|
||||
// * event queue: a `b.ev` batch is stamped with its game time (`gt`, the snapshot it was drained with); a batch
|
||||
// without one is placed inside the latest snapshot interval (newest snapshot time minus half an interval),
|
||||
// and handed out by `takeEvents()` once renderT passes the stamp. Stale cosmetic events (> `eventMaxLag`
|
||||
// game s behind) are dropped by the caller's choice (`isCosmeticEvent`); state events are always delivered.
|
||||
// game s behind) are dropped by the caller's choice (`isCosmeticEvent`); state events — an enemy's form fx
|
||||
// included — are always delivered, and a full queue sheds only cosmetic ones.
|
||||
//
|
||||
// Snapshot tuple layout (DESIGN §8.2): [id, x, y, hp, maxHp, sp, spMax, flags, anim]. Two optional lists ride along
|
||||
// (server/sim/Battle.js snapshot, user playtest #4 items 8 / 9):
|
||||
@@ -27,6 +28,8 @@
|
||||
// `units`): downAt(time) returns the list of the snapshot at `time`.
|
||||
// Game times in both (`cooldownEnd`, `respawnAt`) are on the snapshots' clock, so a view compares them with renderT.
|
||||
|
||||
import { fxForm } from '../../../shared/protocol.js';
|
||||
|
||||
export const TUPLE = Object.freeze({ ID: 0, X: 1, Y: 2, HP: 3, MAXHP: 4, SP: 5, SPMAX: 6, FLAGS: 7, ANIM: 8, EL: 9, EL_FILL: 10, EL_UNTIL: 11, EL_DUR: 12 });
|
||||
/** Element keys a snapshot `elem` entry may carry (server/sim/constants.js ELEMENT_ORDER). */
|
||||
const ELEMENT_KEYS = new Set(['neural', 'erosion', 'burn', 'apoptosis', 'necrosis']);
|
||||
@@ -37,7 +40,13 @@ const clamp = (v, lo, hi) => (v < lo ? lo : v > hi ? hi : v);
|
||||
|
||||
/** Cosmetic event kinds that may be dropped when far behind (never state-changing). */
|
||||
export const COSMETIC_EVENTS = new Set(['atk', 'dmg', 'heal', 'fx', 'layer', 'bounty']);
|
||||
export const isCosmeticEvent = (ev) => Array.isArray(ev) && COSMETIC_EVENTS.has(ev[0]);
|
||||
/**
|
||||
* Whether an event may be dropped when stale or shed from a full queue. An 'fx' that carries an enemy's model `form`
|
||||
* (shared/protocol.js fxForm) is state: dropping it left the view on the old model after a long main-thread stall, on a
|
||||
* watched field after a hidden tab and on a field entered late (user report #5 after 0.1.0) — the fourth place the client
|
||||
* keeps it, with battle/runner.js keepsState and screens/game.js keepEarly.
|
||||
*/
|
||||
export const isCosmeticEvent = (ev) => Array.isArray(ev) && COSMETIC_EVENTS.has(ev[0]) && fxForm(ev) === undefined;
|
||||
|
||||
/**
|
||||
* Game time (s) of a b.snap / b.ev payload, or NaN. On the wire every frame is `{ t: '<type>', … }`, so the server
|
||||
@@ -308,9 +317,12 @@ export class SnapshotBuffer {
|
||||
|
||||
/**
|
||||
* Remove and return (in order) the queued events due at `time` (default renderT). When `dropCosmeticBefore`
|
||||
* is a number, cosmetic events stamped earlier than it are discarded instead of returned.
|
||||
* is a number, cosmetic events stamped earlier than it are discarded instead of returned; a state event stamped
|
||||
* earlier is returned, and when `late` (a Map) is given it records that event → how far (game s) its stamp lies
|
||||
* before `time`, so the caller can skip its stale cosmetics (render/app.js: a late form fx switches the model without
|
||||
* replaying its telegraph and with its closing clip shortened).
|
||||
*/
|
||||
takeEvents(time = this.renderT, out = [], dropCosmeticBefore = null) {
|
||||
takeEvents(time = this.renderT, out = [], dropCosmeticBefore = null, late = null) {
|
||||
if (!this.events.length || !Number.isFinite(time)) return out;
|
||||
let n = 0;
|
||||
while (n < this.events.length && this.events[n].t <= time) n++;
|
||||
@@ -318,7 +330,10 @@ export class SnapshotBuffer {
|
||||
const list = this.events;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const e = list[i];
|
||||
if (typeof dropCosmeticBefore === 'number' && e.t < dropCosmeticBefore && isCosmeticEvent(e.ev)) continue;
|
||||
if (typeof dropCosmeticBefore === 'number' && e.t < dropCosmeticBefore) {
|
||||
if (isCosmeticEvent(e.ev)) continue;
|
||||
if (late) late.set(e.ev, time - e.t);
|
||||
}
|
||||
out.push(e.ev);
|
||||
}
|
||||
const rest = list.length - n;
|
||||
|
||||
Reference in new issue
Block a user