diff --git a/source/funkin/backend/system/Flags.hx b/source/funkin/backend/system/Flags.hx index 9003cf21a9..2d1a7eb26b 100644 --- a/source/funkin/backend/system/Flags.hx +++ b/source/funkin/backend/system/Flags.hx @@ -227,6 +227,14 @@ class Flags { public static var DISABLE_LANGUAGES:Bool = false; public static var DISABLE_AUTOUPDATER:Bool = false; + /** + * DEBUG ONLY — REMEMBER TO REMOVE THIS BEFORE SHIPPING YOUR MOD! + * When enabled, every asset cache (textures, sounds, fonts, shaders) + * is cleared on every state switch/reload, forcing a re-fetch from disk as if the game just started. + * This flag exists purely for debugging stale asset issues and must be deleted from release builds. + */ + public static var CLEAR_ASSET_CACHE_ON_STATE_SWITCH:Bool = false; + @:also(funkin.backend.MusicBeatTransition.script) public static var DEFAULT_TRANSITION_SCRIPT:String = ""; @:also(funkin.menus.PauseSubState.script) diff --git a/source/funkin/backend/system/modules/FunkinCache.hx b/source/funkin/backend/system/modules/FunkinCache.hx index e1d8283497..19cbe22fc9 100644 --- a/source/funkin/backend/system/modules/FunkinCache.hx +++ b/source/funkin/backend/system/modules/FunkinCache.hx @@ -42,6 +42,34 @@ class FunkinCache extends AssetCache { FlxG.signals.postStateSwitch.add(function() { instance.clearSecondLayer(); }); + + FlxG.signals.preStateCreate.add(function(_) { + if (Flags.CLEAR_ASSET_CACHE_ON_STATE_SWITCH) + clearAllCaches(); + }); + } + + /** + Clears every asset cache (textures, sounds, fonts, shader programs) so everything is re-fetched from disk, as if the game just started. + **/ + public static function clearAllCaches() { + @:privateAccess + for (graphic in [for (g in FlxG.bitmap._cache) g]) { + if (graphic != null && graphic.assetsKey != null) + FlxG.bitmap.removeByKey(graphic.key); + } + if (instance != null) + instance.clearAll(); + clearShaderProgramCache(); + } + + /** + Clears openfl's compiled shader program cache, so edited shaders get recompiled on next use. + **/ + public static function clearShaderProgramCache() { + @:privateAccess + if (FlxG.stage != null && FlxG.stage.context3D != null && FlxG.stage.context3D.__programs != null) + FlxG.stage.context3D.__programs.clear(); } public function moveToSecondLayer() { @@ -53,6 +81,24 @@ class FunkinCache extends AssetCache { sound = []; } + /** + Completely clears both cache layers (including lime's own asset cache), + **/ + public function clearAll() { + for (k in [for (k in bitmapData.keys()) k]) + removeBitmapData(k); + for (k in [for (k in bitmapData2.keys()) k]) + removeBitmapData(k); + for (k in [for (k in font.keys()) k]) + removeFont(k); + for (k in [for (k in font2.keys()) k]) + removeFont(k); + for (k in [for (k in sound.keys()) k]) + removeSound(k); + for (k in [for (k in sound2.keys()) k]) + removeSound(k); + } + public function clearSecondLayer() { for(k=>b in bitmapData2) { FlxG.bitmap.removeByKey(k);