From 4fa0334e7bd393d8357b737cc6063d9a65ccb27f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 1 Apr 2025 16:41:46 -0400 Subject: [PATCH 01/23] easier script for creating macos universal binaries --- art | 2 +- docs/COMPILING_MAC.md | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 docs/COMPILING_MAC.md diff --git a/art b/art index 4efa0536a..78dc31021 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit 4efa0536a3a5ce41f7f4ee2fb2c631ba3e7793fd +Subproject commit 78dc310219370144719b4eeef9b3b511c5a44532 diff --git a/docs/COMPILING_MAC.md b/docs/COMPILING_MAC.md new file mode 100644 index 000000000..d62a8b86b --- /dev/null +++ b/docs/COMPILING_MAC.md @@ -0,0 +1,10 @@ +# Mac Compiling Guide + Considerations + +There's a few extra considerations when compiling FNF for Mac that *we* have to handle when creating a wider release. +- [Creating a Universal Binary](#creating-a-universal-binary) +- Code-signing +- Notarizing + +## Creating a Universal Binary + +Run the `art/macos-universal.sh` script, which automatically compiles release versions of both arm64 and x86 of Funkin. You can also see there for reference of how it's done. From 54cd52db766064f1d1a8dddb08cd2816c7209cb9 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 1 Apr 2025 14:48:16 -0400 Subject: [PATCH 02/23] Fix an issue where story mode medals would not be awarded without a personal best. --- source/funkin/play/PlayState.hx | 25 +++++++++---------- source/funkin/play/ResultState.hx | 3 ++- .../ui/charSelect/CharSelectSubState.hx | 2 ++ .../ui/debug/results/ResultsDebugSubState.hx | 2 ++ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 3b8d3e8b9..ac4e1670e 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -3017,7 +3017,7 @@ class PlayState extends MusicBeatSubState } }); - // Award various medals based on variation, difficulty, and scoring rank. + // Award various medals based on variation, difficulty, song ID, and scoring rank. if (scoreRank == ScoringRank.SHIT) Medals.award(LossRating); if (scoreRank >= ScoringRank.PERFECT && currentDifficulty == 'hard') Medals.award(PerfectRatingHard); if (scoreRank == ScoringRank.PERFECT_GOLD && currentDifficulty == 'hard') Medals.award(GoldPerfectRatingHard); @@ -3062,19 +3062,18 @@ class PlayState extends MusicBeatSubState }, }; - if (currentSong.validScore - && Save.instance.isLevelHighScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, data)) + #if FEATURE_NEWGROUNDS + // Award a medal for beating a Story level. + Medals.awardStoryLevel(PlayStatePlaylist.campaignId); + + // Submit the score for the Story level to Newgrounds. + Leaderboards.submitLevelScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, PlayStatePlaylist.campaignScore); + + Events.logCompleteLevel(PlayStatePlaylist.campaignId); + #end + + if (Save.instance.isLevelHighScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, data)) { - #if FEATURE_NEWGROUNDS - // Award a medal for beating a Story level. - Medals.awardStoryLevel(PlayStatePlaylist.campaignId); - - // Submit the score for the Story level to Newgrounds. - Leaderboards.submitLevelScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, PlayStatePlaylist.campaignScore); - - Events.logCompleteLevel(PlayStatePlaylist.campaignId); - #end - Save.instance.setLevelScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, data); isNewHighscore = true; } diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 976fcd5ee..9a6cb0343 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -502,8 +502,9 @@ class ResultState extends MusicBeatSubState clearPercentCounter.curNumber = clearPercentTarget; #if FEATURE_NEWGROUNDS + var isScoreValid = !(params?.isPracticeMode ?? false) && !(params?.isBotPlayMode ?? false); // This is the easiest spot to do the medal calculation lol. - if (clearPercentTarget == 69) Medals.award(Nice); + if (isScoreValid && clearPercentTarget == 69) Medals.award(Nice); #end clearPercentCounter.flash(true); diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index eb7adb6a7..48a88be33 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -425,6 +425,7 @@ class CharSelectSubState extends MusicBeatSubState else { #if FEATURE_NEWGROUNDS + // Make the character unlock medal retroactive. if (availableChars.size() > 1) Medals.award(CharSelect); #end @@ -570,6 +571,7 @@ class CharSelectSubState extends MusicBeatSubState }); #if FEATURE_NEWGROUNDS + // Grant the medal when the player unlocks a character. Medals.award(CharSelect); #end diff --git a/source/funkin/ui/debug/results/ResultsDebugSubState.hx b/source/funkin/ui/debug/results/ResultsDebugSubState.hx index 011888991..81628f30f 100644 --- a/source/funkin/ui/debug/results/ResultsDebugSubState.hx +++ b/source/funkin/ui/debug/results/ResultsDebugSubState.hx @@ -126,6 +126,8 @@ class ResultsDebugSubState extends MusicBeatSubState characterId: "bf", difficultyId: "nightmare", isNewHighscore: true, + isPracticeMode: true, // Invalidates achievements/scores. + isBotPlayMode: true, // Invalidates achievements/scores. scoreData: { score: 1_234_567, From 17a4be66b92be9aafb4df6a4df9afc7b80924f29 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 1 Apr 2025 15:14:54 -0400 Subject: [PATCH 03/23] Fix highscores not submitting to the website unless they are a personal best. --- source/funkin/play/PlayState.hx | 4 ++++ source/funkin/save/Save.hx | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index ac4e1670e..9f4c4954f 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2975,6 +2975,10 @@ class PlayState extends MusicBeatSubState // adds current song data into the tallies for the level (story levels) Highscore.talliesLevel = Highscore.combineTallies(Highscore.tallies, Highscore.talliesLevel); + #if FEATURE_NEWGROUNDS + Leaderboards.submitSongScore(currentSong.id, suffixedDifficulty, data); + #end + if (!isPracticeMode && !isBotPlayMode) { #if FEATURE_NEWGROUNDS diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 1eb22d48b..332610fe3 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -730,10 +730,6 @@ class Save // Directly set the highscore. setSongScore(songId, difficultyId, newScoreData); - #if FEATURE_NEWGROUNDS - Leaderboards.submitSongScore(songId, difficultyId, newScoreData.score); - #end - return; } From 3bd79b822e226bbdb3599315c95d5de9232b7bcd Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 1 Apr 2025 19:27:18 -0400 Subject: [PATCH 04/23] Fix a deprecation warning. --- source/funkin/save/Save.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 332610fe3..503fc8348 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -983,6 +983,7 @@ class Save * If you set slot to `2`, it will load an independent save file from slot 2. * @param slot */ + @:haxe.warning("-WDeprecated") static function loadFromSlot(slot:Int):Save { trace('[SAVE] Loading save from slot $slot...'); From f8b212a3189bed4f39874fe3f3c36507f67f9161 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 1 Apr 2025 19:28:28 -0400 Subject: [PATCH 05/23] Improve null safety of medal and leaderboard classes. --- source/funkin/api/newgrounds/Events.hx | 16 +++-- source/funkin/api/newgrounds/Leaderboards.hx | 31 ++++++---- source/funkin/api/newgrounds/Medals.hx | 63 ++++++++++---------- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/source/funkin/api/newgrounds/Events.hx b/source/funkin/api/newgrounds/Events.hx index f38baf2a0..3335e57f1 100644 --- a/source/funkin/api/newgrounds/Events.hx +++ b/source/funkin/api/newgrounds/Events.hx @@ -8,6 +8,7 @@ import io.newgrounds.objects.events.Result; /** * Use Newgrounds to perform basic telemetry. Ignore if not logged in to Newgrounds. */ +@:nullSafety class Events { // Only allow letters, numbers, spaces, dashes, and underscores. @@ -16,16 +17,13 @@ class Events public static function logEvent(eventName:String):Void { #if (FEATURE_NEWGROUNDS && FEATURE_NEWGROUNDS_EVENTS) - if (NewgroundsClient.instance.isLoggedIn()) - { - var eventHandler = NG.core.calls.event; + var eventHandler = NG.core.calls.event; - if (eventHandler != null) - { - var sanitizedEventName = EVENT_NAME_REGEX.replace(eventName, ''); - var outcomeHandler = onEventLogged.bind(sanitizedEventName, _); - eventHandler.logEvent(sanitizedEventName).addOutcomeHandler(outcomeHandler).send(); - } + if (eventHandler != null) + { + var sanitizedEventName = EVENT_NAME_REGEX.replace(eventName, ''); + var outcomeHandler = onEventLogged.bind(sanitizedEventName, _); + eventHandler.logEvent(sanitizedEventName).addOutcomeHandler(outcomeHandler).send(); } #end } diff --git a/source/funkin/api/newgrounds/Leaderboards.hx b/source/funkin/api/newgrounds/Leaderboards.hx index 43939ec64..5c7e5e73e 100644 --- a/source/funkin/api/newgrounds/Leaderboards.hx +++ b/source/funkin/api/newgrounds/Leaderboards.hx @@ -4,29 +4,33 @@ package funkin.api.newgrounds; import io.newgrounds.Call.CallError; import io.newgrounds.objects.ScoreBoard as LeaderboardData; import io.newgrounds.objects.events.Outcome; +import io.newgrounds.utils.ScoreBoardList; class Leaderboards { public static function listLeaderboardData():Map { - if (NewgroundsClient.instance.leaderboards == null) + var leaderboardList:Null = NewgroundsClient.instance.leaderboards; + if (leaderboardList == null) { trace('[NEWGROUNDS] Not logged in, cannot fetch medal data!'); return []; } - - var result:Map = []; - - for (leaderboardId in NewgroundsClient.instance.leaderboards.keys()) + else { - var leaderboardData = NewgroundsClient.instance.leaderboards.get(leaderboardId); - if (leaderboardData == null) continue; + var result:Map = []; - // A little hacky, but it works. - result.set(cast leaderboardId, leaderboardData); + for (leaderboardId in leaderboardList.keys()) + { + var leaderboardData = leaderboardList.get(leaderboardId); + if (leaderboardData == null) continue; + + // A little hacky, but it works. + result.set(cast leaderboardId, leaderboardData); + } + + return result; } - - return result; } /** @@ -42,7 +46,10 @@ class Leaderboards if (NewgroundsClient.instance.isLoggedIn()) { - var leaderboardData = NewgroundsClient.instance.leaderboards.get(leaderboard.getId()); + var leaderboardList = NewgroundsClient.instance.leaderboards; + if (leaderboardList == null) return; + + var leaderboardData:Null = leaderboardList.get(leaderboard.getId()); if (leaderboardData != null) { leaderboardData.postScore(score, function(outcome:Outcome):Void { diff --git a/source/funkin/api/newgrounds/Medals.hx b/source/funkin/api/newgrounds/Medals.hx index cd3c6be7a..5674ae15d 100644 --- a/source/funkin/api/newgrounds/Medals.hx +++ b/source/funkin/api/newgrounds/Medals.hx @@ -5,54 +5,55 @@ import io.newgrounds.objects.Medal as MedalData; import funkin.util.plugins.NewgroundsMedalPlugin; import flixel.graphics.FlxGraphic; import openfl.display.BitmapData; +import io.newgrounds.utils.MedalList; import haxe.Json; class Medals { - public static var medalJSON:Array; + public static var medalJSON:Array = []; public static function listMedalData():Map { - if (NewgroundsClient.instance.medals == null) + var medalList = NewgroundsClient.instance.medals; + + if (medalList == null) { trace('[NEWGROUNDS] Not logged in, cannot fetch medal data!'); return []; } - - var result:Map = []; - - for (medalId in NewgroundsClient.instance.medals.keys()) + else { - var medalData = NewgroundsClient.instance.medals.get(medalId); - if (medalData == null) continue; + // TODO: Why do I have to do this, @:nullSafety is fucked up + var result:Map = []; - // A little hacky, but it works. - result.set(cast medalId, medalData); + for (medalId in medalList.keys()) + { + var medalData = medalList.get(medalId); + if (medalData == null) continue; + + // A little hacky, but it works. + result.set(cast medalId, medalData); + } + + return result; } - - return result; - } - - static function isValid(medalData:MedalData):Bool - { - // IDK why medalData can exist but _data can be null... - // TODO: Move checks to the NG library. - @:privateAccess - return (medalData != null && medalData._data != null); } public static function award(medal:Medal):Void { if (NewgroundsClient.instance.isLoggedIn()) { - var medalData = NewgroundsClient.instance.medals.get(medal.getId()); - if (!isValid(medalData)) + var medalList = NewgroundsClient.instance.medals; + if (medalList == null) return; + + var medalData:Null = medalList.get(medal.getId()); + @:privateAccess + if (medalData == null || medalData._data == null) { trace('[NEWGROUNDS] Could not retrieve data for medal: ${medal}'); return; } - - if (!medalData.unlocked) + else if (!medalData.unlocked) { trace('[NEWGROUNDS] Awarding medal (${medal}).'); medalData.sendUnlock(); @@ -70,8 +71,6 @@ class Medals // We have to use a medal image from the game files. We use a Base64 encoded image that NG spits out. // TODO: Wait, don't they give us the medal icon? - var g:FlxGraphic = null; - var localMedalData:Null = medalJSON.filter(function(jsonMedal) { #if FEATURE_NEWGROUNDS_TESTING_MEDALS return medal == jsonMedal.idTest; @@ -86,10 +85,14 @@ class Medals // Lime/OpenFL parses it without the included prefix stuff, so we remove it. str = str.replace("data:image/png;base64,", "").trim(); var bitmapData = BitmapData.fromBase64(str, "image/png"); - if (str != null) g = FlxGraphic.fromBitmapData(bitmapData); - g.persist = true; + var medalGraphic:Null = null; + if (str != null) + { + medalGraphic = FlxGraphic.fromBitmapData(bitmapData); + medalGraphic.persist = true; + } - NewgroundsMedalPlugin.play(medalData.value, medalData.name, g); + NewgroundsMedalPlugin.play(medalData.value, medalData.name, medalGraphic); #end } else @@ -119,7 +122,7 @@ class Medals trace('[NEWGROUNDS] Failed to parse local medal data!'); for (error in parser.errors) funkin.data.DataError.printError(error); - medalJSON = null; + medalJSON = []; } else { From 102ac4bfc8250ae7e07371e0660357e52ac8b854 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 2 Apr 2025 02:30:08 -0400 Subject: [PATCH 06/23] Fix a bug where restarting the level would add more Tankmen to the background. --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 24eb271f3..0722c8cf3 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 24eb271f3bb3370a665d08e0b7e587a2ed9faf29 +Subproject commit 0722c8cf3f39834f38acbbc564066b0630716fe8 From f935526baaa46a9e0a690936eee6cda37dd10c4e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 31 Mar 2025 23:26:58 -0400 Subject: [PATCH 07/23] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 0722c8cf3..6cd1a21e6 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0722c8cf3f39834f38acbbc564066b0630716fe8 +Subproject commit 6cd1a21e618461c48e97e800a0a7573514df10cd From 8291fe0407fc5298b9d71fda8b48f6db898204f8 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 2 Apr 2025 04:12:06 -0400 Subject: [PATCH 08/23] Make the back of ABot's stereo display slightly wider. --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6cd1a21e6..d8da3e01e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6cd1a21e618461c48e97e800a0a7573514df10cd +Subproject commit d8da3e01ec68cc5f9e5a169a75890838ccb39791 From c94b3a3b6579de27b68491994c70eafe3246395c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 2 Apr 2025 13:41:54 -0400 Subject: [PATCH 09/23] 2024 -> 2025 0.6.x changelog date fixins (closes FUNK-1740) --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec5717c73..7f911d413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,18 +4,18 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.6.2] - 2024-03-31 +## [0.6.2] - 2025-03-31 ### Added - 0.6 credits list updated ### Fixed - Additional shader fix for Stress Pico crashing at the end (was the same issue as Senpai Pico shader error, just in a different shaderfile) -## [0.6.1] - 2024-03-31 +## [0.6.1] - 2025-03-31 ### Fixed - Hopefully Senpai Pico/Erect mix shader isn't brokey - NG API encryption key was added proper, so medals + leaderboards posting should work -## [0.6.0] - 2024-03-31 +## [0.6.0] - 2025-03-31 The Pit Stop 2 update! ### Added - Added six (!) new playable songs! Check them out in the Freeplay menu for their respective characters. From 52be941b4503da0ac76918e2482ab1804866f2cf Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 2 Apr 2025 13:55:54 -0400 Subject: [PATCH 10/23] Auto Pause -> Pause on Unfocus (was changed before but prob bad merge somewhere reverted it?) --- source/funkin/ui/options/PreferencesMenu.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index c26febb83..ff5ae1f13 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -112,7 +112,7 @@ class PreferencesMenu extends Page createPrefItemCheckbox('Debug Display', 'If enabled, FPS and other debug stats will be displayed.', function(value:Bool):Void { Preferences.debugDisplay = value; }, Preferences.debugDisplay); - createPrefItemCheckbox('Auto Pause', 'If enabled, game automatically pauses when it loses focus.', function(value:Bool):Void { + createPrefItemCheckbox('Pause on Unfocus', 'If enabled, game automatically pauses when it loses focus.', function(value:Bool):Void { Preferences.autoPause = value; }, Preferences.autoPause); createPrefItemCheckbox('Launch in Fullscreen', 'Automatically launch the game in fullscreen on startup', function(value:Bool):Void { From 62621881c0ff11b4cb37fbd20e3229075e786eb6 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 2 Apr 2025 16:18:58 -0400 Subject: [PATCH 11/23] data -> data.score --- source/funkin/play/PlayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 9f4c4954f..7ac949424 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2976,7 +2976,7 @@ class PlayState extends MusicBeatSubState Highscore.talliesLevel = Highscore.combineTallies(Highscore.tallies, Highscore.talliesLevel); #if FEATURE_NEWGROUNDS - Leaderboards.submitSongScore(currentSong.id, suffixedDifficulty, data); + Leaderboards.submitSongScore(currentSong.id, suffixedDifficulty, data.score); #end if (!isPracticeMode && !isBotPlayMode) From 9b5032ee8426d95718e26ba79851be704723278d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 2 Apr 2025 21:54:27 -0400 Subject: [PATCH 12/23] quick patch for cory --- source/funkin/api/newgrounds/Events.hx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/funkin/api/newgrounds/Events.hx b/source/funkin/api/newgrounds/Events.hx index 3335e57f1..f54a607c9 100644 --- a/source/funkin/api/newgrounds/Events.hx +++ b/source/funkin/api/newgrounds/Events.hx @@ -17,13 +17,16 @@ class Events public static function logEvent(eventName:String):Void { #if (FEATURE_NEWGROUNDS && FEATURE_NEWGROUNDS_EVENTS) - var eventHandler = NG.core.calls.event; - - if (eventHandler != null) + if (NewgroundsClient.instance.isLoggedIn()) { - var sanitizedEventName = EVENT_NAME_REGEX.replace(eventName, ''); - var outcomeHandler = onEventLogged.bind(sanitizedEventName, _); - eventHandler.logEvent(sanitizedEventName).addOutcomeHandler(outcomeHandler).send(); + var eventHandler = NG.core.calls.event; + + if (eventHandler != null) + { + var sanitizedEventName = EVENT_NAME_REGEX.replace(eventName, ''); + var outcomeHandler = onEventLogged.bind(sanitizedEventName, _); + eventHandler.logEvent(sanitizedEventName).addOutcomeHandler(outcomeHandler).send(); + } } #end } From afb4a3dd6856ecdbbe5daf76d644cc4e9d420edf Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 2 Apr 2025 22:59:20 -0400 Subject: [PATCH 13/23] Remove some unused/redundant debug hotkeys. --- source/funkin/play/ResultState.hx | 27 ----------------- source/funkin/ui/charSelect/CharSelectGF.hx | 14 --------- source/funkin/ui/freeplay/FreeplayDJ.hx | 30 ------------------- source/funkin/ui/freeplay/FreeplayState.hx | 10 ------- source/funkin/ui/title/TitleState.hx | 3 -- source/funkin/ui/transition/LoadingState.hx | 4 --- .../funkin/ui/transition/StickerSubState.hx | 5 ---- 7 files changed, 93 deletions(-) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 9a6cb0343..87aa2cb50 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -698,33 +698,6 @@ class ResultState extends MusicBeatSubState override function update(elapsed:Float):Void { - // if(FlxG.keys.justPressed.R){ - // FlxG.switchState(() -> new funkin.play.ResultState( - // { - // storyMode: false, - // title: "Cum Song Erect by Kawai Sprite", - // songId: "cum", - // difficultyId: "nightmare", - // isNewHighscore: true, - // scoreData: - // { - // score: 1_234_567, - // tallies: - // { - // sick: 200, - // good: 0, - // bad: 0, - // shit: 0, - // missed: 0, - // combo: 0, - // maxCombo: 69, - // totalNotesHit: 200, - // totalNotes: 200 // 0, - // } - // }, - // })); - // } - // maskShaderSongName.swagSprX = songName.x; maskShaderDifficulty.swagSprX = difficulty.x; diff --git a/source/funkin/ui/charSelect/CharSelectGF.hx b/source/funkin/ui/charSelect/CharSelectGF.hx index 8e8cf5994..095551741 100644 --- a/source/funkin/ui/charSelect/CharSelectGF.hx +++ b/source/funkin/ui/charSelect/CharSelectGF.hx @@ -54,20 +54,6 @@ class CharSelectGF extends FlxAtlasSprite implements IBPMSyncedScriptedClass doFade(animInInfo); default: } - - #if FEATURE_DEBUG_FUNCTIONS - if (FlxG.keys.justPressed.J) - { - alpha = 1; - x = y = 0; - fadingStatus = FADE_OUT; - } - if (FlxG.keys.justPressed.K) - { - alpha = 0; - fadingStatus = FADE_IN; - } - #end } public function onStepHit(event:SongTimeScriptEvent):Void {} diff --git a/source/funkin/ui/freeplay/FreeplayDJ.hx b/source/funkin/ui/freeplay/FreeplayDJ.hx index 7c3ecb46f..6c6ab9535 100644 --- a/source/funkin/ui/freeplay/FreeplayDJ.hx +++ b/source/funkin/ui/freeplay/FreeplayDJ.hx @@ -183,36 +183,6 @@ class FreeplayDJ extends FlxAtlasSprite default: // I shit myself. } - - #if FEATURE_DEBUG_FUNCTIONS - if (FlxG.keys.pressed.CONTROL) - { - if (FlxG.keys.justPressed.LEFT) - { - this.offsetX -= FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); - } - - if (FlxG.keys.justPressed.RIGHT) - { - this.offsetX += FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); - } - - if (FlxG.keys.justPressed.UP) - { - this.offsetY -= FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); - } - - if (FlxG.keys.justPressed.DOWN) - { - this.offsetY += FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); - } - - if (FlxG.keys.justPressed.C) - { - currentState = (currentState == Idle ? Cartoon : Idle); - } - } - #end } function onFinishAnim(name:String):Void diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index ed875512b..b02dbc7c7 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1300,16 +1300,6 @@ class FreeplayState extends MusicBeatSubState difficultyId: "hard" }, grpCapsules.members[curSelected]); } - - // if (FlxG.keys.justPressed.H) - // { - // rankDisplayNew(fromResultsParams); - // } - - // if (FlxG.keys.justPressed.G) - // { - // rankAnimSlam(fromResultsParams); - // } #end // ^<-- FEATURE_DEBUG_FUNCTIONS if (controls.FREEPLAY_CHAR_SELECT && !busy) diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index b12a1f024..fef121adf 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -264,9 +264,6 @@ class TitleState extends MusicBeatState if (gamepad != null) { if (gamepad.justPressed.START) pressedEnter = true; - #if switch - if (gamepad.justPressed.B) pressedEnter = true; - #end } // If you spam Enter, we should skip the transition. diff --git a/source/funkin/ui/transition/LoadingState.hx b/source/funkin/ui/transition/LoadingState.hx index ce9b6b9de..7957ab6ca 100644 --- a/source/funkin/ui/transition/LoadingState.hx +++ b/source/funkin/ui/transition/LoadingState.hx @@ -171,10 +171,6 @@ class LoadingState extends MusicBeatSubState } FlxG.watch.addQuick('percentage?', callbacks.numRemaining / callbacks.length); } - - #if FEATURE_DEBUG_FUNCTIONS - if (FlxG.keys.justPressed.SPACE) trace('fired: ' + callbacks.getFired() + ' unfired:' + callbacks.getUnfired()); - #end } function onLoad():Void diff --git a/source/funkin/ui/transition/StickerSubState.hx b/source/funkin/ui/transition/StickerSubState.hx index 5a17d6e11..9e98dbb6d 100644 --- a/source/funkin/ui/transition/StickerSubState.hx +++ b/source/funkin/ui/transition/StickerSubState.hx @@ -301,11 +301,6 @@ class StickerSubState extends MusicBeatSubState override public function update(elapsed:Float):Void { super.update(elapsed); - - // if (FlxG.keys.justPressed.ANY) - // { - // regenStickers(); - // } } var switchingState:Bool = false; From eb9c2c2c99ead7ac47cad0b6f913e88370cc773d Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 2 Apr 2025 23:41:37 -0400 Subject: [PATCH 14/23] Fix Pixo's freeplay AFK animation not playing (properly this time). --- .../graphics/adobeanimate/FlxAtlasSprite.hx | 19 ++++++++++++++++++- source/funkin/ui/freeplay/FreeplayDJ.hx | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx index d3eba3306..5541b2184 100644 --- a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx +++ b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx @@ -35,6 +35,11 @@ class FlxAtlasSprite extends FlxAnimate */ public var onAnimationComplete:FlxTypedSignalVoid> = new FlxTypedSignal(); + /** + * Signal dispatched when a looping animation finishes playing. + */ + public var onAnimationLoop:FlxTypedSignalVoid> = new FlxTypedSignal(); + var currentAnimation:String; var canPlayOtherAnims:Bool = true; @@ -307,7 +312,7 @@ class FlxAtlasSprite extends FlxAnimate { anim.curFrame = (fr != null) ? fr.index : 0; anim.resume(); - // _onAnimationComplete not called since this is a loop. + _onAnimationLoop(); } else if (fr != null && anim.curFrame != anim.length - 1) { @@ -331,6 +336,18 @@ class FlxAtlasSprite extends FlxAnimate } } + function _onAnimationLoop():Void + { + if (currentAnimation != null) + { + onAnimationLoop.dispatch(currentAnimation); + } + else + { + onAnimationLoop.dispatch(''); + } + } + var prevFrames:Map = []; public function replaceFrameGraphic(index:Int, ?graphic:FlxGraphicAsset):Void diff --git a/source/funkin/ui/freeplay/FreeplayDJ.hx b/source/funkin/ui/freeplay/FreeplayDJ.hx index 6c6ab9535..792d0c8d9 100644 --- a/source/funkin/ui/freeplay/FreeplayDJ.hx +++ b/source/funkin/ui/freeplay/FreeplayDJ.hx @@ -58,6 +58,7 @@ class FreeplayDJ extends FlxAtlasSprite FlxG.console.registerObject("dj", this); onAnimationComplete.add(onFinishAnim); + onAnimationLoop.add(onFinishAnim); FlxG.console.registerFunction("freeplayCartoon", function() { currentState = Cartoon; From c1573387836797518c369b960f1bf303d5645ce1 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 3 Apr 2025 00:34:15 -0400 Subject: [PATCH 15/23] Fix certain characters pixel icons not displaying properly in the chart editor. --- source/funkin/play/character/CharacterData.hx | 4 ++-- source/funkin/ui/PixelatedIcon.hx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/funkin/play/character/CharacterData.hx b/source/funkin/play/character/CharacterData.hx index 54e7a6afb..9465ccfc3 100644 --- a/source/funkin/play/character/CharacterData.hx +++ b/source/funkin/play/character/CharacterData.hx @@ -296,7 +296,7 @@ class CharacterDataParser charPath += "monsterpixel"; case "mom" | "mom-car": charPath += "mommypixel"; - case "pico-blazin" | "pico-playable" | "pico-speaker": + case "pico-blazin" | "pico-playable" | "pico-speaker" | "pico-pixel" | "pico-holding-nene": charPath += "picopixel"; case "gf-christmas" | "gf-car" | "gf-pixel" | "gf-tankmen" | "gf-dark": charPath += "gfpixel"; @@ -308,7 +308,7 @@ class CharacterDataParser charPath += "senpaipixel"; case "spooky-dark": charPath += "spookypixel"; - case "tankman-atlas": + case "tankman-atlas" | "tankman-bloody": charPath += "tankmanpixel"; case "pico-christmas" | "pico-dark": charPath += "picopixel"; diff --git a/source/funkin/ui/PixelatedIcon.hx b/source/funkin/ui/PixelatedIcon.hx index a37261411..280ed98d0 100644 --- a/source/funkin/ui/PixelatedIcon.hx +++ b/source/funkin/ui/PixelatedIcon.hx @@ -28,7 +28,7 @@ class PixelatedIcon extends FlxFilteredSprite charPath += "monsterpixel"; case "mom" | "mom-car": charPath += "mommypixel"; - case "pico-blazin" | "pico-playable" | "pico-speaker": + case "pico-blazin" | "pico-playable" | "pico-speaker" | "pico-pixel" | "pico-holding-nene": charPath += "picopixel"; case "gf-christmas" | "gf-car" | "gf-pixel" | "gf-tankmen": charPath += "gfpixel"; From 68e9daffe808e9c3f9c5e39e580aaa96753e28bf Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 3 Apr 2025 00:29:47 -0400 Subject: [PATCH 16/23] Zero out the ABot visualizer before the song starts. --- assets | 2 +- source/funkin/audio/visualize/ABotVis.hx | 124 ++++++----------------- 2 files changed, 33 insertions(+), 93 deletions(-) diff --git a/assets b/assets index d8da3e01e..0303a03f4 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d8da3e01ec68cc5f9e5a169a75890838ccb39791 +Subproject commit 0303a03f43b078d5263b541de1ff504fd7cfcde5 diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index 731473d35..5d8633e0f 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -9,14 +9,17 @@ import funkin.vis.dsp.SpectralAnalyzer; using Lambda; +@:nullSafety class ABotVis extends FlxTypedSpriteGroup { // public var vis:VisShit; - var analyzer:SpectralAnalyzer; + var analyzer:Null = null; var volumes:Array = []; - public var snd:FlxSound; + public var snd:Null = null; + + static final BAR_COUNT:Int = 7; // TODO: Make the sprites easier to soft code. public function new(snd:FlxSound, pixel:Bool) @@ -25,7 +28,7 @@ class ABotVis extends FlxTypedSpriteGroup this.snd = snd; - var visCount = pixel ? (7 + 1) : (7 + 1); + var visCount = pixel ? (BAR_COUNT + 1) : (BAR_COUNT + 1); var visScale = pixel ? 6 : 1; var visFrms:FlxAtlasFrames = Paths.getSparrowAtlas(pixel ? 'characters/abotPixel/aBotVizPixel' : 'characters/abot/aBotViz'); @@ -58,8 +61,10 @@ class ABotVis extends FlxTypedSpriteGroup public function initAnalyzer():Void { + if (snd == null) return; + @:privateAccess - analyzer = new SpectralAnalyzer(snd._channel.__audioSource, 7, 0.1, 40); + analyzer = new SpectralAnalyzer(snd._channel.__audioSource, BAR_COUNT, 0.1, 40); // A-Bot tuning... analyzer.minDb = -65; analyzer.maxDb = -25; @@ -77,16 +82,17 @@ class ABotVis extends FlxTypedSpriteGroup // analyzer.fftN = 2048; } + public function dumpSound():Void + { + snd = null; + analyzer = null; + } + var visTimer:Float = -1; var visTimeMax:Float = 1 / 30; override function update(elapsed:Float) { - // updateViz(); - - // updateFFT(elapsed); - - // super.update(elapsed); } @@ -97,8 +103,8 @@ class ABotVis extends FlxTypedSpriteGroup override function draw() { - if (analyzer != null) drawFFT(); super.draw(); + drawFFT(); } /** @@ -106,7 +112,7 @@ class ABotVis extends FlxTypedSpriteGroup */ function drawFFT():Void { - var levels = analyzer.getLevels(); + var levels = (analyzer != null) ? analyzer.getLevels() : getDefaultLevels(); for (i in 0...min(group.members.length, levels.length)) { @@ -118,12 +124,6 @@ class ABotVis extends FlxTypedSpriteGroup // decrement our animFrame, so we can get a value from 0-5 for animation frames animFrame -= 1; - #if desktop - // Web version scales with the Flixel volume level. - // This line brings platform parity but looks worse. - // animFrame = Math.round(animFrame * FlxG.sound.volume); - #end - animFrame = Math.floor(Math.min(5, animFrame)); animFrame = Math.floor(Math.max(0, animFrame)); @@ -133,79 +133,19 @@ class ABotVis extends FlxTypedSpriteGroup } } - // function updateFFT(elapsed:Float) - // { - // if (vis.snd != null) - // { - // vis.checkAndSetBuffer(); - // if (vis.setBuffer) - // { - // var remappedShit:Int = 0; - // if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); - // else - // remappedShit = Std.int(FlxMath.remapToRange(Conductor.instance.songPosition, 0, vis.snd.length, 0, vis.numSamples)); - // var fftSamples:Array = []; - // var swagBucks = remappedShit; - // for (i in remappedShit...remappedShit + (Std.int((44100 * (1 / 144))))) - // { - // var left = vis.audioData[swagBucks] / 32767; - // var right = vis.audioData[swagBucks + 1] / 32767; - // var balanced = (left + right) / 2; - // swagBucks += 2; - // fftSamples.push(balanced); - // } - // var freqShit = vis.funnyFFT(fftSamples); - // for (i in 0...group.members.length) - // { - // var getSliceShit = function(s:Int) { - // var powShit = FlxMath.remapToRange(s, 0, group.members.length, 0, MathUtil.logBase(10, freqShit[0].length)); - // return Math.round(Math.pow(10, powShit)); - // }; - // // var powShit:Float = getSliceShit(i); - // var hzSliced:Int = getSliceShit(i); - // var sliceLength:Int = Std.int(freqShit[0].length / group.members.length); - // var volSlice = freqShit[0].slice(hzSliced, getSliceShit(i + 1)); - // var avgVel:Float = 0; - // for (slice in volSlice) - // { - // avgVel += slice; - // } - // avgVel /= volSlice.length; - // avgVel *= 10000000; - // volumes[i] += avgVel - (elapsed * (volumes[i] * 50)); - // var animFrame:Int = Std.int(volumes[i]); - // animFrame = Math.floor(Math.min(5, animFrame)); - // animFrame = Math.floor(Math.max(0, animFrame)); - // animFrame = Std.int(Math.abs(animFrame - 5)); // shitty dumbass flip, cuz dave got da shit backwards lol! - // group.members[i].animation.curAnim.curFrame = animFrame; - // if (FlxG.keys.justPressed.U) - // { - // trace(avgVel); - // trace(group.members[i].animation.curAnim.curFrame); - // } - // } - // // group.members[0].animation.curAnim.curFrame = - // } - // } - // } - // public function updateViz() - // { - // if (vis.snd != null) - // { - // var remappedShit:Int = 0; - // vis.checkAndSetBuffer(); - // if (vis.setBuffer) - // { - // // var startingSample:Int = Std.int(FlxMath.remapToRange) - // if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); - // for (i in 0...group.members.length) - // { - // var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, remappedShit, remappedShit + 500)); - // var left = vis.audioData[sampleApprox] / 32767; - // var animFrame:Int = Std.int(FlxMath.remapToRange(left, -1, 1, 0, 6)); - // group.members[i].animation.curAnim.curFrame = animFrame; - // } - // } - // } - // } + /** + * Explicitly define the default levels to draw when the analyzer is not available. + * @return Array + */ + static function getDefaultLevels():Array + { + var result:Array = []; + + for (i in 0...BAR_COUNT) + { + result.push({value: 0, peak: 0.0}); + } + + return result; + } } From d31ef123639b3220a0fb29ca0ba444ab52c8aecf Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 4 Apr 2025 14:28:12 -0400 Subject: [PATCH 17/23] Use public submodule URLs (would be nice if this was automatic but oh well) --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index ad8099e60..f9d5fd497 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "assets"] path = assets - url = https://github.com/FunkinCrew/Funkin-assets-secret + url = https://github.com/FunkinCrew/Funkin.assets [submodule "art"] path = art - url = https://github.com/FunkinCrew/Funkin-art-secret + url = https://github.com/FunkinCrew/Funkin.art From 3dd3338ab20db7df68e7bf1480c745024bf0fc01 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Fri, 4 Apr 2025 18:32:03 -0600 Subject: [PATCH 18/23] Remove 0.6.0 Changelog entries that weren't implemented + polish --- CHANGELOG.md | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f911d413..f30cef15c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,20 +4,34 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + ## [0.6.2] - 2025-03-31 + ### Added -- 0.6 credits list updated + +- Updated the 0.6 credits list + ### Fixed -- Additional shader fix for Stress Pico crashing at the end (was the same issue as Senpai Pico shader error, just in a different shaderfile) + +- Additional shader fix for Stress (Pico Mix) crashing at the end (was the same issue as Senpai Pico shader error, just in a different shaderfile) + + ## [0.6.1] - 2025-03-31 + ### Fixed + - Hopefully Senpai Pico/Erect mix shader isn't brokey - NG API encryption key was added proper, so medals + leaderboards posting should work + + ## [0.6.0] - 2025-03-31 The Pit Stop 2 update! + ### Added + - Added six (!) new playable songs! Check them out in the Freeplay menu for their respective characters. - Cocoa (Pico Mix) - Senpai (Pico Mix) @@ -38,7 +52,6 @@ The Pit Stop 2 update! - The new sticker system isn't fully available to mods yet, but we're working on it! - New option in the Preferences menu: Strumline Backgrounds! - Options in the Preferences menu now display an on-screen description when selected. -- Added a little easter egg to Pico's Good Results Screen animation. - The HOME and END keys now jump to the top and bottom of the Freeplay song list, respectively. ([bb974c2](https://github.com/FunkinCrew/Funkin/commit/bb974c264270d10ff503784063e5d77bb352b3f7)) - by @AbnormalPoof in [#4103](https://github.com/FunkinCrew/Funkin/pull/4103) - Added an option to launch the game in fullscreen. ([ee53ccd](https://github.com/FunkinCrew/Funkin/commit/ee53ccd32721e0790adfe82c60d4aca419db0a7f)) - by @AbnormalPoof in [#3738](https://github.com/FunkinCrew/Funkin/pull/3738) - Added descriptions for each item in the Preferences menu. ([a17b0e8](https://github.com/FunkinCrew/Funkin/commit/a17b0e8b3cc1d56fcdc0b51eaca9fd57cdb5bce0)) - by @anysad in [#3872](https://github.com/FunkinCrew/Funkin/pull/3872) @@ -52,42 +65,31 @@ The Pit Stop 2 update! - Added `DEBUG_BUILD` value to `Constants` to indicate whether a build has debug functions enabled. ([ad45b72](https://github.com/FunkinCrew/Funkin/commit/ad45b72b1ae8eb73a12dc51bcb59f66cc55e7bbd)) - by @AbnormalPoof in [#3853](https://github.com/FunkinCrew/Funkin/pull/3853) ### Changed + - Switched from hxCodec to hxvlc for video playback. This may break a mod or two. - Check the [Funkin Modding Docs](https://funkincrew.github.io/funkin-modding-docs/09-migration/09-02-0.5.0-to-0.6.0.html) for more info on how to update your mods. - Polymod should now ignore `.git` files when loading mods. -- Lots of improvements to issue and pull request organization. - by @Hundrec and @AbnormalPoof +- Lots of improvements to GitHub issue and pull request organization. - by @Hundrec and @AbnormalPoof - Overhauled the Changelog to improve readability and properly credit contributors. ([4383fcf](https://github.com/FunkinCrew/Funkin/commit/4383fcf32c280a1c0ee7b9c80d255611d497cabc)) - by @Hundrec in [#4296](https://github.com/FunkinCrew/Funkin/pull/4296) and [#4298](https://github.com/FunkinCrew/Funkin/pull/4298) - Made various improvements to the screenshot function. ([9ce7bbc](https://github.com/FunkinCrew/Funkin/commit/9ce7bbcfbb8f30ae120c876194f89bc4c787f585)) - by @Lasercar in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082) - Accept keybinds (Z and Space by default) can now be used to exit the Results screen. ([edb270d](https://github.com/FunkinCrew/Funkin/commit/edb270d15e41784dccbf75639ac731840e80fe23)) - by @JVNpixels in [#3799](https://github.com/FunkinCrew/Funkin/pull/3799) - Reordered UI keybinds in the controls menu for consistency. ([a01bcc3](https://github.com/FunkinCrew/Funkin/commit/a01bcc3da836ec52851ca9de13ef459daf61269a)) - by @lemz1 in [#3027](https://github.com/FunkinCrew/Funkin/pull/3027) - New save files now have default Freeplay controls for gamepads. ([2b7f62e](https://github.com/FunkinCrew/Funkin/commit/2b7f62edd33de5527e259d9e5643f926d35da734)) - by @MrMadera in [#3934](https://github.com/FunkinCrew/Funkin/pull/3934) -- Renamed “Auto Pause” preference to “Pause on Unfocus” for clarity. ([49a21c1](https://github.com/FunkinCrew/Funkin/commit/49a21c198236fbecbe5902bb106f78939cc6442a)) - by @JackXson-Real in [#4346](https://github.com/FunkinCrew/Funkin/pull/4346) - Made scrolling smoother in the Chart Editor. ([20d9016](https://github.com/FunkinCrew/Funkin/commit/20d90169845f1e50f849e39f4c5f818359756c78)) - by @ninjamuffin99 in [#3768](https://github.com/FunkinCrew/Funkin/pull/3768) -- The Chart Editor now clears the undo/redo history after loading a new song. ([c7bdc1a](https://github.com/FunkinCrew/Funkin/commit/c7bdc1abe265678468920ca3cc3d7eface5d6925)) - by @Lasercar in [#4308](https://github.com/FunkinCrew/Funkin/pull/4308) - Mods with missing dependencies are now skipped instead of preventing all mods from loading. ([1c2fb43](https://github.com/FunkinCrew/Funkin/commit/1c2fb43ae16cf40be5ef94c40b047e8e772b1211)) - by @AbnormalPoof in [#3993](https://github.com/FunkinCrew/Funkin/pull/3993) - Slightly improved flexibility for modding note hit animations. ([3aad825](https://github.com/FunkinCrew/Funkin/commit/3aad825f865c4ed87016983d44121e2c1610d332)) - by @TechnikTil in [#3936](https://github.com/FunkinCrew/Funkin/pull/3936) - Introduced several QoL modding changes. ([785c4be](https://github.com/FunkinCrew/Funkin/commit/785c4be88b52dc1b5899013822fc004ba7d9894d)) - by @Kade-github in [#4009](https://github.com/FunkinCrew/Funkin/pull/4009) - Lots of smaller bug fixes. -## New Contributors for 0.6.0 +### Fixed -* @PatoFlamejanteTV made their first contribution in [#3843](https://github.com/FunkinCrew/Funkin/pull/3843) -* @sphis-Sinco made their first contribution in [#3881](https://github.com/FunkinCrew/Funkin/pull/3881) -* @MrMadera made their first contribution in [#3934](https://github.com/FunkinCrew/Funkin/pull/3934) -* @Lasercar made their first contribution in [#4100](https://github.com/FunkinCrew/Funkin/pull/4065) -* @MidyGamy made their first contribution in [#4068](https://github.com/FunkinCrew/Funkin/pull/4068) -* @MrScottyPieey made their first contribution in [#4085](https://github.com/FunkinCrew/Funkin/pull/4085) -* @JackXson-Real made their first contribution in [#4346](https://github.com/FunkinCrew/Funkin/pull/4346) - -# Fixed - Fixed a bug where the song would restart from the beginning instead of moving to the Results screen. ([3667c51](https://github.com/FunkinCrew/Funkin/commit/3667c51c1efe14cfe7c810e2f35991f08f50781a)) - by @KoloInDaCrib in [#4309](https://github.com/FunkinCrew/Funkin/pull/4309) and @Lasercar in [#4330](https://github.com/FunkinCrew/Funkin/pull/4330) - Reduced stuttering when resyncing instrumental and voices tracks. ([22d41d2](https://github.com/FunkinCrew/Funkin/commit/22d41d21b88acb7422a0afcda8414682710bd2ed)) - by @TechnikTil in [#3955](https://github.com/FunkinCrew/Funkin/pull/3955) - Songs with only instrumental tracks no longer stutter. ([dfe02ec](https://github.com/FunkinCrew/Funkin/commit/dfe02ec668b61d6308f459c978d12a7487f9dc28)) - by @KoloInDaCrib in [#3861](https://github.com/FunkinCrew/Funkin/pull/3861) -- The mouse cursor is no longer visible outside of debug editors. ([1c12b84](https://github.com/FunkinCrew/Funkin/commit/1c12b8467eca350eb28138473360d5358fa620e2)) - by @sphis-Sinco in [#3881](https://github.com/FunkinCrew/Funkin/pull/3881) +- The debug mouse cursor no longer flickers before the Title Screen loads. ([1c12b84](https://github.com/FunkinCrew/Funkin/commit/1c12b8467eca350eb28138473360d5358fa620e2)) - by @sphis-Sinco in [#3881](https://github.com/FunkinCrew/Funkin/pull/3881) - Unbound keys now display as [N/A] instead of crashing the game. ([94e5d3c](https://github.com/FunkinCrew/Funkin/commit/94e5d3ca258cbaa5d9ab6f0cb26feda83b3433a2)) - by @NotHyper-474 in [#4355](https://github.com/FunkinCrew/Funkin/pull/4355) - Songs can no longer be spam-selected after selecting an instrumental in Freeplay. ([0e0c4ae](https://github.com/FunkinCrew/Funkin/commit/0e0c4aeb7745cfb9479685ccbb635cf3743cddbb)) - by @AbnormalPoof in [#3866](https://github.com/FunkinCrew/Funkin/pull/3866) - The Random capsule can now switch to Erect/Nightmare difficulties in Freeplay. ([6f32747](https://github.com/FunkinCrew/Funkin/commit/6f327474f30374f50774f432ea3ccb6d02579445)) - by @KoloInDaCrib in [#3838](https://github.com/FunkinCrew/Funkin/pull/3838) -- The millions place digit of the Freeplay score now updates properly. ([3719ca6](https://github.com/FunkinCrew/Funkin/commit/3719ca6ce7a170c3c890cdb2aeea3e4534b91736)) - by @Lasercar in [#4065](https://github.com/FunkinCrew/Funkin/pull/4065) - Fixed a rare bug where a song would not register as beaten. ([a3e2373](https://github.com/FunkinCrew/Funkin/commit/a3e23733db104b1ef00cfcff17db3a5d032a4d67)) - by @AbnormalPoof in [#3820](https://github.com/FunkinCrew/Funkin/pull/3820) - The difficulty graphic on the Results screen no longer cuts off incorrectly. ([b13bf05](https://github.com/FunkinCrew/Funkin/commit/b13bf05d16ff2977309e0c7ba3f049c0134e8902)) - by @AbnormalPoof in [#4161](https://github.com/FunkinCrew/Funkin/pull/4161) - Four-digit long Total Notes values in the Results screen no longer overflow to the right. ([2be4c0c](https://github.com/FunkinCrew/Funkin/commit/2be4c0c7196e018a43f9697f015179f3efc3fcdb)) - by @Hundrec in [#4356](https://github.com/FunkinCrew/Funkin/pull/4356) @@ -99,6 +101,16 @@ The Pit Stop 2 update! - Removed an unused class from Polymod blacklist. ([06c12e3](https://github.com/FunkinCrew/Funkin/commit/06c12e36c6bd6df4e2be32a3bec540172e79e162)) - by @AbnormalPoof in [#3729](https://github.com/FunkinCrew/Funkin/pull/3729) - Many additional small bug fixes. +## New Contributors for 0.6.0 + +* @PatoFlamejanteTV made their first contribution in [#3843](https://github.com/FunkinCrew/Funkin/pull/3843) +* @sphis-Sinco made their first contribution in [#3881](https://github.com/FunkinCrew/Funkin/pull/3881) +* @MrMadera made their first contribution in [#3934](https://github.com/FunkinCrew/Funkin/pull/3934) +* @MidyGamy made their first contribution in [#4068](https://github.com/FunkinCrew/Funkin/pull/4068) +* @Lasercar made their first contribution in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082) +* @MrScottyPieey made their first contribution in [#4085](https://github.com/FunkinCrew/Funkin/pull/4085) + + ## [0.5.3] - 2024-10-18 This patch resolves a critical issue that could cause user's save data to become corrupted. It is recommended that users switch to this version immediately and avoid using version 0.5.2. From af14d42939fe198c128c1d842a9a903e369909b9 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Fri, 4 Apr 2025 19:02:47 -0600 Subject: [PATCH 19/23] Oops, one more lil space --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f30cef15c..0a34ec499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,7 +61,7 @@ The Pit Stop 2 update! - Added offsets support for album titles. ([69d8570](https://github.com/FunkinCrew/Funkin/commit/69d8570a9eb06011ed6dd95fcbef83d90f7f8684)) - by @AbnormalPoof in [#3618](https://github.com/FunkinCrew/Funkin/pull/3618) - Added three new properties to stage data: `angle`, `scroll`, and `alpha`. ([ff56b19](https://github.com/FunkinCrew/Funkin/commit/ff56b1948aef42bbb6bb4ede4f9b2012d49ab044)) - by @AbnormalPoof in [#3720](https://github.com/FunkinCrew/Funkin/pull/3720) - Added script events for losing/gaining focus. ([4b127b6](https://github.com/FunkinCrew/Funkin/commit/4b127b64130f6f753d0574ec66a1672322e4bd13)) - by @AbnormalPoof in [#3721](https://github.com/FunkinCrew/Funkin/pull/3721) -- Added 10 new functions to `ReflectUtil`.([6216655](https://github.com/FunkinCrew/Funkin/commit/62166554e7a176245d1a63bd15122033044c4e40)) - by @AbnormalPoof in [#3622](https://github.com/FunkinCrew/Funkin/pull/3622), [#3809](https://github.com/FunkinCrew/Funkin/pull/3809), and [#4019](https://github.com/FunkinCrew/Funkin/pull/4019) +- Added 10 new functions to `ReflectUtil`. ([6216655](https://github.com/FunkinCrew/Funkin/commit/62166554e7a176245d1a63bd15122033044c4e40)) - by @AbnormalPoof in [#3622](https://github.com/FunkinCrew/Funkin/pull/3622), [#3809](https://github.com/FunkinCrew/Funkin/pull/3809), and [#4019](https://github.com/FunkinCrew/Funkin/pull/4019) - Added `DEBUG_BUILD` value to `Constants` to indicate whether a build has debug functions enabled. ([ad45b72](https://github.com/FunkinCrew/Funkin/commit/ad45b72b1ae8eb73a12dc51bcb59f66cc55e7bbd)) - by @AbnormalPoof in [#3853](https://github.com/FunkinCrew/Funkin/pull/3853) ### Changed From 1823373d7ed5e2b05e253cb57daf10b391c11158 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Sat, 5 Apr 2025 00:02:18 -0600 Subject: [PATCH 20/23] Add a few fixes and changes from 0.6.0 --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a34ec499..93ac9acea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,8 @@ The Pit Stop 2 update! - Switched from hxCodec to hxvlc for video playback. This may break a mod or two. - Check the [Funkin Modding Docs](https://funkincrew.github.io/funkin-modding-docs/09-migration/09-02-0.5.0-to-0.6.0.html) for more info on how to update your mods. - Polymod should now ignore `.git` files when loading mods. +- The pause menu can now be opened and closed rapidly. +- Adjusted difficulty ratings and scroll speeds for many songs. - Lots of improvements to GitHub issue and pull request organization. - by @Hundrec and @AbnormalPoof - Overhauled the Changelog to improve readability and properly credit contributors. ([4383fcf](https://github.com/FunkinCrew/Funkin/commit/4383fcf32c280a1c0ee7b9c80d255611d497cabc)) - by @Hundrec in [#4296](https://github.com/FunkinCrew/Funkin/pull/4296) and [#4298](https://github.com/FunkinCrew/Funkin/pull/4298) - Made various improvements to the screenshot function. ([9ce7bbc](https://github.com/FunkinCrew/Funkin/commit/9ce7bbcfbb8f30ae120c876194f89bc4c787f585)) - by @Lasercar in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082) @@ -79,10 +81,15 @@ The Pit Stop 2 update! - Mods with missing dependencies are now skipped instead of preventing all mods from loading. ([1c2fb43](https://github.com/FunkinCrew/Funkin/commit/1c2fb43ae16cf40be5ef94c40b047e8e772b1211)) - by @AbnormalPoof in [#3993](https://github.com/FunkinCrew/Funkin/pull/3993) - Slightly improved flexibility for modding note hit animations. ([3aad825](https://github.com/FunkinCrew/Funkin/commit/3aad825f865c4ed87016983d44121e2c1610d332)) - by @TechnikTil in [#3936](https://github.com/FunkinCrew/Funkin/pull/3936) - Introduced several QoL modding changes. ([785c4be](https://github.com/FunkinCrew/Funkin/commit/785c4be88b52dc1b5899013822fc004ba7d9894d)) - by @Kade-github in [#4009](https://github.com/FunkinCrew/Funkin/pull/4009) -- Lots of smaller bug fixes. +- Lots of smaller changes. ### Fixed +- Shaders no longer create thin seams within atlas sprites. +- Completing a song in Practice Mode no longer plays a new rank animation in the Freeplay menu. +- Fixed lots of charting issues across many songs. +- The Chart Editor grid now properly adjusts to the new BPM after switching variations. +- Fixed a few crashes in the Stage Editor. - Fixed a bug where the song would restart from the beginning instead of moving to the Results screen. ([3667c51](https://github.com/FunkinCrew/Funkin/commit/3667c51c1efe14cfe7c810e2f35991f08f50781a)) - by @KoloInDaCrib in [#4309](https://github.com/FunkinCrew/Funkin/pull/4309) and @Lasercar in [#4330](https://github.com/FunkinCrew/Funkin/pull/4330) - Reduced stuttering when resyncing instrumental and voices tracks. ([22d41d2](https://github.com/FunkinCrew/Funkin/commit/22d41d21b88acb7422a0afcda8414682710bd2ed)) - by @TechnikTil in [#3955](https://github.com/FunkinCrew/Funkin/pull/3955) - Songs with only instrumental tracks no longer stutter. ([dfe02ec](https://github.com/FunkinCrew/Funkin/commit/dfe02ec668b61d6308f459c978d12a7487f9dc28)) - by @KoloInDaCrib in [#3861](https://github.com/FunkinCrew/Funkin/pull/3861) From 08fb5b8459374f489d57097b32590947ec8b62f6 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Thu, 10 Apr 2025 22:49:12 -0600 Subject: [PATCH 21/23] Two more Chart Editor entries in Changelog --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93ac9acea..13cc8626a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,10 +51,11 @@ The Pit Stop 2 update! - Added new stickers which appear when exiting Pico songs! - The new sticker system isn't fully available to mods yet, but we're working on it! - New option in the Preferences menu: Strumline Backgrounds! -- Options in the Preferences menu now display an on-screen description when selected. +- New song event type in the Chart Editor: Set Health Icon! + - This event is now used in Stress (Pico Mix). - The HOME and END keys now jump to the top and bottom of the Freeplay song list, respectively. ([bb974c2](https://github.com/FunkinCrew/Funkin/commit/bb974c264270d10ff503784063e5d77bb352b3f7)) - by @AbnormalPoof in [#4103](https://github.com/FunkinCrew/Funkin/pull/4103) - Added an option to launch the game in fullscreen. ([ee53ccd](https://github.com/FunkinCrew/Funkin/commit/ee53ccd32721e0790adfe82c60d4aca419db0a7f)) - by @AbnormalPoof in [#3738](https://github.com/FunkinCrew/Funkin/pull/3738) -- Added descriptions for each item in the Preferences menu. ([a17b0e8](https://github.com/FunkinCrew/Funkin/commit/a17b0e8b3cc1d56fcdc0b51eaca9fd57cdb5bce0)) - by @anysad in [#3872](https://github.com/FunkinCrew/Funkin/pull/3872) +- Added on-screen descriptions for each item in the Preferences menu. ([a17b0e8](https://github.com/FunkinCrew/Funkin/commit/a17b0e8b3cc1d56fcdc0b51eaca9fd57cdb5bce0)) - by @anysad in [#3872](https://github.com/FunkinCrew/Funkin/pull/3872) - Added precise scrolling in the Chart Editor using Ctrl-Mouse Wheel. ([0d8e4a5](https://github.com/FunkinCrew/Funkin/commit/0d8e4a53305d6d069454812766300122f3581e31)) - by @ninjamuffin99 in [#3806](https://github.com/FunkinCrew/Funkin/pull/3806) - Added a “None” option to the character selector in the Chart Editor. ([d9637d3](https://github.com/FunkinCrew/Funkin/commit/d9637d3a19466b9fc68a102676c46a74ef504909)) - by @Lasercar in [#4279](https://github.com/FunkinCrew/Funkin/pull/4279) - Added the ability to flip the character in the Animation Editor. ([de02137](https://github.com/FunkinCrew/Funkin/commit/de02137d7c7d1779e85aeda34743f506a5b9cc27)) - by @AbnormalPoof in [#3028](https://github.com/FunkinCrew/Funkin/pull/3028) @@ -71,6 +72,8 @@ The Pit Stop 2 update! - Polymod should now ignore `.git` files when loading mods. - The pause menu can now be opened and closed rapidly. - Adjusted difficulty ratings and scroll speeds for many songs. +- Chart Editor event fields now allow for values to be as specific as desired. + - For example, the Zoom Camera event can now be set to 0.9857. - Lots of improvements to GitHub issue and pull request organization. - by @Hundrec and @AbnormalPoof - Overhauled the Changelog to improve readability and properly credit contributors. ([4383fcf](https://github.com/FunkinCrew/Funkin/commit/4383fcf32c280a1c0ee7b9c80d255611d497cabc)) - by @Hundrec in [#4296](https://github.com/FunkinCrew/Funkin/pull/4296) and [#4298](https://github.com/FunkinCrew/Funkin/pull/4298) - Made various improvements to the screenshot function. ([9ce7bbc](https://github.com/FunkinCrew/Funkin/commit/9ce7bbcfbb8f30ae120c876194f89bc4c787f585)) - by @Lasercar in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082) From d86fe68d80f1b7991cca071fc8f31cf03684ecfd Mon Sep 17 00:00:00 2001 From: Abnormal <86753001+AbnormalPoof@users.noreply.github.com> Date: Sat, 29 Mar 2025 02:08:28 -0500 Subject: [PATCH 22/23] docs: Add missing documentation to the remaining functions in `Module` --- source/funkin/modding/module/Module.hx | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/source/funkin/modding/module/Module.hx b/source/funkin/modding/module/Module.hx index 57f0cc2da..012b9869f 100644 --- a/source/funkin/modding/module/Module.hx +++ b/source/funkin/modding/module/Module.hx @@ -57,6 +57,9 @@ class Module implements IPlayStateScriptedClass implements IStateChangingScripte // TODO: Half of these aren't actually being called!!!!!!! + /** + * Called when ANY script event is dispatched. + */ public function onScriptEvent(event:ScriptEvent) {} /** @@ -71,55 +74,138 @@ class Module implements IPlayStateScriptedClass implements IStateChangingScripte */ public function onDestroy(event:ScriptEvent) {} + /** + * Called every frame. + */ public function onUpdate(event:UpdateScriptEvent) {} + /** + * Called when the game is paused. + */ public function onPause(event:PauseScriptEvent) {} + /** + * Called when the game is resumed. + */ public function onResume(event:ScriptEvent) {} + /** + * Called when the song begins. + */ public function onSongStart(event:ScriptEvent) {} + /** + * Called when the song ends. + */ public function onSongEnd(event:ScriptEvent) {} + /** + * Called when the player dies. + */ public function onGameOver(event:ScriptEvent) {} + /** + * Called when a note on the strumline has been rendered and is now onscreen. + * This gets dispatched for both the player and opponent strumlines. + */ public function onNoteIncoming(event:NoteScriptEvent) {} + /** + * Called when a note has been hit. + * This gets dispatched for both the player and opponent strumlines. + */ public function onNoteHit(event:HitNoteScriptEvent) {} + /** + * Called when a note has been missed. + * This gets dispatched for both the player and opponent strumlines. + */ public function onNoteMiss(event:NoteScriptEvent) {} + /** + * Called when the player presses a key without any notes present. + */ public function onNoteGhostMiss(event:GhostMissNoteScriptEvent) {} + /** + * Called when a step is hit in the song. + */ public function onStepHit(event:SongTimeScriptEvent) {} + /** + * Called when a beat is hit in the song. + */ public function onBeatHit(event:SongTimeScriptEvent) {} + /** + * Called when a song event is triggered. + */ public function onSongEvent(event:SongEventScriptEvent) {} + /** + * Called when the countdown begins. + */ public function onCountdownStart(event:CountdownScriptEvent) {} + /** + * Called for every step in the countdown. + */ public function onCountdownStep(event:CountdownScriptEvent) {} + /** + * Called when the countdown ends, but BEFORE the song starts. + */ public function onCountdownEnd(event:CountdownScriptEvent) {} + /** + * Called when the song's chart has been parsed and loaded. + */ public function onSongLoaded(event:SongLoadScriptEvent) {} + /** + * Called when the game is about to switch to a new state. + */ public function onStateChangeBegin(event:StateChangeScriptEvent) {} + /** + * Called after the game has switched to a new state. + */ public function onStateChangeEnd(event:StateChangeScriptEvent) {} + /** + * Called when the game regains focus. + * This does not get called if "Auto Pause" is disabled. + */ public function onFocusGained(event:FocusScriptEvent) {} + /** + * Called when the game loses focus. + * This does not get called if "Auto Pause" is disabled. + */ public function onFocusLost(event:FocusScriptEvent) {} + /** + * Called when the game is about to open a substate. + */ public function onSubStateOpenBegin(event:SubStateScriptEvent) {} + /** + * Called when a substate has been opened. + */ public function onSubStateOpenEnd(event:SubStateScriptEvent) {} + /** + * Called when the game is about to close a substate. + */ public function onSubStateCloseBegin(event:SubStateScriptEvent) {} + /** + * Called when a substate has been closed. + */ public function onSubStateCloseEnd(event:SubStateScriptEvent) {} + /** + * Called when the song has been restarted. + */ public function onSongRetry(event:SongRetryEvent) {} } From 0c674ac23bde6400fe7deef9515d99129e3d7dd3 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Mon, 21 Apr 2025 20:55:57 -0600 Subject: [PATCH 23/23] Specify "flip horizontally" shortcut in Changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13cc8626a..68e751f16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,7 @@ The Pit Stop 2 update! - Added on-screen descriptions for each item in the Preferences menu. ([a17b0e8](https://github.com/FunkinCrew/Funkin/commit/a17b0e8b3cc1d56fcdc0b51eaca9fd57cdb5bce0)) - by @anysad in [#3872](https://github.com/FunkinCrew/Funkin/pull/3872) - Added precise scrolling in the Chart Editor using Ctrl-Mouse Wheel. ([0d8e4a5](https://github.com/FunkinCrew/Funkin/commit/0d8e4a53305d6d069454812766300122f3581e31)) - by @ninjamuffin99 in [#3806](https://github.com/FunkinCrew/Funkin/pull/3806) - Added a “None” option to the character selector in the Chart Editor. ([d9637d3](https://github.com/FunkinCrew/Funkin/commit/d9637d3a19466b9fc68a102676c46a74ef504909)) - by @Lasercar in [#4279](https://github.com/FunkinCrew/Funkin/pull/4279) -- Added the ability to flip the character in the Animation Editor. ([de02137](https://github.com/FunkinCrew/Funkin/commit/de02137d7c7d1779e85aeda34743f506a5b9cc27)) - by @AbnormalPoof in [#3028](https://github.com/FunkinCrew/Funkin/pull/3028) +- Added the ability to flip the character horizontally in the Animation Editor by pressing G. ([de02137](https://github.com/FunkinCrew/Funkin/commit/de02137d7c7d1779e85aeda34743f506a5b9cc27)) - by @AbnormalPoof in [#3028](https://github.com/FunkinCrew/Funkin/pull/3028) - Added offsets support for album titles. ([69d8570](https://github.com/FunkinCrew/Funkin/commit/69d8570a9eb06011ed6dd95fcbef83d90f7f8684)) - by @AbnormalPoof in [#3618](https://github.com/FunkinCrew/Funkin/pull/3618) - Added three new properties to stage data: `angle`, `scroll`, and `alpha`. ([ff56b19](https://github.com/FunkinCrew/Funkin/commit/ff56b1948aef42bbb6bb4ede4f9b2012d49ab044)) - by @AbnormalPoof in [#3720](https://github.com/FunkinCrew/Funkin/pull/3720) - Added script events for losing/gaining focus. ([4b127b6](https://github.com/FunkinCrew/Funkin/commit/4b127b64130f6f753d0574ec66a1672322e4bd13)) - by @AbnormalPoof in [#3721](https://github.com/FunkinCrew/Funkin/pull/3721)