Compare commits

..
454 Commits
Author SHA1 Message Date
HundrecandGitHub e62c5a223c Merge to sync commit histories
Build and Upload nightly game builds / gather-changes (push) Canceled after 0s
Build and Upload nightly game builds / gather-tags (push) Canceled after 0s
Build and Upload nightly game builds / build-game-on-host (macos, macos) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-on-host (windows, windows) (push) Canceled after 0s
Build and Upload nightly game builds / docker-image (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (html5) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (linux) (push) Canceled after 0s
2025-09-19 01:33:29 +08:00
Hundrec 5fc7491121 Merge changes from main 2025-09-19 01:28:01 +08:00
Hundrec 9598455118 KoloInDaKrib 2025-09-19 01:27:42 +08:00
Nightfall-16andHundrec 0e4b9753a0 contribute I guess 2025-09-19 01:26:12 +08:00
Nightfall-16andHundrec 2bbe3d788d crash 2025-09-19 01:26:12 +08:00
Nightfall-16andHundrec cd731d7e40 work 2025-09-19 01:26:12 +08:00
Nightfall-16andHundrec e11e3d51c2 please work 2025-09-19 01:26:12 +08:00
Nightfall-16andHundrec b19b78df5d please work now 2025-09-19 01:26:12 +08:00
Hundrec 1a061cbbcc 0.7.5 changelog and version bump
Set the date for the 0.7.5 patch
2025-09-18 16:24:18 +08:00
MoonDroid 9908c8be32 Fix html5 builds from crashing and not compiling 2025-09-18 14:55:52 +07:00
MoonDroid 8522deab64 Adjust warning message 2025-09-18 14:55:52 +07:00
MoonDroid 7e93521666 Add custom context warnings for environment errors
woo!! im proud of this !!
2025-09-18 14:55:52 +07:00
MoonDroidandMihai Alexandru 5aeb3a28fb Add AnsiUtil for ease of ansi use
Co-Authored-By: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-09-18 14:55:52 +07:00
MAJigsaw77andMoonDroid b5db93726a Rewrite Environment macro. 2025-09-18 14:55:52 +07:00
EliteMasterEricandHundrec 20de8db41b Update to the latest commit on the hxcpp-debugger fork. 2025-09-18 14:43:08 +08:00
Hundrec 5d73d65fdc Fix Eggnog Erect cutscene crash 2025-09-18 03:03:31 +08:00
8c750d368d Update openfl and flixel for ASTC fixes.
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-09-18 01:44:25 +07:00
Hundrec 8d328ace84 Fix HTML5 compile error 2025-09-18 01:03:00 +08:00
MAJigsaw77andHundrec 9d825f00aa Use Sys.println instead of trace` for Admob events. 2025-09-16 22:56:11 +08:00
Honton129andAbnormal c7b68507a8 Typo Fix on PlayStatePlaylist
that was bothering me
2025-09-15 05:08:37 -05:00
Hyper_andHundrec 970ccf2f4a fix: Chart loading fixes
* Prevents charter from deleting `default` variation when there's more than one variation available.
* Fixes song variation list not being saved into `default` metadata file.
* Fixes chart data not being assigned its respective variation when loading from FNFC.
2025-09-15 03:12:43 +08:00
PixelandHundrec 479036a400 Add ability to pause during Credits scroll 2025-09-15 03:09:33 +08:00
KoloandHundrec 80d7ace714 remove the stupid chud gibberish 2025-09-15 03:06:44 +08:00
Hundrec a7d5736e14 Adjust Stage Editor exit confirm prompt 2025-09-15 03:02:15 +08:00
LasercarandHundrec b31be1043c chart name in backup filename 2025-09-15 03:02:14 +08:00
Hundrec 6c4d27a842 Nudge Chart Editor menubar for new debug display 2025-09-15 02:55:39 +08:00
Hundrec fdab26ce56 Fix Pico not shooting in Stress upon restarting 2025-09-15 02:26:22 +08:00
VioletSnowLeopardandHundrec 8ead5eeb08 change save shortcuts to CTRL+S and CTRL+SHIFT+S 2025-09-15 02:18:53 +08:00
Hundrec c4ebd3175d Remove beatHit() flash from Freeplay backing card
It's a cool idea, but too distracting, especially for Pico's blue backing card
2025-09-15 02:13:45 +08:00
e593bc8a61 Fix Debug Display memory leak on Linux
Co-authored-by: Linus Torvalds <torvalds@linux-foundation.org>
2025-09-15 02:03:55 +08:00
Hyper_andHundrec cb554bd5f7 the one line fix 2025-09-15 01:59:37 +08:00
Hyper_andHundrec dd54acfbd1 this pointless condition was pissing me off 2025-09-15 01:59:37 +08:00
LasercarandHundrec 6783f04139 No Chudding allowed 2025-09-15 01:56:03 +08:00
PurSnakeandHundrec 11eb4060d0 duh 2025-09-15 01:56:03 +08:00
VioletSnowLeopardandHundrec b5357acf98 Fallback to default if metadata voices don't exist 2025-09-15 01:50:09 +08:00
Hyper_andHundrec f85f2f03d9 another one liner god damn it
Fixes a crash when there's some previously focused text fields,
and the user tries to exit via the confirmation dialog.
Before a state switch HaxeUI tries to reset the tooltip manager and
remove all components, which in this case causes it to refocus a text field,
which tries to access a destroyed camera to retrieve the bounds.
Doing this ensures there's no text fields for it to do that.
2025-09-15 01:41:38 +08:00
VioletSnowLeopardandHundrec 146a6cde68 Fix typo - pause *button* 2025-09-14 18:23:41 +08:00
AbnormalandHundrec 65105df9ac disable smoothing on the baked bitmaps 2025-09-14 17:31:01 +08:00
AbnormalandHundrec 9106ef215a add the lighting to pico's rank animation (had to bake the blendmode lol) 2025-09-14 17:31:01 +08:00
Megalives6193andHundrec 38426bc5d7 [GITHUB] Fix Logo In README.md 2025-09-14 04:35:22 +08:00
KoloandHundrec 79e8b5d71e fix: Prevent crashing by replacing the state constructor if needed 2025-09-14 03:14:38 +08:00
MoonDroidandHundrec 6e954cfac0 Update astc compression rate for results excellent bf 2025-09-13 21:56:48 +08:00
MAJigsaw77andAbnormal 041d33b2d3 Fixes to the audio config stuff. 2025-09-12 16:26:15 -05:00
MoonDroid 1b5b0925ed chore: Rename the define and remove redundant block 2025-09-11 03:39:25 +07:00
Karim AkraandMoonDroid cd0bc85b76 added FEATURE_LOG_TRACE_FILE for logging all the logs into a text file 2025-09-11 03:39:25 +07:00
MAJigsaw77andHundrec d4929164b6 Update hxvlc. 2025-09-10 12:35:35 +08:00
Abnormal 7bc06861b5 add an extra line 2025-09-09 12:39:19 -05:00
Abnormal 3ccbed2cbb clarify dev build in outdated libraries 2025-09-09 12:39:19 -05:00
MAJigsaw77andAbnormal 29c0b0f8eb Add support for dev libs in project.hxp haxelibs check. 2025-09-09 12:39:19 -05:00
AbnormalandEric 7ff0753472 scripted freeplay and popups shot dead on august 32nd, 2031 with no traces found 2025-09-09 05:35:35 -04:00
AbnormalandEric 19328abb9e and then there were 7 2025-09-09 05:35:35 -04:00
AbnormalandEric feb0863358 and then there were 8 2025-09-09 05:35:35 -04:00
AbnormalandEric 43e51e9a4a erm......sorry modders you're gonna have to do the work yourself lol 2025-09-09 05:35:35 -04:00
AbnormalandEric 3b610d8910 add a TON of modding stuff 2025-09-09 05:35:35 -04:00
PurSnakeandHundrec 63ec749c7a Disable Freeplay intro when coming from stickers 2025-09-09 03:53:51 +08:00
Hyper_andHundrec c8e6a78154 don't check libraries on display 2025-09-09 03:45:48 +08:00
Az989YTandHundrec 89b2b7fcc3 change event dispatching to match comment order 2025-09-09 03:14:55 +08:00
kade-githubandAbnormal 1b1c781426 bump polymod 2025-09-08 14:11:42 -05:00
kade-githubandEric 5c8a888b77 remove includes that dont matter 2025-09-08 15:00:28 -04:00
kade-githubandEric 257576b4d3 Allow for scripted state reloading 2025-09-08 15:00:28 -04:00
sector-aandEric 56f0a7780d Debug Display HTML5 Fixes 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric faa47e8f3e More tweaks 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric b99d599bce Fix iOS compile. 2025-09-08 13:02:48 -04:00
92bc856f5b Fix macos compile.
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-09-08 13:02:48 -04:00
sector-aandEric 0490ca8145 Debug display bg opacity preference 2025-09-08 13:02:48 -04:00
sector-aandEric c9b8f21f61 Debug Display modes!!! 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric 60caa80a84 One more graph adjustment 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric 477f85a71e Adjust graphs width. 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric b5aed5fb4f Adjusted the graphs. 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric 7d714ecfeb Add MemoryUtil for Apple external. 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric f3ff132e90 Adjust the external API a little. 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric 1912155b32 Organized some small stuff 2025-09-08 13:02:48 -04:00
sector-aandEric daa87c8c58 The new debug display is mostly done! 2025-09-08 13:02:48 -04:00
sector-aandEric ad87832662 The graph is done 2025-09-08 13:02:48 -04:00
MAJigsaw77andEric b8b0a5bf73 Added task mem and adjusted the counter. 2025-09-08 13:02:48 -04:00
sector-aandEric 5a8b681e2f FPS Graph (unfinished) 2025-09-08 13:02:48 -04:00
sector-aandEric 5a6a3f5599 Small tweaks 2025-09-08 13:02:48 -04:00
sector-aandEric bab422029b FunkinCounter (unfinished) 2025-09-08 13:02:48 -04:00
Hyper_andHundrec 88fc5f9ed6 refactor: use null-safe list functions in Medals and Leaderboards 2025-09-08 22:45:32 +08:00
Hundrec f3c7cfd799 Hide the A-Bot visualizer when restarting 2025-09-08 17:10:38 +08:00
Hundrec 231439d808 Adjust haxelib warning message 2025-09-08 16:51:37 +08:00
AbnormalandHundrec d6f80730a5 check the library versions and warn the user of any outdated ones 2025-09-08 16:51:37 +08:00
AwesomezPro99andHundrec 9cfee0398a Fix stress pico bricks 2025-09-07 14:29:39 +08:00
Hyper_andAbnormal aa5956a30b Force texture to be uploaded to the GPU
Fixes an issue where multi-sparrow characters cause a stutter when the alternative sprites are displayed
2025-09-06 22:15:28 -05:00
Hundrec b9d68957e0 Cache Stress Tankmen into FunkinMemory 2025-09-07 02:37:57 +08:00
kade-githubandHundrec 1b9f5c62fb Fix a bug with Lag Adjustment strumline 2025-09-07 02:23:59 +08:00
kade-githubandHundrec a0a57ca94d Make strumlineNotes and noteHoldCovers public 2025-09-07 02:23:59 +08:00
sector-aandHundrec 271451b9df Update assets 2025-09-07 01:39:13 +08:00
sector-aandHundrec 21458f26f2 Fix dialogue proceeding when pressing the pause button 2025-09-07 01:39:13 +08:00
kade-github c1b4d4d53e space... STATE_CREATE 2025-09-06 09:41:24 -07:00
kade-github 28d71dc2fe add onStateCreate to Module 2025-09-06 09:41:24 -07:00
AwesomezPro99andHundrec a10bbf60ac Fix menu music fade in 2025-09-06 16:37:08 +08:00
KoloandHundrec 4e572b171f cancel login if ongoing 2025-09-06 16:15:36 +08:00
Hundrec cc768c83aa Remove extra line 2025-09-06 16:09:06 +08:00
LasercarandHundrec 035f3770d5 No more audio playback while dragging playheads
This commit specifically fixes the note preview playhead.
2025-09-06 16:09:06 +08:00
LasercarandHundrec 2d95754d49 Chart editor audio playback while dragging playheads fix
Two down, one to go
2025-09-06 16:09:06 +08:00
VioletSnowLeopardandHundrec 47b1cee6d5 don't open welcome dialog multiple times 2025-09-06 15:59:38 +08:00
lemz1andHundrec 4ebd00bc06 haxe ui focus check 2025-09-06 15:40:00 +08:00
AwesomezPro99andHundrec 66554ec4b6 Fix backing card beat hit check 2025-09-06 15:22:24 +08:00
MAJigsaw77andHundrec bfc798c629 Update extension-admob. 2025-09-06 15:11:46 +08:00
EliteMasterEric 6b334b941a Add some import aliases so scripts don't break. 2025-09-05 17:16:54 -04:00
sector-aandEric b06090a477 Move CharacterData to data/character 2025-09-05 17:16:54 -04:00
VioletSnowLeopardandHundrec ca5fbb65e5 add *the* checkbox to crash template 2025-09-06 05:08:28 +08:00
KoloandEric c2305f32f0 this bug seems kinda old why has nobody reported it before 2025-09-05 15:51:55 -04:00
VioletSnowLeopardandEric 747446e2e4 rank anim only plays when changing difficulties 2025-09-05 14:15:56 -04:00
MrMaderaandEric 250d2188b9 Add ability to press back to exit Character Select 2025-09-05 13:23:51 -04:00
kade-github 61c710fe20 some fixes and goodness 2025-09-05 09:45:56 -07:00
KoloandKade 0fd6f5b3b7 that fucking ghost that i hate 2025-09-05 09:45:56 -07:00
HundrecandAbnormal 8a204c606a Bring back Freeplay rank slamming animation
Another Freeplay fix caused by the same commit!

Manually reverts changes from https://github.com/FunkinCrew/Funkin/commit/f7a48bcb3b9ab0f5393552b828b8687c6ae6926c where Cam converted the FreeplayRank class into a FlxSpriteGroup.
2025-09-04 14:04:28 -05:00
MAJigsaw77andMoonDroid 4401ea0c9a Organize ios project folder a little. 2025-09-04 13:32:06 +07:00
sector-aandMoonDroid 12ace54b2b Update assets 2025-09-04 13:15:58 +07:00
f15cd73dff revert changes to cache in flxpartialsound
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-09-04 10:49:40 +07:00
b39d7bb5a0 Don't log info if the command is clean (or display)
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-09-04 10:12:20 +07:00
f1066a2b0d Fix Freeplay capsule offsetting once and for all
And nudge the Gold Perfect sparkles to where they used to be in 0.5.3

Both of these issues were introduced in 0.6.0 and have finally been uprooted. Huzzah!

Co-Authored-By: Lasercar <64717068+lasercar@users.noreply.github.com>
Co-Authored-By: Kolo <67389779+koloindacrib@users.noreply.github.com>
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
Co-Authored-By: Hyper_ <40342021+nothyper-474@users.noreply.github.com>
Co-Authored-By: Linus Torvalds <1024025+torvalds@users.noreply.github.com>
2025-09-03 18:44:24 -05:00
MAJigsaw77andHundrec b04b555b38 Intialize hxvlc asynchronously. 2025-09-04 04:28:02 +08:00
MoonDroid f349eedc72 fix: Re-add backbutton transitioning 2025-09-03 18:28:19 +07:00
VioletSnowLeopardandMoonDroid ee2f3c32eb Fixes for the recent update 2025-09-03 18:28:19 +07:00
LasercarandMoonDroid 0f99a1c7c2 Fix for https://github.com/FunkinCrew/Funkin/issues/3627 2025-09-03 18:28:19 +07:00
LasercarandMoonDroid 95aba09cd6 Fix target variation
Also no need to do instrumental stuff if not random
2025-09-03 18:28:19 +07:00
VioletSnowLeopardandMoonDroid 811b9e3343 don't freeze game if it fails to find target song/difficulty 2025-09-03 18:28:19 +07:00
VioletSnowLeopardandMoonDroid 37b9823b36 minor fix
Don't allow letter sort input while the instrumental selector is up
2025-09-03 18:28:19 +07:00
VioletSnowLeopardandMoonDroid 555684afda choose if you want the instrumental to be random 2025-09-03 18:28:19 +07:00
VioletSnowLeopardandMoonDroid 0d5c6ac963 selecting random can choose a random available instrumental 2025-09-03 18:28:19 +07:00
Cameron TaylorandMoonDroid db67a6928c ignroe VarTypeHint since it's a bit incompatible with final 2025-09-03 17:35:24 +07:00
Cameron TaylorandMoonDroid 9c34ab5f9c checkstyle fixins for AnsiTrace.hx 2025-09-03 17:35:24 +07:00
Cameron TaylorandMoonDroid f09074b79d add checkstyle regex to ignore long lines if they are strings (w/ whitespace) 2025-09-03 17:35:24 +07:00
Cameron TaylorandMoonDroid a5842fbe3f some checkstyle changes 2025-09-03 17:35:24 +07:00
8db654e63d Add support for 16K page sizes on Android.
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-09-03 17:11:36 +07:00
MoonDroid 60144c0dc7 refactor: make time formatter extensible and easier to read 2025-09-03 16:12:59 +07:00
MAJigsaw77andMoonDroid 830b5dfd71 Properly formatted build time. 2025-09-03 16:12:59 +07:00
MAJigsaw77andHundrec 12d81f0f3b Fix setting the window fullscreen from preloader. 2025-09-03 16:56:23 +08:00
sector-aandMoonDroid 8c835447c8 Improved positioning of the Dialogue Box and the Portrait 2025-09-03 06:32:53 +07:00
AbnormalandGitHub d9b35b9a96 Merge pull request #1676 from FunkinCrew/git/i'm-mergin'-it-redux
Build and Upload nightly game builds / gather-changes (push) Canceled after 0s
Build and Upload nightly game builds / gather-tags (push) Canceled after 0s
Build and Upload nightly game builds / build-game-on-host (macos, macos) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-on-host (windows, windows) (push) Canceled after 0s
Build and Upload nightly game builds / docker-image (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (html5) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (linux) (push) Canceled after 0s
2025-09-01 13:11:07 -05:00
Hundrec 93cac00472 Merge to match commit histories 2025-09-02 02:08:18 +08:00
Hundrec ab94fb633c A few tweaks to the Contributing Guide 2025-09-02 01:58:40 +08:00
Hundrec bd79c8bf7d Reword the checkbox 2025-09-02 01:58:40 +08:00
AbnormalandHundrec 3ee0894f89 add *the* checkbox (thunder and lightning noises) 2025-09-02 01:58:40 +08:00
Hundrec 735b44c1cc Merge changes from main into develop 2025-09-02 01:33:32 +08:00
HundrecandAbnormal d9580c580d Bump submod for HTML5 script error fix
We got trolled boys

Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2025-08-31 16:52:22 -05:00
Hundrec 0ac4bb1ba3 A few tweaks to the Contributing Guide 2025-08-30 21:27:13 +08:00
AbnormalandHundrec 7bd9af1f04 0.7.4 changelog + version bump 2025-08-29 20:17:00 +08:00
sector-aandHundrec 81b21674e9 Update assets 2025-08-29 20:01:19 +08:00
MAJigsaw77andKade 54ad34e5d0 Fix the app icon not working on Linux. 2025-08-27 14:57:20 -07:00
Cameron TaylorandHundrec f6fb11de4c hardcode 'touch here to play' graphic to be scaled at 0.5x instead FUNK-2710 2025-08-28 03:25:53 +08:00
MoonDroidandHundrec 83aa45a318 4x4 Compression for all of pico's results animations 2025-08-28 01:19:11 +08:00
MoonDroidandHundrec 65186a336d Update Mobile build number 2025-08-28 00:40:24 +08:00
KoloandHundrec 3a41b696d3 Ugh, I'm NEW 2025-08-27 23:19:36 +08:00
Hundrec 9c08a6ce68 Refactor alt inst checks in song scripts 2025-08-27 23:18:32 +08:00
EliteMasterEricandHundrec 62650836b8 Fix a busted Pico metadata JSON (why wasn't there an error?) 2025-08-27 23:18:32 +08:00
EliteMasterEricandHundrec e4fdf1019a Explicitly specify the variation for a bunch of song requests to fix some bugs 2025-08-27 23:18:32 +08:00
Hundrec 9dfda77d1e Bump submod for a few regressions in song scripts 2025-08-27 21:12:41 +08:00
Hyper_andHundrec fe6c8cabd6 the living dead capsules 😱 2025-08-27 15:19:56 +08:00
Hundrec 8b8d249813 Bump submod for New song labels 2025-08-25 22:54:31 +08:00
MAJigsaw77andHundrec c6ee23fec2 Add back the callbackutil initialization oops. 2025-08-24 20:06:04 +08:00
MAJigsaw77andAbnormal 345d96a7bc Oops 2025-08-23 23:32:33 -05:00
7f7fc3fa90 Prevent re-initialization of specific core features.
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-23 23:32:33 -05:00
AbnormalandHundrec 7c17e72e63 add proper blend modes to the freeplay djs (now with 100% less black lines) 2025-08-24 01:52:59 +08:00
Hundrec 1d2f971a26 Bump submod to fix Tankman not fading 2025-08-24 01:26:52 +08:00
Hundrec 7d97bb525a Bump submod to fix Darnell Erect isSongNew check 2025-08-24 01:24:21 +08:00
MAJigsaw77andHundrec da74f782d3 Fix censored cutscenes. 2025-08-23 20:06:51 +08:00
EliteMasterEricandMihai Alexandru 107ef7c83f Bump polymod 2025-08-23 11:15:21 +03:00
HundrecandAbnormal 0412d865f1 Fix later notes being hit before earlier ones
Bug introduced in 0.6.3 by this commit: https://github.com/FunkinCrew/Funkin/commit/c41c80099873e92d6b5d48de0276c03b1db8d04f
2025-08-22 11:47:36 -05:00
HundrecandMario Hernando 50e114fc12 Bump submod for gradient optimization
Co-Authored-By: Mario Hernando <97055307+maybemaru@users.noreply.github.com>
2025-08-22 16:13:07 +08:00
MAJigsaw77andAbnormal ce6577a9ed Update astc-compressor again. 2025-08-21 18:33:00 -05:00
MAJigsaw77andAbnormal 7fbe7b55c1 Update astc-compressor. 2025-08-21 18:33:00 -05:00
MoonDroidandAbnormal fb649c5d48 Exclude week 2 stairs from compression 2025-08-21 18:33:00 -05:00
MoonDroidandAbnormal 0ae8d62520 Scripts to organize astc data because its gettin' big and i love alphabetically sorting everything 2025-08-21 18:33:00 -05:00
MoonDroidandAbnormal 5b34446469 Updaet astc exclusion list so things would look better!! 2025-08-21 18:33:00 -05:00
MaybeMaruandAbnormal 8d1bfa105c Update PureColor.hx 2025-08-21 18:30:01 -05:00
Hyper_andMihai Alexandru a2e9277851 the swappening part 2 2025-08-21 23:14:09 +03:00
HundrecandKolo 2425054940 Clamp clear percent to avoid floating point errors
A clear percent higher than 100% would play the rank slam animation of a pink P over an E, but the P would immediately revert to an E.
This change makes sure any values above 100% become exactly 100%.

Update Scoring.hx

Update Scoring.hx

Co-Authored-By: Kolo <67389779+koloindacrib@users.noreply.github.com>
2025-08-22 00:02:53 +08:00
Abnormal 2bbfbc8968 NOTE TO ERIC: typedefs are not classes. These should be fine to remove since I don't think you can import them anyway. 2025-08-21 09:51:01 -05:00
EliteMasterEricandAbnormal 5922b927b7 Add backwards compatibility for some classes that got moved. 2025-08-21 09:51:01 -05:00
EliteMasterEricandAbnormal ebc5133062 Rename dialogue registry classes to make them build properly on Windows 2025-08-21 09:51:01 -05:00
Abnormal 7e2094070c make entry params typed woohoo!!! 2025-08-21 09:51:01 -05:00
Abnormal 20187540b3 fix a null-safey compilation error 2025-08-21 09:51:01 -05:00
Abnormal c94d6bbb66 feat: Variation-specific song scripts 2025-08-21 09:51:01 -05:00
EliteMasterEricandHundrec 3d8b9a18b3 Fixed an issue where legacy note data wasn't returning the right note kind. 2025-08-21 22:32:39 +08:00
EliteMasterEricandHundrec f428f5860d Fix an issue where some formats of legacy note data weren't parsed correctly. 2025-08-21 22:32:39 +08:00
AwesomezPro99andHundrec 2645d56514 Fixed Legacy Chart Scroll Speed 2025-08-21 22:32:39 +08:00
BurgerballsandEric 3f5ef4abe0 Camera bop offset 2025-08-20 23:41:32 -04:00
anysadandEric 75d8c5cc7a fix: fixing the fix 2025-08-20 16:41:27 -04:00
Hundrec 9c7dded259 Bump submod for two more charts 2025-08-20 20:11:01 +08:00
MAJigsaw77andMoonDroid 6a564905c0 Small adjustments to prints. 2025-08-20 17:04:05 +07:00
MAJigsaw77andMoonDroid 8a3d36d3fc Dont print additional trailing slash. 2025-08-20 17:04:05 +07:00
MAJigsaw77andMoonDroid de9e30534e Use Xml instead of a string array for the mods provider on Android. 2025-08-20 17:04:05 +07:00
MAJigsaw77andMoonDroid d42be225ca Remove unnecessary permissions removal on Android. 2025-08-20 17:04:05 +07:00
f7af64111c Offsets and notekinds for Pico animations
Includes hey, cheer, cock, and shoot
For Pico (Dark), hey and cheer

Adds hey and cheer to both

Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-20 16:59:24 +07:00
069bebb127 Fix duplicate gasp in Pico Doppelganger cutscene
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-20 16:26:14 +07:00
da8609f1d9 Adjust note splash offsets
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-20 15:59:10 +07:00
MAJigsaw77andHundrec a11ae53c51 Check if the host platform is Windows. 2025-08-20 05:43:48 +08:00
MaybeMaruandHundrec 1d22e073a2 Disable blue shader when unnecessary 2025-08-20 05:30:24 +08:00
MaybeMaruandHundrec 9da770f6cd oop 2025-08-20 05:30:24 +08:00
MaybeMaruandHundrec d414a4974a Mobile fix 2025-08-20 05:30:24 +08:00
MaybeMaruandHundrec 6f193c4bd8 A lot of stuff 2025-08-20 05:30:24 +08:00
Cameron TaylorandEric 520f7fbe68 create ConsoleMacro to allow easy initialization of classes into flixels console 2025-08-19 16:05:08 -04:00
Cameron TaylorandEric aaa722abcf change debug_dumpSave -> debug_dumpSaveJsonSave 2025-08-19 16:05:08 -04:00
anysadandEric f878624f44 fix: no more playtesting while dialog is open 2025-08-19 15:43:30 -04:00
Hundrecandjohfy 355ea561fa Fix lighting on DJ turntable lights
Finally.

Co-Authored-By: johfy <85341402+johferson@users.noreply.github.com>
2025-08-19 20:45:03 +08:00
Cameron TaylorandMoonDroid 7f6c0d56cd fix options menu being able to be pressed during fade 2025-08-19 19:28:23 +07:00
Cameron TaylorandMoonDroid a21eace70c fix main menu spam when FlxTransition stuff ends 2025-08-19 19:28:23 +07:00
anysadandAbnormal 47813eac31 fix: oopsie! no more big ranks 2025-08-19 00:10:26 -05:00
Cameron TaylorandHundrec 943afe2ffc remove mconsole, mcover, mockatoo, and munit from hmm 2025-08-19 04:53:39 +08:00
HundrecandRozebud 89127b2b00 Fix Week 3 Erect script error
Co-Authored-By: Rozebud <35246975+thatrozebuddude@users.noreply.github.com>
2025-08-19 04:45:34 +08:00
MoonDroidandAbnormal aab1330531 chore: Use .set() instead of getting a new instance of flxpoint, also add an if statement for better clarity!
woo!
2025-08-18 15:16:00 -05:00
PurSnakeandAbnormal 8bab6196e5 RESPECT 2025-08-18 15:16:00 -05:00
Hundrec 4e183a4dc9 Additional 0.7.4 charting changes
1. Blazin' - fixed an incorrect rhythm
2. South Erect - fixed minor misalignments
3. Cocoa Erect - added hey animation
4. Eggnog (Pico Mix) - fixed minor misalignments
2025-08-19 04:12:07 +08:00
HundrecandAbnormal ec2cc44cc3 Revert "Fix events still moving when not moved"
This reverts commit 45ba0cb7a6.
2025-08-17 16:38:03 -05:00
Hundrec 663987fbcd Change Monster and Winter Horrorland to Vol 2 2025-08-18 04:39:57 +08:00
LasercarandAbnormal 172041d4f7 chart editor context menu solitaire fix 2025-08-17 13:47:41 -05:00
HundrecandAbnormal 422da38662 Add min scale to SetHealthIcon event 2025-08-17 13:44:27 -05:00
LasercarandAbnormal 9b81ebc4f2 The default events now have minimum values
lol, lmao, imagine coding a input to have minimum values but just.. not setting a value?
2025-08-17 13:44:27 -05:00
LasercarandAbnormal 0b9ad0905e Toggle both hitsound audio volumes to 0 2025-08-17 13:41:05 -05:00
LasercarandAbnormal 1e1b5643a8 Audio playback volume toggle hotkeys
Shift + M for metronome
Shift + H for hitsounds
Shift + I for instrumental
Shift + V for vocals
Shift + B for Boyfriend vocals
Shift + D for Dad vocals
2025-08-17 13:41:05 -05:00
LasercarandAbnormal 45ba0cb7a6 Fix events still moving when not moved 2025-08-17 13:34:27 -05:00
LasercarandAbnormal b1406e07f5 Mention that this prevents the issue from happening 2025-08-17 13:34:27 -05:00
LasercarandAbnormal 4b655879f7 Don't move the notes if they weren't actually moved 2025-08-17 13:34:27 -05:00
JVN-PixelsandAbnormal fabfaa3a9c Fix Typo In MusicBeatState 2025-08-17 13:26:57 -05:00
HundrecandHyper_ 6d5249df79 Bump submod for charter field
Co-Authored-By: Hyper_ <40342021+nothyper-474@users.noreply.github.com>
2025-08-18 02:03:37 +08:00
Hyper_andHundrec 23b163cb69 Charter for new chart metadata dialog 2025-08-18 02:03:37 +08:00
Karim AkraandHundrec 1b84c21c36 Remove "accidentally" leftover math on the conductor 2025-08-18 01:53:50 +08:00
HundrecandHyper_ a87eb25765 Bump submod to fix Nene freezing
Co-Authored-By: Hyper_ <40342021+nothyper-474@users.noreply.github.com>
2025-08-17 09:59:01 +08:00
cyn0x8andHundrec df67b642a8 chart editor song id option + manifest id fix 2025-08-17 09:46:41 +08:00
Hundrec 6eefe9e31e Fix "Starting BPM" text being tiny 2025-08-17 09:40:04 +08:00
HundrecandKade fea34c4a7b Bring back Pause Menu offset adjustment for now 2025-08-16 17:11:24 -07:00
sector-aandHundrec 10e8cbbac3 Fix pixel icon search 2025-08-17 07:12:51 +08:00
MAJigsaw77andHundrec 37812ae2f8 Add isWindows check back. 2025-08-17 05:22:12 +08:00
MAJigsaw77andHundrec acb1930d7e Make the unicode check acually work. 2025-08-17 05:22:12 +08:00
b98095f8aa Fix the Chart Editor character switcher whoopsie
A public PR made it no longer selectable

Co-Authored-By: Kolo <67389779+koloindacrib@users.noreply.github.com>
2025-08-16 15:38:47 -05:00
Karim AkraandHundrec 724992d3b3 Prevent the conductor from doing excessive nromal updates 2025-08-17 03:45:35 +08:00
HundrecandAbnormal 89e07dac76 Add 2 sec fade and shorten timer to 37.5 sec
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2025-08-17 03:37:38 +08:00
EliteMasterEricandHundrec 2fb973049a Tweak a couple clamp calls 2025-08-17 03:37:38 +08:00
EliteMasterEricandHundrec dc20586e95 Switch from random weights to cycling, and remove Gameshark. 2025-08-17 03:37:38 +08:00
EliteMasterEricandHundrec ccb4c03b85 Implement new videos for attract state. 2025-08-17 03:37:38 +08:00
EliteMasterEricandHundrec f2732cb253 Rework attract state to play multiple videos. 2025-08-17 03:37:38 +08:00
AbnormalandHundrec bf2b1af185 cut down senpai's length by 8 seconds like how it was in legacy 2025-08-17 02:23:22 +08:00
MaybeMaruandAbnormal a2b347e31e Improve note batching 2025-08-15 12:27:53 -05:00
KoloandAbnormal 4317f129e7 fuuuuuuuucckkkkkkkkkkkkkkkkkkk 2025-08-15 10:00:50 -05:00
VioletSnowLeopardandMihai Alexandru 51eec4522e ensure song starts at starting bpm
works when start time isn't zero
2025-08-15 16:59:21 +03:00
HundrecandMihai Alexandru 21c16c3a50 Adjust a few notekind names 2025-08-15 16:38:33 +03:00
LasercarandMihai Alexandru b7a5761730 Add missing note kinds
Also clarifies that ugh and pretty good are for tankman only
2025-08-15 16:38:33 +03:00
unknownandMihai Alexandru ff09cb88cd use System.totalMemoryNumber 2025-08-15 16:27:00 +03:00
JVN-PixelsandMihai Alexandru d1a96f791f Home + End Keybinds - Story Mode 2025-08-15 16:24:28 +03:00
HundrecandMihai Alexandru 84bafa43b7 Remove extra line 2025-08-15 16:08:35 +03:00
LasercarandMihai Alexandru 223e837fe8 Character icon clickable in playstate fix 2025-08-15 16:08:35 +03:00
KoloandHundrec 50c601a7f0 FOUND media 2025-08-15 06:16:45 +08:00
KoloandHundrec f870ed2858 don't register classes twice silly 2025-08-15 06:13:02 +08:00
Hundrec f1d6906616 Remove laginator because song restarting fix works 2025-08-15 05:31:04 +08:00
Karim AkraandHundrec aec3c646d5 make sure the conductor's lerp doesn't exceed the resync threshold 2025-08-15 05:31:04 +08:00
Hyper_andAbnormal e7f7f4794f oops, you forgot this! 2025-08-14 16:16:58 -05:00
Cameron TaylorandEric 517eb4eb48 input util functions for less verbose key combos 2025-08-14 14:34:55 -04:00
Hundrecandsector-a 8cba81d207 Add nene-tankmen and apply shaders to A-Bot
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-08-14 22:02:32 +08:00
Cameron TaylorandKade 5831852edf use x and o as placeholder cross and checkmark 2025-08-13 19:50:33 -07:00
Cameron TaylorandKade 114bb37c7f some unicode/utf windows fixies 2025-08-13 19:50:33 -07:00
Cameron TaylorandKade 1db75cc55e use different unicode for checkmark and X 2025-08-13 19:50:33 -07:00
Cameron TaylorandKade 248516244c string sort the feature flags 2025-08-13 19:50:33 -07:00
Cameron TaylorandKade b108c0fd95 render feature flags in the compile debug into cute table 2025-08-13 19:50:33 -07:00
Cameron TaylorandKade 2a804f29fd rework main menu a lot more to use our state machine stuff 2025-08-13 19:49:21 -07:00
Cameron TaylorandKade b03828adf3 implement more verbose state machine to handle main menu navigation 2025-08-13 19:49:21 -07:00
AbnormalandEric 657a25996b use params 2025-08-13 13:15:26 -04:00
AbnormalandEric 842ec2c1cd feat: Scoped Modules 2025-08-13 13:15:26 -04:00
EliteMasterEricandAbnormal 4268462d90 Bump... but real? 2025-08-13 11:53:49 -05:00
HundrecandEric 031007992a Revert "Prevent the song from drifting away after a lagspike"
This reverts commit 7fd74edf2b.
2025-08-13 12:46:49 -04:00
HundrecandAbnormal cea7db410c Nudge Stress audio files 23ms earlier 2025-08-13 11:40:08 -05:00
anysadandHundrec 0e181877cf typo fix: notes are not props! 2025-08-14 00:23:46 +08:00
HundrecandAbnormal ef1216de46 Add comment to clarify double note in offset menu 2025-08-13 11:09:08 -05:00
b4b2e8da9d Freeplay Favorites now separated by variation (#1575)
Absolute Cinema

Co-authored-by: Kolo <67389779+KoloInDaCrib@users.noreply.github.com>
2025-08-14 00:01:10 +08:00
JackXson-RealandHundrec d95f239dfb fix mobile finally(?) 2025-08-13 14:35:28 +08:00
Karim AkraandGitHub 495690f41c Don't use any lerping on the conductor when the song isn't playing! 2025-08-13 10:47:47 +07:00
KoloandAbnormal b166cd9a7e save the goddamn changes graahhhhhh 2025-08-12 20:18:56 -05:00
KoloandAbnormal 7f82b48e3f whatever. go my destroy() override 2025-08-12 20:18:56 -05:00
JackXson-RealandHundrec 1fc611d130 fix main menu scrolling during transition 2025-08-13 05:35:33 +08:00
KoloandHundrec 57a276d17c lasercar nagged me to move the change somewhere else 2025-08-13 02:06:17 +08:00
KoloandHundrec 9b1b22c9d5 i literally had to set the holdNoteSprite to null that's all 2025-08-13 02:06:17 +08:00
MaybeMaruandAbnormal f6de4c54d3 Small optimizations 2025-08-12 12:49:54 -05:00
PurSnakeandHundrec e3aceacb59 one commit - one condition in changeDiff
welp, its fully done
i hope
💯
2025-08-12 23:27:33 +08:00
PurSnakeandHundrec 546375087c make albumRoll great again season 2 2025-08-12 23:27:33 +08:00
PurSnakeandHundrec c093e0ca1c make albumRoll great again 2025-08-12 23:27:33 +08:00
AbnormalandHundrec 7c6efba577 bump submod again FUUUUUUUUUUUUUUUUUUUUUUUUUCK 2025-08-12 15:56:39 +08:00
MoonDroidandCameron Taylor 6f5e3a50d2 Embarrassing update flixel ref 2025-08-11 21:35:41 -04:00
MoonDroidandCameron Taylor 2d0d5f8a2e For some reason if you don't do this the saved playbackrate becomes inconsistent :( 2025-08-11 21:35:41 -04:00
MoonDroidandCameron Taylor 826249f78c Update hmm flixel ref 2025-08-11 21:35:41 -04:00
MoonDroidandCameron Taylor 0af4c82723 Change floor to round for leftover pitch/playbackRate rounding 2025-08-11 21:35:41 -04:00
MoonDroidandCameron Taylor c16e45049b chore: Switch FlxMath.clamp calls to .clamp instead 2025-08-11 21:35:41 -04:00
MoonDroidandCameron Taylor ae00e14a5b chore: Remove useless line from WelcomeDialog 2025-08-11 21:35:41 -04:00
MoonDroidandCameron Taylor 42a9c43127 chore: Switch all FlxMath.bound calls to .clamp calls instead 2025-08-11 21:35:41 -04:00
Cameron TaylorandKade 17ece1423a don't log "starting prebuild tasks" 2025-08-11 18:26:50 -07:00
AbnormalandHundrec 6540faefdd update assets submodule with the latest changes 2025-08-12 06:57:28 +08:00
HundrecandKade eb24d4d19e Polish all the charts
Makes various changes to each chart:
* Adjust the length of every hold note trail to match the vocals as closely as possible, across all variations and difficulties
* Revise Easy and Normal charts to be more consistent with the player's chart (from Week 1 to Week 3)
* Fix a handful of charting errors reported on GitHub with Cory
* Fix even more charting errors not reported on GitHub
* Additional bits to make these the most polished charts yet
2025-08-11 09:58:25 -07:00
KoloandAbnormal 01a2458c12 force the tween graaahhhhhhhhh 2025-08-11 11:37:06 -05:00
AbnormalandHundrec 38e7e230d8 bump hscript to fix an issue with final variables 2025-08-10 01:13:41 +08:00
MikolkaandHundrec 84f119036b Update hmm.json 2025-08-10 00:47:51 +08:00
AbnormalandHundrec 74a783c3db bump assets 2025-08-09 02:41:54 +08:00
AbnormalandHundrec 09d5926455 bump polymod hscript and flxanimate woohoo!!!!!!!! 2025-08-09 02:31:49 +08:00
sector-aandHundrec 5f8b7787cb Remove a left-over trace 2025-08-09 01:34:15 +08:00
Cameron TaylorandKade a7156978a1 small regex change to checkstyle to allow leading underscores (_instance is now an allowed variable name) 2025-08-07 13:29:44 -07:00
65349f4714 Trim env lines to fix issues with CRLF line endings
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-08 01:04:58 +07:00
MoonDroid 93ad7e8932 Update exclusions to ASTC textures 2025-08-08 01:04:18 +07:00
Karim AkraandMoonDroid df388dfaa6 why are we configuring assets before ASTC?? 2025-08-08 01:04:18 +07:00
Karim AkraandMoonDroid c142add8a1 fixed an oopsie with exclusions 2025-08-08 01:04:18 +07:00
Karim AkraandMoonDroid a75c41b813 Update astc-compressor!! 2025-08-08 01:04:18 +07:00
Karim AkraandMoonDroid 7fd74edf2b Prevent the song from drifting away after a lagspike 2025-08-08 01:02:55 +07:00
Karim AkraandAbnormal 44370c2653 Fix chromebooks using mobile layout! 2025-08-07 09:56:03 -05:00
Hyper_andKade 1fbb7604dd nuh uh *gives back ability to fullscreen* 2025-08-06 15:30:15 -07:00
0e52744718 Fix visual bugs when selecting between two hold note trails in Chart Editor
Co-authored-by: Kolo <67389779+KoloInDaCrib@users.noreply.github.com>
2025-08-06 15:26:24 -07:00
PurSnakeandAbnormal feb55b2625 stuff 2025-08-06 11:47:10 -05:00
HundrecandAbnormal 4341a53486 Revert turntable lights changes 2025-08-05 16:21:05 -05:00
Karim AkraandHundrec 0566cd3e58 get this out of here at once 2025-08-06 01:02:34 +08:00
Karim AkraandHundrec a2f7fa9ef4 Fixed the lerp speed when changing playback rate 2025-08-06 01:02:34 +08:00
Karim AkraandHundrec 3a30b681b6 tweaked the ease ratio 2025-08-06 01:02:34 +08:00
Karim AkraandHundrec 0bd4ce4c97 Adjusted the lerp ratio to work better on lower FPS & added threshold for normal conductor updates 2025-08-06 01:02:34 +08:00
Karim AkraandHundrec df0d977e6c Adjust the conductor arguments for smoother notes scrolling 2025-08-06 01:02:34 +08:00
Hundrec 059b412e85 Reword the checkbox 2025-08-05 23:16:18 +08:00
AbnormalandHundrec 27a072f4e1 add *the* checkbox (thunder and lightning noises) 2025-08-05 23:16:18 +08:00
LasercarandMihai Alexandru 1df0cb95f6 Fix onNoteHoldDrop logic
Co-Authored-By: Lasercar <64717068+Lasercar@users.noreply.github.com>
2025-08-05 15:00:01 +03:00
MAJigsaw77andEric ce83e962bf Fix swapped args oops. 2025-08-05 01:14:22 -04:00
MAJigsaw77andEric fb293ebcd2 Add a custom ApplicationMain to enable some winapi stuff. 2025-08-05 01:14:22 -04:00
MAJigsaw77andEric bb7b00cf77 Replace the application popup. 2025-08-05 01:14:22 -04:00
MAJigsaw77andEric e16391a05c Add winapi stuff. 2025-08-05 01:14:22 -04:00
AbnormalandHundrec 5aba4b54a5 Fix some warnings/crashes in Week 6 2025-08-05 06:14:42 +08:00
EricandHundrec cb611f77a0 Update documentation in FreeplayDJ.hx 2025-08-05 06:04:08 +08:00
AbnormalandHundrec b5345e1da2 lol we forgot 2025-08-05 05:54:22 +08:00
AbnormalandHundrec 8d6590e765 bump art submod 2025-08-05 05:09:29 +08:00
AbnormalandGitHub e39b32bab0 Merge pull request #1530 from FunkinCrew/cool-merging 2025-08-04 15:42:34 -05:00
HundrecandGitHub d5754c5da2 Merge public docs changes
Merge main into develop because it would be so awesome
2025-08-05 04:17:09 +08:00
HundrecandGitHub fbe83be936 Merge branch 'develop' into cool-merging 2025-08-05 04:15:55 +08:00
AbnormalandHundrec 8d14df77ff bump the submod wooHOOOOOOOOO 2025-08-05 03:49:07 +08:00
Herman KhomichandAbnormal 55358463f8 Remove repeated creation of strumlineScale in a row / Strumline.hx 2025-08-04 14:21:26 -05:00
AbnormalandHundrec 4ea99656f2 no more PROPER TURNTABLE LIGHTS FIX *vine boom* 2025-08-05 01:58:10 +08:00
Hyper_andHundrec 34ce13c5df chore: Add null safety to PlayState and LoadingState 2025-08-05 01:18:53 +08:00
AbnormalandMihai Alexandru 1d8679941e fix tankman variant names 2025-08-04 20:12:22 +03:00
086f28fef1 fix invisible pixels on some sprites
Co-authored-by: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com>
2025-08-04 19:51:50 +03:00
fb4967c94b fix the pico blazin death confirm offsets
Co-authored-by: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com>
2025-08-04 19:46:24 +03:00
AbnormalandMihai Alexandru 293b70bbed update the submod 2025-08-04 19:31:56 +03:00
AbnormalandMihai Alexandru 64f4620b5a dude........fuck yes. 2025-08-04 19:31:56 +03:00
JackXson-RealandAbnormal 9c1e22309b decrease preview volume from 80% to 70% 2025-08-03 15:59:12 -05:00
JackXson-RealandAbnormal 4ecef6db74 increase preview volume to 80% 2025-08-03 15:59:12 -05:00
KoloandAbnormal b128741075 mb gang 2025-08-03 15:49:36 -05:00
AwesomezPro99andAbnormal 86e69cfbd1 Fixed Window Title When Pressing F4 2025-08-03 15:36:26 -05:00
Karim AkraandGitHub aa8690fce3 Merge pull request #1489 from FunkinCrew/pr-5565/SrtHero278/pointer-fixes
[PUBLIC PR] Properly add the touch pointer on playstate
2025-08-03 17:45:12 +03:00
MrMaderaandHundrec e281bdddca south button now works! 2025-08-03 21:29:29 +08:00
MoonDroidandMihai Alexandru 19fdda7cd9 fix: Call Math.round and FlxMath.clamp for better readability and slightly better functionality
what a mouthful :(
2025-08-03 15:54:16 +03:00
MoonDroidandMihai Alexandru d72b989bf5 Delete useless line 2025-08-03 15:54:16 +03:00
LasercarandMihai Alexandru cd99905bdf Fix volumes being reset to 100% after playtest 2025-08-03 15:54:16 +03:00
LasercarandMihai Alexandru 3f82f3792b Set playspeed after variation load 2025-08-03 15:54:16 +03:00
trofim.alandMihai Alexandru 1d8ed5198c api version 0.7.0
Update example mod's API version so it actually loads. part 2.
2025-08-03 13:41:33 +03:00
AwesomezPro99andMihai Alexandru 8cd3785e3c Fix Blazin' Death Pause 2025-08-03 13:01:13 +03:00
MAJigsaw77andMoonDroid 7e01e7332b Fix html5 compile. 2025-08-03 12:48:54 +07:00
MAJigsaw77andMoonDroid c3a837b054 Dont compile the android classes on other targets. 2025-08-03 12:48:54 +07:00
MAJigsaw77andMoonDroid a92567886c Relocate the external folder outside of mobile package. 2025-08-03 12:48:54 +07:00
4cbfaefc1a Slightly longer fade transition
Co-authored-by: VirtuGuy <103977942+VirtuGuy@users.noreply.github.com>
2025-08-02 22:10:26 +03:00
AwesomezPro99andMihai Alexandru 705e6b3308 Add Camera Fade To Song Select 2025-08-02 22:10:26 +03:00
AbnormalandMihai Alexandru 56878befef update the haxelibs.......yippee...... 2025-08-02 21:59:30 +03:00
AbnormalandMihai Alexandru 44cdbb08c4 asset changes wooooooooooooooo 2025-08-02 17:18:18 +03:00
KoloandMihai Alexandru d6fe54ee79 gyafyhaswguhyshbughsd 2025-08-02 17:18:18 +03:00
KoloandMihai Alexandru 32c775ef3f tooltips....BUT FOR NOTES! 2025-08-02 17:18:18 +03:00
PurSnakeandMihai Alexandru 1605514424 Seriously? 2025-08-02 17:02:31 +03:00
Hyper_andMihai Alexandru 743e8b13c2 me...................................................................................... 2025-08-02 16:22:18 +03:00
EricandGitHub cf89d672e7 Merge pull request #5392 from SantiagoCalebe/main
Just a lil' update of the readme
2025-08-02 08:55:57 -04:00
KoloandAbnormal 661ddb15f7 me......................................................................... 2025-08-02 07:16:05 -05:00
Hundrec 72fa82716d A little more README polish 2025-08-02 18:54:18 +08:00
SantiagoandGitHub a069ca2dc6 I think i have a problem 2025-08-02 07:46:57 -03:00
SantiagoandGitHub 90a2d7a1ad ??? 2025-08-02 07:41:13 -03:00
cyn0x8andMihai Alexandru 3170346b83 Create ModStore.hx 2025-08-02 11:32:44 +03:00
anysadandMihai Alexandru e6d737125e feature: are you sure? 2025-08-02 11:28:17 +03:00
AwesomezPro99andMihai Alexandru 3d88fbb11f Update PreferencesMenu.hx 2025-08-02 11:10:03 +03:00
JVN-PixelsandMihai Alexandru 0d6bc2bedd Fix NOR in Freeplay after spamming the letter keybinds 2025-08-02 11:07:04 +03:00
anysadandMihai Alexandru da5f691865 fix: no more animation editor crash 2025-08-02 11:03:23 +03:00
Hyper_andMihai Alexandru f63cbf073a Restore a lost change from #4787 2025-08-02 10:55:58 +03:00
KoloandMihai Alexandru 30721c3a30 tfw changeDiff wasn't even being called 2025-08-02 10:49:15 +03:00
JackXson-RealandMihai Alexandru 2b1f346097 Add enter/exit animation for charSelect nametag part 2 2025-08-02 10:38:32 +03:00
Mihai AlexandruandGitHub 12117557c7 Merge branch 'master' into pr-5565/SrtHero278/pointer-fixes 2025-08-02 10:33:33 +03:00
Hundrec 6b0e607af0 Update another contributor's name 2025-08-02 04:37:19 +08:00
Hundrec 2263b36cd7 Add a new contributor to Changelog and adjust spacing 2025-08-02 04:37:19 +08:00
AbnormalandHundrec 2dcc528847 bump polymod to optimize some shiiiiiiiiiiiiiiiit 2025-08-02 02:19:14 +08:00
ExcodeFNFandHundrec 5cb33e895c Freeplay CoolColors Array Removal 2025-08-02 02:01:36 +08:00
AwesomezPro99andHundrec 1b91f3b57c Fixed DJ Flicker After New Rank 2025-08-02 01:28:14 +08:00
EricandHundrec e5e3270fef Update hmm.json to optimize FlxAnimate 2025-08-02 00:43:57 +08:00
EliteMasterEricandMihai Alexandru e003a38cab Exclude the debug print function when we aren't in the build step 2025-08-01 18:32:37 +03:00
SrtHero278andMoonDroid 890d1dafcb include the camera parameter in the comment 2025-08-01 19:48:39 +07:00
SrtHero278andMoonDroid 9d2cfa9686 Fix touch pointer positioning when in PlayState 2025-08-01 19:48:39 +07:00
e6fd5d9b12 Make the Android back button close the game when in TitleState
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 13:59:02 +07:00
Cameron TaylorandMoonDroid 967397311b remove tiny uncommented code, and simplify an unneeded variable initialization 2025-08-01 13:15:56 +07:00
Cameron TaylorandMoonDroid 542f59ef72 tallyCompletion() function for cleanup + constency 2025-08-01 13:15:56 +07:00
065ee74aea Scoreable notekinds
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 13:05:11 +07:00
312b5c8812 Flair adjustments to the build process
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 12:05:21 +07:00
e9aa6872a3 Bump libs refs
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 12:03:58 +07:00
4f9b63f22c Configure the android adaptive icons through lime & moved the icons stuff to art submodule
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 01:17:29 +07:00
MAJigsaw77 962519e7f0 Fix android compile. 2025-07-28 10:41:31 +03:00
MAJigsaw77 34bae4a431 Fix compile once again. 2025-07-28 10:41:31 +03:00
Karim AkraandMihai Alexandru 79478080f6 oops 2025-07-28 10:41:31 +03:00
Karim AkraandMihai Alexandru 65a3ccc8fe add the same changes to the .env parser on project.hxp !! 2025-07-28 10:41:31 +03:00
Karim AkraandMihai Alexandru 4ac851c387 add support for target specific environment values
and renamed `GLOBAL_ADMOB_PUBLISHER` to `MOBILE_GLOBAL_ADMOB_PUBLISHER` !!
2025-07-28 10:41:31 +03:00
MAJigsaw77andAbnormal 70d5730b70 Fix compile. 2025-07-27 00:56:31 -05:00
Abnormal c527fed70c conflict stuffs lol 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal 054a5cd00b fix fullscreen bug and show clear save data if logged out of ng 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal 19c5de8fe2 HOPEFULLY FIX EVERYTHING WRONG (this time it was tested between two computers) 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal dbc26fd621 hopefully fix everything with load from ng 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal eb1986b246 move clear save data to the top, add clear ng save data 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal d661d93184 rewrite NGSaveSlot.load to be async, dont precache assets, error handling 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal 4a07d0a347 make newgrounds functions in Save static and only available if newgrounds feature flag is enabled, make sure base save slot is loaded and is not empty, and recover save data in case newgrounds doesnt wanna play nice 2025-07-27 00:56:31 -05:00
TechnikTilandAbnormal 832f01345f Add Save Data Options, also allow user to load and save with Newgrounds Save Slots. 2025-07-27 00:56:31 -05:00
MAJigsaw77andAbnormal e8d41c938c Use no-traces define instead of the flag. 2025-07-26 13:46:48 -05:00
MAJigsaw77andAbnormal a94bd7f36c Fix compiling. 2025-07-26 13:43:19 -05:00
EliteMasterEricandAbnormal c185f10e65 Move Discord client ID to .env 2025-07-26 13:43:19 -05:00
Cameron TaylorandMihai Alexandru 52f3c63071 mobile fix where the capsules don't properly shift away from the letter sorting crap 2025-07-26 12:31:38 +03:00
Cameron TaylorandMihai Alexandru e71062b914 some lil variable renaming in SongMenuItem.hx 2025-07-26 12:31:38 +03:00
Cameron TaylorandMihai Alexandru 3aa6a36b5e small function renaming 2025-07-26 12:31:38 +03:00
MAJigsaw77 a89fa9c121 Acually fix it (oops). 2025-07-26 11:55:36 +03:00
MAJigsaw77 cb2015f51a Fix a workflow compile error. 2025-07-26 11:55:36 +03:00
MAJigsaw77 139ce3847c Fix for env vars that contain = as one of thier characters. 2025-07-26 11:55:36 +03:00
EliteMasterEricandMihai Alexandru 87b40c1203 Obsolete NewgroundsCredentials.hx for storing secret keys in favor of .env 2025-07-26 11:55:36 +03:00
b9852c316b offset menu changes
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-26 10:36:29 +03:00
444697620c Use round instead of floor to fix rounding errors in Preferences.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-26 10:04:00 +03:00
6abeefb15d Set cliprect for clear percent.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 17:43:34 +03:00
530bd1f11d Add onPause callback to pause substate.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 17:36:34 +03:00
sector-aandGitHub 76c0dea92b Move results and death haptics to scripts. 2025-07-25 17:23:04 +03:00
2d7a2202f5 Fix song restarting bug (for good??).
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 16:45:55 +03:00
1f18a3d1f4 Fix diff dots alignment.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 16:37:39 +03:00
0d57f61ffa Scale up the bg in debug menu on widescreen
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 16:19:46 +03:00
MAJigsaw77 9fa70775b9 Use funkin.Assets instead of openfl.utils.Assets. 2025-07-25 16:15:51 +03:00
sector-aandMihai Alexandru 463afb43c0 assets submod 2025-07-25 16:15:51 +03:00
sector-aandMihai Alexandru 2833827fbf Change the way game searches for pixel icons 2025-07-25 16:15:51 +03:00
SantiagoandGitHub 01cd72e805 Merge branch 'main' into main 2025-07-22 14:13:22 -03:00
EricandGitHub 72e0ff6c9b Merge pull request #5487 from Lasercar/bunker-infiltrated
Bump to 0.7.4
2025-07-22 11:59:45 -04:00
EricandGitHub 2586154376 Merge pull request #5488 from FunkinCrew/develop-v0.7.3
Update main branch to v0.7.3
2025-07-22 11:59:01 -04:00
Lasercar 82367dffc2 Bunker infiltrated 2025-07-23 00:30:15 +10:00
charlesisfelineandHundrec 7c675ecf17 the psych confusion continues! 2025-07-22 10:03:25 +08:00
Hundrec b4e52df156 3
Build and Upload nightly game builds / gather-changes (push) Canceled after 0s
Build and Upload nightly game builds / gather-tags (push) Canceled after 0s
Build and Upload nightly game builds / build-game-on-host (macos, macos) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-on-host (windows, windows) (push) Canceled after 0s
Build and Upload nightly game builds / docker-image (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (html5) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (linux) (push) Canceled after 0s
2025-07-22 07:56:14 +08:00
Hundrec cf70bf2c6c Friday Night Funkin' if it was good 2025-07-22 07:56:14 +08:00
Hyper_andHundrec fb6d1b36d3 lasercar................................................................................................................................................................................................. 2025-07-22 07:43:15 +08:00
MoonDroidandCameron Taylor 0c0c63bc03 fix: Move hasInitialized to onPurchasesUpdate instead. 2025-07-21 19:08:14 -04:00
Hyper_andHundrec 01620fda9b The most deranged line loss of all time 2025-07-22 06:41:46 +08:00
cherryandHundrec 3bcd6813c1 Clear key from correct map 2025-07-22 06:12:56 +08:00
sector-aandCameron Taylor d44966efd2 Prevent AA calculations if AA_STAGES are 0 in DropShadow shaders 2025-07-21 18:02:18 -04:00
79c3e2de11 assets ref
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-07-22 04:50:15 +07:00
Karim AkraandHundrec 8372d47d11 Fixed the menu item getting disabled if you hit back during the transition 2025-07-22 05:21:40 +08:00
MoonDroidandHundrec d89ebdf58f Attempt to fix the soft lock issue for Main Menu. 2025-07-22 05:21:40 +08:00
kade-githubandsector-a 1e8c472084 holy shit 2025-07-21 23:16:43 +03:00
kade-githubandsector-a 17cef6f897 fix for winblows 2025-07-21 23:16:43 +03:00
kade-githubandsector-a 2cc43ee1f6 text fix for my mobile fellas 2025-07-21 23:16:43 +03:00
EricandHundrec 2277acccfa Update hmm.json 2025-07-22 04:00:29 +08:00
EricandGitHub 351719ab13 Merge pull request #5438 from FunkinCrew/EliteMasterEric-patch-4
Update lime, openfl, flixel repo URLs in hmm.json
2025-07-21 13:05:40 -04:00
EricandGitHub 4ecfe9863e Update lime, openfl, flixel repo URLs in hmm.json 2025-07-21 13:05:15 -04:00
EricandGitHub 48e140e5c0 Merge pull request #5432 from FunkinCrew/develop-0.7.2
Release the mobile source code already
2025-07-21 12:17:54 -04:00
HundrecandGitHub e6bb965d6b Merge branch 'main' into develop-0.7.2 2025-07-22 00:13:47 +08:00
BaranandAbnormal b00376c88c 0.7.2 bumping is real 2025-07-21 10:33:13 -05:00
SantiagoandGitHub 96a1796905 readme update 2025-07-17 17:39:53 -03:00
CrusherNotDripandAbnormal 541bb78da9 Bump to 0.7.1 2025-07-16 21:51:46 -05:00
HundrecandAbnormal 5f5fff870c Update issue templates for Mobile 2025-07-14 08:25:10 -05:00
CrusherNotDripandAbnormal 52acd86cdf bump versions to 0.7.0 2025-07-14 07:38:31 -05:00
EricandGitHub 29f7aca135 Merge pull request #5183 from Hundrec/patch-13
[DOCS] Fix a link in a Changelog entry
2025-06-06 01:14:53 -04:00
HundrecandGitHub 35d4d24731 that's not even the right link
what
2025-06-01 01:50:33 -06:00
HundrecandGitHub c0dde5c936 missed one
funkin.assets
2025-06-01 01:46:27 -06:00
256 changed files with 6686 additions and 3050 deletions
+19 -6
View File
@@ -14,19 +14,20 @@ body:
- label: I have read the [Contributing Guide](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md)
- label: I have checked the Issues/Discussions pages to see if my issue has already been reported
- label: I have properly titled my issue
- label: I did not have any mods installed when I encountered this issue
- type: dropdown
attributes:
label: Platform
description: Which platform are you playing on?
options:
- Android
- iOS/iPadOS
- Newgrounds (Web/HTML5)
- Itch.io (Web/HTML5)
- Itch.io (Downloadable Build) - Windows
- Itch.io (Downloadable Build) - MacOS
- Itch.io (Downloadable Build) - Linux
- Google Playstore - Android
- App Store - iOS
- Windows (Downloadable Build)
- MacOS (Downloadable Build)
- Linux (Downloadable Build)
- Compiled from GitHub Source Code
validations:
required: true
@@ -43,11 +44,23 @@ body:
- Safari
- Other (Specify in Description field)
- type: input
attributes:
label: Mobile Device Model
description: (Mobile users only) What mobile device are you playing on?
placeholder: ex. iPhone 17, Galaxy S25, iPad 11th Gen
- type: input
attributes:
label: Mobile OS Version
description: (Mobile users only) What version is your Operating System?
placeholder: ex. iOS 26.0, Android 15, iPadOS 26.0
- type: input
attributes:
label: Version
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
placeholder: ex. 0.6.4
placeholder: ex. 0.7.5
validations:
required: true
+9 -19
View File
@@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: "# PLEASE READ THE [CONTRIBUTING GUIDE](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md) BEFORE OPENING ISSUES!"
- type: checkboxes
attributes:
label: Issue Checklist
@@ -21,35 +21,25 @@ body:
label: Platform
description: Which platform are you playing on?
options:
- Android
- iOS/iPadOS
- Newgrounds (Web/HTML5)
- Itch.io (Web/HTML5)
- Itch.io (Downloadable Build) - Windows
- Itch.io (Downloadable Build) - MacOS
- Itch.io (Downloadable Build) - Linux
- Windows (Downloadable Build)
- MacOS (Downloadable Build)
- Linux (Downloadable Build)
- Compiled from GitHub Source Code
validations:
required: true
- type: dropdown
attributes:
label: Browser
description: (Web/HTML5 users only) Which browser are you playing on?
options:
- Google Chrome
- Microsoft Edge
- Firefox
- Opera
- Safari
- Other (Specify in Description field)
- type: input
attributes:
label: Version
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
placeholder: ex. 0.6.4
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
placeholder: ex. 0.7.5
validations:
required: true
- type: markdown
attributes:
value: "## Describe the charting issue(s)."
+6 -4
View File
@@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: "# PLEASE READ THE [CONTRIBUTING GUIDE](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md) BEFORE OPENING ISSUES!"
- type: checkboxes
attributes:
label: Issue Checklist
@@ -22,6 +22,8 @@ body:
label: Platform
description: Which platform are you compiling for?
options:
- Android
- iOS/iPadOS
- Web/HTML5
- Desktop (Windows)
- Desktop (Mac)
@@ -33,11 +35,11 @@ body:
- type: input
attributes:
label: Version
description: Which version are you compiling? The game version is in the bottom left corner of the main menu or in the project.hxp file.
placeholder: ex. 0.6.4
description: Which version are you compiling? The game version is in the bottom left corner of the main menu or in the project.hxp file.
placeholder: ex. 0.7.5
validations:
required: true
- type: markdown
attributes:
value: "## Describe your compiling issue."
+23 -8
View File
@@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: "# PLEASE READ THE [CONTRIBUTING GUIDE](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md) BEFORE OPENING ISSUES!"
- type: checkboxes
attributes:
label: Issue Checklist
@@ -15,17 +15,20 @@ body:
- label: I have read the [Contributing Guide](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md)
- label: I have checked the Issues/Discussions pages to see if my issue has already been reported
- label: I have properly titled my issue
- label: I did not have any mods installed when I encountered this issue
- type: dropdown
attributes:
label: Platform
description: Which platform are you playing on?
options:
- Android
- iOS/iPadOS
- Newgrounds (Web/HTML5)
- Itch.io (Web/HTML5)
- Itch.io (Downloadable Build) - Windows
- Itch.io (Downloadable Build) - MacOS
- Itch.io (Downloadable Build) - Linux
- Windows (Downloadable Build)
- MacOS (Downloadable Build)
- Linux (Downloadable Build)
- Compiled from GitHub Source Code
validations:
required: true
@@ -42,11 +45,23 @@ body:
- Safari
- Other (Specify in Description field)
- type: input
attributes:
label: Mobile Device Model
description: (Mobile users only) What mobile device are you playing on?
placeholder: ex. iPhone 17, Galaxy S25, iPad 11th Gen
- type: input
attributes:
label: Mobile OS Version
description: (Mobile users only) What version is your Operating System?
placeholder: ex. iOS 26.0, Android 15, iPadOS 26.0
- type: input
attributes:
label: Version
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
placeholder: ex. 0.6.4
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
placeholder: ex. 0.7.5
validations:
required: true
@@ -61,7 +76,7 @@ body:
- type: textarea
attributes:
label: Description
description: Include screenshots or videos of the crash happening. Provide as much detail as you can.
description: Include screenshots or videos of the crash happening. Provide as much detail as you can.
placeholder: Describe the crash here...
validations:
required: true
@@ -77,7 +92,7 @@ body:
- type: textarea
attributes:
label: Crash logs
description: These can be found in the logs folder where Funkin.exe is.
description: These can be found in the logs folder where Funkin.exe is, or in your mobile device's file explorer.
placeholder: Upload your logs here...
validations:
required: true
+1 -1
View File
@@ -16,7 +16,7 @@ NewgroundsCredentials.hx
# Mobile signing stuff
.apple/
.env
key.keystore
*.keystore
# Exclude JS stuff
node_modules/
+253 -5
View File
@@ -4,6 +4,249 @@ 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.7.5] - 2025-09-19
### Added
- Added an `onStateCreate` event to the Module class.
### Changed
- Gave the debug display a huge upgrade!
- Choose from three settings in the Preferences Menu: Off/Simple/Advanced
- New “Task memory” counter shows how much RAM the game is using on your computer.
- Advanced mode displays graphs for FPS and RAM usage.
- Hot reloading now works in scripted states.
- Made a few more classes scriptable.
- FunkinVideoSprite
- FlxStrip
- FlxTypedGroup
- Strumline
- StageProp​​
- The Random capsule now brings up the option to select a random instrumental. ([0d5c6ac](https://github.com/FunkinCrew/Funkin/commit/0d5c6ac9632ee3bf3977b9bd369daab9f2d95fea)) - by @VioletSnowLeopard in [#5891](https://github.com/FunkinCrew/Funkin/pull/5891)
- The Character Select menu now returns to Freeplay after pressing a back button. ([250d218](https://github.com/FunkinCrew/Funkin/commit/250d2188b9cb2c92d283d8b12ed7de0286324592)) - by @MrMadera in [#5887](https://github.com/FunkinCrew/Funkin/pull/5887)
- Pressing the Shift key in the Credits menu now pauses scrolling. ([479036a](https://github.com/FunkinCrew/Funkin/commit/479036a4008fe1c54adc970c0a476fae6b1b3e94)) - by @JVNpixels in [#2924](https://github.com/FunkinCrew/Funkin/pull/2924)
- Chart Editor and Stage Editor backup files are now given relevant filenames. ([b31be10](https://github.com/FunkinCrew/Funkin/commit/b31be1043ccd1e906a656913b947bae160b451fe)) - by @Lasercar in [#4118](https://github.com/FunkinCrew/Funkin/pull/4118)
- The Animation Editor's onion skin now properly accounts for offsets and displays the idle animation. ([0fd6f5b](https://github.com/FunkinCrew/Funkin/commit/0fd6f5b3b7bd115a3b6821096daa929c220bd235)) - by @KoloInDaCrib in [#5810](https://github.com/FunkinCrew/Funkin/pull/5810)
### Fixed
- The Freeplay new rank animation now shows the new rank slamming onto the old one.
- Freeplay capsules with a Gold Perfect rank no longer become randomly offset when scrolling.
- The Pico Freeplay DJ’s new rank animation now properly renders its lighting.
- Freeplay song previews no longer play replaced or deleted audio files.
- The strumline no longer disappears after re-entering Lag Adjustment.
- Fixed various issues with Week 6 dialogue boxes, portraits, and audio.
- [MOBILE] The strumlines are no longer offset to the left in Blazin’.
- The preloader no longer disables fullscreen mode after completion.
- Attempting to log in to Newgrounds during an ongoing login attempt no longer crashes the game. ([4e572b1](https://github.com/FunkinCrew/Funkin/commit/4e572b171fe901a84f12b4566963fd3c1f4ae6fb)) - by @KoloInDaCrib in [#5922](https://github.com/FunkinCrew/Funkin/pull/5922)
- Added null-safety to Leaderboards and Medals to prevent a rare crash. ([88fc5f9](https://github.com/FunkinCrew/Funkin/commit/88fc5f9ed684e287d7411a59fb4fdf170acfed5a)) - by @NotHyper-474 in [#5926](https://github.com/FunkinCrew/Funkin/pull/5926)
- Freeplay ranks no longer pop out when scrolling through song capsules. ([747446e](https://github.com/FunkinCrew/Funkin/commit/747446e2e420449f422fbc69aafda6128ac8d16e)) - by @VioletSnowLeopard in [#5822](https://github.com/FunkinCrew/Funkin/pull/5822)
- The Freeplay intro no longer plays when returning from a sticker transition. ([63ec749](https://github.com/FunkinCrew/Funkin/commit/63ec749c7a3c90d529e9e8f2f3ed1c8913e8f9a1)) - by @PurSnake in [#5942](https://github.com/FunkinCrew/Funkin/pull/5942)
- Hot-reloading with F5 after earning a rank no longer crashes Freeplay. ([79e8b5d](https://github.com/FunkinCrew/Funkin/commit/79e8b5d71e052953b77b81b66e0a83a7bbeeeeed)) - by @KoloInDaCrib in [#5971](https://github.com/FunkinCrew/Funkin/pull/5971)
- The Main Menu music now fades in consistently when exiting from Freeplay to the Title Screen. ([a10bbf6](https://github.com/FunkinCrew/Funkin/commit/a10bbf60acbbeadfb5a91930745ef4fd338b1a24)) - by @VirtuGuy in [#5855](https://github.com/FunkinCrew/Funkin/pull/5855)
- The game now falls back to default audio files when files specified by the metadata don't exist. ([b5357ac](https://github.com/FunkinCrew/Funkin/commit/b5357acf98bde81a4121a3723061f7c559a0640f)) - by @VioletSnowLeopard in [#5954](https://github.com/FunkinCrew/Funkin/pull/5954)
- The cutscene pause menu no longer persists across songs after exiting a video cutscene. ([c2305f3](https://github.com/FunkinCrew/Funkin/commit/c2305f32f0147f6326e8665d21a6b8a793f45033)) - by @KoloInDaCrib in [#5880](https://github.com/FunkinCrew/Funkin/pull/5880)
- Mashing to skip the Eggnog Erect cutscene no longer crashes the game. ([5ca3c6a](https://github.com/FunkinCrew/funkin.assets/commit/5ca3c6a5745b61a457db149c289784c08e560ee9)) - by @VioletSnowLeopard in [funkin.assets#258](https://github.com/FunkinCrew/funkin.assets/pull/258)
- Stress (Pico Mix) no longer lag spikes when loading in the background tankmen. ([6701405](https://github.com/FunkinCrew/funkin.assets/commit/670140571239ca08c1ae1c5286773d99c2875c2d)) - by @NotHyper-474 and @KoloInDaCrib in [funkin.assets#242](https://github.com/FunkinCrew/funkin.assets/pull/242)
- Stress (Pico Mix) no longer lag spikes when Tankman changes sprites. ([aa5956a](https://github.com/FunkinCrew/Funkin/commit/aa5956a30bdc47d53ebebb4b61a7ebb3f04c7dc6)) - by @NotHyper-474 in [#5939](https://github.com/FunkinCrew/Funkin/pull/5939)
- The bricks in Stress (Pico Mix) no longer move after restarting the song. ([9cfee03](https://github.com/FunkinCrew/Funkin/commit/9cfee0398a057567f80ad68ff6052964da63af09)) - by @VirtuGuy in [#5875](https://github.com/FunkinCrew/Funkin/pull/5875)
- Pico now properly shoots after restarting Stress. ([b0ef0d3](https://github.com/FunkinCrew/funkin.assets/commit/b0ef0d352c199e93903652a95ffdf16a3dc2d569)) - by @7oltan in [funkin.assets#254](https://github.com/FunkinCrew/funkin.assets/pull/254)
- A-Bot's visualizer now zeroes out when restarting the song. ([ba3a8b0](https://github.com/FunkinCrew/funkin.assets/commit/ba3a8b0cbbf785a0729dcf85e25b6e59c0c12657)) - by @KoloInDaCrib in [funkin.assets#246](https://github.com/FunkinCrew/funkin.assets/pull/246)
- Notekinds now properly receive dispatched events last in PlayState. ([89b2b7f](https://github.com/FunkinCrew/Funkin/commit/89b2b7fcc3130db0af1f782594af72ae1f4ce320)) - by @Az989YT in [#5936](https://github.com/FunkinCrew/Funkin/pull/5936)
- Text from .json files is now properly sanitized before it is parsed. ([80d7ace](https://github.com/FunkinCrew/Funkin/commit/80d7ace714efb729cb8f1b23b61fdab4ac655275)) - by @KoloInDaCrib in [#5108](https://github.com/FunkinCrew/Funkin/pull/5108)
- Fixed a crash when exiting the Chart Editor after interacting with a text field. ([f85f2f0](https://github.com/FunkinCrew/Funkin/commit/f85f2f03d97fc1332275f088ddce2b4056f0ded2)) - by @NotHyper-474 in [#5992](https://github.com/FunkinCrew/Funkin/pull/5992)
- Fixed some issues with variation handling in the Chart Editor. ([970ccf2](https://github.com/FunkinCrew/Funkin/commit/970ccf2f4a9b5802b70d0b3c269c8b9e541d53f2)) - by @NotHyper-474 in [#4396](https://github.com/FunkinCrew/Funkin/pull/4396)
- Audio no longer plays when dragging a playhead in the Chart Editor. ([2d95754](https://github.com/FunkinCrew/Funkin/commit/2d95754d492da06920d56de2b2bcbb9b81182af0)) - by @Lasercar in [#4140](https://github.com/FunkinCrew/Funkin/pull/4140)
- The Chart Editor Offsets window song preview no longer continues playing during playtesting. ([11eb406](https://github.com/FunkinCrew/Funkin/commit/11eb4060d03b18a2f3604297eb9a24e54077fe3c)) - by @PurSnake and @Lasercar in [#5973](https://github.com/FunkinCrew/Funkin/pull/5973)
- The fullscreen keybind no longer triggers when typing in a field. ([4ebd00b](https://github.com/FunkinCrew/Funkin/commit/4ebd00bc06a5c94e935f557ba14ba9729faec104)) - by @lemz1 in [#4131](https://github.com/FunkinCrew/Funkin/pull/4131)
- The Stage Editor new stage menu can no longer be opened multiple times at once. ([47b1cee](https://github.com/FunkinCrew/Funkin/commit/47b1cee6d5ee37cd18146ca8098da85610c6b544)) - by @VioletSnowLeopard in [#5873](https://github.com/FunkinCrew/Funkin/pull/5873)
- Adjusted the save hotkeys in the Animation Editor to be usable on Windows. ([8ead5ee](https://github.com/FunkinCrew/Funkin/commit/8ead5eeb0840756a843fdcf0f3f347b087e7182d)) - by @VioletSnowLeopard in [#5974](https://github.com/FunkinCrew/Funkin/pull/5974)
- A few more tiny fixes.
## New Contributors for 0.7.5
* @Az989YT made their first contribution in [#5936](https://github.com/FunkinCrew/Funkin/pull/5936)
## [0.7.4] - 2025-09-01
### Added
- [MOBILE] Added haptics to the can explosion in 2hot.
- Added the `scorable` property to notekinds, which excludes them from tallies.
- Added saving and loading save data using Newgrounds! Check out the new "Save Data Options" button in the Options menu after logging in. ([832f013](https://github.com/FunkinCrew/Funkin/commit/832f01345f441631a5372dbc3382dc8a13c150d6)) - by @TechnikTil in [#4900](https://github.com/FunkinCrew/Funkin/pull/4900)
- Added variation-specific song scripts, improving compatibility between mods. ([c94d6bb](https://github.com/FunkinCrew/Funkin/commit/c94d6bbb6640f7a9fbce8a202fbecf19d36da2f7)) - by @AbnormalPoof in [#5165](https://github.com/FunkinCrew/Funkin/pull/5165)
- Added scoped modules, which only run in a specified state. ([842ec2c](https://github.com/FunkinCrew/Funkin/commit/842ec2c1cd0243741170c431e4095bad2a4842e0)) - by @AbnormalPoof in [#5138](https://github.com/FunkinCrew/Funkin/pull/5138)
- Added ModStore, a helper class that stores data across hot reloads until the game is closed. ([3170346](https://github.com/FunkinCrew/Funkin/commit/3170346b83e5f73a88b3e7135e75ec1be2384929)) - by @cyn0x8 in [#4230](https://github.com/FunkinCrew/Funkin/pull/4230)
- Added hotkeys to toggle individual audio tracks in the Chart Editor. ([1e1b564](https://github.com/FunkinCrew/Funkin/commit/1e1b5643a8536a3061a237e058c45223b66039da)) - by @Lasercar in [#4247](https://github.com/FunkinCrew/Funkin/pull/4247)
- Added visual indicators and tooltips for notekinds. ([32c775e](https://github.com/FunkinCrew/Funkin/commit/32c775ef3f131accd69a04591608420919a607a1)) - by @KoloInDaCrib in [#5284](https://github.com/FunkinCrew/Funkin/pull/5284)
- Added a Charter field to the New Chart dialog in the Chart Editor. ([23b163c](https://github.com/FunkinCrew/Funkin/commit/23b163cb69ffbb8d2ae1c12d965a6ed3a26020e0)) - by @NotHyper-474 in [#5657](https://github.com/FunkinCrew/Funkin/pull/5657)
- Added a Song ID field to the Chart Editor metadata toolbox. ([55f9d24](https://github.com/FunkinCrew/funkin.assets/commit/55f9d24e9dc475b981e4cc087101425e85d3c1e2)) - by @cyn0x8 in [funkin.assets#229](https://github.com/FunkinCrew/funkin.assets/pull/229)
- Added a confirmation prompt when exiting the Chart Editor with an unsaved chart. ([e6d7371](https://github.com/FunkinCrew/Funkin/commit/e6d737125e0031d1efabc73266dfbde6d6c758de)) - by @anysad in [#5091](https://github.com/FunkinCrew/Funkin/pull/5091)
- [ANDROID] Added support for monochrome icons on Android 12 and above. ([5de4e76](https://github.com/FunkinCrew/Funkin/commit/5de4e766b7317c50d3ae40b9525b7c391984d52c)) - by @ThatOneCalculator in [#5507](https://github.com/FunkinCrew/Funkin/pull/5507)
### Changed
- Reworked the Conductor to make note scrolling smoother.
- Reworked Attract Mode.
- The Title Screen fades out and plays a video after a certain amount of time.
- The video alternates between the Mobile Trailer and the BOYFRIEND EVERYWHERE music video, replacing the previous toy commercial.
- The “Input Offsets” menu is now named “Lag Adjustment”.
- Freeplay difficulty dots are now displayed as rows of eight when modded difficulties are present.
- Optimized the way the game searches for Freeplay pixel icons.
- Results Screen and game over haptics are now softcoded.
- [WINDOWS] The window title bar now matches the system theme, light or dark.
- [LINUX] The game now displays with an icon.
- [iOS] The edges of the app icon are now properly filled in.
- Made several improvements and fixes to Polymod and HScript:
- Significantly optimized mod loading, especially with many installed at once. (Thanks KoloInDaCrib!)
- Fixed several cases where script variables would be lost. (Thanks NotHyper-474!)
- Zip mod loading on Linux is now case-insensitive. (Thanks NotHyper-474!)
- Added the ability to import scripted classes. (Thanks lemz1!)
- NOTE: You currently can’t use them in a static context.
- Added the ability to use the `??=` operator. (Thanks lemz1!)
- Added the ability to use the `using` keyword. (Thanks KoloInDaCrib!)
- `final` variables created inside of scripts are now treated as actual `final`s. (Thanks KoloInDaCrib!)
- Added null-safe field assign. (ex. `someVar?.someVar2 = new Class();`) (Thanks NotHyper-474!)
- Improved properties support, behaving more like regular Haxe. (Thanks NotHyper-474!)
- Fixed a null object reference when evaluating static variables with no explicit values. (Thanks NotHyper-474!)
- Fixed a null object reference when iterating over a null variable. (Thanks NotHyper-474!)
- Scripts are now automatically cleared when Polymod is initialized. (Thanks KoloInDaCrib!)
- Polished every chart in the game!
- The lengths of hold notes have been adjusted to match the vocals as closely as possible, across all variations and difficulties.
- Easy and Normal charts from Week 1 to Week 3 have been adjusted for more consistency between the player and opponent.
- Many charting errors have been corrected.
- Accept keybinds and gamepad south buttons now work on the Title Screen. ([e281bdd](https://github.com/FunkinCrew/Funkin/commit/e281bdddca5f31982bdc620e8ea92b080dcd416a)) - by @MrMadera in [#5650](https://github.com/FunkinCrew/Funkin/pull/5650)
- [ANDROID] Pressing the Back button in the Title Screen now closes the game. ([e6fd5d9](https://github.com/FunkinCrew/Funkin/commit/e6fd5d9b129f74703d6bd96744f63cb201afc941)) - by @NotHyper-474 in [#5527](https://github.com/FunkinCrew/Funkin/pull/5527)
- The HOME and END keys now jump to the top and bottom of the Story Mode menu, respectively. ([d1a96f7](https://github.com/FunkinCrew/Funkin/commit/d1a96f791f2ed35accc1c1e9ff548a75b2b9d7ef)) - by @JVNpixels in [#4591](https://github.com/FunkinCrew/Funkin/pull/4591)
- Freeplay favorite songs are now separated by variation. ([b4b2e8d](https://github.com/FunkinCrew/Funkin/commit/b4b2e8da9dde41d730556a41e6bb18b0f3d8d7db)) - by @KoloInDaCrib in [#5154](https://github.com/FunkinCrew/Funkin/pull/5154)
- Freeplay preview volumes now play at 70% volume, up from 40%. ([4ecef6d](https://github.com/FunkinCrew/Funkin/commit/4ecef6db744bab7e3fe5de0d680d813cc3bd1ea7)) - by @JackXson-Real in [#5645](https://github.com/FunkinCrew/Funkin/pull/5645)
- Selecting a song in the Freeplay menu now plays a fade-out transition. ([705e6b3](https://github.com/FunkinCrew/Funkin/commit/705e6b330806c3157bca7301b1e43cd78acdb23a)) - by @VirtuGuy in [#5626](https://github.com/FunkinCrew/Funkin/pull/5626)
- Implemented null safety to PlayState and LoadingState. ([34ce13c](https://github.com/FunkinCrew/Funkin/commit/34ce13c5dfd52760675a1d09efa489bcb108e607)) - by @NotHyper-474 in [#4789](https://github.com/FunkinCrew/Funkin/pull/4789)
- Health icons now have an offset variable. ([8bab619](https://github.com/FunkinCrew/Funkin/commit/8bab6196e50420c6586441f2d321bd1c139567c3)) - by @PurSnake in [#5760](https://github.com/FunkinCrew/Funkin/pull/5760)
- The "hey" notekind now plays the animation for BF (Christmas). ([91d5970](https://github.com/FunkinCrew/funkin.assets/commit/91d5970e0274aa0a31fc6f2b05c114730256408f)) - by @JackXson-Real in [funkin.assets#225](https://github.com/FunkinCrew/funkin.assets/pull/225)
- Added an "offset" property to the Set Camera Bop event, enabling more flexible camera bops. ([3f5ef4a](https://github.com/FunkinCrew/Funkin/commit/3f5ef4abe09bbd222bb9e5e212d63973b1b87175)) - by @Burgerballs in [#3575](https://github.com/FunkinCrew/Funkin/pull/3575)
- Added caching to multi-sparrow characters and fixed textures not being properly cached. ([feb55b2](https://github.com/FunkinCrew/Funkin/commit/feb55b26258e1dd0c4d209e2fa8af1dfb32ea684)) - by @PurSnake in [#5684](https://github.com/FunkinCrew/Funkin/pull/5684)
- Optimized the way Freeplay backing card text is rendered. ([f6de4c5](https://github.com/FunkinCrew/Funkin/commit/f6de4c54d37d3febc01db20d84885ccd3e21e833)) - by @MaybeMaru in [#5730](https://github.com/FunkinCrew/Funkin/pull/5730)
- Optimized the rendering of many visual elements in Freeplay. ([6f193c4](https://github.com/FunkinCrew/Funkin/commit/6f193c4bd88675f46d9455a5310129f1517c8e18)) - by @MaybeMaru in [#5773](https://github.com/FunkinCrew/Funkin/pull/5773)
- Optimized the way notes are rendered, especially when many are visible at once. ([a2b347e](https://github.com/FunkinCrew/Funkin/commit/a2b347e31e7a539f12131980ffeaf980e3e677af)) - by @MaybeMaru in [#5752](https://github.com/FunkinCrew/Funkin/pull/5752)
- Image assets for gradients are now smaller and stretched in-game for better optimization. ([fab646c](https://github.com/FunkinCrew/funkin.assets/commit/fab646ce4a3045dcd6aa2ab86c403a40ee89bfa3)) - by @MaybeMaru in [funkin.assets#227](https://github.com/FunkinCrew/funkin.assets/pull/227)
### Fixed
- The song no longer restarts from an earlier point in the song instead of ending.
- Perfect ranks no longer occasionally disappear after the rank slam animation.
- Later notes are no longer hit before earlier notes on songs with high scroll speeds.
- [MOBILE] Clearing save data no longer crashes the game.
- [MOBILE] Cutscenes no longer continue playing behind the Pause Menu after losing focus.
- [MOBILE] Freeplay capsules now properly shift away from under the letter sort bar.
- [MOBILE] The Options button now animates properly after the first interaction.
- [HTML5] The “Touch here to play” button is no longer too large.
- Shaders now apply to A-Bot.
- Adjusted offsets for some of Pico’s special animations.
- Trimmed the extra silence at the beginning of Stress.
- Trimmed the extra silence at the end of Senpai.
- Monster and Winter Horrorland now display the correct album.
- The “Haptics intensity” preference no longer displays inconsistent values.
- The Lag Adjustment menu no longer permanently stops sending notes.
- The Results Screen clear percentage now disappears behind the sound system.
- The Debug Menu background now accounts for wider aspect ratios.
- The Legacy Chart Importer now imports charts properly.
- Fixed the “Starting BPM” text in the Chart Editor being tiny.
- Chromebooks no longer use touch controls.
- Enabled note recycling, resulting in a significant performance boost during songs. ([57a276d](https://github.com/FunkinCrew/Funkin/commit/57a276d17c293f40d6b27a89816b1659fc8b078f)) - by @KoloInDaCrib and @NotHyper-474 in [#5732](https://github.com/FunkinCrew/Funkin/pull/5732)
- Misses are now properly processed for recycled notes. ([e7f7f47](https://github.com/FunkinCrew/Funkin/commit/e7f7f4794f410b74eab79941531f19c68737f94e)) - by @NotHyper-474 in [#5751](https://github.com/FunkinCrew/Funkin/pull/5751)
- Bad save data no longer causes the game to immediately crash. ([84f1190](https://github.com/FunkinCrew/Funkin/commit/84f119036b44881488e47136f23f960855d47897)) - by @mikolka9144 in [#5703](https://github.com/FunkinCrew/Funkin/pull/5703)
- Spamming the Reset and Accept buttons no longer softlocks the game over screen. ([01a2458](https://github.com/FunkinCrew/Funkin/commit/01a2458c1281440947f1aab586752e7ff490fe37)) - by @KoloInDaCrib in [#5714](https://github.com/FunkinCrew/Funkin/pull/5714)
- Pressing F4 while calibrating or testing offsets no longer results in a softlock. ([7f82b48](https://github.com/FunkinCrew/Funkin/commit/7f82b48e3face75791955d28e807b7919d668be6)) - by @KoloInDaCrib in [#5716](https://github.com/FunkinCrew/Funkin/pull/5716)
- Spamming through the Freeplay letter sort lists no longer crashes the game. ([0d6bc2b](https://github.com/FunkinCrew/Funkin/commit/0d6bc2bedd4494838db288247c4b13ec4031f0a8)) - by @JVNpixels in [#5578](https://github.com/FunkinCrew/Funkin/pull/5578)
- Main menu items can no longer be scrolled and selected again after selecting an item. ([1fc611d](https://github.com/FunkinCrew/Funkin/commit/1fc611d1308e26f50cc01658b0ab7b848f05debe)) - by @JackXson-Real in [#5680](https://github.com/FunkinCrew/Funkin/pull/5680)
- Fixed a crash caused by parsing CRLF line endings incorrectly. ([65349f4](https://github.com/FunkinCrew/Funkin/commit/65349f47145f44c94dae8a7a39004968da48cf0d)) - by @NotHyper-474 in [#5656](https://github.com/FunkinCrew/Funkin/pull/5656)
- Fixed a script error when playing a Week 3 Erect song after a Week 3 (Pico Mix) song. ([6ecada8](https://github.com/FunkinCrew/funkin.assets/commit/6ecada82ac0072826132cad8f9e11f07006f9977)) - by @ThatRozebudDude in [funkin.assets#131](https://github.com/FunkinCrew/funkin.assets/pull/131)
- Boyfriend's vocals no longer double up after restarting in Week 3. ([743e8b1](https://github.com/FunkinCrew/Funkin/commit/743e8b13c28d9f0471b392edc3127973f6fef329)) - by @NotHyper-474 in [#5408](https://github.com/FunkinCrew/Funkin/pull/5408)
- Songs with BPM changes now restart at the correct BPM. ([51eec45](https://github.com/FunkinCrew/Funkin/commit/51eec4522e49ed7ed2c9457b5224c3b06e758958)) - by @VioletSnowLeopard in [#4721](https://github.com/FunkinCrew/Funkin/pull/4721)
- Dropped hold notes are now properly handled. ([1df0cb9](https://github.com/FunkinCrew/Funkin/commit/1df0cb95f6a86d41dc5ef2d19a28c4c09952a69a)) - by @Lasercar in [#5172](https://github.com/FunkinCrew/Funkin/pull/5172)
- Fullscreen keybinds now work properly on Web builds. ([1fbb760](https://github.com/FunkinCrew/Funkin/commit/1fbb7604ddf4fb8d311b9b414cbcfa0fd9bab255)) - by @NotHyper-474 in [#5664](https://github.com/FunkinCrew/Funkin/pull/5664)
- Corrected the heights of characters in the intro text font. ([90242e2](https://github.com/FunkinCrew/funkin.assets/commit/90242e2e200fca38f5f535986db49b7a53282d1f)) - by @SpritersBlock in [funkin.assets#190](https://github.com/FunkinCrew/funkin.assets/pull/190)
- PureColor shaders now properly apply anti-aliasing. ([8d1bfa1](https://github.com/FunkinCrew/Funkin/commit/8d1bfa105c89f68ab1f14a197f8c0a5e4fe7fb14)) - by @MaybeMaru in [#5781](https://github.com/FunkinCrew/Funkin/pull/5781)
- The Preferences menu camera now remembers its position when exiting and re-entering. ([3d88fbb](https://github.com/FunkinCrew/Funkin/commit/3d88fbb11fea2b52d399f37cb8154795329c31c2)) - by @VirtuGuy in [#5608](https://github.com/FunkinCrew/Funkin/pull/5608)
- The Freeplay DJ no longer flickers between animations. ([1b91f3b](https://github.com/FunkinCrew/Funkin/commit/1b91f3b57cda3310db2f5196650b89c8d88e69be)) - by @VirtuGuy in [#5598](https://github.com/FunkinCrew/Funkin/pull/5598)
- The Freeplay DJ's turntable lights now glow properly. ([0c5a965](https://github.com/FunkinCrew/funkin.assets/commit/0c5a965400937cbdac55ed9317a2a00a9d4343ae)) - by @Johferson in [funkin.assets#211](https://github.com/FunkinCrew/funkin.assets/pull/211)
- The Random capsule now opens the selected song with the correct variation. ([1605514](https://github.com/FunkinCrew/Funkin/commit/160551442453fccc0961c570701bdba7bee95ef0)) - by @PurSnake in [#5611](https://github.com/FunkinCrew/Funkin/pull/5611)
- Newly earned Freeplay ranks no longer appear larger than others. ([47813ea](https://github.com/FunkinCrew/Funkin/commit/47813eac3157927f851713cc4c41c5eb5fac2e19)) - by @anysad in [#5768](https://github.com/FunkinCrew/Funkin/pull/5768)
- Freeplay now displays the correct number of difficulty stars after returning from a song. ([30721c3](https://github.com/FunkinCrew/Funkin/commit/30721c3a30f7e980557d055daa30e7e5501b83e3)) - by @KoloInDaCrib in [#5560](https://github.com/FunkinCrew/Funkin/pull/5560)
- Removed stray pixels around pixel icons in Freeplay and Character Select. ([b1d770b](https://github.com/FunkinCrew/funkin.assets/commit/b1d770b7f69cb73bd35a279ba5b26908e0cd94be)) - by @Hundrec in [funkin.assets#69](https://github.com/FunkinCrew/funkin.assets/pull/69)
- The nametag in the Character Select screen now fades and moves as other elements do. ([2b1f346](https://github.com/FunkinCrew/Funkin/commit/2b1f346097efadcad19058c4ed9cefe4f84c8b64)) - by @JackXson-Real in [#5583](https://github.com/FunkinCrew/Funkin/pull/5583)
- [MOBILE] The touch pointer now displays during songs. ([9d2cfa9](https://github.com/FunkinCrew/Funkin/commit/9d2cfa9686880170c5c398786c72d878974eaf93)) - by @SrtHero278 in [#5565](https://github.com/FunkinCrew/Funkin/pull/5565)
- Note splashes are now more centered on the strumline. ([cfa6016](https://github.com/FunkinCrew/funkin.assets/commit/cfa6016eeacb745cb2787c99f8d1f156ab4d16e8)) - by @JVNpixels in [funkin.assets#234](https://github.com/FunkinCrew/funkin.assets/pull/234)
- Removed stray pixels from BF's old icon and aligned its losing icon. ([e57dc54](https://github.com/FunkinCrew/funkin.assets/commit/e57dc54fe333f8fa3f3933164b423128c74f4c38)) - by @Hundrec in [funkin.assets#93](https://github.com/FunkinCrew/funkin.assets/pull/93)
- Daddy Dearest's idle animation now plays on beat. ([b4c1aa9](https://github.com/FunkinCrew/funkin.assets/commit/b4c1aa95aad45c42256432ec81cce8bf35107fa7)) - by @qt2k4 in [funkin.assets#148](https://github.com/FunkinCrew/funkin.assets/pull/148)
- Boyfriend (Dark)'s idle animation now properly syncs with his regular idle. ([d1610f1](https://github.com/FunkinCrew/funkin.assets/commit/d1610f1e6f0d5b0db0af34e3d00e7a1fc1d4a4b5)) - by @TechnikTil in [funkin.assets#203](https://github.com/FunkinCrew/funkin.assets/pull/203)
- Spooky Kids (Dark)'s idle animation now properly syncs with their regular idle. ([aa28bd7](https://github.com/FunkinCrew/funkin.assets/commit/aa28bd74a33ab0026649d19e642c41b4f1c5cd06)) - by @Honton129 in [funkin.assets#213](https://github.com/FunkinCrew/funkin.assets/pull/213)
- Lightning now appears more regularly during South and Monster in Story Mode. ([c5f4a8e](https://github.com/FunkinCrew/funkin.assets/commit/c5f4a8e55f18cbc2e57a72743320da79358b1816)) - by @JackXson-Real in [funkin.assets#222](https://github.com/FunkinCrew/funkin.assets/pull/222)
- The Picos no longer gasp twice in the Week 3 doppelganger cutscene. ([7b30a14](https://github.com/FunkinCrew/funkin.assets/commit/7b30a1418ef4597e567a22a2ea1bc1d9e4b061da)) - by @Lasercar in [funkin.assets#231](https://github.com/FunkinCrew/funkin.assets/pull/231)
- The Week 3 train now consistently plays its sound. ([469ce39](https://github.com/FunkinCrew/funkin.assets/commit/469ce397b8eef3be47f8fadaa61a500e1a87ca3a)) - by @Lasercar in [funkin.assets#212](https://github.com/FunkinCrew/funkin.assets/pull/212)
- Nene no longer freezes after playing two animations at once. ([d346ebd](https://github.com/FunkinCrew/funkin.assets/commit/d346ebdbf4781b49a081e0719221cf584fc3fe55)) - by @NotHyper-474 in [funkin.assets#228](https://github.com/FunkinCrew/funkin.assets/pull/228)
- The Week 4 car now properly pauses with the game. ([26d1cff](https://github.com/FunkinCrew/funkin.assets/commit/26d1cffe19793c67a89f299b7a60be95c5656282)) - by @NotHyper-474 in [funkin.assets#114](https://github.com/FunkinCrew/funkin.assets/pull/114)
- Pressing Reset and Pause at the same time no longer breaks the game over animation in Blazin'. ([8cd3785](https://github.com/FunkinCrew/Funkin/commit/8cd3785e3c3e913ed791204814eba86eb7142a5d)) - by @VirtuGuy in [#5639](https://github.com/FunkinCrew/Funkin/pull/5639)
- Pico's Blazin' death animation no longer lags and offsets improperly. ([2cb42fe](https://github.com/FunkinCrew/funkin.assets/commit/2cb42fec422313db4e8000c963be0539221c9e21)) - by @KoloInDaCrib in [funkin.assets#217](https://github.com/FunkinCrew/funkin.assets/pull/217)
- Pico and Darnell now properly punch with their other arms in Blazin'. ([4fb015f](https://github.com/FunkinCrew/funkin.assets/commit/4fb015f20261995ce41370910989094f4f2f26bb)) - by @Honton129 in [funkin.assets#221](https://github.com/FunkinCrew/funkin.assets/pull/221)
- Pico's Perfect Results Screen animation now syncs with the music. ([0531e27](https://github.com/FunkinCrew/funkin.assets/commit/0531e27feed83dcc9a1703b3df654fd3bba1bd8a)) - by @JackXson-Real in [funkin.assets#201](https://github.com/FunkinCrew/funkin.assets/pull/201)
- Filled in invisible pixels in the Story Mode button. ([c83ea78](https://github.com/FunkinCrew/funkin.assets/commit/c83ea788485693e22d429d81db8eb4da202e0140)) - by @D4rkJony in [funkin.assets#214](https://github.com/FunkinCrew/funkin.assets/pull/214)
- Filled in invisible pixels in Tankman's icons. ([cb46973](https://github.com/FunkinCrew/funkin.assets/commit/cb46973bf8d9f48cd4738d483957c1edb501b386)) - by @JackXson-Real in [funkin.assets#224](https://github.com/FunkinCrew/funkin.assets/pull/224)
- Scripted classes are no longer registered twice after hot-reloading. ([f870ed2](https://github.com/FunkinCrew/Funkin/commit/f870ed2858507273c4dbbca3e4b8b97d80a8d2ec)) - by @KoloInDaCrib in [#5743](https://github.com/FunkinCrew/Funkin/pull/5743)
- The Chart Editor now properly uses the song ID from the manifest. ([df67b64](https://github.com/FunkinCrew/Funkin/commit/df67b642a8d7f7460e36a42c570a1ff2303751fd)) - by @cyn0x8 in [#4168](https://github.com/FunkinCrew/Funkin/pull/4168)
- Dragging and dropping a Chart Editor selection in the same place no longer breaks the selection. ([4b65587](https://github.com/FunkinCrew/Funkin/commit/4b655879f763f6dbe34c89fc4a781cae9ff4abd8)) - by @Lasercar in [#4185](https://github.com/FunkinCrew/Funkin/pull/4185)
- Clicking between hold note trails no longer causes visual errors in the Chart Editor. ([0e52744](https://github.com/FunkinCrew/Funkin/commit/0e527447188dbd3d850154a73f61467c1b8e585a)) - by @KoloInDaCrib in [#5683](https://github.com/FunkinCrew/Funkin/pull/5683)
- Holding Shift and Right Click over a note no longer produces a solitaire effect in the Chart Editor. ([172041d](https://github.com/FunkinCrew/Funkin/commit/172041d4f779271533e0d1c529297540bfec337a)) - by @Lasercar in [#4139](https://github.com/FunkinCrew/Funkin/pull/4139)
- Chart Editor event properties now have minimum values. ([9b81ebc](https://github.com/FunkinCrew/Funkin/commit/9b81ebc4f2c1c70b33d7351210c40c9a0e48ecc8)) - by @Lasercar in [#4110](https://github.com/FunkinCrew/Funkin/pull/4110)
- Added missing notekinds to the Chart Editor Notes window. ([b7a5761](https://github.com/FunkinCrew/Funkin/commit/b7a5761730d43f27891dfec1c23fcb5e66daccf1)) - by @Lasercar in [#4286](https://github.com/FunkinCrew/Funkin/pull/4286)
- Playback speed is now preserved when a new song or variation is loaded in the Chart Editor. ([3f82f37](https://github.com/FunkinCrew/Funkin/commit/3f82f3792b056a03724a0d1a320b7549a7b59844)) - by @Lasercar in [#4212](https://github.com/FunkinCrew/Funkin/pull/4212)
- The Legacy Chart Importer now properly imports scroll speeds. ([2645d56](https://github.com/FunkinCrew/Funkin/commit/2645d56514dd1a27a050ff432c3cd4122f958e10)) - by @VirtuGuy in [#5655](https://github.com/FunkinCrew/Funkin/pull/5655)
- Opponent characters now play singing animations when selected as the player character. ([8ee24c8](https://github.com/FunkinCrew/funkin.assets/commit/8ee24c84de6aa6e6313699198f35f61991612d04)) - by @Lasercar in [funkin.assets#141](https://github.com/FunkinCrew/funkin.assets/pull/141)
- The Chart Editor character selector window no longer opens when clicking while playtesting. ([223e837](https://github.com/FunkinCrew/Funkin/commit/223e837fe8d9ce227e289a38bdfc095e4d81c48a)) - by @Lasercar in [#4350](https://github.com/FunkinCrew/Funkin/pull/4350)
- Renamed Nene's pixel variant to Nene (Pixel) in the Chart Editor. ([69a7898](https://github.com/FunkinCrew/funkin.assets/commit/69a78988e3d6042d2e4779c9a4055c5de73ee775)) - by @JVNpixels in [funkin.assets#208](https://github.com/FunkinCrew/funkin.assets/pull/208)
- Renamed Tankman's variants in the Chart Editor. ([70c43b7](https://github.com/FunkinCrew/funkin.assets/commit/70c43b792078d913c4c4d9fc019e378249d08b78)) - by @ExtraCode75 in [funkin.assets#209](https://github.com/FunkinCrew/funkin.assets/pull/209)
- Pressing F4 in the Chart Editor now properly resets the window title. ([86e69cf](https://github.com/FunkinCrew/Funkin/commit/86e69cfbd1b1bd3daa49181b827fa813cb716703)) - by @VirtuGuy in [#5651](https://github.com/FunkinCrew/Funkin/pull/5651)
- Saving a character in the Animation Editor no longer crashes the game. ([da5f691](https://github.com/FunkinCrew/Funkin/commit/da5f6918656d4a1ad3e83233b358034db92ca675)) - by @anysad in [#5519](https://github.com/FunkinCrew/Funkin/pull/5519)
- The Stage Editor can now properly load modded stages. ([50c601a](https://github.com/FunkinCrew/Funkin/commit/50c601a7f0f27fc0f155e2bfbcb8ef54631aeac7)) - by @KoloInDaCrib in [#5744](https://github.com/FunkinCrew/Funkin/pull/5744)
- XML files exported from the Stage Editor now account for rotated frames. ([661ddb1](https://github.com/FunkinCrew/Funkin/commit/661ddb15f72c2dae22f41a922a521740ab3617f0)) - by @KoloInDaCrib in [#5303](https://github.com/FunkinCrew/Funkin/pull/5303)
- A few more adjustments for good measure.
## New Contributors for 0.7.4
* @ThatOneCalculator made their first contribution in [#5507](https://github.com/FunkinCrew/Funkin/pull/5507)
* @SrtHero278 made their first contribution in [#5565](https://github.com/FunkinCrew/Funkin/pull/5565)
* @VirtuGuy made their first contribution in [#5598](https://github.com/FunkinCrew/Funkin/pull/5598)
* @SpritersBlock made their first contribution in [funkin.assets#190](https://github.com/FunkinCrew/funkin.assets/pull/190)
* @Johferson made their first contribution in [funkin.assets#211](https://github.com/FunkinCrew/funkin.assets/pull/211)
* @Honton129 made their first contribution in [funkin.assets#213](https://github.com/FunkinCrew/funkin.assets/pull/213)
* @D4rkJony made their first contribution in [funkin.assets#214](https://github.com/FunkinCrew/funkin.assets/pull/214)
## [0.7.3] - 2025-07-21
### Fixed
- Fixed stuttering throughout the game caused by the Polymod upgrade. (Thanks NotHyper-474!)
- [MOBILE] Fixed buttons in the Main Menu not working.
- [iOS] The Upgrade button no longer appears if you have already purchased it (actually this time).
- Fixed the countdown overlapping itself when restarting the song. (Thanks NotHyper-474!)
- Optimized the Week 6 Erect stage.
- Fixed an oversight when clearing the cache. (Thanks cherrythecool!)
- The Input Offset Test menu text now displays in the correct position.
- Fixed script errors appearing in the Week 3 Erect stage.
- Fixed adding variations in the Chart Editor erasing difficulties. (Thanks NotHyper-474!)
## New Contributors for 0.7.3
* @cherrythecool made their first contribution in [#5458](https://github.com/FunkinCrew/Funkin/pull/5458)
## [0.7.2] - 2025-07-18
### Added
@@ -23,7 +266,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Scripted classes can now create static fields and functions.
- Scripted classes can now create variables with the `final` keyword.
- Scripted classes can now access variables from another scripted class with `class.someVariable`, instead of `class.scriptGet("someVariable")`
- This applies to functions too: `class.someFunction()`
- This applies to functions too: `class.someFunction()`
- Scripted classes that don't extend another class can now be created!
- This only works if you access the class in a static context. Creating an instance of said class doesn't work just yet!
- Added support for properties (`get_` and `set_` functions) (Thanks KoloInDaCrib!)
@@ -33,7 +276,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- You can import them in another script as usual.
- Added support for renaming imported classes using the `as` keyword. (Thanks KoloInDaCrib!)
- Fixed `try`/`catch` blocks not working properly. (Thanks NotHyper-474!)
- Fixed null-safe field access not working properly for functions (ex. `class?.someFunction()). (Thanks KoloInDaCrib!)
- Fixed null-safe field access not working properly for functions (ex. `class?.someFunction()`). (Thanks KoloInDaCrib!)
- Fixed Linux being case-sensitive with filenames. (Thanks mikolka9144!)
### Fixed
@@ -68,6 +312,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* @Smokey555 made their first contribution in [#3318](https://github.com/FunkinCrew/Funkin/pull/3318)
* @CCobaltDev made their first contribution in [#3318](https://github.com/FunkinCrew/Funkin/pull/3318)
* @mikolka9144 made their first contribution in [polymod#212](https://github.com/larsiusprime/polymod/pull/212)
@@ -412,7 +657,7 @@ Select. ([3d3e2bd](https://github.com/FunkinCrew/Funkin/commit/3d3e2bd3786b85814
* @JackXson-Real made their first contribution in [#4346](https://github.com/FunkinCrew/Funkin/pull/4346)
* @VioletSnowLeopard made their first contribution in [#4382](https://github.com/FunkinCrew/Funkin/pull/4382)
* @superpowers04 made their first contribution in [#4729](https://github.com/FunkinCrew/Funkin/pull/4729)
* @ShadzXD made their first contribution in [#62](https://github.com/FunkinCrew/Funkin/pull/4729)
* @ShadzXD made their first contribution in [funkin.assets#62](https://github.com/FunkinCrew/funkin.assets/pull/62)
@@ -685,6 +930,7 @@ This patch resolves a critical issue that could cause user's save data to become
## [0.5.0] - 2024-09-12
The Playable Pico Update!
### Added
- Added a new Character Select screen to switch between playable characters in Freeplay.
@@ -805,7 +1051,7 @@ The Playable Pico Update!
### Fixed
- Control binds in the controls menu no longer overlap their names.
- Attempting to exit the gameover screen and retry the song at the same time no longer crashes the game. ([thanks DMMaster636 for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709))
- Attempting to exit the gameover screen and retry the song at the same time no longer crashes the game. ([thanks DM-kun for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709))
- Botplay mode now handles the player's animations properly during hold notes. ([thanks Hundrec!](https://github.com/FunkinCrew/Funkin/pull/2683))
- Camera movement now pauses when the game is paused. ([thanks Matriculaso!](https://github.com/FunkinCrew/Funkin/pull/2684))
- Pico's gameplay sprite no longer appears on the gameover screen when dying from an explosion in 2hot.
@@ -819,13 +1065,14 @@ The Playable Pico Update!
## New Contributors for 0.4.1
* @Hundrec made their first contribution in [#2661](https://github.com/FunkinCrew/Funkin/pull/2661)
* @DMMaster636 made their first contribution in [#2709](https://github.com/FunkinCrew/Funkin/pull/2709)
* @DM-kun made their first contribution in [#2709](https://github.com/FunkinCrew/Funkin/pull/2709)
* @eltociear made their first contribution in [#2730](https://github.com/FunkinCrew/Funkin/pull/2730)
## [0.4.0] - 2024-06-06
The Pit Stop 1 update!
### Added
- 2 new Erect remixes, Eggnog and Satin Panties. Check them out from the Freeplay menu!
@@ -997,6 +1244,7 @@ The Pit Stop 1 update!
## [0.3.0] - 2024-04-30
The Weekend 1 update!
### Added
- New Story Level: Weekend 1, starring Pico, Darnell, and Nene.
+13 -2
View File
@@ -1,14 +1,25 @@
# Friday Night Funkin'
<div align='center'><img src="https://fridaynightfunkin.wiki.gg/images/FNF_logo.png" width="800">
Friday Night Funkin' is a rhythm game. Built using HaxeFlixel for Ludum Dare 47.
<h2>Friday Night Funkin' is a rhythm game. Built using HaxeFlixel for <a href="https://ldjam.com/events/ludum-dare/47">Ludum Dare 47.</a></h2>
This game was made with love to Newgrounds and its community. Extra love to Tom Fulp.
</div>
- [Playable web demo on Newgrounds!](https://www.newgrounds.com/portal/view/770371)
- [Demo download builds for Windows, Mac, and Linux from Itch.io!](https://ninja-muffin24.itch.io/funkin)
- [Download Android builds from Google Play!](https://play.google.com/store/apps/details?id=me.funkin.fnf)
- [Download iOS builds from the App Store!](https://apps.apple.com/app/id6740428530)
<div align='center'>
<table>
<tr>
<td><img src="https://fridaynightfunkin.wiki.gg/images/d/d7/Title_Card.gif" alt="Title Screen" width="350"/></td>
<td><img src="https://fridaynightfunkin.wiki.gg/images/9/99/Menu.png" alt="Main Menu" width="350"/></td>
</tr>
</table>
</div>
# Getting Started
**PLEASE USE THE LINKS ABOVE IF YOU JUST WANT TO PLAY THE GAME**
+1 -1
Submodule art updated: 67e550dbd2...094ff10919
+1 -1
Submodule assets updated: 2546f94b8d...5ca3c6a574
+135
View File
@@ -0,0 +1,135 @@
{
"input": "./assets",
"output": "./astc-textures/",
"quality": "medium",
"blocksize": "10x10",
"colorprofile": "cl",
"custom": [
{
"asset": "asset/shared/images/resultScreen/results-pico/resultsPERFECT/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "asset/shared/images/resultScreen/results-pico/resultsGREAT/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "asset/shared/images/resultScreen/results-pico/resultsGOOD/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/resultScreen/results-bf/resultsEXCELLENT/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "asset/shared/images/resultScreen/results-pico/resultsSHIT/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "assets/preload/images/NOTE_assets.png",
"blocksize": "4x4"
},
{
"asset": "assets/preload/images/NOTE_hold_assets.png",
"blocksize": "4x4"
},
{
"asset": "assets/preload/images/StrumlineNotes.png",
"blocksize": "4x4"
},
{
"asset": "assets/preload/images/alphabet.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/NOTE_hold_assets.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/holdCoverBlue.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/holdCoverGreen.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/holdCoverPurple.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/holdCoverRed.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/latencyArrow.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/latencyReceptor.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/noteSplashes.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/noteStrumline.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/notes.png",
"blocksize": "4x4"
},
{
"asset": "assets/week1/image/erect/bg.png",
"blocksize": "8x8"
},
{
"asset": "assets/week1/image/erect/lights.png",
"blocksize": "6x6"
},
{
"asset": "assets/week1/images/erect/crowd.png",
"blocksize": "8x8"
},
{
"asset": "assets/week1/images/erect/server.png",
"blocksize": "8x8"
}
],
"excludes": [
"assets/preload/images/cursor/",
"assets/preload/images/fonts/",
"assets/preload/images/freeplay/",
"assets/preload/images/icons/",
"assets/preload/images/soundtray/",
"assets/preload/images/stageBuild/",
"assets/preload/images/titleEnter.png",
"assets/preload/images/titleEnter_mobile.png",
"assets/preload/images/ui/popup/pixel/*",
"assets/shared/images/characters/abotPixel/*",
"assets/shared/images/characters/bfPixel.png",
"assets/shared/images/characters/bfPixelsDEAD.png",
"assets/shared/images/characters/gfPixel.png",
"assets/shared/images/characters/nenePixel/*",
"assets/shared/images/characters/picoPixel/*",
"assets/shared/images/characters/senpai.png",
"assets/shared/images/characters/spirit.png",
"assets/shared/images/healthBar.png",
"assets/shared/images/resultScreen/*",
"assets/shared/images/resultScreen/clearPercent/",
"assets/shared/images/resultScreen/rankText/",
"assets/shared/images/ui/chart-editor/",
"assets/shared/images/ui/countdown/pixel/*",
"assets/week1/*",
"assets/week1/images/erect/brightLightSmall.png",
"assets/week1/images/erect/lightAbove.png",
"assets/week1/images/erect/lightgreen.png",
"assets/week1/images/erect/lightred.png",
"assets/week1/images/erect/orangeLight.png",
"assets/week2/images/erect/stairsDark.png",
"assets/week2/images/erect/stairsLight.png",
"assets/week6/"
]
}
+34 -21
View File
@@ -1,10 +1,9 @@
{
"extendsConfigPath": "",
"defineCombinations": [],
"defaultSeverity": "INFO",
"extendsConfigPath": "",
"numberOfCheckerThreads": 5,
"baseDefines": [],
"version": 1,
"exclude": {},
"defineCombinations": [],
"checks": [
{
"props": {},
@@ -40,12 +39,6 @@
"props": {},
"type": "AvoidStarImport"
},
{
"props": {
"severity": "IGNORE"
},
"type": "AvoidTernaryOperator"
},
{
"props": {},
"type": "BlockBreakingConditional"
@@ -71,7 +64,6 @@
{
"props": {
"severity": "IGNORE",
"policy": "aligned",
"allowSingleline": true
},
@@ -80,7 +72,7 @@
{
"props": {
"ignoreExtern": true,
"format": "^[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*$",
"format": "^?:_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*$",
"tokens": ["INLINE", "NOTINLINE"]
},
"type": "ConstantName"
@@ -108,13 +100,12 @@
{
"props": {
"lineStyle": "onestar",
"startStyle": "twostars",
"severity": "IGNORE"
"startStyle": "ignore"
},
"type": "DocCommentStyle"
},
{
"props": {},
"props": { "severity": "IGNORE" },
"type": "Dynamic"
},
{
@@ -193,6 +184,14 @@
},
"type": "FileLength"
},
{
"type": "FileNameCase",
"props": {}
},
{
"type": "Final",
"props": {}
},
{
"props": {
"option": "upperCase"
@@ -245,7 +244,7 @@
{
"props": {
"max": 160,
"ignorePattern": "^$"
"ignorePattern": "^(\\s*['\"][^'\"]*['\"].*)$"
},
"type": "LineLength"
},
@@ -348,7 +347,7 @@
{
"props": {
"allowSingleLineStatement": true,
"tokens": ["FOR", "ELSE_IF", "WHILE", "DO_WHILE"]
"tokens": ["ELSE_IF", "WHILE", "DO_WHILE"]
},
"type": "NeedBraces"
},
@@ -580,6 +579,12 @@
"props": {},
"type": "TrailingWhitespace"
},
{
"type": "Type",
"props": {
"ignoreEnumAbstractValues": true
}
},
{
"props": {
"tokens": ["CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF", "TYPEDEF_DEF"]
@@ -612,11 +617,18 @@
"type": "UnusedLocalVar"
},
{
"type": "VarTypeHint",
"props": {
"typeHintPolicy": "enforce_all",
"ignoreEnumAbstractValues": true
},
"type": "VarTypeHint"
"ignoreEnumAbstractValues": true,
"severity": "IGNORE"
}
},
{
"type": "VariableInitialisation",
"props": {
"allowFinal": false
}
},
{
"props": {
@@ -665,5 +677,6 @@
"type": "WhitespaceAround"
}
],
"numberOfCheckerThreads": 5
"exclude": {},
"version": 1
}
-21
View File
@@ -1,21 +0,0 @@
assets/preload/images/cursor/*
assets/preload/images/freeplay/*
assets/preload/images/icons/*
assets/preload/images/titleEnter.png
assets/preload/images/titleEnter_mobile.png
assets/preload/images/soundtray/*
assets/preload/images/stageBuild/*
assets/preload/images/ui/popup/pixel/
assets/shared/images/characters/abotPixel/
assets/shared/images/characters/bfPixel.png
assets/shared/images/characters/bfPixelsDEAD.png
assets/shared/images/characters/gfPixel.png
assets/shared/images/characters/nenePixel/
assets/shared/images/characters/picoPixel/
assets/shared/images/characters/senpai.png
assets/shared/images/characters/spirit.png
assets/shared/images/resultScreen/*
assets/shared/images/ui/chart-editor/*
assets/shared/images/ui/countdown/pixel/
assets/week1/
assets/week6/*
+7 -10
View File
@@ -60,7 +60,7 @@ This section provides guidelines to follow when [opening an issue](https://githu
## Requirements
Make sure you're playing:
- the latest version of the game (currently v0.6.4)
- the latest version of the game (currently v0.7.5)
- without any mods
- on [Newgrounds](https://www.newgrounds.com/portal/view/770371) or downloaded from [itch.io](https://ninja-muffin24.itch.io/funkin)
@@ -122,9 +122,6 @@ Also only report one issue or enhancement at a time! If you have multiple bug re
Once you're sure your issue is unique and specific, feel free to submit it.
> [!IMPORTANT]
> **DO NOT CLOSE YOUR ISSUE FOR ANY REASON!** Your issue will be taken care of by a moderator!
**Thank you for opening issues!**
# Part 3: Pull Requests
@@ -132,20 +129,20 @@ Community members are welcome to contribute their changes by [opening pull reque
This section covers guidelines for opening and managing pull requests (PRs).
## Choosing a base branch
When creating a branch in your fork, base your branch on either the `main` or `develop` branch depending on the types of changes you want to make.
When creating a branch in your fork, base your branch on either the `develop` or `main` branch depending on the types of changes you want to make.
> [!CAUTION]
> Avoid using your fork's default branch (`main` in this case) for your PR. This is considered an [anti-pattern](https://jmeridth.com/posts/do-not-issue-pull-requests-from-your-master-branch/) by GitHub themselves!
> Instead, make a separate branch for your additions (ex. `docs/fix-typo` or `minor-bugfix`).
Choose the `main` branch if you modify:
- Documentation (`.md` files)
- GitHub files (`.yml` files or anything in the `.github` folder)
Choose the `develop` branch if you modify:
- Game code (`.hx` files)
- Any other type of file
Choose the `main` branch if you modify:
- Documentation (`.md` files)
- GitHub files (`.yml` files or anything in the `.github` folder)
> [!TIP]
> When in doubt, base your branch on the `develop` branch.
@@ -399,7 +396,7 @@ If you only modify files in the `assets` folder, open a PR in the `funkin.assets
If you simultaneously modify files from both repositories, then open two separate PRs and explain the connection in your PR descriptions.
Be sure to choose `main` as the base branch for `funkin.assets` PRs, as no `develop` branch exists for that repository.
Be sure to choose `develop` as the base branch for `funkin.assets` PRs, just as you would in the `Funkin` repository.
### Charting PRs
Charting PRs make changes such as **adjusting chart metadata**.
+1 -1
View File
@@ -6,7 +6,7 @@
"name": "EliteMasterEric"
}
],
"api_version": "0.5.0",
"api_version": "0.7.0",
"mod_version": "1.0.0",
"license": "Apache-2.0"
}
+1 -1
View File
@@ -6,7 +6,7 @@
"name": "EliteMasterEric"
}
],
"api_version": "0.5.0",
"api_version": "0.7.0",
"mod_version": "1.0.0",
"license": "Apache-2.0"
}
+21 -49
View File
@@ -4,49 +4,49 @@
"name": "FlxPartialSound",
"type": "git",
"dir": null,
"ref": "3c9f63e3501c20c0b60442089dc05306f5a87968",
"url": "https://github.com/FunkinDroidTeam/FlxPartialSound.git"
"ref": "4e86b724ca43489a59ea465a46ffc12598e5df15",
"url": "https://github.com/FunkinCrew/FlxPartialSound.git"
},
{
"name": "astc-compressor",
"type": "git",
"dir": null,
"ref": "8c9f56927c523df7b849352c6951f04112fe15cc",
"ref": "b7a91b3072dc16e785a9bde847f17ba0ef15dd47",
"url": "https://github.com/KarimAkra/astc-compressor"
},
{
"name": "extension-admob",
"type": "git",
"dir": null,
"ref": "a53d5916bdcb2e48913f94d9ae1d949b049dcdc1",
"ref": "96385202f6f951b2bde0cbe836c5da21dde1f36e",
"url": "https://github.com/FunkinCrew/extension-admob"
},
{
"name": "extension-androidtools",
"type": "haxelib",
"version": "2.2.1"
"version": "2.2.2"
},
{
"name": "extension-haptics",
"type": "haxelib",
"version": "1.0.3"
"version": "1.0.4"
},
{
"name": "extension-iapcore",
"type": "haxelib",
"version": "1.0.3"
"version": "1.0.4"
},
{
"name": "extension-iarcore",
"type": "haxelib",
"version": "1.0.2"
"version": "1.0.3"
},
{
"name": "flixel",
"type": "git",
"dir": null,
"ref": "08fc955ca87f192a971719a675f1d3b21709725d",
"url": "https://github.com/FunkinCrew/flixel-mobile"
"ref": "5cf3515e665812179a9b413629325b608b3a9815",
"url": "https://github.com/FunkinCrew/flixel"
},
{
"name": "flixel-addons",
@@ -59,7 +59,7 @@
"name": "flxanimate",
"type": "git",
"dir": null,
"ref": "39c1572add28869c558b218fffed13df1b64f376",
"ref": "49214278b9124823582cdcecd94f4a1de9a4b36b",
"url": "https://github.com/FunkinCrew/flxanimate"
},
{
@@ -104,21 +104,21 @@
"name": "hscript",
"type": "git",
"dir": null,
"ref": "d60bb2947fa609fdc875ccfae89666a6984eeaf2",
"ref": "8c1d238b069ef97cec13f5121b29d2afe2b8985d",
"url": "https://github.com/FunkinCrew/hscript"
},
{
"name": "hxcpp",
"type": "git",
"dir": null,
"ref": "4e24283a047f11bded6affabbc9ec405156e026e",
"ref": "363d3d0a8d3ac450f5ba1b4c3357353656b71e82",
"url": "https://github.com/FunkinCrew/hxcpp"
},
{
"name": "hxcpp-debug-server",
"type": "git",
"dir": "hxcpp-debug-server",
"ref": "147294123f983e35f50a966741474438069a7a8f",
"ref": "7459934666a473a4cc4d066ba4a93ef92f1ce94c",
"url": "https://github.com/FunkinCrew/hxcpp-debugger"
},
{
@@ -143,7 +143,7 @@
{
"name": "hxvlc",
"type": "haxelib",
"version": "2.2.2"
"version": "2.2.4"
},
{
"name": "json2object",
@@ -170,36 +170,8 @@
"name": "lime",
"type": "git",
"dir": null,
"ref": "c750ebf6b48c4bc018abe9855fbae5ffdbc4771a",
"url": "https://github.com/FunkinCrew/lime-mobile"
},
{
"name": "mconsole",
"type": "git",
"dir": null,
"ref": "06c0499ed8f80628a0e6e55ffa32c3cbd688a838",
"url": "https://github.com/massive-oss/mconsole"
},
{
"name": "mcover",
"type": "git",
"dir": "src",
"ref": "c3c47cd682b0b202a41caee95321989391b617ef",
"url": "https://github.com/massive-oss/mcover"
},
{
"name": "mockatoo",
"type": "git",
"dir": "src",
"ref": "13d77a0a8eaf5e789ef5dae6cd33eee812deda36",
"url": "https://github.com/FunkinCrew/mockatoo"
},
{
"name": "munit",
"type": "git",
"dir": "src",
"ref": "f61be7f7ba796595f45023ca65164a485aba0e7e",
"url": "https://github.com/FunkinCrew/MassiveUnit"
"ref": "f109a083023a9e5622342257993fc745d9bbb959",
"url": "https://github.com/FunkinCrew/lime"
},
{
"name": "newgrounds",
@@ -212,21 +184,21 @@
"name": "openfl",
"type": "git",
"dir": null,
"ref": "a0df7c3afe360c9af59a76e45007dbf4e53b5131",
"url": "https://github.com/FunkinCrew/openfl-mobile"
"ref": "e6296200292a76b5f7b8684a991ead6b05ae4507",
"url": "https://github.com/FunkinCrew/openfl"
},
{
"name": "polymod",
"type": "git",
"dir": null,
"ref": "3e030c81de99ca84acde681431f806d8103bcf6e",
"ref": "47d9a2775e3fd8f6dd17d6f4b99b8798709da435",
"url": "https://github.com/larsiusprime/polymod"
},
{
"name": "thx.core",
"type": "git",
"dir": null,
"ref": "76d87418fadd92eb8e1b61f004cff27d656e53dd",
"ref": "2bf2b992e06159510f595554e6b952e47922f128",
"url": "https://github.com/fponticelli/thx.core"
},
{
+22
View File
@@ -0,0 +1,22 @@
# Organizes astc-compression-data alphabetically because i hate it when it's not organized -zack
$InputFile = "./astc-compression-data.json"
$OutputFile = "./astc-compression-data.json"
if (-not (Test-Path $InputFile)) {
Write-Host "❌ File $InputFile not found"
exit 1
}
if (-not (Get-Command jq -ErrorAction SilentlyContinue)) {
Write-Host "jq is not installed. Download from https://jqlang.github.io/jq/ or install via:"
Write-Host " winget install jqlang.jq"
exit 1
}
jq '.
| .custom = ( .custom | sort_by(.asset) )
| .excludes = ( .excludes | sort )
' $InputFile | Out-File -Encoding utf8 $OutputFile
Write-Host "✅ Sorted JSON written to $OutputFile WOOHOOO !!"
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
# Organizes astc-compression-data alphabetically because i hate it when it's not organized -zack
INPUT_FILE="./astc-compression-data.json"
OUTPUT_FILE="./astc-compression-data.json"
# Check jq
if ! command -v jq &> /dev/null; then
echo "jq is not installed. Install it with:"
echo " macOS: brew install jq"
echo " Linux (Debian/Ubuntu): sudo apt-get install jq"
exit 1
fi
if [ ! -f "$INPUT_FILE" ]; then
echo "❌ File $INPUT_FILE not found"
exit 1
fi
jq '.
| .custom = ( .custom | sort_by(.asset) )
| .excludes = ( .excludes | sort )
' "$INPUT_FILE" > "$OUTPUT_FILE".tmp && mv "$OUTPUT_FILE".tmp "$OUTPUT_FILE"
echo "✅ Sorted JSON written to $OUTPUT_FILE WOOHOOO !!"
+363 -138
View File
@@ -5,8 +5,10 @@ import hxp.*;
import lime.tools.*;
import sys.FileSystem;
import sys.io.File;
import haxe.io.Bytes;
import haxe.io.Path;
import haxe.ds.Map;
import haxe.xml.Printer;
using StringTools;
@@ -29,13 +31,13 @@ class Project extends HXProject
* REMEMBER TO CHANGE THIS WHEN THE GAME UPDATES!
* You only have to change it here, the rest of the game will query this value.
*/
static final VERSION:String = "0.7.2";
static final VERSION:String = "0.7.5";
/**
* The build's number and version code.
* Used when publishing the game to mobile app stores. Should increment with each patch.
*/
static final BUILD_NUMBER:Int = 2;
static final BUILD_NUMBER:Int = 56;
/**
* The game's name. Used as the default window title.
@@ -58,6 +60,11 @@ class Project extends HXProject
*/
static final SOURCE_DIR:String = "source";
/**
* The relative location of the templates folder.
*/
static final TEMPLATES_DIR:String = "templates";
/**
* The fully qualified class path for the game's preloader.
* Particularly important on HTML5 but we use it on all platforms.
@@ -103,30 +110,11 @@ class Project extends HXProject
static final ANDROID_EXTENSIONS:Array<String> = ["funkin.extensions.CallbackUtil"];
//
// ASTC COMPRESSION
//
/**
* The quality of the compression process.
* This doesn't exactly reduce the quality of the outputted texture..
* But it changes how hard the CPU gotta work to maintin the quality and details of the image while compressing.
* possible values: fastest, fast, medium, thorough, exhaustive.
*/
static var ASTC_QUALITY:String = "medium";
/**
* The team ID to use for the iOS app. Configured in XCode.
*/
static var IOS_TEAM_ID:String = "Z7G7AVNGSH";
/**
* The block size of the ASTC compressed textures.
* Higher block size means lower quality and lighter file size for the generated compressed textures.
* possible block sizes: 4x4, 4x6, 6x6, 8x8 ... 12x12.
*/
static var ASTC_BLOCKSIZE:String = "10x10";
/**
* A list of asset file globs to exclude from ASTC compression when creating optimized mobile builds.
*/
@@ -330,10 +318,10 @@ class Project extends HXProject
static final FEATURE_HAPTICS:FeatureFlag = "FEATURE_HAPTICS";
/**
* `-DFEATURE_INPUT_OFFSETS`
* `-DFEATURE_LAG_ADJUSTMENT`
* If this flag is enabled, the input offsets menu will be available to configure your audio and visual offsets.
*/
static final FEATURE_INPUT_OFFSETS:FeatureFlag = "FEATURE_INPUT_OFFSETS";
static final FEATURE_LAG_ADJUSTMENT:FeatureFlag = "FEATURE_LAG_ADJUSTMENT";
/**
* `-DFEATURE_LOG_TRACE`
@@ -342,6 +330,13 @@ class Project extends HXProject
*/
static final FEATURE_LOG_TRACE:FeatureFlag = "FEATURE_LOG_TRACE";
/**
* `-DFEATURE_DEBUG_FILE_LOGGING`
* If this flag is enabled, the game will print debug traces to a log file near the game's executable.
* Disable to improve performance a bunch.
*/
static final FEATURE_DEBUG_FILE_LOGGING:FeatureFlag = "FEATURE_DEBUG_FILE_LOGGING";
/**
* `-DFEATURE_MOBILE_ADVERTISEMENTS`
* If this flag is enabled, Google AdMob will be enabled.
@@ -487,6 +482,7 @@ class Project extends HXProject
envConfig = readEnvironmentFile("./.env");
flair();
configureApp();
displayTarget();
@@ -498,14 +494,12 @@ class Project extends HXProject
configureOutputDir();
configurePolymod();
configureHaxelibs();
configureASTCTextures();
configureAssets();
configureIcons();
readASTCExclusion();
if (FEATURE_COMPRESSED_TEXTURES.isEnabled(this))
if (!isLinux())
{
runASTCCompressor();
configureIcons();
}
if (FEATURE_MOBILE_ADVERTISEMENTS.isEnabled(this))
@@ -523,7 +517,10 @@ class Project extends HXProject
configureIOS();
}
info("Done configuring project.");
if (!isDisplay())
{
checkLibraries();
}
}
/**
@@ -532,10 +529,9 @@ class Project extends HXProject
function flair()
{
// TODO: Implement this.
info("Friday Night Funkin'");
info("Friday Night Funkin' - " + VERSION);
info("Initializing build...");
info("Target Version: " + VERSION);
info("Git Branch: " + getGitBranch());
info("Git Commit: " + getGitCommit());
info("Git Modified? " + getGitModified());
@@ -551,8 +547,7 @@ class Project extends HXProject
this.meta.title = TITLE;
// ios uses this character code instead of spaces...
if (isIOS())
this.meta.title = ~/ /ig.replace(TITLE, "\u2002");
if (isIOS()) this.meta.title = ~/ /ig.replace(TITLE, "\u2002");
this.meta.version = VERSION;
this.meta.packageName = PACKAGE_NAME;
@@ -566,6 +561,9 @@ class Project extends HXProject
// If for some reason we have multiple source directories, we can add more entries here.
this.sources.push(SOURCE_DIR);
// Templates stuff
this.templatePaths.push(TEMPLATES_DIR);
// Tell Lime to run some prebuild and postbuild scripts.
this.preBuildCallbacks.push(buildHaxeCLICommand(PREBUILD_HX));
this.postBuildCallbacks.push(buildHaxeCLICommand(POSTBUILD_HX));
@@ -795,8 +793,13 @@ class Project extends HXProject
// FEATURE FLAGS
//
// Should be true on debug builds or if GITHUB_BUILD is enabled.
FEATURE_DEBUG_FUNCTIONS.apply(this, isDebug() || GITHUB_BUILD.isEnabled(this));
FEATURE_RESULTS_DEBUG.apply(this, isDebug() || GITHUB_BUILD.isEnabled(this));
FEATURE_FUNKVIS.apply(this, true);
FEATURE_LOG_TRACE.apply(this, true);
FEATURE_DEBUG_FILE_LOGGING.apply(this, FEATURE_DEBUG_FUNCTIONS.isEnabled(this));
FEATURE_NAUGHTYNESS.apply(this, true);
FEATURE_OPEN_URL.apply(this, true);
FEATURE_PARTIAL_SOUNDS.apply(this, true);
@@ -806,10 +809,6 @@ class Project extends HXProject
// HXCPP has trouble with iOS simulator builds though...
FEATURE_VIDEO_PLAYBACK.apply(this, !isIOSSimulator());
// Should be true on debug builds or if GITHUB_BUILD is enabled.
FEATURE_DEBUG_FUNCTIONS.apply(this, isDebug() || GITHUB_BUILD.isEnabled(this));
FEATURE_RESULTS_DEBUG.apply(this, isDebug() || GITHUB_BUILD.isEnabled(this));
// Should be true on desktop, non-tester builds.
// We don't want testers to accidentally leak songs to their Discord friends!
FEATURE_DISCORD_RPC.apply(this, isDesktop() && !FEATURE_DEBUG_FUNCTIONS.isEnabled(this));
@@ -829,7 +828,7 @@ class Project extends HXProject
FEATURE_STAGE_EDITOR.apply(this, !(isWeb() || isMobile()));
// Should be true except on web builds (some asset stuff breaks it)
FEATURE_INPUT_OFFSETS.apply(this, !isWeb());
FEATURE_LAG_ADJUSTMENT.apply(this, !isWeb());
// Should be true except on web and mobile builds.
// Screenshots doesn't work there, and mobile has its own screenshots anyway.
@@ -860,6 +859,73 @@ class Project extends HXProject
// Since mobile is pretty memory safe (I'm looking at you Apple...) we need them BADLY to have the game run properly.
// It's kept off for desktop due to the low ASTC support on desktop GPUs (which seem to be only among Intergrated Graphics).
FEATURE_COMPRESSED_TEXTURES.apply(this, isMobile() && isRelease());
renderFlagsTable();
}
/**
* Renders a cute little table of which feature flags are enabled and which are disabled
*/
function renderFlagsTable():Void
{
var enabledWidth:Int = 0;
var disabledWidth:Int = 0;
var enabledFlags:Array<String> = [];
var disabledFlags:Array<String> = [];
var unicodeCheck:String = "✓ ";
var unicodeCross:String = "× ";
if (isWindowsHost())
{
#if (!target.unicode)
// lime build tools uses neko (unless compiling with `-eval`), and neko on windows doesn't support UTF8/unicode characters
// so we need to remove our cute emoji!
unicodeCheck = "o ";
unicodeCross = "x ";
#end
}
for (flagStr in this.haxedefs.keys())
{
if (!flagStr.startsWith(FeatureFlag.INVERSE_PREFIX))
{
// we do flagStr.length + 3 to accomodate for adding the "✓ " at the beginning
enabledWidth = Std.int(Math.max(flagStr.length + 3, enabledWidth));
enabledFlags.push(unicodeCheck + flagStr);
}
else
{
disabledWidth = Std.int(Math.max(flagStr.length, disabledWidth));
disabledFlags.push(unicodeCross + flagStr.substring(FeatureFlag.INVERSE_PREFIX.length));
}
}
enabledFlags.sort(function(a, b) return a > b ? 1 : -1);
disabledFlags.sort(function(a, b) return a > b ? 1 : -1);
var horizontalDivider:String = "".rpad("-", enabledWidth + disabledWidth);
info(horizontalDivider);
// Header
info("FEATURE FLAGS");
info('Enabled Flags $unicodeCheck'.rpad(" ", enabledWidth + 5) + 'Disabled Flags $unicodeCross');
info(horizontalDivider);
while (enabledFlags.length > 0 || disabledFlags.length > 0)
{
var outputLine:String = "";
if (enabledFlags.length > 0) outputLine += enabledFlags.shift();
outputLine = outputLine.rpad(" ", enabledWidth + 5);
outputLine += "| ";
if (disabledFlags.length > 0) outputLine += disabledFlags.shift() ?? "";
info(outputLine);
}
info(horizontalDivider);
}
/**
@@ -890,7 +956,7 @@ class Project extends HXProject
if (FEATURE_LOG_TRACE.isDisabled(this))
{
addHaxeFlag("--no-traces");
setHaxedef("no-traces");
}
// Disable the built in pause screen when unfocusing the game.
@@ -973,44 +1039,26 @@ class Project extends HXProject
// we use a dedicated 'tracy' folder, since it generally needs a recompile when in use
if (FEATURE_DEBUG_TRACY.isEnabled(this)) buildDir += "-tracy";
info('Output directory: $buildDir');
// trailing slash might not be needed, works fine on macOS without it, but I haven't tested on Windows!
buildDir += "/";
info('Output directory: $buildDir');
// setenv('BUILD_DIR', buildDir);
app.path = buildDir;
}
function configureAndroid()
{
javaPaths.push(Path.join([SOURCE_DIR, 'funkin/mobile/external/android/java']));
javaPaths.push(Path.join([SOURCE_DIR, 'funkin/external/android/java']));
if (isRelease())
{
if (envConfig != null)
{
keystore = new Keystore();
keystore.path = Std.string(envConfig.get('ANDROID_KEYSTORE_PATH'));
keystore.alias = Std.string(envConfig.get('ANDROID_KEYSTORE_ALIAS'));
keystore.password = Std.string(envConfig.get('ANDROID_KEYSTORE_PASSWORD'));
}
Reflect.setField(config.get('android.manifest'), 'xmlns:tools', 'http://schemas.android.com/tools');
final permissionsConfig:Array<String> = [
'<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />',
'<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />'
];
final xmlChildren:Null<Array<String>> = config.get('android.manifest').xmlChildren;
if (xmlChildren != null)
{
config.get('android.manifest').xmlChildren = xmlChildren.concat(permissionsConfig);
}
else
{
config.get('android.manifest').xmlChildren = permissionsConfig;
keystore.path = Std.string(envConfig.get('KEYSTORE_PATH'));
keystore.alias = Std.string(envConfig.get('KEYSTORE_ALIAS'));
keystore.password = Std.string(envConfig.get('KEYSTORE_PASSWORD'));
}
if (isBundle())
@@ -1019,23 +1067,31 @@ class Project extends HXProject
}
}
final modsFolderProvider = [
'<provider android:authorities="$PACKAGE_NAME.docprovider" android:name="funkin.provider.DataFolderProvider" android:grantUriPermissions="true" android:exported="true" android:permission="android.permission.MANAGE_DOCUMENTS">',
' <intent-filter>',
' <action android:name="android.content.action.DOCUMENTS_PROVIDER" />',
' </intent-filter>',
'</provider>'
];
final modsFolderProvider:Xml = Xml.createElement('provider');
modsFolderProvider.set('android:authorities', '$PACKAGE_NAME.docprovider');
modsFolderProvider.set('android:name', 'funkin.provider.DataFolderProvider');
modsFolderProvider.set('android:grantUriPermissions', 'true');
modsFolderProvider.set('android:exported', 'true');
modsFolderProvider.set('android:permission', 'android.permission.MANAGE_DOCUMENTS');
final xmlChildren:Null<Array<String>> = config.get('android.application').xmlChildren;
final intentFilter:Xml = Xml.createElement('intent-filter');
if (xmlChildren != null)
final action:Xml = Xml.createElement('action');
action.set('android:name', 'android.content.action.DOCUMENTS_PROVIDER');
intentFilter.addChild(action);
modsFolderProvider.addChild(intentFilter);
@:nullSafety(Off)
{
config.get('android.application').xmlChildren = xmlChildren.concat(modsFolderProvider);
}
else
{
config.get('android.application').xmlChildren = modsFolderProvider;
if (config.get('android.application').xmlChildren != null)
{
config.get('android.application').xmlChildren.push(Printer.print(modsFolderProvider));
}
else
{
config.get('android.application').xmlChildren = [Printer.print(modsFolderProvider)];
}
}
final extensions:Null<Array<String>> = config.getArrayString('android.extension');
@@ -1238,7 +1294,14 @@ class Project extends HXProject
addAsset("LICENSE.md", "LICENSE.md", "art", shouldEmbedArt);
addAsset("CHANGELOG.md", "CHANGELOG.md", "art", shouldEmbedArt);
info('Done configuring assets.');
if (shouldEmbed)
{
info('Done embedding assets.');
}
else
{
info('Done including assets.');
}
}
/**
@@ -1251,27 +1314,7 @@ class Project extends HXProject
if (isAndroid())
{
// Adaptive icons
// TODO: Add Adapative Icons in Lime
templatePaths.push("templates");
var androidTheme:String = "@style/LimeAppMainTheme";
if (window.fullscreen != null && window.fullscreen)
{
androidTheme += "Fullscreen";
}
final iconXmlChild:Dynamic = {
"android:label": meta.title,
"android:allowBackup": "true",
"android:theme": androidTheme,
"android:hardwareAccelerated": "true",
"android:allowNativeHeapPointerTagging": ANDROID_TARGET_SDK_VERSION >= 30 ? "false" : null,
"android:largeHeap": "true",
"android:icon": "@mipmap/ic_launcher",
"android:roundIcon": "@mipmap/ic_launcher_round"
};
config.set('android.application', iconXmlChild);
adaptiveIcon = new AdaptiveIcon('art/icons/android/', true);
}
else if (isIOS())
{
@@ -1302,8 +1345,24 @@ class Project extends HXProject
addIcon("art/icons/icon32.png", 32);
addIcon("art/icons/icon64.png", 64);
addIcon("art/icons/iconOG.png");
}
info('Done configuring icons.');
info('Done configuring icons.');
}
/**
* Configure the astc textures.
*/
function configureASTCTextures()
{
if (!(isDisplay() || isClean()))
{
readASTCExclusion();
if (FEATURE_COMPRESSED_TEXTURES.isEnabled(this))
{
runASTCCompressor();
}
}
}
@@ -1314,15 +1373,7 @@ class Project extends HXProject
{
if (envConfig == null) return;
if (isAndroid())
{
setenv("ADMOB_APPID", Std.string(envConfig.get('ANDROID_ADMOB_APP_ID')));
}
if (isIOS())
{
setenv("ADMOB_APPID", Std.string(envConfig.get('IOS_ADMOB_APP_ID')));
}
setenv("ADMOB_APPID", Std.string(envConfig.get('ADMOB_APP_ID')));
}
//
@@ -1360,6 +1411,21 @@ class Project extends HXProject
return this.architectures.contains(Architecture.X64);
}
public function isWindowsHost():Bool
{
return System.hostPlatform == WINDOWS;
}
public function isMacHost():Bool
{
return System.hostPlatform == MAC;
}
public function isLinuxHost():Bool
{
return System.hostPlatform == LINUX;
}
public function isWindows():Bool
{
return this.target == Platform.WINDOWS;
@@ -1420,6 +1486,11 @@ class Project extends HXProject
return this.command == "display";
}
public function isClean():Bool
{
return this.command == "clean";
}
public function isDebug():Bool
{
return this.debug;
@@ -1642,6 +1713,101 @@ class Project extends HXProject
return commitHashSplice;
}
@SuppressWarnings('checkstyle:Dynamic')
static function checkLibraries():Void
{
var outdatedLibraries:Map<String, Array<String>> = new Map<String, Array<String>>();
var hmmData:Dynamic = haxe.Json.parse(sys.io.File.getContent(#if ios '../../../../../' + #end 'hmm.json'));
var dependencies:Array<Dynamic> = cast hmmData.dependencies;
for (library in dependencies)
{
var libraryName:String = cast(library.name, String).replace(".", ",");
var libraryDev:String = readLibraryDev(libraryName);
var libraryCurrentVersion:String = readLibraryCurrentVersion(libraryName);
switch (library.type)
{
case 'haxelib':
if (libraryDev != "")
{
outdatedLibraries.set(libraryName, [libraryDev, library.version]);
}
else if (library.version != libraryCurrentVersion)
{
outdatedLibraries.set(libraryName, [libraryCurrentVersion, library.version]);
}
case 'git':
if (libraryDev != "")
{
outdatedLibraries.set(libraryName, [libraryDev, library.ref]);
}
else
{
var commitHash:String = readLibraryGitCommitHash(libraryName);
if (commitHash != library.ref && commitHash != "")
outdatedLibraries.set(libraryName, [commitHash, library.ref]);
}
}
}
if (Lambda.count(outdatedLibraries) > 0)
{
Sys.println("\x1b[1;33m\nWARNING: The following haxelibs diverge from the versions set in hmm.json."
+ "\n\nThey may be outdated, so it is recommended to abort compilation and run `hmm reinstall [library]` to update each library."
+ "\n\nYou may ignore this warning if your libraries are newer than the versions in hmm.json, or if you know what you're doing.\n\x1b[0m");
for (libraryName in outdatedLibraries.keys())
{
var versions:Null<Array<String>> = outdatedLibraries.get(libraryName);
if (versions == null) continue;
var outdatedVersion:String = versions[0];
var expectedVersion:String = versions[1];
var isDev:Bool = outdatedVersion.contains("/");
Sys.println("- " + libraryName.replace(",", ".") + (isDev ? "\x1b[1;34m (Development Build)\x1b[0m" : ""));
Sys.println(" \x1b[38;5;203mCurrent version: " + outdatedVersion + "\x1b[0m");
Sys.println(" \x1b[38;5;82mExpected version: " + expectedVersion + "\x1b[0m\n");
}
}
}
static function readLibraryCurrentVersion(libraryName:String):String
{
var path = haxe.io.Path.join([haxe.io.Path.addTrailingSlash(Sys.getCwd()), '.haxelib', libraryName, '.current']);
if (sys.FileSystem.exists(path))
return sys.io.File.getContent(path);
return '';
}
static function readLibraryDev(libraryName:String):String
{
var path = haxe.io.Path.join([haxe.io.Path.addTrailingSlash(Sys.getCwd()), '.haxelib', libraryName, '.dev']);
if (sys.FileSystem.exists(path))
return sys.io.File.getContent(path);
return '';
}
static function readLibraryGitCommitHash(libraryName:String):String
{
var gitProccess = new sys.io.Process("git", ["-C", ".haxelib/" + libraryName + "/git", "rev-parse", "HEAD"]);
gitProccess.exitCode(true);
return gitProccess.stdout.readAll().toString().trim();
}
public function getGitBranch():String
{
// Cannibalized from GitCommit.hx
@@ -1703,7 +1869,8 @@ class Project extends HXProject
*/
public function error(message:String):Void
{
Log.error('${message}');
Sys.stderr().write(Bytes.ofString('[ERROR] ${message}'));
Sys.exit(1);
}
/**
@@ -1711,9 +1878,9 @@ class Project extends HXProject
*/
public function info(message:String):Void
{
if (command != "display")
if (!(isDisplay() || isClean()))
{
Log.info('[INFO] ${message}');
Sys.println('[INFO] ${message}');
}
}
@@ -1738,48 +1905,114 @@ class Project extends HXProject
}
var env = new Map<String, Dynamic>();
for (line in envFile.split('\n'))
{
if (line == "" || line.startsWith("#")) continue;
line = line.trim();
var parts = line.split('=');
if (parts.length != 2) continue;
if (line.length <= 0 || line.startsWith('#') || shouldExcludeEnvKey(line))
{
continue;
}
env.set(parts[0], parts[1]);
final index:Int = line.indexOf('=');
if (index == -1)
{
continue;
}
final value:String = line.substr(index + 1);
if (value.length == 0)
{
continue;
}
env.set(stripEnvTargetPrefix(line.substr(0, index)), value);
}
return env;
}
public function shouldExcludeEnvKey(key:String):Bool
{
final android:Bool = key.startsWith('ANDROID_');
final ios:Bool = key.startsWith('IOS_');
final mobile:Bool = key.startsWith('MOBILE_') || ios || android;
final web:Bool = key.startsWith('WEB_');
final desktop:Bool = key.startsWith('DESKTOP_');
if (isWeb() && (mobile || desktop)) return true;
if (isDesktop() && (mobile || web)) return true;
if (isAndroid() && (ios || web || desktop)) return true;
if (isIOS() && (android || web || desktop)) return true;
return false;
}
public function stripEnvTargetPrefix(key:String):String
{
final index:Int = key.indexOf('_');
if (index == -1)
{
return key;
}
final prefix:String = key.substr(0, index);
final rest:String = key.substr(index + 1);
if (isAndroid() && (prefix == 'ANDROID' || prefix == 'MOBILE'))
{
return rest;
}
else if (isIOS() && (prefix == 'IOS' || prefix == 'MOBILE'))
{
return rest;
}
else if (isWeb() && prefix == 'WEB')
{
return rest;
}
else if (isDesktop() && prefix == 'DESKTOP')
{
return rest;
}
return key;
}
public function readASTCExclusion():Void
{
astcExcludes = File.getContent('./compression-excludes.txt').trim().split('\n');
@:nullSafety(Off)
astcExcludes = haxe.Json.parse(File.getContent('./astc-compression-data.json')).excludes;
for (i in 0...astcExcludes.length)
astcExcludes[i] = astcExcludes[i].trim();
}
public function isASTCExcluded(filePath:String):Bool
public function isASTCExcluded(file:String):Bool
{
for (exclusion in astcExcludes)
{
if (exclusion.endsWith("/*"))
if (exclusion.endsWith("/"))
{
var normalizedFilePath = Path.normalize(filePath);
var normalizedExclusion = Path.normalize(exclusion.substr(0, exclusion.length - 2));
var normalizedFilePath = Path.normalize(file);
var normalizedExclusion = Path.normalize(exclusion);
if (normalizedFilePath.startsWith(normalizedExclusion)) return true;
}
else if (exclusion.endsWith("/"))
else if (exclusion.endsWith("/*"))
{
var normalizedExclusion = Path.normalize(exclusion);
var fileDirectory = Path.directory(Path.normalize(filePath));
var normalizedExclusion = Path.normalize(exclusion.substr(0, exclusion.length - 2));
var fileDirectory = Path.directory(Path.normalize(file));
if (fileDirectory == normalizedExclusion) return true;
}
else
{
if (filePath == exclusion) return true;
if (file == exclusion) return true;
}
}
@@ -1790,16 +2023,12 @@ class Project extends HXProject
{
info('Compressing ASTC textures...');
var args:Array<String> = ['run', 'astc-compressor'];
args = args.concat(['-i', './assets']);
args = args.concat(['-o', './astc-textures/assets/']);
args = args.concat(['-blocksize', ASTC_BLOCKSIZE]);
args = args.concat(['-quality', ASTC_QUALITY]);
args = args.concat(['-excludes', './compression-excludes.txt']);
var args:Array<String> = ['run', 'astc-compressor', 'compress-from-json'];
args = args.concat(['-json', './astc-compression-data.json']);
Sys.command('haxelib', args);
info('Finished compressing ASTC textures!');
info('Done compressing ASTC textures.');
}
}
@@ -1807,9 +2036,9 @@ class Project extends HXProject
* An object representing a feature flag, which can be enabled or disabled.
* Includes features such as automatic generation of compile defines and inversion.
*/
abstract FeatureFlag(String)
abstract FeatureFlag(String) from String to String
{
static final INVERSE_PREFIX:String = "NO_";
public static final INVERSE_PREFIX:String = "NO_";
public function new(input:String)
{
@@ -1834,13 +2063,11 @@ abstract FeatureFlag(String)
if (isEnabled(project))
{
// If this flag was already enabled, disable the inverse.
project.info('Enabling feature flag ${this}');
getInverse().disable(project, false);
}
else if (getInverse().isEnabled(project))
{
// If the inverse flag was already enabled, disable this flag.
project.info('Disabling feature flag ${this}');
disable(project, false);
}
else
@@ -1848,13 +2075,11 @@ abstract FeatureFlag(String)
if (enableByDefault)
{
// Enable this flag if it was unset, and disable the inverse.
project.info('Enabling feature flag ${this}');
enable(project, true);
}
else
{
// Disable this flag if it was unset, and enable the inverse.
project.info('Disabling feature flag ${this}');
disable(project, true);
}
}
+23 -47
View File
@@ -6,13 +6,12 @@ import flixel.FlxState;
import funkin.ui.FullScreenScaleMode;
import funkin.Preferences;
import funkin.util.logging.CrashHandler;
import funkin.ui.debug.MemoryCounter;
import funkin.ui.debug.FunkinDebugDisplay;
import funkin.save.Save;
import haxe.ui.Toolkit;
#if hxvlc
import hxvlc.util.Handle;
#end
import openfl.display.FPS;
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.Lib;
@@ -30,7 +29,6 @@ class Main extends Sprite
var initialState:Class<FlxState> = funkin.InitState; // The FlxState the game starts with.
var zoom:Float = -1; // If -1, zoom is automatically calculated to fit the window dimensions.
var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode.
var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets
// You can pretty much ignore everything from here on - your code should go in your states.
@@ -84,32 +82,17 @@ class Main extends Sprite
setupGame();
}
var video:Video;
var netStream:NetStream;
var overlay:Sprite;
/**
* A frame counter displayed at the top left.
* The debug display at the top left.
*/
public static var fpsCounter:FPS;
/**
* A RAM counter displayed at the top left.
*/
public static var memoryCounter:MemoryCounter;
public static var debugDisplay:FunkinDebugDisplay;
function setupGame():Void
{
initHaxeUI();
// addChild gets called by the user settings code.
fpsCounter = new FPS(10, 3, 0xFFFFFF);
#if !html5
// addChild gets called by the user settings code.
// TODO: disabled on HTML5 (todo: find another method that works?)
memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF);
#end
debugDisplay = new FunkinDebugDisplay(10, 10, 0xFFFFFF);
#if mobile
// Add this signal so we can reposition and resize the memory and fps counter.
@@ -121,7 +104,16 @@ class Main extends Sprite
#if hxvlc
// Initialize hxvlc's Handle here so the videos are loading faster.
Handle.init();
Handle.initAsync(function(success:Bool):Void {
if (success)
{
trace('[HXVLC] LibVLC instance initialized!');
}
else
{
trace('[HXVLC] LibVLC instance failed to initialize!');
}
});
#end
// Don't call anything from the preferences until the save is loaded!
@@ -133,7 +125,8 @@ class Main extends Sprite
WindowUtil.setVSyncMode(funkin.Preferences.vsyncMode);
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash, startFullscreen);
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash,
(FlxG.stage.window.fullscreen || Preferences.autoFullscreen));
// FlxG.game._customSoundTray wants just the class, it calls new from
// create() in there, which gets called when it's added to the stage
@@ -145,6 +138,7 @@ class Main extends Sprite
#if FEATURE_DEBUG_FUNCTIONS
game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil());
funkin.util.macro.ConsoleMacro.init();
#end
#if !html5
@@ -190,41 +184,23 @@ class Main extends Sprite
scale = Math.min(scale, 1);
#end
final thypos:Float = Math.max(FullScreenScaleMode.notchSize.x, 10);
if (fpsCounter != null)
if (debugDisplay != null)
{
fpsCounter.scaleX = fpsCounter.scaleY = scale;
debugDisplay.scaleX = debugDisplay.scaleY = scale;
if (FlxG.game != null)
{
if (lerp)
{
fpsCounter.x = flixel.math.FlxMath.lerp(fpsCounter.x, FlxG.game.x + thypos, FlxG.elapsed * 3);
debugDisplay.x = flixel.math.FlxMath.lerp(debugDisplay.x, FlxG.game.x + thypos, FlxG.elapsed * 3);
}
else
{
fpsCounter.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10;
debugDisplay.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10;
}
fpsCounter.y = FlxG.game.y + (3 * scale);
}
}
if (memoryCounter != null)
{
memoryCounter.scaleX = memoryCounter.scaleY = scale;
if (FlxG.game != null)
{
if (lerp)
{
memoryCounter.x = flixel.math.FlxMath.lerp(memoryCounter.x, FlxG.game.x + thypos, FlxG.elapsed * 3);
}
else
{
memoryCounter.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10;
}
memoryCounter.y = FlxG.game.y + (13 * scale);
debugDisplay.y = FlxG.game.y + (3 * scale);
}
}
}
+36 -5
View File
@@ -3,6 +3,8 @@ package source; // Yeah, I know...
import sys.FileSystem;
import sys.io.File;
using StringTools;
/**
* A script which executes after the game is built.
*/
@@ -27,14 +29,43 @@ class Postbuild
sys.FileSystem.deleteFile(BUILD_TIME_FILE);
var buildTime:Float = roundToTwoDecimals(end - start);
trace('Build took: ${buildTime} seconds');
Sys.println('[INFO] Build took: ${format(end - start)}');
}
}
static function roundToTwoDecimals(value:Float):Float
static function format(time:Float, decimals:Int = 1):String
{
return Math.round(value * 100) / 100;
var units = [
{name: "day", secs: 86400},
{name: "hour", secs: 3600},
{name: "minute", secs: 60},
{name: "second", secs: 1}
];
var parts:Array<String> = [];
var remaining:Float = time;
for (unit in units)
{
var value:Float;
if (unit.name == "second")
{
// handle seconds with decimals
value = Math.round(remaining * Math.pow(10, decimals)) / Math.pow(10, decimals);
}
else
{
value = Math.floor(remaining / unit.secs);
remaining %= unit.secs;
}
//
if (value > 0 || (unit.name == "second" && parts.length == 0))
{
parts.push('${value} ${unit.name}${value == 1 ? "" : "s"}');
}
}
return parts.join(" ");
}
}
+2 -30
View File
@@ -9,28 +9,16 @@ class Prebuild
{
static inline final BUILD_TIME_FILE:String = '.build_time';
static final NG_CREDS_PATH:String = './source/funkin/api/newgrounds/NewgroundsCredentials.hx';
static final NG_CREDS_TEMPLATE:String = "package funkin.api.newgrounds;
class NewgroundsCredentials
{
public static final APP_ID:String = #if API_NG_APP_ID haxe.macro.Compiler.getDefine(\"API_NG_APP_ID\") #else 'INSERT APP ID HERE' #end;
public static final ENCRYPTION_KEY:String = #if API_NG_ENC_KEY haxe.macro.Compiler.getDefine(\"API_NG_ENC_KEY\") #else 'INSERT ENCRYPTION KEY HERE' #end;
}";
static function main():Void
{
var start:Float = Sys.time();
trace('[PREBUILD] Performing pre-build tasks...');
// Sys.println('[INFO] Performing pre-build tasks...');
saveBuildTime();
buildCredsFile();
var end:Float = Sys.time();
var duration:Float = end - start;
trace('[PREBUILD] Finished pre-build tasks in $duration seconds.');
// Sys.println('[INFO] Finished pre-build tasks in $duration seconds.');
}
static function saveBuildTime():Void
@@ -41,20 +29,4 @@ class NewgroundsCredentials
fo.writeDouble(now);
fo.close();
}
static function buildCredsFile():Void
{
if (sys.FileSystem.exists(NG_CREDS_PATH))
{
trace('[PREBUILD] NewgroundsCredentials.hx already exists, skipping.');
}
else
{
trace('[PREBUILD] Creating NewgroundsCredentials.hx...');
var fileContents:String = NG_CREDS_TEMPLATE;
sys.io.File.saveContent(NG_CREDS_PATH, fileContents);
}
}
}
+13 -1
View File
@@ -5,6 +5,7 @@ import flixel.util.FlxSignal;
import flixel.math.FlxMath;
import funkin.data.song.SongData.SongTimeChange;
import funkin.data.song.SongDataUtils;
import funkin.play.PlayState;
import funkin.save.Save;
import funkin.util.TimerUtil.SongSequence;
import haxe.Timer;
@@ -113,6 +114,17 @@ class Conductor
if (currentTimeChange == null) return Constants.DEFAULT_BPM;
@:privateAccess
if (PlayState.instance != null && PlayState.instance.startingSong)
{
for (i in 0...timeChanges.length)
{
if (PlayState.instance.startTimestamp >= timeChanges[i].timeStamp) currentTimeChange = timeChanges[i];
if (PlayState.instance.startTimestamp < timeChanges[i].timeStamp) break;
}
}
return currentTimeChange.bpm;
}
@@ -417,7 +429,7 @@ class Conductor
// If the song is playing, limit the song position to the length of the song or beginning of the song.
if (FlxG.sound.music != null && FlxG.sound.music.playing)
{
this.songPosition = FlxMath.bound(Math.min(this.combinedOffset, 0), songPos, currentLength);
this.songPosition = Math.min(this.combinedOffset, 0).clamp(songPos, currentLength);
this.songPositionDelta += FlxG.elapsed * 1000 * FlxG.sound.music.pitch;
}
else
+47 -21
View File
@@ -117,10 +117,7 @@ class FunkinMemory
*/
public static function cacheTexture(key:String):Void
{
if (currentCachedTextures.exists(key))
{
return; // Already cached.
}
if (currentCachedTextures.exists(key)) return;
if (previousCachedTextures.exists(key))
{
@@ -135,13 +132,13 @@ class FunkinMemory
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
return;
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
currentCachedTextures.set(key, graphic);
}
trace('Successfully cached graphic: $key');
graphic.persist = true;
currentCachedTextures.set(key, graphic);
forceRender(graphic);
}
/**
@@ -150,26 +147,55 @@ class FunkinMemory
*/
static function permanentCacheTexture(key:String):Void
{
if (permanentCachedTextures.exists(key))
{
return; // Already cached.
}
if (permanentCachedTextures.exists(key)) return;
var graphic:Null<FlxGraphic> = FlxGraphic.fromAssetKey(key, false, null, true);
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
permanentCachedTextures.set(key, graphic);
return;
}
trace('Successfully cached graphic: $key');
graphic.persist = true;
permanentCachedTextures.set(key, graphic);
forceRender(graphic);
currentCachedTextures = permanentCachedTextures;
}
/**
* Forces the GPU to load and upload a FlxGraphic.
*/
private static function forceRender(graphic:FlxGraphic):Void
{
if (graphic == null) return;
var bmp:Null<FlxGraphic> = FlxG.bitmap.get(graphic.key);
if (bmp != null && bmp.bitmap != null) var _:Int = bmp.bitmap.width; // Trigger
// Draws sprite and actually caches it.
var sprite = new flixel.FlxSprite();
sprite.loadGraphic(graphic);
sprite.draw(); // Draw sprite and load it into game's memory.
graphic.bitmap?.getTexture(FlxG.stage.context3D); // Just in case that didn't work...
sprite.destroy();
}
/**
* Checks, if graphic with given path cached in memory.
*/
public static inline function isGraphicCached(path:String):Bool
return permanentCachedTextures.exists(path) || currentCachedTextures.exists(path) || previousCachedTextures.exists(path);
public static function getCachedGraphic(path:String):Null<FlxGraphic>
{
if (permanentCachedTextures.exists(path)) return permanentCachedTextures.get(path);
if (currentCachedTextures.exists(path)) return currentCachedTextures.get(path);
if (previousCachedTextures.exists(path)) return previousCachedTextures.get(path); // just in case
return null;
}
/**
* Prepares the cache for purging unused textures.
*/
@@ -350,7 +376,7 @@ class FunkinMemory
if (sound != null)
{
Assets.cache.removeSound(key);
previousCachedTextures.remove(key);
previousCachedSounds.remove(key);
}
}
Assets.cache.clear("songs");
+145 -131
View File
@@ -11,9 +11,9 @@ import flixel.math.FlxRect;
import flixel.system.debug.log.LogStyle;
import flixel.util.FlxColor;
import funkin.graphics.FunkinSprite;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
import funkin.data.dialogue.speaker.SpeakerRegistry;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.SpeakerRegistry;
import funkin.data.freeplay.album.AlbumRegistry;
import funkin.data.freeplay.player.PlayerRegistry;
import funkin.data.freeplay.style.FreeplayStyleRegistry;
@@ -24,7 +24,7 @@ import funkin.data.event.SongEventRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.story.level.LevelRegistry;
import funkin.modding.module.ModuleHandler;
import funkin.play.character.CharacterData.CharacterDataParser;
import funkin.data.character.CharacterData.CharacterDataParser;
import funkin.play.notes.notekind.NoteKindManager;
import funkin.play.PlayStatePlaylist;
import funkin.ui.debug.charting.ChartEditorState;
@@ -55,6 +55,13 @@ import funkin.api.newgrounds.NewgroundsClient;
@:nullSafety
class InitState extends FlxState
{
/**
* Simply states whether the "core stuff" is ready or not.
* This is used to prevent re-initialization of specific core features.
*/
@:noCompletion
static var _coreInitialized:Bool = false;
/**
* Perform a bunch of game setup, then immediately transition to the title screen.
*/
@@ -78,159 +85,163 @@ class InitState extends FlxState
*/
function setupShit():Void
{
//
// GAME SETUP
//
if (!_coreInitialized)
{
//
// GAME SETUP
//
// Setup window events (like callbacks for onWindowClose)
// and fullscreen keybind setup
WindowUtil.initWindowEvents();
// Disable the thing on Windows where it tries to send a bug report to Microsoft because why do they care?
WindowUtil.disableCrashHandler();
// Setup window events (like callbacks for onWindowClose) and fullscreen keybind setup
WindowUtil.initWindowEvents();
#if FEATURE_DEBUG_TRACY
funkin.util.WindowUtil.initTracy();
#end
#if FEATURE_DEBUG_TRACY
funkin.util.WindowUtil.initTracy();
#end
#if FEATURE_HAPTICS
// Setup Haptic feedback
extension.haptics.Haptic.initialize();
#end
#if FEATURE_HAPTICS
// Setup Haptic feedback
extension.haptics.Haptic.initialize();
#end
#if FEATURE_MOBILE_ADVERTISEMENTS
// Setup Admob
funkin.mobile.util.AdMobUtil.init();
#end
#if FEATURE_MOBILE_ADVERTISEMENTS
// Setup Admob
funkin.mobile.util.AdMobUtil.init();
#end
#if FEATURE_MOBILE_IAP
// Setup In-App purchases
funkin.mobile.util.InAppPurchasesUtil.init();
#end
#if FEATURE_MOBILE_IAP
// Setup In-App purchases
funkin.mobile.util.InAppPurchasesUtil.init();
#end
#if FEATURE_MOBILE_IAR
// Setup In-App purchases
funkin.mobile.util.InAppReviewUtil.init();
#end
#if FEATURE_MOBILE_IAR
// Setup In-App reviews
funkin.mobile.util.InAppReviewUtil.init();
#end
#if ios
// Setup Audio session
funkin.mobile.external.ios.AudioSession.initialize();
#end
#if android
// Setup Callback util.
funkin.external.android.CallbackUtil.init();
#end
// This ain't a pixel art game! (most of the time)
FlxSprite.defaultAntialiasing = true;
#if ios
// Setup Audio session
funkin.external.apple.AudioSession.initialize();
#end
// Disable default keybinds for volume (we manually control volume in MusicBeatState with custom binds)
FlxG.sound.volumeUpKeys = [];
FlxG.sound.volumeDownKeys = [];
FlxG.sound.muteKeys = [];
// This ain't a pixel art game! (most of the time)
FlxSprite.defaultAntialiasing = true;
// A small jumpstart to the soundtray, it usually sets itself to inactive (somewhere...)
// but that makes our soundtray not show up on init if we have the game muted.
// We set it to active so it at least calls it's update function once (see FlxGame.onEnterFrame(), it's called there)
// and also see FunkinSoundTray.update() to see what we do and how we check if we are muted or not
#if !mobile
FlxG.game.soundTray.active = true;
#end
// Disable default keybinds for volume (we manually control volume in MusicBeatState with custom binds)
FlxG.sound.volumeUpKeys = [];
FlxG.sound.volumeDownKeys = [];
FlxG.sound.muteKeys = [];
// Set the game to a lower frame rate while it is in the background.
FlxG.game.focusLostFramerate = 30;
// A small jumpstart to the soundtray, it usually sets itself to inactive (somewhere...)
// but that makes our soundtray not show up on init if we have the game muted.
// We set it to active so it at least calls it's update function once (see FlxGame.onEnterFrame(), it's called there)
// and also see FunkinSoundTray.update() to see what we do and how we check if we are muted or not
#if !mobile
FlxG.game.soundTray.active = true;
#end
// Makes Flixel use frame times instead of locked movements per frame for things like tweens
FlxG.fixedTimestep = false;
// Set the game to a lower frame rate while it is in the background.
FlxG.game.focusLostFramerate = 30;
setupFlixelDebug();
// Makes Flixel use frame times instead of locked movements per frame for things like tweens
FlxG.fixedTimestep = false;
//
// FLIXEL TRANSITIONS
//
setupFlixelDebug();
// Diamond Transition
var diamond:FlxGraphic = FlxGraphic.fromClass(GraphicTransTileDiamond);
diamond.persist = true;
diamond.destroyOnNoUse = false;
//
// FLIXEL TRANSITIONS
//
// NOTE: tileData is ignored if TransitionData.type is FADE instead of TILES.
var tileData:TransitionTileData = {asset: diamond, width: 32, height: 32};
// Diamond Transition
var diamond:FlxGraphic = FlxGraphic.fromClass(GraphicTransTileDiamond);
diamond.persist = true;
diamond.destroyOnNoUse = false;
FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
// Don't play transition in when entering the title state.
FlxTransitionableState.skipNextTransIn = true;
// NOTE: tileData is ignored if TransitionData.type is FADE instead of TILES.
var tileData:TransitionTileData = {asset: diamond, width: 32, height: 32};
FlxG.signals.gameResized.add(function(width:Int, height:Int) {
FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
});
// SDL for some reason enables VSync on focus lost/gained in Android
// Since we don't really need VSync on Android we're gonna forcefully disable it on these signals for now
// This is fixed on SDL3 from what I've heared but that doodoo isn't working poperly for Android
#if android
FlxG.signals.focusLost.add(function() {
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
FlxG.signals.focusGained.add(function() {
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
#end
FlxG.signals.gameResized.add(function(width:Int, height:Int) {
FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
});
//
// NEWGROUNDS API SETUP
//
#if FEATURE_NEWGROUNDS
NewgroundsClient.instance.init();
#end
// SDL for some reason enables VSync on focus lost/gained in Android
// Since we don't really need VSync on Android we're gonna forcefully disable it on these signals for now
// This is fixed on SDL3 from what I've heared but that doodoo isn't working poperly for Android
#if android
FlxG.signals.focusLost.add(function() {
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
FlxG.signals.focusGained.add(function() {
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
#end
//
// DISCORD API SETUP
//
#if FEATURE_DISCORD_RPC
DiscordClient.instance.init();
//
// NEWGROUNDS API SETUP
//
#if FEATURE_NEWGROUNDS
NewgroundsClient.instance.init();
#end
lime.app.Application.current.onExit.add(function(exitCode) {
DiscordClient.instance.shutdown();
});
#end
//
// DISCORD API SETUP
//
#if FEATURE_DISCORD_RPC
DiscordClient.instance.init();
//
// ANDROID SETUP
//
#if android
FlxG.android.preventDefaultKeys = [flixel.input.android.FlxAndroidKey.BACK];
funkin.mobile.external.android.CallbackUtil.init();
#end
lime.app.Application.current.onExit.add(function(exitCode) {
DiscordClient.instance.shutdown();
});
#end
//
// FLIXEL PLUGINS
//
// Plugins provide a useful interface for globally active Flixel objects,
// that receive update events regardless of the current state.
// TODO: Move scripted Module behavior to a Flixel plugin.
#if FEATURE_DEBUG_FUNCTIONS
funkin.util.plugins.MemoryGCPlugin.initialize();
#end
#if FEATURE_SCREENSHOTS
funkin.util.plugins.ScreenshotPlugin.initialize();
#end
#if FEATURE_NEWGROUNDS
funkin.util.plugins.NewgroundsMedalPlugin.initialize();
#end
funkin.util.plugins.EvacuateDebugPlugin.initialize();
funkin.util.plugins.ForceCrashPlugin.initialize();
funkin.util.plugins.ReloadAssetsDebugPlugin.initialize();
#if !mobile
funkin.util.plugins.VolumePlugin.initialize();
#end
funkin.util.plugins.WatchPlugin.initialize();
#if mobile
funkin.util.plugins.TouchPointerPlugin.initialize();
funkin.mobile.input.ControlsHandler.initInputTrackers();
#end
//
// ANDROID SETUP
//
#if android
FlxG.android.preventDefaultKeys = [flixel.input.android.FlxAndroidKey.BACK];
#end
//
// FLIXEL PLUGINS
//
// Plugins provide a useful interface for globally active Flixel objects,
// that receive update events regardless of the current state.
// TODO: Move scripted Module behavior to a Flixel plugin.
#if FEATURE_DEBUG_FUNCTIONS
funkin.util.plugins.MemoryGCPlugin.initialize();
#end
#if FEATURE_SCREENSHOTS
funkin.util.plugins.ScreenshotPlugin.initialize();
#end
#if FEATURE_NEWGROUNDS
funkin.util.plugins.NewgroundsMedalPlugin.initialize();
#end
funkin.util.plugins.EvacuateDebugPlugin.initialize();
funkin.util.plugins.ForceCrashPlugin.initialize();
funkin.util.plugins.ReloadAssetsDebugPlugin.initialize();
#if !mobile
funkin.util.plugins.VolumePlugin.initialize();
#end
funkin.util.plugins.WatchPlugin.initialize();
#if mobile
funkin.util.plugins.TouchPointerPlugin.initialize();
funkin.mobile.input.ControlsHandler.initInputTrackers();
#end
_coreInitialized = true;
}
//
// GAME DATA PARSING
@@ -279,6 +290,9 @@ class InitState extends FlxState
*/
function startGame():Void
{
// Don't play transition in when entering the title state.
FlxTransitionableState.skipNextTransIn = true;
#if SONG
// -DSONG=bopeebo
startSong(defineSong(), defineDifficulty());
@@ -386,7 +400,7 @@ class InitState extends FlxState
*/
function startSong(songId:String, difficultyId:String = 'normal'):Void
{
var songData:Null<funkin.play.song.Song> = funkin.data.song.SongRegistry.instance.fetchEntry(songId);
var songData:Null<funkin.play.song.Song> = funkin.data.song.SongRegistry.instance.fetchEntry(songId, {variation: Constants.DEFAULT_VARIATION});
if (songData == null)
{
@@ -458,7 +472,7 @@ class InitState extends FlxState
var targetSong:Null<funkin.play.song.Song> = null;
if (targetSongId != null) targetSong = SongRegistry.instance.fetchEntry(targetSongId);
if (targetSongId != null) targetSong = SongRegistry.instance.fetchEntry(targetSongId, {variation: Constants.DEFAULT_VARIATION});
if (targetSongId == null)
{
+72 -32
View File
@@ -7,6 +7,7 @@ import funkin.mobile.util.InAppPurchasesUtil;
import funkin.save.Save;
import funkin.util.WindowUtil;
import funkin.util.HapticUtil.HapticsMode;
import funkin.ui.debug.FunkinDebugDisplay.DebugDisplayMode;
/**
* A core class which provides a store of user-configurable, globally relevant values.
@@ -137,27 +138,70 @@ class Preferences
/**
* If enabled, an FPS and memory counter will be displayed even if this is not a debug build.
* Always disabled on mobile.
* @default `false`
* @default `Off`
*/
public static var debugDisplay(get, set):Bool;
public static var debugDisplay(get, set):DebugDisplayMode;
static function get_debugDisplay():Bool
static function get_debugDisplay():DebugDisplayMode
{
#if mobile
return false;
return DebugDisplayMode.OFF;
#end
return Save?.instance?.options?.debugDisplay ?? false;
var value = Save?.instance?.options?.debugDisplay ?? 'Off';
return switch (value)
{
case "Simple":
DebugDisplayMode.SIMPLE;
case "Advanced":
DebugDisplayMode.ADVANCED;
default:
DebugDisplayMode.OFF;
};
}
static function set_debugDisplay(value:Bool):Bool
static function set_debugDisplay(value:DebugDisplayMode):DebugDisplayMode
{
if (value != Save.instance.options.debugDisplay)
var string;
switch (value)
{
toggleDebugDisplay(value);
case DebugDisplayMode.SIMPLE:
string = "Simple";
case DebugDisplayMode.ADVANCED:
string = "Advanced";
default:
string = "Off";
};
if (string != Save.instance.options.debugDisplay)
{
setDebugDisplayMode(value);
}
var save = Save.instance;
save.options.debugDisplay = value;
save.options.debugDisplay = string;
save.flush();
return value;
}
/**
* Opacity of the debug display's background.
* @default `50`
*/
public static var debugDisplayBGOpacity(get, set):Int;
static function get_debugDisplayBGOpacity():Int
{
return Save?.instance?.options?.debugDisplayBGOpacity ?? 50;
}
static function set_debugDisplayBGOpacity(value:Int):Int
{
setDebugDisplayBGOpacity(value / 100);
var save:Save = Save.instance;
save.options.debugDisplayBGOpacity = value;
save.flush();
return value;
}
@@ -459,18 +503,15 @@ class Preferences
{
// Apply the autoPause setting (enables automatic pausing on focus lost).
FlxG.autoPause = Preferences.autoPause;
// WindowUtil.setVSyncMode(Preferences.vsyncMode);
// Apply the debugDisplay setting (enables the FPS and RAM display).
toggleDebugDisplay(Preferences.debugDisplay);
setDebugDisplayMode(Preferences.debugDisplay);
setDebugDisplayBGOpacity(Preferences.debugDisplayBGOpacity / 100);
#if web
toggleFramerateCap(Preferences.unlockedFramerate);
#end
#if desktop
// Apply the autoFullscreen setting (launches the game in fullscreen automatically)
FlxG.fullscreen = Preferences.autoFullscreen;
#end
#if mobile
// Apply the allowScreenTimeout setting.
lime.system.System.allowScreenTimeout = Preferences.screenTimeout;
@@ -485,26 +526,25 @@ class Preferences
#end
}
static function toggleDebugDisplay(show:Bool):Void
static function setDebugDisplayMode(mode:DebugDisplayMode):Void
{
if (show)
if (FlxG.game.parent.contains(Main.debugDisplay))
{
// Enable the debug display.
FlxG.game.parent.addChild(Main.fpsCounter);
#if !html5
FlxG.game.parent.addChild(Main.memoryCounter);
#end
FlxG.game.parent.removeChild(Main.debugDisplay);
}
else
{
// Disable the debug display.
FlxG.game.parent.removeChild(Main.fpsCounter);
#if !html5
FlxG.game.parent.removeChild(Main.memoryCounter);
#end
}
if (mode == DebugDisplayMode.OFF) return;
Main.debugDisplay.isAdvanced = (mode == DebugDisplayMode.ADVANCED);
FlxG.game.parent.addChild(Main.debugDisplay);
}
static function setDebugDisplayBGOpacity(value:Float):Void
{
if (Main.debugDisplay == null) return;
Main.debugDisplay.backgroundOpacity = value;
}
#if mobile
+21 -3
View File
@@ -8,10 +8,12 @@ import hxdiscord_rpc.Types.DiscordRichPresence;
import hxdiscord_rpc.Types.DiscordUser;
import sys.thread.Thread;
@:build(funkin.util.macro.EnvironmentMacro.build())
@:nullSafety
class DiscordClient
{
static final CLIENT_ID:String = "816168432860790794";
@:envField
static final DISCORD_CLIENT_ID:Null<String>;
public static var instance(get, never):DiscordClient;
static var _instance:Null<DiscordClient> = null;
@@ -40,12 +42,28 @@ class DiscordClient
{
trace('[DISCORD] Initializing connection...');
// Discord.initialize(CLIENT_ID, handlers, true, null);
Discord.Initialize(CLIENT_ID, cpp.RawPointer.addressOf(handlers), 1, "");
if (!hasValidCredentials())
{
FlxG.log.warn("Tried to initialize Discord connection, but credentials are invalid!");
return;
}
@:nullSafety(Off)
{
Discord.Initialize(DISCORD_CLIENT_ID, cpp.RawPointer.addressOf(handlers), 1, "");
}
createDaemon();
}
/**
* @returns `false` if the client ID is invalid.
*/
static function hasValidCredentials():Bool
{
return !(DISCORD_CLIENT_ID == null || DISCORD_CLIENT_ID == "" || (DISCORD_CLIENT_ID != null && DISCORD_CLIENT_ID.contains(" ")));
}
var daemon:Null<Thread> = null;
function createDaemon():Void
+2 -8
View File
@@ -37,10 +37,7 @@ class Leaderboards
if (NewgroundsClient.instance.isLoggedIn())
{
var leaderboardList = NewgroundsClient.instance.leaderboards;
if (leaderboardList == null) return;
var leaderboardData:Null<LeaderboardData> = leaderboardList.get(leaderboard.getId());
var leaderboardData:Null<LeaderboardData> = listLeaderboardData().get(leaderboard.getId());
if (leaderboardData != null)
{
leaderboardData.postScore(score, function(outcome:Outcome<CallError>):Void {
@@ -67,10 +64,7 @@ class Leaderboards
// Silently reject retrieving scores from unknown leaderboards.
if (leaderboard == Leaderboard.Unknown) return;
var leaderboardList = NewgroundsClient.instance.leaderboards;
if (leaderboardList == null) return;
var leaderboardData:Null<LeaderboardData> = leaderboardList.get(leaderboard.getId());
var leaderboardData:Null<LeaderboardData> = listLeaderboardData().get(leaderboard.getId());
if (leaderboardData == null) return;
var user:Null<User> = null;
+2 -10
View File
@@ -30,11 +30,7 @@ class Medals
{
if (NewgroundsClient.instance.isLoggedIn())
{
var medalList = NewgroundsClient.instance.medals;
@:privateAccess
if (medalList == null || medalList._map == null) return;
var medalData:Null<MedalData> = medalList.get(medal.getId());
var medalData:Null<MedalData> = listMedalData().get(medal.getId());
@:privateAccess
if (medalData == null || medalData._data == null)
{
@@ -120,11 +116,7 @@ class Medals
public static function fetchMedalData(medal:Medal):Null<FetchedMedalData>
{
var medalList = NewgroundsClient.instance.medals;
@:privateAccess
if (medalList == null || medalList._map == null) return null;
var medalData:Null<MedalData> = medalList.get(medal.getId());
var medalData:Null<MedalData> = listMedalData().get(medal.getId());
@:privateAccess
if (medalData == null || medalData._data == null)
{
+156
View File
@@ -0,0 +1,156 @@
package funkin.api.newgrounds;
#if FEATURE_NEWGROUNDS
import io.newgrounds.utils.SaveSlotList;
import io.newgrounds.objects.SaveSlot;
import io.newgrounds.Call.CallError;
import io.newgrounds.objects.events.Outcome;
import funkin.save.Save;
@:nullSafety
@:access(funkin.save.Save)
class NGSaveSlot
{
public static var instance(get, never):NGSaveSlot;
static var _instance:Null<NGSaveSlot> = null;
static function get_instance():NGSaveSlot
{
if (_instance == null)
{
return loadInstance();
}
return _instance;
}
public static function loadInstance():NGSaveSlot
{
var loadedSave:NGSaveSlot = loadSlot(Save.BASE_SAVE_SLOT);
if (_instance == null) _instance = loadedSave;
return loadedSave;
}
static function loadSlot(slot:Int):NGSaveSlot
{
trace('[NEWGROUNDS] Getting save slot from ID $slot');
var saveSlot:Null<SaveSlot> = NewgroundsClient.instance.saveSlots?.getById(slot);
var saveSlotObj:NGSaveSlot = new NGSaveSlot(saveSlot);
return saveSlotObj;
}
public var ngSaveSlot:Null<SaveSlot> = null;
public function new(?ngSaveSlot:Null<SaveSlot>)
{
this.ngSaveSlot = ngSaveSlot;
#if FLX_DEBUG
FlxG.console.registerClass(NGSaveSlot);
FlxG.console.registerClass(Save);
#end
}
/**
* Saves `data` to the newgrounds save slot.
* @param data The raw save data.
*/
public function save(data:RawSaveData):Void
{
var encodedData:String = haxe.Serializer.run(data);
try
{
ngSaveSlot?.save(encodedData, function(outcome:Outcome<CallError>) {
switch (outcome)
{
case SUCCESS:
trace('[NEWGROUNDS] Successfully saved save data to save slot!');
case FAIL(error):
trace('[NEWGROUNDS] Failed to save data to save slot!');
trace(error);
}
});
}
catch (error:String)
{
trace('[NEWGROUNDS] Failed to save data to save slot!');
trace(error);
}
}
public function load(?onComplete:Null<Dynamic->Void>, ?onError:Null<CallError->Void>):Void
{
try
{
ngSaveSlot?.load(function(outcome:SaveSlotOutcome):Void {
switch (outcome)
{
case SUCCESS(value):
trace('[NEWGROUNDS] Loaded save slot with the ID of ${ngSaveSlot?.id}!');
#if FEATURE_DEBUG_FUNCTIONS
trace('Save Slot Data:');
trace(value);
#end
if (onComplete != null && value != null)
{
var decodedData:Dynamic = haxe.Unserializer.run(value);
onComplete(decodedData);
}
case FAIL(error):
trace('[NEWGROUNDS] Failed to load save slot with the ID of ${ngSaveSlot?.id}!');
trace(error);
if (onError != null)
{
onError(error);
}
}
});
}
catch (error:String)
{
trace('[NEWGROUNDS] Failed to load save slot with the ID of ${ngSaveSlot?.id}!');
trace(error);
if (onError != null)
{
onError(RESPONSE({message: error, code: 500}));
}
}
}
public function clear():Void
{
try
{
ngSaveSlot?.clear(function(outcome:Outcome<CallError>) {
switch (outcome)
{
case SUCCESS:
trace('[NEWGROUNDS] Successfully cleared save slot!');
case FAIL(error):
trace('[NEWGROUNDS] Failed to clear save slot!');
trace(error);
}
});
}
catch (error:String)
{
trace('[NEWGROUNDS] Failed to clear save slot!');
trace(error);
}
}
public function checkSlot():Void
{
trace('[NEWGROUNDS] Checking save slot with the ID of ${ngSaveSlot?.id}...');
trace(' Is null? ${ngSaveSlot == null}');
trace(' Is empty? ${ngSaveSlot?.isEmpty() ?? false}');
}
}
#end
@@ -10,13 +10,22 @@ import io.newgrounds.NGLite.LoginOutcome;
import io.newgrounds.NGLite.LoginFail;
import io.newgrounds.objects.events.Outcome;
import io.newgrounds.utils.MedalList;
import io.newgrounds.utils.SaveSlotList;
import io.newgrounds.utils.ScoreBoardList;
import io.newgrounds.objects.User;
@:build(funkin.util.macro.EnvironmentMacro.build())
@:nullSafety
class NewgroundsClient
{
@:envField
static final API_NG_APP_ID:Null<String>;
@:envField
static final API_NG_ENC_KEY:Null<String>;
public static var instance(get, never):NewgroundsClient;
static var _instance:Null<NewgroundsClient> = null;
static function get_instance():NewgroundsClient
@@ -29,14 +38,15 @@ class NewgroundsClient
public var user(get, never):Null<User>;
public var medals(get, never):Null<MedalList>;
public var leaderboards(get, never):Null<ScoreBoardList>;
public var saveSlots(get, never):Null<SaveSlotList>;
private function new()
{
trace('[NEWGROUNDS] Initializing client...');
#if FEATURE_NEWGROUNDS_DEBUG
trace('[NEWGROUNDS] App ID: ${NewgroundsCredentials.APP_ID}');
trace('[NEWGROUNDS] Encryption Key: ${NewgroundsCredentials.ENCRYPTION_KEY}');
trace('[NEWGROUNDS] App ID: ${API_NG_APP_ID}');
trace('[NEWGROUNDS] Encryption Key: ${API_NG_ENC_KEY}');
#end
if (!hasValidCredentials())
@@ -45,9 +55,12 @@ class NewgroundsClient
return;
}
var debug = #if FEATURE_NEWGROUNDS_DEBUG true #else false #end;
NG.create(NewgroundsCredentials.APP_ID, getSessionId(), debug, onLoginResolved);
NG.core.setupEncryption(NewgroundsCredentials.ENCRYPTION_KEY);
@:nullSafety(Off)
{
NG.create(API_NG_APP_ID, getSessionId(), #if FEATURE_NEWGROUNDS_DEBUG true #else false #end, onLoginResolved);
NG.core.setupEncryption(API_NG_ENC_KEY);
}
}
public function init()
@@ -92,6 +105,12 @@ class NewgroundsClient
return;
}
if (NG.core.attemptingLogin)
{
trace("[NEWGROUNDS] Login attempt ongoing, will not login until finished.");
return;
}
if (onSuccess != null && onError != null)
{
NG.core.requestLogin(onLoginResolvedWithCallbacks.bind(_, onSuccess, onError));
@@ -166,12 +185,12 @@ class NewgroundsClient
*/
static function hasValidCredentials():Bool
{
return !(NewgroundsCredentials.APP_ID == null
|| NewgroundsCredentials.APP_ID == ""
|| NewgroundsCredentials.APP_ID.contains(" ")
|| NewgroundsCredentials.ENCRYPTION_KEY == null
|| NewgroundsCredentials.ENCRYPTION_KEY == ""
|| NewgroundsCredentials.ENCRYPTION_KEY.contains(" "));
return !(API_NG_APP_ID == null
|| API_NG_APP_ID == ""
|| (API_NG_APP_ID != null && API_NG_APP_ID.contains(" "))
|| API_NG_ENC_KEY == null
|| API_NG_ENC_KEY == ""
|| (API_NG_ENC_KEY != null && API_NG_ENC_KEY.contains(" ")));
}
function onLoginResolved(outcome:LoginOutcome):Void
@@ -236,6 +255,8 @@ class NewgroundsClient
trace('[NEWGROUNDS] Submitting leaderboard request...');
NG.core.scoreBoards.loadList(onFetchedLeaderboards);
trace('[NEWGROUNDS] Submitting save slot request...');
NG.core.saveSlots.loadList(onFetchedSaveSlots);
}
function onLoginFailed(result:LoginFail):Void
@@ -301,6 +322,13 @@ class NewgroundsClient
// trace(funkin.api.newgrounds.Leaderboards.listLeaderboardData());
}
function onFetchedSaveSlots(outcome:Outcome<CallError>):Void
{
trace('[NEWGROUNDS] Fetched save slots!');
NGSaveSlot.instance.checkSlot();
}
function get_user():Null<User>
{
if (NG.core == null || !this.isLoggedIn()) return null;
@@ -319,6 +347,12 @@ class NewgroundsClient
return NG.core.scoreBoards;
}
function get_saveSlots():Null<SaveSlotList>
{
if (NG.core == null || !this.isLoggedIn()) return null;
return NG.core.saveSlots;
}
static function getSessionId():Null<String>
{
#if js
+3 -3
View File
@@ -72,7 +72,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
override function set_volume(value:Float):Float
{
// Uncap the volume.
_volume = FlxMath.bound(value, 0.0, MAX_VOLUME);
_volume = value.clamp(0.0, MAX_VOLUME);
updateTransform();
return _volume;
}
@@ -568,8 +568,8 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
if (_sound == null) return;
// Create a channel manually if the sound is considered important.
var pan:Float = FlxMath.bound(SoundMixer.__soundTransform.pan + _transform.pan, -1, 1);
var volume:Float = FlxMath.bound(SoundMixer.__soundTransform.volume * _transform.volume, 0, MAX_VOLUME);
var pan:Float = (SoundMixer.__soundTransform.pan + _transform.pan).clamp(-1, 1);
var volume:Float = (SoundMixer.__soundTransform.volume * _transform.volume).clamp(0, MAX_VOLUME);
var audioSource:AudioSource = new AudioSource(_sound.__buffer);
audioSource.offset = Std.int(startTime);
+5 -4
View File
@@ -5,20 +5,21 @@ import funkin.util.VersionUtil;
import haxe.Constraints.Constructible;
/**
* The entry's constructor function must take a single argument, the entry's ID.
* The entry's constructor function takes 2 arguments, the entry ID and optional parameters.
*/
typedef EntryConstructorFunction = String->Void;
typedef EntryConstructorFunction = (String, ?Dynamic) -> Void;
/**
* A base type for a Registry, which is an object which handles loading scriptable objects.
*
* @param T The type to construct. Must implement `IRegistryEntry`.
* @param J The type of the JSON data used when constructing.
* @param P The type of the parameters used for `fetchEntry()`.
*/
@:nullSafety
@:generic
@:autoBuild(funkin.util.macro.DataRegistryMacro.buildRegistry())
abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructorFunction>), J>
abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructorFunction>), J, P>
{
/**
* The ID of the registry. Used when logging.
@@ -186,7 +187,7 @@ abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructo
* @param id The ID of the entry to fetch.
* @return The entry, or `null` if it does not exist.
*/
public function fetchEntry(id:String):Null<T>
public function fetchEntry(id:String, ?params:Null<P>):Null<T>
{
return entries.get(id);
}
+3 -3
View File
@@ -99,7 +99,7 @@ class DataParse
case JArray(values):
return Either.Left(legacyNoteSectionArray(json, name));
case JObject(fields):
return Either.Right(cast Tools.getValue(json));
return Either.Right(legacyNoteData(json, name));
default:
throw 'Expected property $name to be note data, but it was ${json.value}.';
}
@@ -121,7 +121,7 @@ class DataParse
}
}
public static function backdropData(json:Json, name:String):funkin.data.dialogue.conversation.ConversationData.BackdropData
public static function backdropData(json:Json, name:String):funkin.data.dialogue.ConversationData.BackdropData
{
switch (json.value)
{
@@ -152,7 +152,7 @@ class DataParse
}
}
public static function outroData(json:Json, name:String):Null<funkin.data.dialogue.conversation.ConversationData.OutroData>
public static function outroData(json:Json, name:String):Null<funkin.data.dialogue.ConversationData.OutroData>
{
switch (json.value)
{
@@ -1,4 +1,4 @@
package funkin.play.character;
package funkin.data.character;
import funkin.data.animation.AnimationData;
import funkin.modding.events.ScriptEvent;
@@ -8,6 +8,11 @@ import funkin.play.character.ScriptedCharacter.ScriptedBaseCharacter;
import funkin.play.character.ScriptedCharacter.ScriptedMultiSparrowCharacter;
import funkin.play.character.ScriptedCharacter.ScriptedPackerCharacter;
import funkin.play.character.ScriptedCharacter.ScriptedSparrowCharacter;
import funkin.play.character.AnimateAtlasCharacter;
import funkin.play.character.BaseCharacter;
import funkin.play.character.SparrowCharacter;
import funkin.play.character.MultiSparrowCharacter;
import funkin.play.character.PackerCharacter;
import funkin.util.assets.DataAssets;
import funkin.util.VersionUtil;
import haxe.Json;
@@ -288,35 +293,23 @@ class CharacterDataParser
{
var charPath:String = "freeplay/icons/";
// FunkinCrew please dont skin me alive for copying pixelated icon and changing it a tiny bit
switch (char)
final charIDParts:Array<String> = char.split("-");
var iconName:String = "";
var lastValidIconName:String = "";
for (i in 0...charIDParts.length)
{
case "bf-christmas" | "bf-car" | "bf-pixel" | "bf-holding-gf" | "bf-dark":
charPath += "bfpixel";
case "monster-christmas":
charPath += "monsterpixel";
case "mom" | "mom-car":
charPath += "mommypixel";
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";
case "dad":
charPath += "dadpixel";
case "darnell-blazin":
charPath += "darnellpixel";
case "senpai-angry":
charPath += "senpaipixel";
case "spooky-dark":
charPath += "spookypixel";
case "tankman-atlas" | "tankman-bloody":
charPath += "tankmanpixel";
case "pico-christmas" | "pico-dark":
charPath += "picopixel";
default:
charPath += '${char}pixel';
iconName += charIDParts[i];
if (Assets.exists(Paths.image(charPath + '${iconName}pixel')))
{
lastValidIconName = iconName;
}
if (i < charIDParts.length - 1) iconName += '-';
}
charPath += '${lastValidIconName}pixel';
if (!Assets.exists(Paths.image(charPath)))
{
trace('[WARN] Character ${char} has no freeplay icon.');
+39
View File
@@ -0,0 +1,39 @@
# Dialogue Conversation Data Schema Changelog
All notable changes to this project 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).
## [1.0.0]
Initial release.
# Dialogue Box Data Schema Changelog
All notable changes to this project 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).
## [1.1.0]
### Added
- Added an option to specify the font used by the dialogue box. Defaults to `Arial` if unspecified.
## [1.0.0]
Initial release.
# Dialogue Speaker Data Schema Changelog
All notable changes to this project 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).
## [1.0.0]
Initial release.
@@ -1,4 +1,4 @@
package funkin.data.dialogue.conversation;
package funkin.data.dialogue;
/**
* A type definition for the data for a specific conversation.
@@ -1,4 +1,4 @@
package funkin.data.dialogue.conversation;
package funkin.data.dialogue;
import funkin.play.cutscene.dialogue.Conversation;
import funkin.play.cutscene.dialogue.ScriptedConversation;
@@ -6,7 +6,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class ConversationRegistry extends BaseRegistry<Conversation, ConversationData> implements ISingleton implements DefaultRegistryImpl
class ConversationRegistry extends BaseRegistry<Conversation, ConversationData, ConversationEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the dialogue box data format.
@@ -22,3 +22,8 @@ class ConversationRegistry extends BaseRegistry<Conversation, ConversationData>
super('CONVERSATION', 'dialogue/conversations', CONVERSATION_DATA_VERSION_RULE);
}
}
typedef ConversationEntryParams =
{
var placeholder:String;
}
@@ -1,4 +1,4 @@
package funkin.data.dialogue.dialoguebox;
package funkin.data.dialogue;
import funkin.data.animation.AnimationData;
@@ -1,13 +1,13 @@
package funkin.data.dialogue.dialoguebox;
package funkin.data.dialogue;
import funkin.play.cutscene.dialogue.DialogueBox;
import funkin.data.dialogue.dialoguebox.DialogueBoxData;
import funkin.data.dialogue.DialogueBoxData;
import funkin.play.cutscene.dialogue.ScriptedDialogueBox;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class DialogueBoxRegistry extends BaseRegistry<DialogueBox, DialogueBoxData> implements ISingleton implements DefaultRegistryImpl
class DialogueBoxRegistry extends BaseRegistry<DialogueBox, DialogueBoxData, DialogueBoxEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the dialogue box data format.
@@ -23,3 +23,5 @@ class DialogueBoxRegistry extends BaseRegistry<DialogueBox, DialogueBoxData> imp
super('DIALOGUEBOX', 'dialogue/boxes', DIALOGUEBOX_DATA_VERSION_RULE);
}
}
typedef DialogueBoxEntryParams = Dynamic;
@@ -1,4 +1,4 @@
package funkin.data.dialogue.speaker;
package funkin.data.dialogue;
import funkin.data.animation.AnimationData;
@@ -1,4 +1,4 @@
package funkin.data.dialogue.speaker;
package funkin.data.dialogue;
import funkin.play.cutscene.dialogue.Speaker;
import funkin.play.cutscene.dialogue.ScriptedSpeaker;
@@ -6,7 +6,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class SpeakerRegistry extends BaseRegistry<Speaker, SpeakerData> implements ISingleton implements DefaultRegistryImpl
class SpeakerRegistry extends BaseRegistry<Speaker, SpeakerData, SpeakerEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the speaker data format.
@@ -22,3 +22,5 @@ class SpeakerRegistry extends BaseRegistry<Speaker, SpeakerData> implements ISin
super('SPEAKER', 'dialogue/speakers', SPEAKER_DATA_VERSION_RULE);
}
}
typedef SpeakerEntryParams = {}
@@ -1,9 +0,0 @@
# Dialogue Conversation Data Schema Changelog
All notable changes to this project 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).
## [1.0.0]
Initial release.
@@ -1,13 +0,0 @@
# Dialogue Box Data Schema Changelog
All notable changes to this project 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).
## [1.1.0]
### Added
- Added an option to specify the font used by the dialogue box. Defaults to `Arial` if unspecified.
## [1.0.0]
Initial release.
@@ -1,9 +0,0 @@
# Dialogue Speaker Data Schema Changelog
All notable changes to this project 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).
## [1.0.0]
Initial release.
@@ -7,7 +7,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class AlbumRegistry extends BaseRegistry<Album, AlbumData> implements ISingleton implements DefaultRegistryImpl
class AlbumRegistry extends BaseRegistry<Album, AlbumData, AlbumEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the album data format.
@@ -23,3 +23,5 @@ class AlbumRegistry extends BaseRegistry<Album, AlbumData> implements ISingleton
super('ALBUM', 'ui/freeplay/albums', ALBUM_DATA_VERSION_RULE);
}
}
typedef AlbumEntryParams = {}
@@ -8,7 +8,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> implements ISingleton implements DefaultRegistryImpl
class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData, PlayerEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the stage data format.
@@ -147,3 +147,5 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
#end
}
}
typedef PlayerEntryParams = {}
@@ -7,7 +7,8 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class FreeplayStyleRegistry extends BaseRegistry<FreeplayStyle, FreeplayStyleData> implements ISingleton implements DefaultRegistryImpl
class FreeplayStyleRegistry extends BaseRegistry<FreeplayStyle, FreeplayStyleData, FreeplayStyleEntryParams> implements ISingleton
implements DefaultRegistryImpl
{
/**
* The current version string for the style data format.
@@ -23,3 +24,5 @@ class FreeplayStyleRegistry extends BaseRegistry<FreeplayStyle, FreeplayStyleDat
super('FREEPLAYSTYLE', 'ui/freeplay/styles', FREEPLAYSTYLE_DATA_VERSION_RULE);
}
}
typedef FreeplayStyleEntryParams = {}
@@ -165,7 +165,7 @@ typedef NoteStyleAssetData<T> =
var assetPath:String;
/**
* The scale to render the prop at.
* The scale to render the note at.
* @default 1.0
*/
@:default(1.0)
@@ -181,7 +181,7 @@ typedef NoteStyleAssetData<T> =
var offsets:Null<Array<Float>>;
/**
* If true, the prop is a pixel sprite, and will be rendered without anti-aliasing.
* If true, the note is a pixel sprite, and will be rendered without anti-aliasing.
*/
@:default(false)
@:optional
@@ -7,7 +7,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData> implements ISingleton implements DefaultRegistryImpl
class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData, NoteStyleEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the note style data format.
@@ -30,3 +30,5 @@ class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData> implement
return notestyle;
}
}
typedef NoteStyleEntryParams = {}
+17
View File
@@ -1117,6 +1117,23 @@ class SongNoteDataRaw implements ICloneable<SongNoteDataRaw>
return 'SongNoteData(${this.time}ms, ' + (this.length > 0 ? '[${this.length}ms hold]' : '') + ' ${this.data}'
+ (this.kind != '' ? ' [kind: ${this.kind}])' : ')');
}
public function buildTooltip():String
{
if ((this.kind?.length ?? 0) == 0) return "";
var result:String = 'Kind: ${this.kind}';
if (this.params.length == 0) return result;
result += "\nParams:";
for (param in params)
{
result += '\n- ${param.name}: ${param.value}';
}
return result;
}
}
/**
+47 -7
View File
@@ -15,8 +15,7 @@ import funkin.data.DefaultRegistryImpl;
using funkin.data.song.migrator.SongDataMigrator;
@:nullSafety
class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleton implements DefaultRegistryImpl
@:nullSafety class SongRegistry extends BaseRegistry<Song, SongMetadata, SongEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the stage data format.
@@ -37,6 +36,8 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
public static var DEFAULT_GENERATEDBY(get, never):String;
public var scriptedSongVariations:Map<String, Song> = new Map<String, Song>();
static function get_DEFAULT_GENERATEDBY():String
{
return '${Constants.TITLE} - ${Constants.VERSION}';
@@ -63,9 +64,17 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
if (entry != null)
{
log('Successfully created scripted entry (${entryCls} = ${entry.id})');
entries.set(entry.id, entry);
scriptedEntryIds.set(entry.id, entryCls);
if (entry.variation != null)
{
scriptedSongVariations.set('${entry.id}:${entry.variation}', entry);
log('Successfully created scripted entry (${entryCls} = ${entry.id}, ${entry.variation})');
}
else
{
entries.set(entry.id, entry);
scriptedEntryIds.set(entry.id, entryCls);
log('Successfully created scripted entry (${entryCls} = ${entry.id})');
}
}
else
{
@@ -120,6 +129,28 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
return parseEntryMetadataRaw(contents);
}
/**
* We override `fetchEntry` to handle song variations!
*/
public override function fetchEntry(id:String, ?params:SongEntryParams):Null<Song>
{
var variation:String = params?.variation ?? Constants.DEFAULT_VARIATION;
if (variation != Constants.DEFAULT_VARIATION)
{
if (scriptedSongVariations.exists('${id}:${variation}'))
{
var variationSongScript:Null<Song> = scriptedSongVariations.get('${id}:${variation}');
if (variationSongScript != null)
{
return variationSongScript;
}
}
}
return super.fetchEntry(id, params);
}
public function parseEntryMetadata(id:String, ?variation:String):Null<SongMetadata>
{
variation = variation == null ? Constants.DEFAULT_VARIATION : variation;
@@ -395,12 +426,13 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
}
}
public function parseEntryChartDataRawWithMigration(contents:String, ?fileName:String = 'raw', version:thx.semver.Version):Null<SongChartData>
public function parseEntryChartDataRawWithMigration(contents:String, ?fileName:String = 'raw', version:thx.semver.Version,
?variation:String):Null<SongChartData>
{
// If a version rule is not specified, do not check against it.
if (SONG_CHART_DATA_VERSION_RULE == null || VersionUtil.validateVersion(version, SONG_CHART_DATA_VERSION_RULE))
{
return parseEntryChartDataRaw(contents, fileName);
return parseEntryChartDataRaw(contents, fileName, variation);
}
else
{
@@ -517,3 +549,11 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
return allDifficulties;
}
}
typedef SongEntryParams =
{
/**
* The variation ID for the song.
*/
var variation:String;
}
@@ -10,6 +10,8 @@ class ChartManifestData
*/
public static final CHART_MANIFEST_DATA_VERSION:thx.semver.Version = "1.0.0";
public static final invalidIdRegex:EReg = ~/[\/\\:*?"<>|]/g;
@:default(funkin.data.song.importer.ChartManifestData.CHART_MANIFEST_DATA_VERSION)
@:jcustomparse(funkin.data.DataParse.semverVersion)
@:jcustomwrite(funkin.data.DataWrite.semverVersion)
@@ -19,7 +21,11 @@ class ChartManifestData
* The internal song ID for this chart.
* The metadata and chart data file names are derived from this.
*/
public var songId:String;
public var songId(default, set):String;
public function set_songId(value:String):String
{
return songId = invalidIdRegex.replace(value.trim(), '');
}
public function new(songId:String)
{
@@ -120,6 +120,11 @@ class LegacyNote
public inline function getKind():String
{
return this.alt ? 'alt' : 'normal';
return this.alt ? 'alt' : '';
}
public function toString():String
{
return 'LegacyNote(${this.time}, ${this.data}, ${this.length}, ${this.alt})';
}
}
@@ -37,7 +37,7 @@ class FNFLegacyImporter
{
trace('Migrating song metadata from FNF Legacy.');
var songMetadata:SongMetadata = new SongMetadata('Import', Constants.DEFAULT_ARTIST, 'default');
var songMetadata:SongMetadata = new SongMetadata('Import', Constants.DEFAULT_ARTIST, Constants.DEFAULT_CHARTER, Constants.DEFAULT_VARIATION);
// Set generatedBy string for debugging.
songMetadata.generatedBy = 'Chart Editor Import (FNF Legacy)';
@@ -95,8 +95,8 @@ class FNFLegacyImporter
switch (songData.song.speed)
{
case Left(speed):
// All difficulties will use the one scroll speed.
songChartData.scrollSpeed.set('default', speed);
// Sets the scroll speed for the difficulty.
songChartData.scrollSpeed.set(difficulty, speed);
case Right(speeds):
if (speeds.easy != null) songChartData.scrollSpeed.set('easy', speeds.easy);
if (speeds.normal != null) songChartData.scrollSpeed.set('normal', speeds.normal);
@@ -24,7 +24,7 @@ class SongDataMigrator
public static function migrate_SongMetadata_v2_1_0(input:SongData_v2_1_0.SongMetadata_v2_1_0):SongMetadata
{
var result:SongMetadata = new SongMetadata(input.songName, input.artist, input.variation);
var result:SongMetadata = new SongMetadata(input.songName, input.artist, Constants.DEFAULT_CHARTER, input.variation);
result.version = SongRegistry.SONG_METADATA_VERSION;
result.timeFormat = input.timeFormat;
result.divisions = input.divisions;
@@ -66,7 +66,7 @@ class SongDataMigrator
public static function migrate_SongMetadata_v2_0_0(input:SongData_v2_0_0.SongMetadata_v2_0_0):SongMetadata
{
var result:SongMetadata = new SongMetadata(input.songName, input.artist, input.variation);
var result:SongMetadata = new SongMetadata(input.songName, input.artist, Constants.DEFAULT_CHARTER, input.variation);
result.version = SongRegistry.SONG_METADATA_VERSION;
result.timeFormat = input.timeFormat;
result.divisions = input.divisions;
+3 -1
View File
@@ -6,7 +6,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class StageRegistry extends BaseRegistry<Stage, StageData> implements ISingleton implements DefaultRegistryImpl
class StageRegistry extends BaseRegistry<Stage, StageData, StageEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the stage data format.
@@ -22,3 +22,5 @@ class StageRegistry extends BaseRegistry<Stage, StageData> implements ISingleton
super('STAGE', 'stages', STAGE_DATA_VERSION_RULE);
}
}
typedef StageEntryParams = {}
@@ -5,7 +5,7 @@ import funkin.ui.transition.stickers.StickerPack;
import funkin.ui.transition.stickers.ScriptedStickerPack;
@:nullSafety
class StickerRegistry extends BaseRegistry<StickerPack, StickerData>
class StickerRegistry extends BaseRegistry<StickerPack, StickerData, StickerEntryParams>
{
/**
* The current version string for the sticker pack data format.
@@ -90,3 +90,5 @@ class StickerRegistry extends BaseRegistry<StickerPack, StickerData>
return ScriptedStickerPack.listScriptClasses();
}
}
typedef StickerEntryParams = {}
@@ -7,7 +7,7 @@ import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class LevelRegistry extends BaseRegistry<Level, LevelData> implements ISingleton implements DefaultRegistryImpl
class LevelRegistry extends BaseRegistry<Level, LevelData, LevelEntryParams> implements ISingleton implements DefaultRegistryImpl
{
/**
* The current version string for the level data format.
@@ -56,3 +56,5 @@ class LevelRegistry extends BaseRegistry<Level, LevelData> implements ISingleton
return result;
}
}
typedef LevelEntryParams = {}
@@ -1,5 +1,6 @@
package funkin.mobile.external.android;
package funkin.external.android;
#if android
import lime.system.JNI;
import flixel.util.FlxSignal;
@@ -9,7 +10,6 @@ import flixel.util.FlxSignal;
@:unreflective
class CallbackUtil
{
#if android
/**
* The result code for `DATA_FOLDER_CLOSED` activity.
*/
@@ -42,7 +42,6 @@ class CallbackUtil
initCallBackJNI(new CallbackHandler());
}
}
#end
}
/**
@@ -50,8 +49,7 @@ class CallbackUtil
*/
class CallbackHandler #if (lime >= "8.0.0") implements JNISafety #end
{
#if android
@:allow(funkin.mobile.external.android.CallbackUtil)
@:allow(funkin.external.android.CallbackUtil)
function new():Void {}
/**
@@ -68,5 +66,5 @@ class CallbackHandler #if (lime >= "8.0.0") implements JNISafety #end
{
if (CallbackUtil.onActivityResult != null) CallbackUtil.onActivityResult.dispatch(requestCode, resultCode);
}
#end
}
#end
@@ -1,12 +1,12 @@
package funkin.mobile.external.android;
package funkin.external.android;
#if android
/**
* A Utility class to manage the Application's Data folder on Android.
*/
@:unreflective
class DataFolderUtil
{
#if android
/**
* Opens the data folder on an Android device using JNI.
*/
@@ -19,5 +19,5 @@ class DataFolderUtil
openDataFolderJNI(CallbackUtil.DATA_FOLDER_CLOSED);
}
}
#end
}
#end
@@ -1,4 +1,4 @@
package funkin.mobile.external.android;
package funkin.external.android;
#if android
import lime.system.JNI;
@@ -1,5 +1,6 @@
package funkin.mobile.external.android;
package funkin.external.android;
#if android
import lime.math.Rectangle;
import lime.system.JNI;
@@ -9,7 +10,6 @@ import lime.system.JNI;
@:unreflective
class ScreenUtil
{
#if android
/**
* Retrieves the dimensions of display cutouts (such as notches) on Android devices.
*
@@ -48,5 +48,5 @@ class ScreenUtil
return [];
}
#end
}
#end
+31
View File
@@ -0,0 +1,31 @@
package funkin.external.apple;
#if ((ios || macos) && cpp)
/**
* A utility class to manage the audio session on apple devices.
*/
@:build(funkin.util.macro.LinkerMacro.xml('project/Build.xml'))
@:include('AudioSession.hpp')
@:unreflective
extern class AudioSession
{
/**
* Initializes the audio session for playback.
*
* This function configures the shared AVAudioSession instance with the following settings:
* - Sets the audio session category to Playback, allowing Bluetooth A2DP and mixing with spoken audio interruptions.
* - For iOS 17.0 and above, disables interruption on route disconnect.
* - For iOS 14.5 and above, prefers no interruptions from system alerts.
*/
@:native('Apple_AudioSession_Initialize')
static function initialize():Void;
/**
* Sets the active state of the shared AVAudioSession.
*
* @param active Whether to activate or deactivate the audio session.
*/
@:native('Apple_AudioSession_SetActive')
static function setActive(active:Bool):Void;
}
#end
+20
View File
@@ -0,0 +1,20 @@
package funkin.external.apple;
#if ((ios || macos) && cpp)
/**
* A utility class to get information about the mem usage.
*/
@:build(funkin.util.macro.LinkerMacro.xml('project/Build.xml'))
@:include('MemoryUtil.hpp')
@:unreflective
extern class MemoryUtil
{
/**
* Retrieves the current process's resident set size (RSS) in bytes on Apple platforms.
*
* @return The resident set size (RSS) in bytes if successful; otherwise, returns 0 on failure.
*/
@:native('Apple_MemoryUtil_GetCurrentProcessRss')
static function getCurrentProcessRss():cpp.SizeT;
}
#end
+36
View File
@@ -0,0 +1,36 @@
package funkin.external.apple;
#if ((ios || macos) && cpp)
/**
* A utility class to get screen related informations on apple devices.
*/
@:build(funkin.util.macro.LinkerMacro.xml('project/Build.xml'))
@:include('ScreenUtil.hpp')
@:unreflective
extern class ScreenUtil
{
/**
* Retrieves the safe area insets for the current screen on iOS devices.
*
* This function populates the provided pointers with the safe area insets (in pixels) for the top, bottom, left, and right edges of the screen.
* On iOS 11 and later, it uses the main window's safeAreaInsets and converts them to pixel values using the screen scale.
* On earlier iOS versions, all insets are set to 0.0.
*
* @param top Pointer to a double to receive the top safe area inset (in pixels).
* @param bottom Pointer to a double to receive the bottom safe area inset (in pixels).
* @param left Pointer to a double to receive the left safe area inset (in pixels).
* @param right Pointer to a double to receive the right safe area inset (in pixels).
*/
@:native('Apple_ScreenUtil_GetSafeAreaInsets')
static function getSafeAreaInsets(top:cpp.RawPointer<Float>, bottom:cpp.RawPointer<Float>, left:cpp.RawPointer<Float>, right:cpp.RawPointer<Float>):Void;
/**
* Retrieves the size of the main screen in pixels.
*
* @param width Pointer to a double where the screen width (in pixels) will be stored.
* @param height Pointer to a double where the screen height (in pixels) will be stored.
*/
@:native('Apple_ScreenUtil_GetScreenSize')
static function getScreenSize(width:cpp.RawPointer<Float>, height:cpp.RawPointer<Float>):Void;
}
#end
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<pragma once="true" />
<files id="haxe">
<compilerflag value="-I${this_dir}/include" />
</files>
<files id="__main__">
<compilerflag value="-I${this_dir}/include" />
</files>
<files id="external-apple">
<compilerflag value="-I${this_dir}/include" />
<file name="${this_dir}/src/AudioSession.mm" />
<file name="${this_dir}/src/MemoryUtil.mm" />
<file name="${this_dir}/src/ScreenUtil.mm" />
</files>
<target id="haxe">
<vflag name="-framework" value="UIKit" unless="macos" />
<vflag name="-framework" value="Foundation" />
<vflag name="-framework" value="AVFAudio" />
<files id="external-apple" />
</target>
</xml>
@@ -0,0 +1,18 @@
#pragma once
/**
* Initializes the audio session for playback.
*
* This function configures the shared AVAudioSession instance with the following settings:
* - Sets the audio session category to Playback, allowing Bluetooth A2DP and mixing with spoken audio interruptions.
* - For iOS 17.0 and above, disables interruption on route disconnect.
* - For iOS 14.5 and above, prefers no interruptions from system alerts.
*/
void Apple_AudioSession_Initialize();
/**
* Sets the active state of the shared AVAudioSession.
*
* @param active Whether to activate or deactivate the audio session.
*/
void Apple_AudioSession_SetActive(bool active);
@@ -0,0 +1,10 @@
#pragma once
#include <cstddef>
/**
* Retrieves the current process's resident set size (RSS) in bytes on Apple platforms.
*
* @return The resident set size (RSS) in bytes if successful; otherwise, returns 0 on failure.
*/
size_t Apple_MemoryUtil_GetCurrentProcessRss();
@@ -0,0 +1,23 @@
#pragma once
/**
* Retrieves the safe area insets for the current screen on iOS devices.
*
* This function populates the provided pointers with the safe area insets (in pixels) for the top, bottom, left, and right edges of the screen.
* On iOS 11 and later, it uses the main window's safeAreaInsets and converts them to pixel values using the screen scale.
* On earlier iOS versions, all insets are set to 0.0.
*
* @param top Pointer to a double to receive the top safe area inset (in pixels).
* @param bottom Pointer to a double to receive the bottom safe area inset (in pixels).
* @param left Pointer to a double to receive the left safe area inset (in pixels).
* @param right Pointer to a double to receive the right safe area inset (in pixels).
*/
void Apple_ScreenUtil_GetSafeAreaInsets(double* top, double* bottom, double* left, double* right);
/**
* Retrieves the size of the main screen in pixels.
*
* @param width Pointer to a double where the screen width (in pixels) will be stored.
* @param height Pointer to a double where the screen height (in pixels) will be stored.
*/
void Apple_ScreenUtil_GetScreenSize(double* width, double* height);
@@ -0,0 +1,43 @@
#import "AudioSession.hpp"
#import <TargetConditionals.h>
#import <Foundation/Foundation.h>
#import <AVFAudio/AVFAudio.h>
void Apple_AudioSession_Initialize()
{
#if TARGET_OS_IOS
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionAllowBluetoothA2DP | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:&error];
if (@available(iOS 17.0, *))
{
[session setPrefersInterruptionOnRouteDisconnect:false error:nil];
}
if (@available(iOS 14.5, *))
{
[session setPrefersNoInterruptionsFromSystemAlerts:true error:nil];
}
if (error)
NSLog(@"Unable to set category of audio session: %@", error);
#endif
}
void Apple_AudioSession_SetActive(bool active)
{
#if TARGET_OS_IOS
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setActive:active error:&error];
if (error)
NSLog(@"Unable to set active of audio session: %@", error);
#endif
}
+15
View File
@@ -0,0 +1,15 @@
#import "MemoryUtil.hpp"
#include <mach/mach.h>
size_t Apple_MemoryUtil_GetCurrentProcessRss()
{
struct task_basic_info info;
mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &count) != KERN_SUCCESS)
return 0;
return info.resident_size;
}
+45
View File
@@ -0,0 +1,45 @@
#import "ScreenUtil.hpp"
#import <TargetConditionals.h>
#if TARGET_OS_IOS
#import <UIKit/UIKit.h>
#endif
#import <Foundation/Foundation.h>
void Apple_ScreenUtil_GetSafeAreaInsets(double* top, double* bottom, double* left, double* right)
{
#if TARGET_OS_IOS
if (@available(iOS 11, *))
{
UIWindow* window = [UIApplication sharedApplication].windows[0];
UIEdgeInsets safeAreaInsets = window.safeAreaInsets;
float scale = [UIScreen mainScreen].scale;
(*top) = safeAreaInsets.top * scale;
(*bottom) = safeAreaInsets.bottom * scale;
(*left) = safeAreaInsets.left * scale;
(*right) = safeAreaInsets.right * scale;
return;
}
#endif
(*top) = 0.0;
(*bottom) = 0.0;
(*left) = 0.0;
(*right) = 0.0;
}
void Apple_ScreenUtil_GetScreenSize(double* width, double* height)
{
#if TARGET_OS_IOS
CGRect screenRect = [[UIScreen mainScreen] bounds];
float scale = [UIScreen mainScreen].scale;
(*width) = (double)screenRect.size.width * scale;
(*height) = (double)screenRect.size.height * scale;
#else
(*width) = 0.0;
(*width) = 0.0;
#endif
}
+83
View File
@@ -0,0 +1,83 @@
package funkin.external.windows;
#if (windows && cpp)
/**
* This class provides handling for Windows API-related functions.
*/
@:build(funkin.util.macro.LinkerMacro.xml('project/Build.xml'))
@:include('winapi.hpp')
extern class WinAPI
{
/**
* Shows a message box with an error icon.
*
* @param message The message to display.
* @param title The title of the message box.
*/
@:native('WINAPI_ShowError')
static function showError(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
/**
* Shows a message box with a warning icon.
*
* @param message The message to display.
* @param title The title of the message box.
*/
@:native('WINAPI_ShowWarning')
static function showWarning(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
/**
* Shows a message box with an information icon.
*
* @param message The message to display.
* @param title The title of the message box.
*/
@:native('WINAPI_ShowInformation')
static function showInformation(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
/**
* Shows a message box with a question icon.
*
* @param message The message to display.
* @param title The title of the message box.
*/
@:native('WINAPI_ShowQuestion')
static function showQuestion(message:cpp.ConstCharStar, title:cpp.ConstCharStar):Void;
/**
* Disables the "Report to Microsoft" dialog that appears when the application crashes.
*/
@:native('WINAPI_DisableErrorReporting')
static function disableErrorReporting():Void;
/**
* Disables Windows ghosting, which prevents the system from marking unresponsive windows as "Not Responding."
*/
@:native('WINAPI_DisableWindowsGhosting')
static function disableWindowsGhosting():Void;
/**
* Retrieves the current working set size (in bytes) of the process.
*
* @return The size of the working set memory used by the process.
*/
@:native('WINAPI_GetProcessMemoryWorkingSetSize')
static function getProcessMemoryWorkingSetSize():cpp.SizeT;
/**
* Sets the dark mode for the active window.
*
* @param enable Whether to enable or disable dark mode.
*/
@:native('WINAPI_SetDarkMode')
static function setDarkMode(enable:Bool):Void;
/**
* Checks if the system is using dark mode.
*
* @return True if system is in dark mode, false otherwise.
*/
@:native('WINAPI_IsSystemDarkMode')
static function isSystemDarkMode():Bool;
}
#end
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<pragma once="true" />
<files id="haxe">
<compilerflag value="-I${this_dir}/include" />
</files>
<files id="__main__">
<compilerflag value="-I${this_dir}/include" />
</files>
<files id="external-windows">
<compilerflag value="-I${this_dir}/include" />
<file name="${this_dir}/src/winapi.cpp" />
</files>
<target id="haxe">
<section if="mingw">
<lib name="-luser32" />
<lib name="-lkernel32" />
<lib name="-ldwmapi" />
<lib name="-ladvapi32" />
</section>
<section unless="mingw">
<lib name="user32.lib" />
<lib name="kernel32.lib" />
<lib name="dwmapi.lib" />
<lib name="advapi32.lib" />
</section>
<files id="external-windows" />
</target>
</xml>
@@ -0,0 +1,66 @@
#pragma once
/**
* Shows an error message box.
*
* @param message The error message to display
* @param title The title of the message box
*/
void WINAPI_ShowError(const char *message, const char *title);
/**
* Shows a warning message box.
*
* @param message The warning message to display
* @param title The title of the message box
*/
void WINAPI_ShowWarning(const char *message, const char *title);
/**
* Shows an information message box.
*
* @param message The information message to display
* @param title The title of the message box
*/
void WINAPI_ShowInformation(const char *message, const char *title);
/**
* Shows a question message box with OK/Cancel buttons.
*
* @param message The question message to display
* @param title The title of the message box
*/
void WINAPI_ShowQuestion(const char *message, const char *title);
/**
* Disables Windows error reporting dialogs.
*/
void WINAPI_DisableErrorReporting();
/**
* Disables Windows ghosting for the current process.
*/
void WINAPI_DisableWindowsGhosting();
/**
* Retrieves the current working set size (in bytes) of the calling process.
*
* This function queries the operating system for the amount of physical memory currently allocated to the process (its working set).
*
* @return The working set size in bytes. Returns 0 if the query fails.
*/
size_t WINAPI_GetProcessMemoryWorkingSetSize();
/**
* Sets dark mode for the active window.
*
* @param enable True to enable dark mode, false to disable
*/
void WINAPI_SetDarkMode(bool enable);
/**
* Checks if the system is using dark mode.
*
* @return True if system is in dark mode, false otherwise
*/
bool WINAPI_IsSystemDarkMode();
+85
View File
@@ -0,0 +1,85 @@
#define WIN32_LEAN_AND_MEAN // Excludes rarely-used APIs like cryptography, DDE, RPC, and shell functions, reducing compile time and binary size.
#define NOMINMAX // Prevents Windows from defining min() and max() macros, which can conflict with standard C++ functions.
#define NOCRYPT // Excludes Cryptographic APIs, such as Encrypt/Decrypt functions.
#define NOCOMM // Excludes serial communication APIs, such as COM port handling.
#define NOKANJI // Excludes Kanji character set support (not needed unless working with Japanese text processing).
#define NOHELP // Excludes Windows Help APIs, removing functions related to WinHelp and other help systems.
#include <windows.h>
#include <psapi.h>
#include <dwmapi.h>
#include <stdint.h>
#include <stdio.h>
void WINAPI_ShowError(const char *message, const char *title)
{
MessageBox(GetActiveWindow(), message, title, MB_OK | MB_ICONERROR);
}
void WINAPI_ShowWarning(const char *message, const char *title)
{
MessageBox(GetActiveWindow(), message, title, MB_OK | MB_ICONWARNING);
}
void WINAPI_ShowInformation(const char *message, const char *title)
{
MessageBox(GetActiveWindow(), message, title, MB_OK | MB_ICONINFORMATION);
}
void WINAPI_ShowQuestion(const char *message, const char *title)
{
MessageBox(GetActiveWindow(), message, title, MB_OKCANCEL | MB_ICONQUESTION);
}
void WINAPI_DisableErrorReporting()
{
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
}
void WINAPI_DisableWindowsGhosting()
{
DisableProcessWindowsGhosting();
}
size_t WINAPI_GetProcessMemoryWorkingSetSize()
{
PROCESS_MEMORY_COUNTERS_EX pmc;
if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
return pmc.WorkingSetSize;
return 0;
}
void WINAPI_SetDarkMode(bool enable)
{
HWND window = GetActiveWindow();
int darkMode = enable ? 1 : 0;
if (DwmSetWindowAttribute(window, 20, &darkMode, sizeof(darkMode)) != S_OK)
DwmSetWindowAttribute(window, 19, &darkMode, sizeof(darkMode));
UpdateWindow(window);
}
bool WINAPI_IsSystemDarkMode()
{
HKEY hKey;
DWORD dwValue = 0;
DWORD dwSize = sizeof(DWORD);
DWORD dwType = REG_DWORD;
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
if (RegQueryValueEx(hKey, "AppsUseLightTheme", NULL, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return dwValue == 0;
}
RegCloseKey(hKey);
}
return false;
}
+13 -108
View File
@@ -12,6 +12,7 @@ import flixel.math.FlxPoint;
import flixel.graphics.frames.FlxFrame.FlxFrameAngle;
import flixel.FlxCamera;
import openfl.system.System;
import funkin.FunkinMemory;
using StringTools;
@@ -23,20 +24,6 @@ using StringTools;
@:nullSafety
class FunkinSprite extends FlxSprite
{
/**
* An internal list of all the textures cached with `cacheTexture`.
* This excludes any temporary textures like those from `FlxText` or `makeSolidColor`.
*/
static var currentCachedTextures:Map<String, FlxGraphic> = [];
/**
* An internal list of textures that were cached in the previous state.
* We don't know whether we want to keep them cached or not.
*/
static var previousCachedTextures:Map<String, FlxGraphic> = [];
static var permanentCachedTextures:Map<String, FlxGraphic> = [];
/**
* @param x Starting X position
* @param y Starting Y position
@@ -216,122 +203,40 @@ class FunkinSprite extends FlxSprite
return FlxG.bitmap.get(key) != null;
}
/**
* Ensure the texture with the given key is cached.
* @param key The key of the texture to cache.
*/
@:deprecated("Use FunkinMemory.cacheTexture() instead")
public static function cacheTexture(key:String):Void
{
// We don't want to cache the same texture twice.
if (currentCachedTextures.exists(key)) return;
if (previousCachedTextures.exists(key))
{
// Move the graphic from the previous cache to the current cache.
var graphic = previousCachedTextures.get(key);
previousCachedTextures.remove(key);
if (graphic != null) currentCachedTextures.set(key, graphic);
return;
}
// Else, texture is currently uncached.
var graphic:FlxGraphic = FlxGraphic.fromAssetKey(key, false, null, true);
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
currentCachedTextures.set(key, graphic);
}
FunkinMemory.cacheTexture(Paths.image(key));
}
@:deprecated("Use FunkinMemory.permanentCacheTexture() instead")
public static function permanentCacheTexture(key:String):Void
{
// We don't want to cache the same texture twice.
if (permanentCachedTextures.exists(key)) return;
// Else, texture is currently uncached.
var graphic:FlxGraphic = FlxGraphic.fromAssetKey(key, false, null, true);
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
permanentCachedTextures.set(key, graphic);
}
currentCachedTextures = permanentCachedTextures;
@:privateAccess FunkinMemory.permanentCacheTexture(Paths.image(key));
}
@:deprecated("Use FunkinMemory.cacheTexture() instead")
public static function cacheSparrow(key:String):Void
{
cacheTexture(Paths.image(key));
FunkinMemory.cacheTexture(Paths.image(key));
}
@:deprecated("Use FunkinMemory.cacheTexture() instead")
public static function cachePacker(key:String):Void
{
cacheTexture(Paths.image(key));
FunkinMemory.cacheTexture(Paths.image(key));
}
/**
* Call this, then `cacheTexture` to keep the textures we still need, then `purgeCache` to remove the textures that we won't be using anymore.
*/
@:deprecated("Use FunkinMemory.preparePurgeTextureCache() instead")
public static function preparePurgeCache():Void
{
previousCachedTextures = currentCachedTextures;
for (graphicKey in previousCachedTextures.keys())
{
if (!permanentCachedTextures.exists(graphicKey)) continue;
previousCachedTextures.remove(graphicKey);
}
currentCachedTextures = permanentCachedTextures;
FunkinMemory.preparePurgeTextureCache();
}
@:deprecated("Use FunkinMemory.purgeCache() instead")
public static function purgeCache():Void
{
// Everything that is in previousCachedTextures but not in currentCachedTextures should be destroyed.
for (graphicKey in previousCachedTextures.keys())
{
var graphic = previousCachedTextures.get(graphicKey);
if (graphic == null) continue;
FlxG.bitmap.remove(graphic);
graphic.destroy();
previousCachedTextures.remove(graphicKey);
}
@:privateAccess
if (FlxG.bitmap._cache == null)
{
@:privateAccess
FlxG.bitmap._cache = new Map();
System.gc();
return;
}
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
if (obj == null) continue;
if (obj.persist) continue;
if (permanentCachedTextures.exists(key)) continue;
if (!(obj.useCount <= 0 || key.contains("characters") || key.contains("charSelect") || key.contains("results"))) continue;
FlxG.bitmap.removeKey(key);
obj.destroy();
}
openfl.Assets.cache.clear("songs");
openfl.Assets.cache.clear("sounds");
openfl.Assets.cache.clear("music");
System.gc();
FunkinMemory.purgeCache();
}
static function isGraphicCached(graphic:FlxGraphic):Bool
@@ -71,7 +71,7 @@ class FlxAtlasSprite extends FlxAnimate
onAnimationComplete.add(cleanupAnimation);
// This defaults the sprite to play the first animation in the atlas,
// then pauses it. This ensures symbols are intialized properly.
// then pauses it. This ensures symbols are initialized properly.
this.anim.play('');
this.anim.pause();
@@ -136,6 +136,9 @@ class DropShadowScreenspace extends DropShadowShader
// essentially just stole this from the AngleMask shader but repurposed it to smooth
// the threshold because without any sort of smoothing it produces horrible edges
float antialias(vec2 fragCoord, float curThreshold, bool useMask) {
if (AA_STAGES == 0.0) {
return intensityPass(fragCoord, curThreshold, useMask);
}
// In GLSL 100, we need to use constant loop bounds
// Well assume a reasonable maximum for AA_STAGES and use a fixed loop
@@ -362,6 +362,9 @@ class DropShadowShader extends FlxShader
// essentially just stole this from the AngleMask shader but repurposed it to smooth
// the threshold because without any sort of smoothing it produces horrible edges
float antialias(vec2 fragCoord, float curThreshold, bool useMask) {
if (AA_STAGES == 0.0) {
return intensityPass(fragCoord, curThreshold, useMask);
}
// In GLSL 100, we need to use constant loop bounds
// Well assume a reasonable maximum for AA_STAGES and use a fixed loop
+2 -2
View File
@@ -17,7 +17,7 @@ class PureColor extends FlxShader
function set_col(val:FlxColor):FlxColor
{
funnyColor.value = [val.red, val.green, val.blue, val.alpha];
funnyColor.value = [val.redFloat, val.greenFloat, val.blueFloat, val.alphaFloat];
return val;
}
@@ -33,7 +33,7 @@ class PureColor extends FlxShader
vec4 color = flixel_texture2D(bitmap, openfl_TextureCoordv);
if (color.a > 0.0 && colSet)
color = vec4(funnyColor.r, funnyColor.g, funnyColor.b, color.a);
color = funnyColor * color.a;
gl_FragColor = color;
}
@@ -0,0 +1,10 @@
package funkin.graphics.video;
/**
* A script that can be tied to a FunkinVideoSprite.
* Create a scripted class that extends FunkinVideoSprite to use this.
*/
#if hxvlc
@:hscriptClass
class ScriptedFunkinVideoSprite extends funkin.graphics.video.FunkinVideoSprite implements polymod.hscript.HScriptedClass {}
#end
-15
View File
@@ -1,15 +0,0 @@
package funkin.mobile.external.ios;
/**
* A Utility class to manage iOS audio.
*/
@:build(funkin.mobile.macros.LinkerMacro.xml('project/Build.xml'))
@:include('AudioSession.hpp')
@:unreflective
extern class AudioSession
{
@:native('initialize')
static function initialize():Void;
@:native('setActive')
static function setActive(active:Bool):Void;
}
-16
View File
@@ -1,16 +0,0 @@
package funkin.mobile.external.ios;
/**
* A Utility class to get iOS screen related informations.
*/
@:build(funkin.mobile.macros.LinkerMacro.xml('project/Build.xml'))
@:include('ScreenUtil.hpp')
@:unreflective
extern class ScreenUtil
{
@:native('getSafeAreaInsets')
static function getSafeAreaInsets(top:cpp.RawPointer<Float>, bottom:cpp.RawPointer<Float>, left:cpp.RawPointer<Float>, right:cpp.RawPointer<Float>):Void;
@:native('getScreenSize')
static function getScreenSize(width:cpp.RawPointer<Float>, height:cpp.RawPointer<Float>):Void;
}
-29
View File
@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<pragma once="true" />
<files id="haxe">
<compilerflag value="-I${this_dir}/ios/include" if="iphoneos || iphonesim" />
</files>
<files id="__main__">
<compilerflag value="-I${this_dir}/ios/include" if="iphoneos || iphonesim" />
</files>
<files id="external-ios" dir="${this_dir}/ios" if="iphoneos || iphonesim">
<compilerflag value="-I${this_dir}/ios/include" />
<file name="src/ScreenUtil.mm" />
<file name="src/AudioSession.mm" />
</files>
<target id="haxe">
<section if="iphoneos || iphonesim">
<vflag name="-framework" value="UIKit" />
<vflag name="-framework" value="Foundation" />
<vflag name="-framework" value="AVFAudio" />
</section>
<files id="external-ios" if="iphoneos || iphonesim" />
</target>
</xml>
@@ -1,4 +0,0 @@
#pragma once
void initialize();
void setActive(bool active);
@@ -1,4 +0,0 @@
#pragma once
void getSafeAreaInsets(double* top, double* bottom, double* left, double* right);
void getScreenSize(double* width, double* height);
@@ -1,41 +0,0 @@
#import <Foundation/Foundation.h>
#import <AVFAudio/AVFAudio.h>
void initialize()
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayback
mode:AVAudioSessionModeDefault
options:AVAudioSessionCategoryOptionAllowBluetoothA2DP|AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
error:&error];
if (@available(iOS 17.0, *))
{
[session setPrefersInterruptionOnRouteDisconnect:false error:nil];
}
if (@available(iOS 14.5, *))
{
[session setPrefersNoInterruptionsFromSystemAlerts:true error:nil];
}
if (error)
{
NSLog(@"Unable to set category of audio session: %@", error);
}
}
void setActive(bool active)
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setActive:YES error:&error];
if (error)
{
NSLog(@"Unable to set active of audio session: %@", error);
}
}
@@ -1,36 +0,0 @@
#import "ScreenUtil.hpp"
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
void getSafeAreaInsets(double* top, double* bottom, double* left, double* right)
{
if (@available(iOS 11, *))
{
UIWindow* window = [UIApplication sharedApplication].windows[0];
UIEdgeInsets safeAreaInsets = window.safeAreaInsets;
float scale = [UIScreen mainScreen].scale;
(*top) = safeAreaInsets.top * scale;
(*bottom) = safeAreaInsets.bottom * scale;
(*left) = safeAreaInsets.left * scale;
(*right) = safeAreaInsets.right * scale;
return;
}
(*top) = 0.0;
(*bottom) = 0.0;
(*left) = 0.0;
(*right) = 0.0;
}
void getScreenSize(double* width, double* height)
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
float scale = [UIScreen mainScreen].scale;
(*width) = (double)screenRect.size.width * scale;
(*height) = (double)screenRect.size.height * scale;
}
@@ -125,7 +125,7 @@ class ControlsHandler
@:noCompletion
private static function get_hasExternalInputDevice():Bool
{
return FlxG.gamepads.numActiveGamepads > 0;
return FlxG.gamepads.numActiveGamepads > 0 #if android || extension.androidtools.Tools.isChromebook() #end;
}
@:noCompletion
@@ -1,37 +0,0 @@
package funkin.mobile.macros;
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.xml.Printer;
import sys.FileSystem;
using haxe.io.Path;
/**
* This class provides a macro to include an XML build file in the metadata of a Haxe class.
* The file must be located relative to the directory of the Haxe class that uses this macro.
*/
@:nullSafety
class LinkerMacro
{
/**
* Adds an XML `<include>` element to the class's metadata, pointing to a specified build file.
* @param file_name The name of the XML file to include. Defaults to `Build.xml` if not provided.
* @return An array of fields that are processed during the build.
*/
public static macro function xml(?file_name:String = 'Build.xml'):Array<Field>
{
final pos:Position = Context.currentPos();
final sourcePath:String = FileSystem.absolutePath(Context.getPosInfos(pos).file.directory()).removeTrailingSlashes();
final fileToInclude:String = Path.join([sourcePath, file_name?.length > 0 ? file_name : 'Build.xml']);
if (!FileSystem.exists(fileToInclude)) Context.error('The specified file "$fileToInclude" could not be found at "$sourcePath".', pos);
final includeElement:Xml = Xml.createElement('include');
includeElement.set('name', fileToInclude);
Context.getLocalClass().get().meta.add(':buildXml', [
{expr: EConst(CString(Printer.print(includeElement, true))), pos: pos}], pos);
return Context.getBuildFields();
}
}
+11 -4
View File
@@ -15,7 +15,14 @@ class FunkinBackButton extends FunkinButton
public var enabled:Bool = true;
var confirming:Bool = false;
public var confirming(get, never):Bool;
function get_confirming():Bool
{
return _confirming;
}
var _confirming:Bool = false;
public var restingOpacity:Float;
@@ -86,7 +93,7 @@ class FunkinBackButton extends FunkinButton
return;
}
confirming = true;
_confirming = true;
FlxTween.cancelTweensOf(this);
HapticUtil.vibrate(0, 0.05, 0.5);
@@ -98,7 +105,7 @@ class FunkinBackButton extends FunkinButton
animation.onFinish.addOnce(function(name:String) {
if (name != 'confirm') return;
confirming = false;
_confirming = false;
held = false;
onConfirmEnd.dispatch();
});
@@ -127,7 +134,7 @@ class FunkinBackButton extends FunkinButton
onDown.removeAll();
onOut.removeAll();
confirming = false;
_confirming = false;
held = false;
onUp.add(playConfirmAnim);
@@ -12,7 +12,16 @@ class FunkinOptionsButton extends FunkinButton
public var onConfirmStart(default, null):FlxSignal = new FlxSignal();
public var onConfirmEnd(default, null):FlxSignal = new FlxSignal();
var confirming:Bool = false;
public var enabled:Bool = true;
public var confirming(get, never):Bool;
function get_confirming():Bool
{
return _confirming;
}
var _confirming:Bool = false;
var instant:Bool = false;
var held:Bool = false;
@@ -49,7 +58,7 @@ class FunkinOptionsButton extends FunkinButton
function playHoldAnim():Void
{
if (confirming || held) return;
if (confirming || held || !enabled) return;
held = true;
@@ -70,7 +79,7 @@ class FunkinOptionsButton extends FunkinButton
return;
}
confirming = true;
_confirming = true;
FlxTween.cancelTweensOf(this);
HapticUtil.vibrate(0, 0.05, 0.5);
@@ -86,17 +95,20 @@ class FunkinOptionsButton extends FunkinButton
animation.onFinish.addOnce(function(name:String) {
if (name != 'confirm') return;
_confirming = false;
held = false;
onConfirmEnd.dispatch();
});
}
function playOutAnim():Void
{
if (confirming) return;
if (confirming || !enabled) return;
FlxTween.cancelTweensOf(this);
HapticUtil.vibrate(0, 0.01, 0.2);
animation.play('idle');
held = false;
}
public function resetCallbacks():Void
@@ -105,7 +117,7 @@ class FunkinOptionsButton extends FunkinButton
onDown.removeAll();
onOut.removeAll();
confirming = false;
_confirming = false;
held = false;
onUp.add(playConfirmAnim);
@@ -270,7 +270,7 @@ class ControlsSchemeMenu extends MusicBeatSubState
*/
function setSelection(index:Int):Void
{
final newIndex:Int = Math.floor(FlxMath.bound(index, 0, hitboxShowcases.length - 1));
final newIndex:Int = Math.floor(index.clamp(0, hitboxShowcases.length - 1));
if (currentIndex != newIndex)
{
@@ -348,7 +348,7 @@ class ControlsSchemeMenu extends MusicBeatSubState
hitboxShowcases.x = MathUtil.smoothLerpPrecision(hitboxShowcases.x, showcasesTargetX, elapsed, 0.5);
final minShowcasesX:Float = -1500 * availableSchemes.length;
hitboxShowcases.x = FlxMath.bound(hitboxShowcases.x, minShowcasesX, 400);
hitboxShowcases.x = hitboxShowcases.x.clamp(minShowcasesX, 400);
final targetIndex:Int = Math.round(hitboxShowcases.x / -1500);
@@ -356,8 +356,9 @@ class ControlsSchemeMenu extends MusicBeatSubState
}
else
{
hitboxShowcases.x = MathUtil.smoothLerpPrecision(hitboxShowcases.x, (-1500 * currentIndex) + (-1500 / (availableSchemes.length + 1) * currentIndex), elapsed, 0.5);
hitboxShowcases.x = MathUtil.smoothLerpPrecision(hitboxShowcases.x, (-1500 * currentIndex) + (-1500 / (availableSchemes.length + 1) * currentIndex),
elapsed, 0.5);
}
#end
}
#end
}

Some files were not shown because too many files have changed in this diff Show More