Hello, I’m using your Hendrix Action/Animation System in a project and ran into two important issues.
I wrote my own fix plugins to solve them and would like to share the results with you.
1. Rendering Bug – “Fullsheet Flash”
Issue:
On the very first movement start (Idle → Walk/Run, or any sprite change), the engine shows the entire spritesheet for exactly 1 frame before the correct animation frame appears.
After that, everything works fine until the next graphic switch.
Cause:
When a new bitmap is ready, updateFrame
has not yet applied a valid rectangle, so PIXI draws the full bitmap once.
Fix:
I wrote a small guard that prevents invalid rectangles from ever reaching the screen:
-
If the current rect is invalid (0Ă—0 or full bitmap), reuse the last valid rect, or skip rendering for that tick.
-
After every
updateFrame
, the last valid rect is remembered. -
No changes to your frame logic, fully compatible with Idle/Walk/Run, 8-dir,
_fX
.
Result:
The fullsheet flash never appears again. Characters always show the correct frame immediately.
Worst case = sprite invisible for 1 tick (instead of flashing).
External Fix Plugin (ready to use):
/*: * @target MZ * @plugindesc [v1.0] Prevents 1-frame fullsheet flash at movement start by guarding invalid frames in render step. Compatible with Hendrix system. * @author Emanuel Allescher */ (() => { "use strict"; function isBitmapReady(sprite) { return sprite && sprite.bitmap && sprite.bitmap.isReady && sprite.bitmap.isReady(); } function currentRect(sprite) { if (!sprite || !sprite._frame) return null; const f = sprite._frame; return { x: f.x|0, y: f.y|0, width: f.width|0, height: f.height|0 }; } function isValidNonFullRect(sprite, rect) { if (!sprite || !sprite.bitmap || !rect) return false; const w = rect.width|0, h = rect.height|0; if (w <= 0 || h <= 0) return false; const bw = sprite.bitmap.width|0, bh = sprite.bitmap.height|0; if (bw > 0 && bh > 0 && w === bw && h === bh) return false; // fullsheet return true; } const _Sprite_Character_updateFrame = Sprite_Character.prototype.updateFrame; Sprite_Character.prototype.updateFrame = function() { _Sprite_Character_updateFrame.call(this); if (!isBitmapReady(this)) return; const rect = currentRect(this); if (isValidNonFullRect(this, rect)) { this._sf_lastValidRect = rect; } }; const _Sprite_Character_setCharacterBitmap = Sprite_Character.prototype.setCharacterBitmap; Sprite_Character.prototype.setCharacterBitmap = function() { _Sprite_Character_setCharacterBitmap.call(this); this._sf_lastValidRect = null; }; const _Sprite_Character__render = Sprite_Character.prototype._render; Sprite_Character.prototype._render = function(renderer) { if (!isBitmapReady(this)) return; const rect = currentRect(this); if (!isValidNonFullRect(this, rect)) { if (this._sf_lastValidRect) { const r = this._sf_lastValidRect; this.setFrame(r.x, r.y, r.width, r.height); } else { return; // skip this tick } } _Sprite_Character__render.call(this, renderer); }; })();
2. Preloader Bug – getLoadingStatus
Issue:
In Hendrix_Animation_Solution.js
, the class PermanentImageCache
defines:
static getLoadingStatus() { return { .this._loadingStatus }; // ❌ invalid syntax }
This breaks preload checks in Scene_Boot.isReady
.
Fix:
It should safely return an object with totals:
static getLoadingStatus() { const s = this._loadingStatus || { total:0, loaded:0, failed:0 }; return { total: s.total | 0, loaded: s.loaded | 0, failed: s.failed | 0 }; }
Result:
-
Scene_Boot.isReady
no longer hangs when preload is active. -
Boot waits correctly until all images are loaded or failed.
Summary
-
Problem 1 (Rendering): 1-frame “fullsheet flash” → fixed by guarding invalid frames.
-
Problem 2 (Preloader):
getLoadingStatus()
invalid → fixed by returning proper object.
Both fixes can be integrated directly into Hendrix_Animation_Solution.js.
For now, I’m sharing my external patch plugin (SF_CharFrameGuard_MZ.js
) in case others need a quick solution.
Thanks again for your great work on this plugin – I hope these notes help improve it further!