Compare commits

...
557 Commits
Author SHA1 Message Date
Hundrec b2215482c2 Bump docs to 0.8.7
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 / docker-image (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 / build-game-in-container (html5) (push) Canceled after 0s
Build and Upload nightly game builds / build-game-in-container (linux) (push) Canceled after 0s
2026-08-23 10:15:12 +08:00
Hundrec 59dae0f601 Bump version to 0.8.7 2026-08-23 10:15:12 +08:00
Hundrec 4d70e13629 Changelog for 0.8.7 2026-08-23 10:15:08 +08:00
Hundrec 83bc17970a Changelog platform formatting for 0.8.6 2026-08-23 10:08:03 +08:00
EricandHundrec 72078e4fec Add note hitsounds link to rejected features 2026-08-23 10:08:02 +08:00
EliteMasterEricandHundrec f5bd835496 Fix pull request label actions overriding each other 2026-08-23 10:08:02 +08:00
Karim AkraandHundrec f2fe179109 playest menu camera reset 2026-08-23 10:08:02 +08:00
MoonDroid b1d91ab5d8 FIx compression data + TouchUtil crash 2026-08-22 12:27:42 +07:00
MAJigsaw77andMoonDroid f09e89e324 Update lime and openfl 2026-08-21 20:59:06 +07:00
MoonDroidandKarim Akra 3c8f7c08ec Rewrite the FNFC java copy function for android
The old one was randomly throwing some crashes such as
* OutOfMemory
* NegativeArraySizeException
* IllegalStateException

This new one should fix those!

Co-Authored-By: Karim Akra <144803230+KarimAkra@users.noreply.github.com>
2026-08-21 14:46:57 +07:00
Hundrec ee9d492bec Bump docs and templates to 0.8.6
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
Including info about new public playtest builds
2026-08-09 06:22:48 +08:00
Hundrec afc251cde7 Bump version to 0.8.6 2026-08-09 06:14:05 +08:00
HundrecandAbnormal b7615eb8dd Changelog for 0.8.6
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2026-08-09 06:13:15 +08:00
Hundrec d2ead0ce4c Bump assets for health icon tweaks 2026-08-09 03:28:25 +08:00
HundrecandHyper_ 22297ee6ed Bump polymod again
Co-Authored-By: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
2026-08-09 03:10:50 +08:00
Hundrec 353473a980 Replace instances of a Contributor in Changelog
VirtuGuy -> realvirtu
2026-08-08 04:24:14 +08:00
Hundrec 9e39b1bfdb Bump CharacterData version to 1.0.2
To account for the new shouldBop property added a while back
2026-08-08 04:05:53 +08:00
Hundrec ab884e1362 Bump polymod 2026-08-08 03:55:21 +08:00
EliteMasterEricandHundrec 86c6f95cae Rewrite the CompiledClassList macro to use a resource 2026-08-08 02:46:40 +08:00
MAJigsaw77andHundrec 7a3422bda6 Bump lime 2026-08-08 02:46:37 +08:00
MAJigsaw77andHundrec fdc73624cf Update libs 2026-08-08 02:45:21 +08:00
MAJigsaw77andHundrec ae5654322c Clean some stuff in ApplicationMain 2026-08-08 02:44:45 +08:00
MAJigsaw77andHundrec 1cfe8b77a4 Update libs 2026-08-08 02:44:45 +08:00
MAJigsaw77andHundrec 15bf019c2d Disable formatting on templates 2026-08-08 02:44:37 +08:00
MAJigsaw77andHundrec d47ba73464 Bump flixel 2026-08-02 21:21:28 +08:00
MAJigsaw77andHundrec 716aeef72d Update libs 2026-08-02 21:20:38 +08:00
MAJigsaw77andHundrec c48a20a03c Add @:unreflective to all mobile utils 2026-08-02 21:19:53 +08:00
MAJigsaw77andHundrec 7b2cd882d3 Backlist all mobile utils 2026-08-02 21:19:53 +08:00
MAJigsaw77andHundrec 954810903c Fix -framework ignored creating static libraries warnings on iOS 2026-08-02 21:16:32 +08:00
MAJigsaw77andHundrec 7f22a34d7e Update libs 2026-08-02 21:15:57 +08:00
MAJigsaw77andHundrec bf6b8eecb8 The death of hashlink 2026-08-02 21:14:21 +08:00
MAJigsaw77andHundrec 77d829e888 Update openfl 2026-07-26 22:57:46 +08:00
FuroandHundrec f2633bb335 Cleanup the extension blacklisting process 2026-07-25 22:41:46 +08:00
nykwonoandHundrec de36ca87e8 Apply new input system changes to offset menu 2026-07-25 22:41:46 +08:00
MAJigsaw77 9749402714 Fix StageEditor compile on Mobile 2026-07-25 13:28:03 +03:00
MAJigsaw77andHundrec 9e08f9d0bc A bunch of iOS improvements 2026-07-25 17:39:02 +08:00
KoloandHundrec e8d91e0f1f implement texture atlas support for the stage editor 2026-07-24 04:01:50 +08:00
Hyper_andHundrec 87fc681c56 Remove display check from FlxMacro
This might solve an issue where Haxe complains that "Module funkin.util.macro.FlxMacro does not define type FlxMacro" during completion.
These checks don't work like you'd expect anyway, and the Haxe developers advise you not to use it outside of macros.
2026-07-24 03:32:39 +08:00
Hyper_andHundrec 709280c9a8 Fix incorrect checks for display during macro context 2026-07-24 03:32:39 +08:00
Daniel VictorandHundrec 20d3e4fb62 Remove the offset hack on my new DropShadowShader 2026-07-24 03:32:39 +08:00
Infinite-SUDO67andHundrec 05c81bc622 Fix Chart Editor event dropdown crash 2026-07-24 03:32:39 +08:00
kiry vajiravuthandHundrec b42cd4b6e1 charteditor wont crash now 2026-07-24 03:32:39 +08:00
kiry vajiravuthandHundrec 8bbd7bc466 even more typo fixes 2026-07-24 00:51:56 +08:00
MAJigsaw77andHundrec 347df2cdea Make the debug display be added to the game itself, not the parent 2026-07-24 00:12:45 +08:00
Infinite-SUDO67andHundrec 4ff781bd3a Adjust Mobile compiling guide docs 2026-07-24 00:12:45 +08:00
MAJigsaw77andHundrec 423d80059c Update extension-admob 2026-07-24 00:12:45 +08:00
MAJigsaw77andHundrec 7bbd0e882b Update lime 2026-07-24 00:12:01 +08:00
MAJigsaw77andHundrec f9d8203238 Implement extension-agesignals 2026-07-24 00:11:45 +08:00
MAJigsaw77andHundrec a18bab932f Update lime and openfl 2026-07-24 00:10:55 +08:00
MAJigsaw77andHundrec ade57d9bb7 Simplify registering prims by doing it in ApplicationMain 2026-07-20 12:31:25 +08:00
LegendandHundrec 347f7cfecb fix(freeplay): song preview not updating after rank animation finishes (#6432) 2026-07-04 21:23:38 +08:00
Ahmed7p39andHundrec 18f5e25496 avoid increasing volume on focus if it was 0 2026-07-04 16:49:47 +08:00
MAJigsaw77andHundrec 0001be960d Update openfl and lime 2026-07-03 16:42:18 +08:00
Cameron TaylorandHundrec 38c8bc94ca bump hmm for flixel: fix for pressing TAB not focusing the flixel console 2026-07-02 05:47:19 +08:00
realvirtuandHundrec d60fe0726f Fix ghost tapping when holding multiple keys 2026-07-01 00:51:28 +08:00
JVN-PixelsandHundrec 2e4115a33c Use the window width rather than the background width 2026-06-30 12:34:31 +08:00
LasercarandHundrec bdf51dcd43 Nest the text squash timers 2026-06-23 22:58:29 +08:00
VICKandHundrec 01d4242392 fix: also clear chart-editor HaxeUI focus on right-click / scroll wheel 2026-06-22 23:52:16 +08:00
VICKandHundrec 86f2f44b46 fix: Clear HaxeUI focus when chart editor toolbox is opened or closed 2026-06-22 23:52:16 +08:00
Hyper_andHundrec ac102396d7 Fix improper fallback to default notestyle on PlayState 2026-06-22 23:52:16 +08:00
AbnormalPoofandHundrec 663e7b307c fix: Fix Thorns crashing when exiting on HTML5 2026-06-22 13:48:50 +08:00
Hundrec afd27bf183 Bump assets for Actions update 2026-06-22 13:27:21 +08:00
LegendandHundrec 90712bf1e6 perf(background-process): improve onExit cleanup / resource disposal (#7235)
- The game now disposes of cached audio / textures, alongside `openfl.Assets` to ensure a proper resource cleanup.
  * Disposing of cached audio / textures upon exiting the game will now be logged to the terminal.
- Set `onExit` handler priority to 99 to ensure cleanup runs after mod exit callbacks.
- Removed HTML5 builds from getting background processed to prevent compilation errors.
- Removed `hxvlc` disposal from background processing.
2026-06-22 12:41:32 +08:00
requazarandHundrec 2a4968115f Fix PlayStatePlaylist using incorrect script variations 2026-06-22 12:41:27 +08:00
kiry vajiravuthandHundrec 395915cb31 probabbly 2026-06-22 12:41:21 +08:00
TechnikTilandHundrec 5de97f420c Remove unused code in PlayState.popUpScore
Signed-off-by: TechnikTil <techniktil@tilnotdrip.org>
2026-06-22 12:41:15 +08:00
zxcksharks (formerly xenkap)andHundrec e51ae1098a Add Funkin' version as compilation flag
for polymod!!!!
2026-06-22 12:41:08 +08:00
zxcksharks (formerly xenkap)andHundrec da1e8e4664 Add a PlayState check to initHealthIcon() and playAnimation()
This allows stages to be fully utilized outside of PlayState.
2026-06-22 12:41:01 +08:00
Ahmed7p39andHundrec 1d82546c29 Update event descriptions to clarify cancelable status 2026-06-22 12:40:47 +08:00
JVN-PixelsandHundrec f42dcecab6 Artistic Expression + Click Sounds in the Animation Editor 2026-06-22 12:40:19 +08:00
Vinegar (Flynn Waiver)andHundrec fdf6a3a2c6 Remove safeMode definition
Removed safeMode Haxe definition from project.hxp

It was not clear on what it was for, and it wasn't referenced anywhere. I've not seen any mods make any use cases of it either.
2026-06-22 12:40:05 +08:00
RafiandHundrec e60cb6bfc5 [GITHUB] Bump some actions dependencies to use Node 24 2026-06-21 21:09:08 +08:00
sector-aandHundrec 4de27f4231 Fix character script errors in chart editor 2026-06-21 12:50:55 +08:00
MAJigsaw77andHundrec 8f952acf91 Clean the ASTC textures when using the clean flag 2026-06-21 12:49:45 +08:00
MAJigsaw77andHundrec 8b8c1cc489 Add Target prefix to the Platform Type and Architecture prints 2026-06-21 12:49:45 +08:00
MAJigsaw77andHundrec 41e10f5f21 Move displayTarget after flair 2026-06-21 12:49:45 +08:00
MAJigsaw77andHundrec f18734f0b4 Update lime to fix the install command 2026-06-21 12:49:45 +08:00
MAJigsaw77andHundrec 6949bd97e4 Dont trace anything when using the run and install commands 2026-06-21 12:49:30 +08:00
MAJigsaw77andHundrec 5ed1ef404b Update astc-compressor 2026-06-21 12:49:30 +08:00
MAJigsaw77andHundrec aa2d6db7e0 Add isRun and isInstall 2026-06-21 12:49:30 +08:00
MAJigsaw77andHundrec 801074735e Make isCleanCommand and isCleanFlag 2026-06-21 12:49:30 +08:00
MAJigsaw77andHundrec fe10c0dad6 Dont check libraries or delete assets on the clean command 2026-06-21 12:49:30 +08:00
MAJigsaw77andHundrec 0207197644 Patch run command on Android and also move the config from iOS to configureApp 2026-06-21 12:49:30 +08:00
MAJigsaw77andHundrec 9730ee1c9e Make run and install commands run faster 2026-06-21 12:49:29 +08:00
AbnormalPoofandHundrec 093eb708ed Bump newgrounds to fix a weird JSON parsing error 2026-06-21 12:42:39 +08:00
MAJigsaw77andHundrec da1933397a Update hxvlc 2026-06-17 17:10:36 +08:00
HundrecandAbnormal 47110a34b0 Bump flixel to the latest commit
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2026-06-17 17:10:27 +08:00
Hyper_andHundrec 4f96d2c070 fix: Sort null elements by zIndex correctly 2026-06-17 17:08:26 +08:00
7oltanandHundrec bd23b5c12f make discord-rpc use characters icon data 2026-06-17 17:07:22 +08:00
MAJigsaw77andHundrec 539048b57b Bump lime and openfl 2026-06-17 17:07:15 +08:00
EliteMasterEricandHundrec 7102cda49d Rewrite some of the formatting rules to improve automatic line wrapping. 2026-06-17 17:02:01 +08:00
Cameron TaylorandHundrec 7bdcd59797 only log in preloader when percent or loading state changes 2026-06-17 17:00:18 +08:00
Cameron TaylorandHundrec 957a339676 round the numbers in preloader 2026-06-17 17:00:18 +08:00
AbnormalPoofandHundrec 5ee192439b Update polymod to the latest commit 2026-06-17 16:59:01 +08:00
MrMaderaandHundrec c239639ac7 Fix controls menu crash when changing a gamepad bind without a controller connected 2026-05-24 00:38:45 -06:00
ComedyLostandHundrec 1762affd7a fix potential freeplay crash when no music playing 2026-05-24 00:38:37 -06:00
Hyper_andHundrec a62e1c08ab feat: (and fix) Reusable and stutter-proof Timer Sequences 2026-05-24 00:38:07 -06:00
KoloandHundrec 0b6198f23a fix getting a new rank making the clip size incorrect 2026-05-24 00:38:07 -06:00
MAJigsaw77andHundrec eff4bcfdf3 Bump FlxPartialSound, openfl and lime 2026-05-24 00:35:06 -06:00
MAJigsaw77andHundrec f5f2fb0fc8 Bump lime and openfl 2026-05-24 00:34:55 -06:00
Kade-gtihubandHundrec a86ff05f69 general fixes rq 2026-05-24 00:34:16 -06:00
kade-githubandHundrec 209cdcff2a move resources to funkin.me 2026-05-24 00:34:16 -06:00
kade-githubandHundrec d25346ee39 theme branding stuff 2026-05-24 00:34:16 -06:00
kade-githubandHundrec 16376c0897 General Dox Setup/Implementation 2026-05-24 00:34:16 -06:00
MrMaderaandHundrec 6fe2089bea Fix controls menu crash when unplugging a gamepad 2026-05-19 17:45:24 -06:00
JVN-PixelsandHundrec 27fd960fb3 Fix broken rectangle size in Lag Adjustment Menu 2026-05-19 17:45:24 -06:00
LegendandHundrec adbe5ba7cb fix(options): prevent crash when hot-reloading in the lag adjustments menu (#7285)
- Added a null check for `FlxG.sound.music` before calling `fadeOut()`.
- Created `switchToOffsets()` to avoid duplicating the original code.
2026-05-19 17:45:24 -06:00
ImVeryBadandHundrec 2bb5397c2b Fix health icon angle lerping too quickly and use a Constant for the half life to allow customizability by modders. 2026-05-19 17:45:24 -06:00
ImVeryBadandHundrec 1fce75feb9 Ignore health icon offsets in Chart Editor to prevent out-of-bounds rendering. 2026-05-19 17:45:24 -06:00
ImVeryBadandHundrec 83bfccc101 Disable page navigation while Save Data prompts are open in Options. 2026-05-19 17:45:24 -06:00
VirtuGuyandHundrec f0a5188cb1 Fix hold notes not always having a cover 2026-05-19 17:45:24 -06:00
AbnormalPoofandHundrec 28cbf3767a Add discordRPCImage to Album and Song data 2026-05-19 17:45:24 -06:00
AbnormalPoofandHundrec e7cd38ee85 Disable RTT on GF Christmas on Web 2026-05-18 16:09:36 -06:00
VirtuGuyandHundrec c1be637101 Fix song restart bug 2026-05-18 15:45:35 -06:00
ImVeryBadandHundrec 6ab6bc62e7 Remove the popup error when a directory in mods has no metadata. 2026-05-18 12:17:59 -06:00
MAJigsaw77andHundrec 8592b44c72 Update hxcpp, lime and openfl 2026-05-18 12:17:59 -06:00
Nebula S. NovaandHundrec 01bce88823 Fix my stupid 2026-05-15 01:11:58 -06:00
Nebula S. NovaandHundrec 6aa8bc3ce9 [BUGFIX] Fix file naming for metadata and chart saves from difficulty toolbox. 2026-05-15 01:11:58 -06:00
LusciousandHundrec 840c0431ec Update AngleMask.hx 2026-05-15 01:11:58 -06:00
Karim AkraandHundrec 4ca9a21ec6 Use GCKeyboard instead of UITextInputContext to check for ios keyboard 2026-05-15 01:11:15 -06:00
Karim AkraandHundrec fec0f66029 Fixed gamepad detection for mobile 2026-05-15 01:11:15 -06:00
Karim AkraandHundrec 30efedb930 Fix keyboard detection for iOS 2026-05-15 01:11:15 -06:00
Karim AkraandHundrec 32c507999a Bump lime to fix the iOS keyboard freeze 2026-05-15 01:11:15 -06:00
Kade-gtihubandHundrec 9f6ea20f3e remove accurate width/height and fix calculations 2026-05-15 01:11:01 -06:00
Hundrec 5b892c8814 Batch of assets bug fixes 2026-05-09 17:33:41 -06:00
ComedyLostandHundrec 504b22126b Fix multiple wether typos 2026-05-09 04:40:42 -06:00
SuperEricandHundrec 67aec2464b Fix typo in comment about songPosition issues 2026-05-09 04:40:42 -06:00
Hundrec c99d4438db Bump assets for typo fixes 2026-05-09 04:40:37 -06:00
Honton129andHundrec ac37968f73 Add `Edit Notes` to the Chart Editor Selection Context Menu 2026-05-09 04:40:11 -06:00
charlesisfelineandHundrec 3752232e3a Blacklist haxe.Http
speedrunning a blacklist pr before kade does it heheheheha
2026-05-09 04:39:49 -06:00
MAJigsaw77andHundrec 7d5fa627cb Add support back for some libs on iOS Simulator 2026-05-09 04:39:37 -06:00
MAJigsaw77andHundrec 4db9d7718c Bump lime and flixel 2026-05-09 04:39:37 -06:00
Kade-gtihubandHundrec cf3e2e05bf Add ClipRect functionality to FunkinGroup 2026-05-09 04:39:16 -06:00
LasercarandHundrec b97012a10d Note input delay doubled when note is hit late 2026-05-05 23:00:45 -06:00
MrMaderaandHundrec e0af5e282e Fix some actions not updating the Freeplay hint properly 2026-05-04 04:14:26 -06:00
Ahmed7p39andHundrec d6ce9e2dff Update pause and resume methods for Conversation 2026-05-04 04:14:26 -06:00
Ahmed7p39andHundrec c0a483f003 Add pause and resume functions for dialogue outro 2026-05-04 04:14:26 -06:00
ComedyLostandHundrec 179d8294e4 Set variables correctly for texture swap shader 2026-05-04 04:14:26 -06:00
EliteMasterEricandHundrec c8f2056823 Disable the MagicNumber rule 2026-05-04 04:14:25 -06:00
EliteMasterEricandHundrec 89e05e200e Disable CodeSimilarity rule 2026-05-04 04:14:25 -06:00
475c7cbf80 Optimize Adjust Color
Co-Authored-By: iLauncherDev <93844852+iLauncherDev@users.noreply.github.com>
2026-05-04 04:13:09 -06:00
AbnormalPoofandHundrec 92331dd8bf Remove 2 unused blend mode shaders 2026-05-04 04:13:05 -06:00
AbnormalPoofandHundrec eba3c2b2b1 Small cleanup 2026-05-04 04:12:59 -06:00
Daniel VictorandHundrec 0e82016232 Rewrite DropShadowShader a little for performance improvement 2026-05-04 04:12:59 -06:00
MAJigsaw77andHundrec 0969465139 Bump lime to fix a couple of things on MacOS 2026-05-04 04:12:59 -06:00
VirtuGuyandHundrec 0e967ebefb Fix camera movement when pausing 2026-05-02 03:00:34 -06:00
MAJigsaw77andHundrec 8730812cf5 Use deltaWheel where possible for more accurate scrolling 2026-05-02 03:00:13 -06:00
MAJigsaw77andHundrec d7fc2ebff6 Bump flixel and openfl 2026-05-02 02:57:48 -06:00
EliteMasterEricandHundrec e4ed5b9cc8 Update polymod to latest experimental 2026-04-30 23:27:00 -06:00
Hyper_andHundrec 7f8a1ab6d0 Chart Editor: Only affect playback rate if "Use Editor Audio Settings" is enabled 2026-04-30 23:27:00 -06:00
EliteMasterEricandHundrec 5e7aaf6894 Fix an issue with HaxeUI and the compilation server. 2026-04-30 23:27:00 -06:00
MAJigsaw77andHundrec 4d501f05c3 Update lime 2026-04-30 23:27:00 -06:00
ImVeryBadandHundrec a25f3e5fb8 Fix runtime errors due to tempVocals being nullable 2026-04-30 23:27:00 -06:00
eb4d9e9323 Patch unicodes not working properly on Windows
Co-Authored-By: Karim Akra <144803230+KarimAkra@users.noreply.github.com>
2026-04-30 23:27:00 -06:00
MAJigsaw77andHundrec 970a29cd5f Bump lime and hxcpp 2026-04-30 23:27:00 -06:00
8e20209391 Update json2object to include a stable and better-formatted Dynamic object writer.
Co-Authored-By: TechnikTil <TechnikTil@users.noreply.github.com>
2026-04-30 23:26:58 -06:00
MAJigsaw77andHundrec 05b703e93d Bump lime, openfl and flixel 2026-04-29 02:07:14 -06:00
Hundrec a079593fdc Adjust some wording 2026-04-27 16:14:02 -06:00
Honton129andHundrec c08a6a86a0 [CHORE] Improve DialogueBoxData.hx Documentation 2026-04-27 16:14:02 -06:00
JVN-PixelsandHundrec dbda7e02ca Fix a few typos 2026-04-27 16:14:02 -06:00
TechnikTilandHundrec 20fc36ea59 Use Constants for time conversion equations
Signed-off-by: TechnikTil <techniktil@tilnotdrip.org>
2026-04-27 16:13:14 -06:00
Hyper_andHundrec 523b9c16eb fix: Fix midpoint not properly offsetting Nametag position 2026-04-27 16:11:27 -06:00
Ahmed7p39andHundrec b75add7c59 Use fullyQualifiedName for scripted class identification to support packages 2026-04-27 16:11:27 -06:00
Kade-gtihubandHundrec fabddc93ab More PlayState null checks 2026-04-20 19:38:33 -06:00
EliteMasterEricandHundrec 4abbd9c15c Update the docs regarding hitzones. 2026-04-20 19:04:38 -06:00
HundrecandTechnikTil a599c6513b Re-export all charts using updated json2object
Co-Authored-By: TechnikTil <techniktil@tilnotdrip.org>
2026-04-18 21:27:21 -06:00
MAJigsaw77andHundrec 05f9764236 Update extension-admob and handle the mediations config internally 2026-04-17 22:49:02 -06:00
MAJigsaw77andHundrec 5824529c12 Fix FileDialogs from not following the last dir it opened 2026-04-17 19:30:23 -06:00
Karim AkraandHundrec 54a15c7045 Set the lime extension lime.projectFile to project.hxp in the vscode settings 2026-04-17 19:30:23 -06:00
sector-aandHundrec 2136f6f5c3 A small nametag refactor 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec b50dc69e05 Update lime again to patch a linux error 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec fe45b409ef Update lime 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec 9d45aeb6ce Pause audio when an Ad runs on Android aswell 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec 778bbfd0f5 Update lime and openfl 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec aac8f598d9 Update flixel and flixel-addons 2026-04-17 19:30:23 -06:00
EliteMasterEricandHundrec bde533def5 Add a "Chart Saved" notification to the menu option (previously only showed when pressing Ctrl-S) 2026-04-17 19:30:23 -06:00
Hundrec 5eaa248451 Fix incorrect line breaks 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec 276e8bb248 Adjust the Path and Development Build ANSI colors in project.hxp 2026-04-17 19:30:23 -06:00
MAJigsaw77andHundrec ec4fef6424 Update lime and hxcpp 2026-04-17 19:30:23 -06:00
AbnormalPoofandHundrec 567aa28905 Bump openfl to fix DARKEN being completely broken on Windows 2026-04-09 14:26:59 -06:00
AbnormalPoofandHundrec e15d39d102 Fix the blend shader not working at all under render texture 2026-04-09 14:26:59 -06:00
MAJigsaw77andHundrec 04e120dfc9 Add svg to hmm. 2026-04-09 14:26:59 -06:00
MAJigsaw77andHundrec 9d12646452 Update lime
Update hmm.json
2026-04-09 14:26:57 -06:00
MAJigsaw77andHundrec ec59410b68 Remove this leftover to patch compile. 2026-04-06 04:18:10 -06:00
MAJigsaw77andHundrec 5ecccbf7fc Add tink_core to hmm. 2026-04-06 04:18:10 -06:00
sector-aandHundrec e17a0d047a Update the presence after enabling the RPC in Preferences 2026-04-06 04:18:10 -06:00
sector-aandHundrec afeb263ae1 Implement a way to hide song's info for Discord RPC 2026-04-06 04:18:10 -06:00
sector-aandHundrec 7af0a69584 Implement DiscordRPC preference 2026-04-06 04:18:10 -06:00
MAJigsaw77andHundrec 378001f8ea Adjustments for the Touch here to play 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec 824bb306f9 Even more warnings cleaned up. 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec 496cffdf99 Don't require field doc comments for enums (they're often self-explanatory) 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec d344741f85 Tweaks to for loops 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec 9f695a28f5 Tweak the rules to allow single-line for loops 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec 5b7e567eb2 Rewrite string literals to use single quotes 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec 93ccad566c Do a whole bunch of code style rewrites across a lot of classes. Still more to do! 2026-04-06 04:18:10 -06:00
EliteMasterEricandHundrec be68ebb920 Standardize doc style comments 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec b83672caab Code style fixes for funkin.api 2026-04-06 04:18:09 -06:00
HundrecandEric 56dabfd5c9 Format .hx files
Co-Authored-By: Eric <4635334+EliteMasterEric@users.noreply.github.com>
2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 71d7d929b4 Only enforce the LongNumberCheck for values over 10_000 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 866055018f Move override to the front of the modifier order 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec e4d12d2a5a Redo the rules for LongNumber checks (update your checkstyle extension!) 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec c71b06c9f2 Update doc comment style to require two stars to open and one star to close (like JavaDocs) 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 72d3d4546f Redo the NeedBraces rule to require braces on if statements with else blocks. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 17cfd2e2f8 Add a rule forbidding long numbers without separators. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 71d7fe0cf6 Re-rework rules for local variable names now that we can filter by FINAL/NOTFINAL 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 1c46c98c84 Re-rework rules for constant names now that we can filter by FINAL/NOTFINAL 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 02c49ba645 Disable the use of nested ternary operators. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec a2cd0ef4ca Use arrow functions for non-member functions (i.e. all inline functions) 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 64b99fedcc Enforce not using "== false" in code. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec f7d6ce4a98 Fix a vague comment. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 8b3372cdab The new TrailingCommas rule doesn't support forcing trailing commas off... 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec f460b604e2 Require parenthesis around the switch condition. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec f1aade4b58 Force a newline after type metadata 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec ccc2383402 Change policy for some rules that were set to "keep existing" 2026-04-06 04:18:09 -06:00
EricandHundrec 3250f28217 Enable style rule for modifier order 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 544a531434 Fix an issue where macro reification would request a newline for the curly braces. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 222eee19bf Modify naming requirements for variables to be less strict. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 47830ffaf3 Fix an issue where enum abstracts would display a message that the type wasn't documented, even if it was. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec b582826fba Update rules for line wrapping on maps. 2026-04-06 04:18:09 -06:00
EliteMasterEricandHundrec 5d14e4f667 Update rules for line wrapping on arrays. 2026-04-06 04:18:08 -06:00
MAJigsaw77andHundrec 97b09ba966 Update hxcpp 2026-04-06 04:18:08 -06:00
ember anaandHundrec e72b67df70 fix: html5 and linux ci builds ^-^ (#2455)
* fix: itch.io upload failing

* feat: the runner now rebuilds lime ndlls (and caches that build) on the fly

* chore: update all the actions used to latest

* chore: update build dependencies to latest

* chore: cleanup build outputs
2026-04-06 04:18:08 -06:00
Hundrec c382cee930 Add a contributor to 0.7.4 New Contributors 2026-04-06 04:18:08 -06:00
AbnormalandHundrec d3ad9d9311 Revert "Rework AtlasText to use FunkinGroup"
This reverts commit 2857fe14122927c2732a858862d7db9b8ff765a4.
2026-04-06 04:18:08 -06:00
LegendandHundrec 0b086689e8 fix: stop resultsMusic when hot-reloading in the chart editor's resultsScreen 2026-04-06 04:18:08 -06:00
ImVeryBadandHundrec cc91faaccc Add shouldBop in HealthIconData to allow any type of icon to bop. 2026-04-06 04:18:08 -06:00
ImVeryBadandHundrec 790e3fb097 Add Albums & Sticker Packs to Chart Editor metadata dialogues 2026-04-06 04:18:08 -06:00
EliteMasterEricandHundrec 982e2b72c1 Fix compilation issue due to currentStage being nullable 2026-04-06 04:18:08 -06:00
LasercarandHundrec e0a6253310 unmute character vocals for animations 2026-04-06 04:18:08 -06:00
EliteMasterEricandHundrec 134984ea0b Fix the return value being wrong. 2026-04-06 04:18:08 -06:00
KoloandHundrec 19610c4309 dont dispatch conductor events if substate is active 2026-04-06 04:18:08 -06:00
03f6cc1552 Implement screenshots on html5
Co-Authored-By: Cameron Taylor <cameron.taylor.ninja@gmail.com>
2026-04-06 04:18:08 -06:00
ImVeryBadandHundrec d6c6d75a45 Fix requestScores in the wrapper to be static and correct trace typo in Leaderboards.hx 2026-04-06 04:18:08 -06:00
ImVeryBadandHundrec ea4f0a4d28 Remove unused fields 2026-04-06 04:18:08 -06:00
FuroandHundrec 66d191d431 Fix Reflect Util by Adding Polymod Blacklist Protection 2026-04-06 04:18:08 -06:00
AbnormalPoofandHundrec bd99345a3c Adjust the file drop comment 2026-04-06 04:18:08 -06:00
AbnormalPoofandHundrec cfdbbb81d4 Re-enable file drop on macOS 2026-04-06 04:18:08 -06:00
EricandHundrec 7f7197f216 Update format haxelib 2026-04-06 04:18:08 -06:00
MAJigsaw77andHundrec 2f949d4af0 Update libs refs 2026-04-06 04:18:08 -06:00
AbnormalPoofandHundrec bc06e7fcc1 Rework AtlasText to use FunkinGroup 2026-04-06 04:18:08 -06:00
MAJigsaw77andHundrec a01b4ce4af Improve file dialogs 2026-04-06 04:18:08 -06:00
Hundrec 965d2053cf Bump assets 2026-04-06 04:18:08 -06:00
Hundrec bdedc0aad2 Bump docs and templates to 0.8.5
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
2026-04-05 13:53:37 -06:00
Hundrec b23b008861 Bump version to 0.8.5 2026-04-05 13:53:37 -06:00
Hundrec acbfa69d48 Changelog for 0.8.5 - Android exclusive fix 2026-04-05 13:53:37 -06:00
Hundrec 648ca8fd13 Bump lime for more fixes 2026-04-05 13:53:35 -06:00
Hundrec 90eabf0b38 Bump docs and templates to 0.8.4
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
2026-03-25 16:19:29 -06:00
Hundrec b3959a5935 Bump version to 0.8.4 2026-03-22 00:02:55 -06:00
HundrecandAbnormal cdca3bf307 Changelog for 0.8.4
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2026-03-22 00:01:19 -06:00
Karim AkraandHundrec e491c5e841 [CHORE] rename mobile FNFCUtil classes for a cleaner structure 2026-03-21 16:01:13 -06:00
Karim AkraandHundrec f9b125e44a [FIX] Bump lime to fix FNFC loading on iOS 2026-03-21 16:01:13 -06:00
VirtuGuyandHundrec 1ceb4fad1a Fix ingame cutscenes crashing on mobile 2026-03-21 06:40:41 -06:00
Hyper_andHundrec 21fc59c997 Fix TextureSwap not loading ASTC assets properly 2026-03-21 06:40:33 -06:00
EliteMasterEricandHundrec 0cbde53f86 Update default value just in case resetEvents(events) doesn't get called. 2026-03-21 04:57:45 -06:00
VirtuGuyandHundrec 5119cf1b72 Fix songs crashing 2026-03-21 04:57:45 -06:00
927f3fc300 Use an optional argument for event querying
Co-Authored-By: Eric <4635334+EliteMasterEric@users.noreply.github.com>
2026-03-20 16:54:27 -06:00
EliteMasterEricandHundrec d1e4a17f46 Add null checks to some scripts 2026-03-20 16:52:53 -06:00
ec868f8ef5 Fix HTML5 not compiling due to blacklisted Polymod field
Co-Authored-By: Kolo <67389779+KoloInDaCrib@users.noreply.github.com>
Co-Authored-By: Keoiki <55053690+Keoiki@users.noreply.github.com>
2026-03-20 04:19:23 -06:00
MAJigsaw77andHundrec 1e0a238463 Patch extension-admob setup command so theres no unexpected behaviour 2026-03-20 03:58:18 -06:00
Hundrec e07e59a288 Undo No Animation hold timer change
It was making animations behave differently after a change to hold timers
2026-03-19 23:29:42 -06:00
ADA-FunniandHundrec d6410d5e42 Fallback for old song metadata files causing the song preview to go mute 2026-03-19 23:29:42 -06:00
TrayfellowandHundrec 5974c1a482 Fix freeplay percentage not fully exiting out if it has 3 digits 2026-03-19 21:02:20 -06:00
KoloandHundrec ffdcbdbf21 optimize the script event dispatching 2026-03-19 21:02:20 -06:00
KoloandHundrec 3b27ec5b66 optimization: potentially optimize how events are queried 2026-03-19 21:02:20 -06:00
FuroandHundrec 56a56dbfaa Include lime and openfl for modding 2026-03-19 20:00:18 -06:00
EliteMasterEricandHundrec 537bd5dd83 Add a few more items to the blacklist 2026-03-19 20:00:18 -06:00
charlesisfelineandHundrec b0fd471f8a Blacklist 'readObject` from scripts 2026-03-19 20:00:18 -06:00
ImVeryBadandHundrec 3633df3fdc Add makeVarArgs to ReflectUtil.hx 2026-03-19 20:00:18 -06:00
VirtuGuyandHundrec e6234397f5 Fix camera movement when paused 2026-03-19 19:34:04 -06:00
MAJigsaw77andHundrec 68ce5ce90b Update lime 2026-03-19 18:50:43 -06:00
MAJigsaw77andHundrec a6066f9905 Update flixel-addons 2026-03-19 04:21:37 -06:00
KolzeandHundrec 75506f71a9 Fix spirit trail being fps-dependent 2026-03-19 04:21:25 -06:00
RaltyandHundrec c4b5462a5a Remove duplicated code in project.hxp 2026-03-19 03:15:35 -06:00
MAJigsaw77andHundrec 47d4d77c86 Update hxcpp 2026-03-19 02:50:50 -06:00
MAJigsaw77andHundrec acf17f6165 Properly adjust the debug display math based of the supported mem usages 2026-03-19 02:50:50 -06:00
MAJigsaw77andHundrec 2db26070c6 Properly delete the assets folder on hl across all desktop targets 2026-03-19 02:50:50 -06:00
MAJigsaw77andHundrec e0f9c7336b Update libs refs 2026-03-19 02:50:50 -06:00
AbnormalPoofandHundrec a28a28ae4c Clamp the DPI scale to 1 in the blend shader 2026-03-18 00:26:45 -06:00
Hundrec 7160f748eb Tweak dropdown width 2026-03-17 23:55:20 -06:00
sector-aandHundrec c8e60bed34 Add additional adjustments in the ZoomCamerasong event for widescreen 2026-03-17 23:55:19 -06:00
sector-aandHundrec 11c826daa6 Resize ENUM dropdowns to make them fit in the frames 2026-03-17 23:55:03 -06:00
sector-aandHundrec 6c887b4632 Put some of least used event params under Advanced frame. 2026-03-17 23:55:03 -06:00
MAJigsaw77andHundrec ecfb897dae Remove useless prints 2026-03-17 22:59:20 -06:00
AbnormalPoofandHundrec 56d5767004 Fix HashLink not clearing assets on macOS 2026-03-17 22:59:12 -06:00
MAJigsaw77andHundrec 7d3bfa32ca Run clearAssets only on non display 2026-03-17 22:59:04 -06:00
KolzeandHundrec 348647f486 Fix global offset changing speed 2026-03-17 22:58:00 -06:00
ExcodeandHundrec 48ed659800 Update LevelData.hx 2026-03-17 22:57:43 -06:00
ExcodeandHundrec 8aafe62f9c Update LevelProp.hx 2026-03-17 22:57:43 -06:00
MrMaderaandHundrec 0f7859bfb6 Gamepad binds showed in Freeplay's hint
_lastDeviceUsed -> lastDeviceUsed
2026-03-17 22:56:32 -06:00
Hundrec c3d3d2e547 Move Week 6 Erect results transition further down 2026-03-17 02:52:50 -06:00
37dc3461af Re-implement curNoteKind.suffix
Co-authored-by: TechnikTil <techniktil@tilnotdrip.org>
2026-03-17 02:52:14 -06:00
MightyTheArmiddiloandHundrec c11ac1f658 Fix Compile Errors With FLX_NO_DEBUG 2026-03-17 02:52:10 -06:00
TrayfellowandHundrec 47bbf67ae6 Updated level schema version 2026-03-17 02:51:46 -06:00
TrayfellowandHundrec 528e9e4f03 Data-driven changeable capsule texts 2026-03-17 02:50:30 -06:00
echolotlandHundrec 7626700495 Consistent line width + fix min/max of easing preview graph 2026-03-16 20:34:42 -06:00
AbnormalPoofandHundrec 0d2a663346 Enable null-safety on FunkinFilterRenderer 2026-03-16 13:08:36 -06:00
TechnikTilandHundrec 22736b27da Add filters to FunkinSprite
This commit also removes `FlxFilteredSprite`

Signed-off-by: TechnikTil <techniktil@tilnotdrip.org>
2026-03-16 13:08:36 -06:00
MAJigsaw77andHundrec dcfad7b7e8 Update libs ref 2026-03-16 13:08:35 -06:00
Hundrec ef625b3d9d Bump assets for a few minor fixes 2026-03-16 04:40:11 -06:00
MAJigsaw77andHundrec 6ce3a2e93e Update hxvlc to fix a couple of issues 2026-03-16 03:47:03 -06:00
SuperEricandHundrec b8c2854007 Adjust backingImage size 2026-03-14 23:36:29 -06:00
JVNpixelsandHundrec 04fffe8ade Commas For Story Mode Score 2026-03-14 23:14:15 -06:00
MAJigsaw77andHundrec c37862445f Update lime ref 2026-03-14 23:00:45 -06:00
VirtuGuyandHundrec 0613e9d295 Fix rimlight alt masks not working on web 2026-03-14 22:24:39 -06:00
MAJigsaw77andHundrec bed249dca0 Remove the framerate options on web 2026-03-14 22:13:54 -06:00
MAJigsaw77andHundrec 139940f9ec Update libs refs 2026-03-14 17:30:27 -06:00
Hyper_andHundrec 36e2f47577 Fix Random capsule not updating OST text 2026-03-13 21:48:13 -06:00
VirtuGuyandHundrec ce493a03c9 Fix favoriting songs breaking song text cycling 2026-03-13 21:48:13 -06:00
AnimatingLegendandHundrec aabd1aa9f7 fix: miss-animation timing in no-anim events 2026-03-13 21:25:52 -06:00
KoloandHundrec 89029220e4 optimization: remove a spammy trace 2026-03-13 21:25:52 -06:00
ImVeryBadandHundrec dca54de087 Add isBlank to StringTools for easier blank string checking. 2026-03-13 21:25:52 -06:00
KoloandHundrec 15bef89d71 Script event support for Song Events 2026-03-12 01:43:08 -06:00
6c1f3800db Fix duplicate asset paths in note styles crashing when exiting PlayState in Chart Editor.
Co-authored-by: Kolo <67389779+koloindacrib@users.noreply.github.com>
2026-03-12 01:43:08 -06:00
AbnormalPoofandHundrec 8507f799a1 Update polymod to the latest commit 2026-03-12 01:43:08 -06:00
EliteMasterEricandHundrec dba2794780 Use the font family instead of the file path 2026-03-12 01:42:47 -06:00
KoloandHundrec 48752e444c softcode freeplay capsule level labels 2026-03-12 01:42:24 -06:00
8a1d74b82c Re-enable FlxG.autoPause when doing stickers
Co-Authored-By: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
2026-03-12 01:40:26 -06:00
AnimatingLegendandHundrec 0d1db6ae9e fix(ui): prevent nametag pixelation on web builds 2026-03-12 01:39:13 -06:00
EliteMasterEricandHundrec 1f1851990f Make sure to update the schema version when adding fields, people! 0.0.x versions for new fields with no breaking changes. 2026-03-12 01:36:31 -06:00
Hyper_andHundrec 67d2a9811b feat: Custom OST names 2026-03-12 01:35:51 -06:00
LasercarandHundrec a782b3f9e8 Improved context menus Directly set the item's position and for hold notes, it's length as well Values can be shown and set in milliseconds or steptime 2026-03-12 01:34:08 -06:00
EricandHundrec 74e28a18ff Add an extra space 2026-03-12 01:31:20 -06:00
MoonDroidandHundrec 220636e01e Style leftover INFO logs with Ansi 2026-03-12 01:31:02 -06:00
MightyTheArmiddiloandHundrec 4f316003af FunkinGroup 2026-03-12 01:28:15 -06:00
AbnormalPoofandHundrec 1a04e35db7 Change instances of FlxG.onMobile to use preprocessor defines 2026-03-11 02:44:30 -06:00
MAJigsaw77andHundrec d3e83dd72d Add Vungle mediation for Admob 2026-03-11 02:34:04 -06:00
c4e2b900c1 Implement SDL3
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
Co-Authored-By: Karim Akra <144803230+KarimAkra@users.noreply.github.com>
2026-03-10 04:54:26 -05:00
AbnormalPoof ac3178118c Remove FlxColorUtil as Polymod supports FlxColor 2026-03-10 04:37:12 -05:00
AbnormalPoof 681f7a6d07 Remove AbstractUtil since Polymod now supports FlxSignal proper 2026-03-10 04:37:00 -05:00
AbnormalPoof aa24c94782 Remove import aliases for abstracts 2026-03-10 04:36:58 -05:00
ComedyLostandAbnormalPoof 7075c8af4b Fix a crash for inst only songs 2026-03-10 04:33:14 -05:00
AbnormalPoof efc33403b6 fix: Fix REDIRECT_ASSETS_FOLDER not working on HashLink on macOS 2026-03-10 04:33:07 -05:00
Hundrec 25a42b8182 Reword Stage Editor unsaved work prompt 2026-03-09 20:16:07 -06:00
KoloandHundrec 0389af2202 fix moving globally offset characters not working 2026-03-09 20:16:07 -06:00
Hyper_andHundrec b694ec08d6 fix: Improve Preloader time on HashLink 2026-03-09 20:16:07 -06:00
PurSnakeandHundrec 423ccfab98 Implement ScriptedBaseFreeplayDJ usage 2026-03-09 09:38:58 -06:00
AbnormalPoofandHundrec edc1f7113b Update polymod to the latest commits 2026-03-09 09:38:58 -06:00
ImVeryBadandHundrec f0b50de9fa Add support for the new Polymod mod ID system. 2026-03-09 09:38:58 -06:00
LasercarandHundrec 0ad2d507ef Random cap difficulty & BPM value visible fix 2026-03-09 09:16:39 -06:00
LasercarandHundrec 6c13444211 Hide character select keybinds until unlock 2026-03-09 09:06:58 -06:00
MightyTheArmiddiloandHundrec 5a0b4310a2 Add onPause dispatching for cutscenes and conversations 2026-03-09 09:06:58 -06:00
LasercarandHundrec 6b1fc0372b Disable edit buttons if no selection 2026-03-09 08:41:21 -06:00
ImVeryBadandHundrec cf69125d25 Clean up Cursor.hx code 2026-03-09 08:34:15 -06:00
Redar13andHundrec 84b2d5b48d Fix GF bopping when switching levels in the story menu. 2026-03-09 08:28:18 -06:00
RudyrueandHundrec dcb5b3a935 fix timing windows being 1 ms tighter 2026-03-09 08:11:45 -06:00
TrofemandHundrec 011f1541b1 control + character icon combination for character preview 2026-03-09 07:50:49 -06:00
sector-aandHundrec 13c1bf8ac0 Fix null object reference when using collapsible 2026-03-09 07:50:49 -06:00
1893f2b2f6 Implement SetTargetBopSpeed Event
Co-Authored-By: Eric <4635334+EliteMasterEric@users.noreply.github.com>
2026-03-09 07:25:40 -06:00
VirtuGuyandHundrec a0caa41edc Fix phillyStreets rain not fading out 2026-03-09 06:55:23 -06:00
FuroandHundrec 456b2ff6c4 Prevent Importing non osu!mania beatmaps 2026-03-09 03:32:32 -06:00
AbnormalPoofandHundrec a1d1b1b2d1 Fix garbage collection being mostly broken on HashLink 2026-03-09 03:32:32 -06:00
Hyper_andHundrec 0db4ce11b7 fix: Make types explicit to fix crash on HashLink 2026-03-09 02:51:06 -06:00
340fd5dcf1 Add proper HashLink support
Co-authored-by: Sinco <113909588+sphis-Sinco@users.noreply.github.com>
2026-03-09 02:51:06 -06:00
EliteMasterEricandHundrec d569690a51 I think I was tired when I made that last commit lmao... 2026-03-09 02:51:06 -06:00
EliteMasterEricandHundrec 4a5afa2fc7 Oops there was a compile error 2026-03-09 02:51:06 -06:00
EliteMasterEricandHundrec 59c593b812 Adjust scroll speed tween duration based on playback rate 2026-03-09 02:51:06 -06:00
EliteMasterEricandHundrec 6ba9e00a9f Adjust camera zoom tween duration based on playback rate 2026-03-09 02:51:06 -06:00
EliteMasterEricandHundrec ec7bdd32e2 Adjust camera follow tween duration based on playback rate 2026-03-09 02:51:06 -06:00
AnimatingLegendandHundrec 939528a9bd refactor: remove discord_rpc from background process
DiscordRPC is being handled somewhere else. having these managers running twice, both for the same reasons its kind of pointless.
2026-03-09 02:51:06 -06:00
LasercarandHundrec 08b3af959d Chart editor - select above/below playhead 2026-03-06 05:17:14 -07:00
FuroandHundrec cea54e394c Legacy Voices System 2026-03-06 03:45:04 -07:00
Honton129andHundrec e710198afe Edit Note option in Context Menu
Shortcut to the  ``Notes`` toolbox by right-clicking a note and selecting ``Edit Note``.
2026-03-06 03:31:27 -07:00
Hyper_andHundrec bf3601ea8d fix: Properly trace Ansi code for exit trace 2026-03-06 03:31:24 -07:00
Hundrec c5566c8644 Exclude Week 7 bricks from ASTC 2026-03-04 23:21:51 -07:00
MAJigsaw77andHundrec 5944f5b55d Add Pangle mediation for Admob 2026-03-04 23:10:39 -07:00
RaltyandHundrec 077fbf6978 Fix sound tray playing multiple sounds at once, not appearing in lags 2026-03-04 23:10:39 -07:00
Hundrec f02bdc4225 Bump assets 2026-03-04 22:39:17 -07:00
EliteMasterEricandHundrec 8da9ed4ea0 Make sure only one stretchy sound plays at a time. 2026-03-04 22:39:17 -07:00
EliteMasterEricandHundrec 5ed4a2ddd0 Flag instrumental and vocal tracks as important to prevent them getting overriden by other sounds. 2026-03-04 22:39:17 -07:00
EliteMasterEricandHundrec 6293e2808b Reuse the sound objects for the stretchy sounds, to prevent too many of them playing at once. 2026-03-04 22:39:15 -07:00
Hundrec c6dc562769 Adjust some wording in the Backup window 2026-03-04 20:45:54 -07:00
marcoandHundrec a607396d04 Rename button text from 'Take Me There' to 'Open In Folder'
makes it clearer about what it does
2026-03-04 20:45:51 -07:00
ImVeryBadandHundrec 365f8dcfea Filter out unavailable difficulties from Story Mode levels. 2026-03-04 20:45:51 -07:00
FuroandHundrec b3eb709f4e Pixel Icon now changes the character value only if its valid 2026-03-04 15:25:30 -07:00
FuroandHundrec fcbce0a66b Fix Rank Slamming Animation 2026-03-04 15:25:21 -07:00
ComedyLostandHundrec 05032e3126 Play danceLeft anim for alternating characters 2026-03-04 15:25:16 -07:00
Hundrec b8a7189e24 Don't do Sys.exit force-kill on Mobile 2026-03-04 02:43:32 -07:00
AnimatingLegendandHundrec 881aba3b03 fix: prevent background processing upon game exit 2026-03-04 01:38:52 -07:00
Hundrec 5480774afe Fix Polymod for Mobile and HTML5 compiling 2026-03-03 17:21:59 -07:00
VirtuGuyandHundrec d62c8af20c Fix hold note length when hitting too early 2026-03-03 16:40:54 -07:00
MoonDroidandHundrec 7d0644f3c8 Add missing feature flag 2026-03-03 15:03:11 -07:00
Hyper_andHundrec fe21c0addd docs: Debug Hotkeys - Remove duplicate entry, fix error and add Mirrored Notes debug key 2026-03-02 20:16:03 -07:00
Hyper_andHundrec 219143c02d fix non existant paths not being sanitized properly on Linux 2026-03-02 20:16:03 -07:00
MightyTheArmiddiloandHundrec 03930a29c3 Remove duplicate blacklisting of the funkin.api.newgrounds package 2026-03-02 20:16:03 -07:00
ImVeryBadandHundrec 5d378cd9f2 Remove more traces from classes. 2026-03-02 20:16:03 -07:00
HundrecandKade e5db402025 Bump Polymod and adjust outdated mod error message
Co-Authored-By: Kade <26305836+Kade-github@users.noreply.github.com>
2026-03-02 20:16:03 -07:00
ImVeryBadandHundrec d348ef3127 Optional dependencies no longer throw window errors and improve log output messages. 2026-03-02 20:16:03 -07:00
Hundrec 9301c0c7dd Remove Song Preview 0 end times 2026-03-02 18:46:33 -07:00
ADA-FunniandHundrec 02ee8e64c8 Fix an issue where metadata stuff was acting weird. 2026-03-02 18:45:28 -07:00
ADA-FunniandHundrec 40eab2e461 Add customisable Freeplay song previews.
Any preview values over 15,000 get turned into 0 (start) and 0.2 (end).
2026-03-02 18:45:28 -07:00
AbnormalPoofandHundrec d6a65ca681 Tweak some animation lengths for Boyfriend DJ 2026-03-02 18:45:15 -07:00
EliteMasterEricandHundrec f8841bab35 Use a float internally to hold the Score, ensuring hold notes get scored correctly relative to the current framerate. 2026-03-02 01:38:30 -07:00
EliteMasterEricandAbnormalPoof dc23a116dd Update the PolymodErrorHandler to display an error message for API version or dependency issues. 2026-03-02 01:50:09 -06:00
AbnormalPoofandHundrec 024994e85a Re-export Boyfriend DJ using the latest BTA 2026-03-01 22:30:40 -07:00
MAJigsaw77andHundrec 9be1633320 Update extension-admob. 2026-03-01 04:21:54 -07:00
AnimatingLegendandHundrec 3b15873fc7 fix: chart editor playback-speed rounding upon reload 2026-02-28 00:05:34 -07:00
ComedyLostandHundrec 786f19c57d Stop playtest results with botplay 2026-02-28 00:05:34 -07:00
ComedyLostandHundrec ccb874e97a Stop the playbar head dragging when in song 2026-02-28 00:05:34 -07:00
VirtuGuyandHundrec f7fd7a57c3 Play SFX When Undoing Add Event 2026-02-28 00:05:33 -07:00
Hundrec 23f79aef58 Update assets submodule 2026-02-27 21:28:49 -07:00
EliteMasterEricandHundrec 2c394cc636 Fix an issue where displaying Tooltips would mess up HaxeUI field focus. 2026-02-27 21:26:11 -07:00
Hundrec d7a0139e4f Adjust focus lost volume level to 25%
Reducing to 50% wasn't noticeable enough, but 25% should be a clean reduction.
2026-02-27 21:25:57 -07:00
Karim AkraandHundrec 562d23005d Properly center the sound tray when the resolution is changed 2026-02-27 21:25:57 -07:00
EliteMasterEricandHundrec 671c152463 Fix a bug when the HUD camera zoom would be disabled when the MAIN camera zoom (different camera!) was above 1.35x. 2026-02-26 20:21:16 -07:00
EliteMasterEricandHundrec 3ce7c7939f Updated tooltips to use the note kind description 2026-02-25 00:52:47 -07:00
EliteMasterEricandHundrec 28450ccfc6 Build the list of note kinds from the NoteKindManager instead of hardcoding it 2026-02-25 00:52:45 -07:00
Hundrec 31dbd68194 Bump version to 0.8.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
2026-02-23 17:11:08 -07:00
Hundrec 29d776061c Changelog for 0.8.3 + adjustments 2026-02-23 17:10:35 -07:00
Hundrec 0805ec914e Bump docs to 0.8.3 2026-02-23 16:47:57 -07:00
Hundrec 98ac6a6ce1 Bump Polymod to fix 2hot script error on Web 2026-02-23 16:04:47 -07:00
ACrazyTownandHundrec 823120cdef Use FlxBitmapText for scoreText 2026-02-23 16:04:29 -07:00
Hundrec 1b13c6c53b Bump version to 0.8.2
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
2026-02-20 22:54:45 -07:00
HundrecandAbnormal 036de96143 Changelog for 0.8.2
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2026-02-20 22:50:57 -07:00
ComedyLostandHundrec 0b046cae9c Fix the Freeplay crash when scrolling too fast 2026-02-20 19:50:18 -07:00
Hundrec a4c5341b3b Revert Freeplay capsule timer clearing change 2026-02-20 17:04:30 -07:00
Hyper_andHundrec 5cbfab4f99 fix: Fix a plugin not initializing cameras on the correct frontend
Kevin and Michael found alive and well emoji whatthehappy
2026-02-19 03:14:51 -07:00
Hundrec baf887155b Bump assets for one minor chart adjustment 2026-02-18 01:24:29 -07:00
ImVeryBadandHundrec a5bbe94871 Add more default imports used by mods 2026-02-17 01:06:38 -07:00
ImVeryBadandHundrec ab26b28130 Remove spammy traces from some classes. 2026-02-17 01:06:38 -07:00
RagdollClashandHundrec 2606031ed2 Add an extra pixel to the cutout bitmaps 2026-02-16 14:23:00 -07:00
RagdollClashandHundrec 72f9d32a2f Account for offset when adding the fake cutouts 2026-02-16 14:23:00 -07:00
AbnormalPoofandHundrec 4b87bbf1cd Use a newer export for Title Screen text that got lost in rebasing 2026-02-16 14:23:00 -07:00
AbnormalPoofandHundrec c9802fdcf2 Fix confirm-hold not playing for pixel icons in Character Select... again 2026-02-16 14:22:56 -07:00
Hundrec e7f252953d Two quick chart fixes 2026-02-15 21:48:14 -07:00
Hundrec 7f299d8348 Revert "Use MenuList camera for Touch Detection instead"
This reverts commit 0400f4bd4a.
2026-02-15 21:01:28 -07:00
9d83d05c96 Blacklist lime.utils.AssetLibrary from scripts
Co-authored-by: charlesisfeline <62410083+charlesisfeline@users.noreply.github.com>
2026-02-15 21:01:28 -07:00
PurSnakeandHundrec d6919683c3 Remove dead objects from Freeplay capsule batching 2026-02-15 21:01:28 -07:00
EliteMasterEricandHundrec 879955c4a2 Format a few additional files. 2026-02-15 21:01:28 -07:00
AbnormalPoofandHundrec 6026e0b908 Run haxe-formatter on every file in source/ 2026-02-15 21:01:26 -07:00
32ef5404d8 fix: ResultsState - Start with song name hidden until the top bar shows up
Co-authored-by: Trayfellow <48515908+trayfellow@users.noreply.github.com>
2026-02-13 20:34:11 -07:00
AbnormalPoofandHundrec 3544a36de0 Rework Monster and Monster (Christmas) to use frame labels 2026-02-13 20:34:01 -07:00
RaltyandHundrec 06a1894946 Use MenuList camera for Touch Detection instead 2026-02-13 20:33:58 -07:00
AbnormalPoofandHundrec 40bb5b7a74 Rework Daddy Dearest to use frame labels 2026-02-13 20:33:41 -07:00
RagdollClashandHundrec 062c2fa331 Prevent goBack() from running if mustNotExit is true
Fixes mobile exiting GameOverSubState regardless of said variable.
2026-02-13 20:33:39 -07:00
AbnormalPoofandHundrec 49846dbc13 Re-export the Title Screen text to texture atlas 2026-02-13 20:33:39 -07:00
Karim AkraandHundrec e5a47aa74d Prevent a weird crash when freeplay is loaded 2026-02-13 20:33:20 -07:00
Karim AkraandHundrec 77fffdf370 Improve scrolling in freeplay for different framerates 2026-02-13 20:33:20 -07:00
EliteMasterEricandHundrec eaad0f2450 Additional readability changes. 2026-02-13 20:33:20 -07:00
77faf38d61 Cleanup GRhythmUtil.mirrorNoteDirection() along with a few other changes... ...like accounting for Strumline.KEY_COUNT which is now public, removing an unused temporary variable, and formatting GRhythmUtil.hx
Co-authored-by: ImVeryBad <nightbear843@yahoo.com>
Co-authored-by: ADA-Funni <codingking263@gmail.com>
2026-02-13 20:33:04 -07:00
gamerbrossandHundrec 134d220298 Fix chart editor vocals waveform with tempo changes 2026-02-13 20:33:04 -07:00
KoloandHundrec d4610f5f16 hide the tooltips when killing notes/events 2026-02-13 20:33:04 -07:00
AbnormalPoofandHundrec f5129b3283 Run oxipng on every image in assets/ 2026-02-13 20:32:51 -07:00
AbnormalPoofandHundrec ee6583fa82 Bump flixel-animate to fix an issue with the character select locks 2026-02-13 20:32:40 -07:00
AbnormalPoofandHundrec af72895e54 Blend with every camera underneath 2026-02-13 20:32:29 -07:00
AbnormalPoofandHundrec 8d17ad3dd1 Add cross-camera blending to the blend shader 2026-02-13 20:32:23 -07:00
EliteMasterEricandHundrec 723dd81e2b Modify several checkstyle and hxformat rules. 2026-02-13 20:32:11 -07:00
AbnormalPoofandHundrec 5c45d24e2e Bump polymod to fix BF DJ's cartoons 2026-02-11 02:05:24 -07:00
AbnormalPoofandHundrec ffe72b89a7 Re-export both Freeplay DJs to use frame labels 2026-02-11 02:05:24 -07:00
AbnormalPoofandHundrec bc92d6cebf Add useAnimatePosition and make BF and Pico use it 2026-02-11 02:05:20 -07:00
AbnormalPoofandHundrec b4bc3ca6cf Frame label support for Freeplay DJs 2026-02-11 02:05:20 -07:00
AbnormalPoofandHundrec 8439272d00 Optimize Character Select atlases 2026-02-11 02:05:02 -07:00
AbnormalPoofandHundrec c5a7442415 Change a final to a var in BF DJ's script 2026-02-11 02:05:00 -07:00
Hundrec 31b7fdf02b Re-export every chart + song metadata in the game
The new 0.8.2 json2object library exports charts consistently!
I've re-exported all 61 songs in the game to ensure that future chart changes have readable diffs!
2026-02-10 18:55:38 -07:00
dafe4fe918 Fix a few comment typos
Very important, thank you

Co-Authored-By: charlesisfeline <62410083+charlesisfeline@users.noreply.github.com>
2026-02-10 18:42:20 -07:00
Hundrec 6737146571 Fix ctrl-click on hold note crashing Chart Editor 2026-02-10 18:41:38 -07:00
Hundrec 33d1fd578e Bump Polymod again to fix error on Web 2026-02-06 15:00:35 -07:00
MAJigsaw77andHundrec 0c9edf93c3 Fix multiple script errors cause by the Polymod update. 2026-02-06 15:00:26 -07:00
AbnormalPoofandHundrec 241f140a98 Bump polymod to the latest commit 2026-02-06 15:00:24 -07:00
EliteMasterEricandHundrec 0311c7373e Remove ScriptedObject since it's deprecated anyway (scripts don't have to extend anything anymore) 2026-02-06 15:00:20 -07:00
EliteMasterEricandHundrec ca95fa78c4 Update polymod to the latest experimental. 2026-02-06 15:00:20 -07:00
EliteMasterEricandHundrec 7fa5d77db7 Switch from .init() to .scriptInit() 2026-02-06 15:00:20 -07:00
AbnormalPoofandHundrec dcc3baae26 Re-export Blazin' characters using BTA 2026-02-03 00:56:16 -07:00
ccb270612c Quad batch capsules to prevent a memory leak
Co-Authored-By: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-Authored-By: Mario Hernando <97055307+MaybeMaru@users.noreply.github.com>
2026-02-02 21:35:06 -07:00
EliteMasterEricandHundrec 404b601012 An extensive review and commenting of various code style enforcements. 2026-02-02 21:35:06 -07:00
AbnormalPoofandHundrec 02d83a766d Re-export the bottom boppers in Week 5 Erect to texture atlas 2026-02-02 21:34:49 -07:00
AbnormalPoofandHundrec f40da353a2 Re-export Pico (Christmas) to texture atlas 2026-02-02 21:34:47 -07:00
ComedyLostandHundrec c0c550e209 Fix Freeplay difficulty graphics not accounting for modded difficulties/variations 2026-02-02 03:26:46 -07:00
AbnormalPoofandHundrec 29ac2ad58b Fix an issue where the sprite didn't respect render texture or stage matrix settings 2026-02-02 03:26:46 -07:00
AbnormalPoofandHundrec 9b0b273004 Adjusted offsets for Pico (Playable) 2026-02-01 03:33:53 -07:00
AbnormalPoofandHundrec 17f120f5ee Fix an issue where multiple characters couldn't be used if they had multiple animate atlases 2026-02-01 03:33:50 -07:00
VirtuGuyandHundrec 284cfc7ebc Use pointer cursor for moveable UI components 2026-02-01 01:23:40 -07:00
Hundrec aa5d30eecc Remove 30% threshold for Chart Editor Results 2026-02-01 01:23:40 -07:00
AbnormalPoofandHundrec c11ecfcb6f Bump polymod to fix in-game cutscenes being unskippable 2026-02-01 01:23:40 -07:00
AbnormalPoofandHundrec aa251af116 Fix Boyfriend (Christmas) being default Boyfriend 2026-01-31 21:15:26 -07:00
AbnormalPoofandHundrec ea7bc750d2 Fix Pico (Playable) throwing null object reference when loaded twice 2026-01-31 21:15:23 -07:00
AbnormalPoofandHundrec a043512f0e Revert a screen bounds fix now that they're fixed in flixel-animate proper 2026-01-31 21:15:23 -07:00
AbnormalPoofandHundrec 5805c310c1 Rework some flickers to use FlxTween.flicker instead of FlxFlicker 2026-01-31 20:22:51 -07:00
AbnormalPoofandHundrec bf0135d48e Bump polymod to the latest experimental commit 2026-01-31 20:10:23 -07:00
AbnormalPoofandHundrec e1f950d3e6 Bump flixel-animate to the latest version 2026-01-31 20:10:23 -07:00
AbnormalPoofandHundrec 018780620d Bump openfl to fix an issue with the Week 6 note splashes 2026-01-31 20:10:23 -07:00
Hundrec ba2f8df30b Fix up 2hot 2026-01-31 17:57:02 -07:00
Hundrec ba77fc6677 Batch of chart fixes and adjustments for 0.8.2
Includes 24 changed charts
View assets commit for diffs
2026-01-31 17:23:19 -07:00
LasercarandHundrec ff3a5c4b9b Cancel screenshot spam timer in pre-state switch 2026-01-31 00:07:57 -07:00
MaybeMaruandHundrec 3aef0e5432 Disable Character Select fade shader when unused 2026-01-31 00:07:57 -07:00
MightyTheArmiddiloandHundrec 83fb754e8e Save the Playtest Results Preference 2026-01-31 00:07:35 -07:00
AbnormalPoofandHundrec 5042448e98 Re-export Nene (Christmas) to texture atlas 2026-01-31 00:07:31 -07:00
AbnormalPoofandHundrec bca18170e7 Disable debug draw for the perspective floor in Spaghetti 2026-01-31 00:07:19 -07:00
EliteMasterEricandHundrec 524468135d Cleanup HScript to stop using Polymod to access other scripted classes (since that can be done directly now). 2026-01-31 00:07:17 -07:00
AbnormalPoofandHundrec de5fe9b950 Fix A-Bot's visualizer showing full bars for a single frame when entering a song 2026-01-29 22:49:19 -07:00
AbnormalPoofandHundrec 17ed98ee4d Re-export Pico (Playable) and Pico (Dark) to texture atlases 2026-01-29 22:27:42 -07:00
AbnormalPoofandHundrec 1b6c2d1f93 Reset the symbol graphic when the Album is destroyed 2026-01-29 22:27:38 -07:00
MAJigsaw77andHundrec 7c90aee994 Fix paths on Windows Subsystem for Linux. 2026-01-29 22:27:38 -07:00
AbnormalPoofandHundrec 96bdfac0b9 Adjust some character scripts 2026-01-29 22:27:22 -07:00
Karim AkraandHundrec 359661b549 FIx the game position on low resolution 4:3 displays 2026-01-29 22:08:00 -07:00
AbnormalPoofandHundrec 1e43902fff Rework 3 Nene variants to use the script extending system 2026-01-29 22:08:00 -07:00
AbnormalPoofandHundrec 84a79f6833 Tweak the blacklist a bit more and add back modOptions map 2026-01-29 22:08:00 -07:00
EliteMasterEricandHundrec bcd3b03a75 Update Polymod again (HScript is now built-in) 2026-01-29 22:07:59 -07:00
EliteMasterEricandHundrec 1ff79a7825 Modified funkin.Save blacklist, and added a new function specifically for retrieving and saving modded preferences in a standard way. 2026-01-29 22:07:59 -07:00
EliteMasterEricandHundrec c3cdddc46e Bump Polymod to the latest version 2026-01-29 22:07:59 -07:00
EliteMasterEricandHundrec ac2f1f602b Tweak FlxSave to use field blacklisting. 2026-01-29 22:07:59 -07:00
Hundrec 40ea803c56 Also process all events other than playAnimation 2026-01-29 22:07:59 -07:00
EliteMasterEricandHundrec dce987b345 Add the processOldEvents parameter to song events, and enable it for FocusCamera. 2026-01-29 22:07:59 -07:00
AbnormalPoofandHundrec 5804aa100d Re-export Pico's GREAT animation to not have huge black and white boxes in the spritemap 2026-01-29 22:07:59 -07:00
HundrecandHyper_ f1276a64a0 Fix crash when saving a chart
Co-Authored-By: Hyper_ <40342021+nothyper-474@users.noreply.github.com>
2026-01-29 22:07:59 -07:00
AbnormalPoofandHundrec 503bbaaa46 Small fix to make the blend shader a lot more accurate 2026-01-29 22:07:59 -07:00
AbnormalPoofandHundrec 0dbd8439bd Remove blend baking from some atlases in the game 2026-01-29 22:07:59 -07:00
LasercarandHundrec 40e5d1a4c1 chart editor - popup when time change added at grid playhead 2026-01-29 22:07:59 -07:00
HundrecandVirtuGuy 58803cd221 Don't smooth the edges of Stage Editor crosshair
Co-Authored-By: VirtuGuy <103977942+virtuguy@users.noreply.github.com>
2026-01-29 22:07:59 -07:00
ff0a226f53 Fix Stage Editor load dialog showing as save
Co-Authored-By: Hyper_ <40342021+nothyper-474@users.noreply.github.com>
Co-Authored-By: Pāvels Rimašs <69017727+anysad@users.noreply.github.com>
2026-01-29 22:07:59 -07:00
LasercarandHundrec 1d19286f6b More Stage Editor selection functionality 2026-01-29 22:07:59 -07:00
KoloandHundrec 5cf114143c reset gameover/pause/countdown stuff after leaving editors 2026-01-29 22:07:59 -07:00
AbnormalPoofandHundrec 8331a1fa7f Re-export the can to restore the unused sparkling effect 2026-01-29 22:07:59 -07:00
db7bee7902 Add support for khronos blend modes, enabling 14 new blend modes to work properly
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: ACrazyTown <47027981+ACrazyTown@users.noreply.github.com>
Co-authored-by: PurSnake <56314743+PurSnake@users.noreply.github.com>
2026-01-29 22:07:59 -07:00
Hundrec 2ba0f37a5a Update LICENSE to 2026 2026-01-29 22:07:59 -07:00
Karim AkraandHundrec 31f873ffc2 add ios assets path to clearAssets 2026-01-29 22:07:59 -07:00
Karim AkraandHundrec f7b5d5c62f Lock the game's controls onto keyboard mode as long as a keyboard/gamepad device is connected 2026-01-29 22:07:59 -07:00
ImVeryBadandHundrec 94570d8c7c Center waveforms on health icons and adjust icon X-offsets in Chart Editor 2026-01-29 22:07:59 -07:00
PurSnakeandHundrec f6036343c9 Change FlxPieDial to FlxRadialGauge and display it more nicely visually 2026-01-29 22:07:59 -07:00
MightyTheArmiddiloandHundrec cc8060db5b Fix hold cover positioning 2026-01-29 22:07:59 -07:00
boopboyandHundrec 511f4d5b64 Make musicSuffix accept any pixel suffix 2026-01-29 22:07:58 -07:00
ComedyLostandHundrec b04a7708b1 Clear Freeplay previews when switching selection
Makes it harder to crash Freeplay when scrolling really fast
2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec dd512d02e7 Fix Missing Album Title Showing Flixel Icon 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec ff89c09b6f Fix album roll after character select exit 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec 429e018749 Fix capsules going offset in ranks 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec babe37a0f0 Fix last BPM digit for capsules 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec 122df21223 Fix freeplay pixel icon not selecting 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec 016c53061c Fix soundtray appearing under stickers 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec 429704676a Apply alpha to onion skin after character change 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec cda1ca6897 Fix crash when closing game within stage editor 2026-01-29 22:07:58 -07:00
KoloandHundrec 8954dee6d6 don't use the default names for stage editor stuff 2026-01-29 22:07:58 -07:00
Hyper_andHundrec b71e12ec5c Fix 2nd measure not being rendered and previous measure check being useless 2026-01-29 22:07:58 -07:00
KoloandHundrec c2055a322d add support for decimals in cam bop offset and rate 2026-01-29 22:07:58 -07:00
KadeandHundrec 583700006c less confusing instructions 2026-01-29 22:07:58 -07:00
Kade-gtihubandHundrec 928c2fcc19 QOL and fixes for OffsetMenu 2026-01-29 22:07:58 -07:00
Hundrec 3c913d29e3 Bump assets 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec 52e015ad14 Fix strange menu scrolling behavior on web 2026-01-29 22:07:58 -07:00
EliteMasterEricandHundrec bef8cf9a0e I got a crash in the Crash Handler when the crash happened before FlxGame initialized. 2026-01-29 22:07:58 -07:00
VirtuGuyandHundrec eae4cb2160 Fix char select lock anim not playing on mobile 2026-01-29 22:07:58 -07:00
Hundrec 955c94ed79 Properly credit contributor in a Changelog entry 2026-01-29 22:07:58 -07:00
KoloandHundrec 95109daedb use character's camera focus point to determine the game over cam position 2026-01-29 22:07:58 -07:00
MoonDroidandHundrec 00f28fdb79 Remove duped function and add extra docs 2026-01-29 22:07:57 -07:00
LasercarandHundrec aad014a0ba Mirror notes Chart Editor command 2026-01-29 22:07:57 -07:00
ImVeryBadandHundrec 4917bd0591 Ignore the .idea folder from mods. 2026-01-29 22:07:57 -07:00
charlesisfelineandHundrec 54943b22f8 Remove unused ButtonRemapSubstate 2026-01-29 22:07:57 -07:00
TrofemandHundrec ec6e26c298 Update example mod's API version to 0.8.0 2026-01-29 22:07:57 -07:00
3db958a76b A bunch of typo fixes
Co-Authored-By: charlesisfeline <62410083+charlesisfeline@users.noreply.github.com>
Co-Authored-By: TechnikTil <techniktil@tilnotdrip.org>
Co-Authored-By: MightyTheArmiddilo <132609476+mightythearmiddilo@users.noreply.github.com>
Co-Authored-By: BaranMuzu <104278499+baranmuzu@users.noreply.github.com>
2026-01-29 22:07:57 -07:00
Karim AkraandHundrec f5f2a2ac4c replace the AVM events with ad load/dismiss events and suspend the audio context instead of each audio manually 2026-01-29 22:07:57 -07:00
Cameron TaylorandHundrec 26fe00b559 fix a few of the scripts to point from art/ -> scripts/ when needed 2026-01-29 22:07:57 -07:00
Cameron TaylorandHundrec 899d793e1c move some scripts from art/ submodule to main funkin repo 2026-01-29 22:07:57 -07:00
AbnormalPoofandHundrec 430e2b9dcc Removed an unused TitleOutline shader 2026-01-29 22:07:57 -07:00
AbnormalPoofandHundrec 9189c35585 Title screen cleanup 2026-01-29 22:07:57 -07:00
Hundrec 0855b4da4e Bump assets submod 2026-01-29 22:07:57 -07:00
EliteMasterEricandHundrec ad9c6581ff Update docs for SongLoadScriptEvent so people know what it does. 2026-01-29 22:07:57 -07:00
Kade-gtihubandHundrec 293d303c16 Add Mirror to PlayState Params 2026-01-29 22:07:57 -07:00
PurSnakeandHundrec e4a4197482 Ease Previews 2026-01-29 22:07:57 -07:00
2886e29d58 Add currentStage var to clean up scripts
Co-Authored-By: Kade <26305836+Kade-github@users.noreply.github.com>
Co-Authored-By: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2026-01-29 22:07:57 -07:00
EliteMasterEricandHundrec 5868cb1d78 Update json2object to respect @:order when exporting + skip default values
* @:order is only for Maps, not Arrays (IDK how this compiled before lol?)
* Don't use @:default on version number.
* Don't use @:default for ChartManifestData
* Don't use @:default for generatedBy
2026-01-13 21:02:24 -07:00
567 changed files with 32042 additions and 12560 deletions
+4 -4
View File
@@ -14,7 +14,7 @@ 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
- label: I did not have any mods installed when I encountered this issue, or the issue is related to mods
- type: dropdown
attributes:
@@ -48,19 +48,19 @@ body:
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
placeholder: ex. iPhone 17, Galaxy S26, iPad 11th Gen
- type: input
attributes:
label: Mobile OS Version
description: (Mobile users only) What version is your Operating System?
placeholder: ex. iOS 26.2, Android 16, iPadOS 26.2
placeholder: ex. iOS 26.4, Android 16, iPadOS 26.4
- 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.8.1
placeholder: ex. 0.8.6 or 0.9 Feature Preview 3
validations:
required: true
+2 -2
View File
@@ -36,7 +36,7 @@ body:
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.8.1
placeholder: ex. 0.8.6 or 0.9 Feature Preview 3
validations:
required: true
@@ -52,7 +52,7 @@ body:
attributes:
label: Location
description: Where did you find the issue(s)? Include the name of the song, the variation, the difficulty, the time/section of the song, and any images or videos.
placeholder: ex. Cocoa Erect on Erect/Nightmare difficulties at Section 30
placeholder: ex. Cocoa Erect [Nightmare] at Section 30, step 5
validations:
required: true
+1 -1
View File
@@ -36,7 +36,7 @@ body:
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.8.1
placeholder: ex. 0.8.6 or `preview/public-playtest`
validations:
required: true
+4 -4
View File
@@ -15,7 +15,7 @@ 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
- label: I did not have any mods installed when I encountered this issue, or the issue is related to mods
- type: dropdown
attributes:
@@ -49,19 +49,19 @@ body:
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
placeholder: ex. iPhone 17, Galaxy S26, iPad 11th Gen
- type: input
attributes:
label: Mobile OS Version
description: (Mobile users only) What version is your Operating System?
placeholder: ex. iOS 26.2, Android 16, iPadOS 26.2
placeholder: ex. iOS 26.4, Android 16, iPadOS 26.4
- 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.8.1
placeholder: ex. 0.8.6 or 0.9 Feature Preview 3
validations:
required: true
+4 -4
View File
@@ -5,7 +5,7 @@ inputs:
haxe:
description: 'Version of haxe to install'
required: true
default: '4.3.6'
default: '4.3.7'
hxcpp-cache:
description: 'Whether to use a shared hxcpp compile cache'
required: true
@@ -71,7 +71,7 @@ runs:
- name: Restore cached dependencies
id: cache-hmm
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: .haxelib
key: haxe-hmm-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}
@@ -98,7 +98,7 @@ runs:
# by default use a shared hxcpp cache
- if: ${{ inputs.hxcpp-cache == 'true' }}
name: Restore hxcpp cache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ inputs.hxcpp-cache-path }}
key: haxe-hxcpp-${{ runner.os }}-${{ github.ref_name }}-${{ github.sha }}
@@ -114,7 +114,7 @@ runs:
# if it's explicitly disabled, still cache export/ since that then contains the builds
- if: ${{ inputs.hxcpp-cache != 'true' }}
name: Restore export cache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ inputs.hxcpp-cache-path }}
key: haxe-export-${{ runner.os }}-${{ github.ref_name }}-${{ github.sha }}
+3 -3
View File
@@ -61,7 +61,7 @@ runs:
- name: Get latest butler version
shell: bash
run: |
LATEST=$(curl -sfL https://broth.itch.ovh/butler/$OS_AND_ARCH/LATEST)
LATEST=$(curl -sfL https://broth.itch.zone/butler/$OS_AND_ARCH/LATEST)
echo BUTLER_LATEST=$LATEST >> "$GITHUB_ENV"
command -v butler \
@@ -70,7 +70,7 @@ runs:
- name: Try to get butler from cache
id: cache-butler
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ env.BUTLER_INSTALL_PATH }}
key: butler-${{ runner.os }}-${{ env.BUTLER_LATEST }}
@@ -88,7 +88,7 @@ runs:
mkdir -p $BUTLER_INSTALL_PATH
cd $BUTLER_INSTALL_PATH
curl -L -o butler.zip https://broth.itch.ovh/butler/$OS_AND_ARCH/LATEST/archive/default
curl -L -o butler.zip https://broth.itch.zone/butler/$OS_AND_ARCH/LATEST/archive/default
unzip butler.zip
chmod +x butler
+38 -15
View File
@@ -24,10 +24,10 @@ jobs:
trigger-build: ${{ steps.should-trigger.outputs.result }}
steps:
- name: Checkout repo
uses: funkincrew/ci-checkout@v7.3.3
uses: funkincrew/ci-checkout@v7.4
with:
submodules: false
- uses: dorny/paths-filter@v3
- uses: dorny/paths-filter@v4
id: filter
with:
base: ${{ github.ref }}
@@ -59,7 +59,7 @@ jobs:
list: ${{ steps.build-tags.outputs.list }}
steps:
- name: Gather build tags
uses: actions/github-script@v7
uses: actions/github-script@v8
id: build-tags
with:
script: |
@@ -96,17 +96,20 @@ jobs:
packages: write
steps:
- name: Checkout repo
uses: funkincrew/ci-checkout@v7.3.3
uses: funkincrew/ci-checkout@v7.4
with:
submodules: false
- name: Log into GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
with:
context: ./build
push: true
@@ -143,14 +146,14 @@ jobs:
run: |
git config --global --replace-all safe.directory $GITHUB_WORKSPACE
- name: Get checkout token
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
id: app_token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PEM }}
owner: ${{ github.repository_owner }}
- name: Checkout repo
uses: funkincrew/ci-checkout@v7.3.3
uses: funkincrew/ci-checkout@v7.4
with:
submodules: 'recursive'
token: ${{ steps.app_token.outputs.token }}
@@ -184,7 +187,7 @@ jobs:
timeout-minutes: 120
- name: Save build artifact to Github Actions
if: ${{ github.event.inputs.save-artifact }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: build-${{ matrix.target }}
path: export/release/${{matrix.target}}/bin/
@@ -212,14 +215,14 @@ jobs:
BUILD_DEFINES: ${{ github.event.inputs.build-defines || '-DGITHUB_BUILD' }}
steps:
- name: Get checkout token
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
id: app_token
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PEM }}
owner: ${{ github.repository_owner }}
- name: Checkout repo
uses: funkincrew/ci-checkout@v7.3.3
uses: funkincrew/ci-checkout@v7.4
with:
submodules: 'recursive'
token: ${{ steps.app_token.outputs.token }}
@@ -233,7 +236,7 @@ jobs:
echo "HAXEPATH=$(haxelib config)" >> "$GITHUB_ENV"
- name: Restore cached dependencies
id: cache-hmm
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: .haxelib
key: haxe-hmm-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}
@@ -242,15 +245,35 @@ jobs:
run: |
git config --global 'url.https://x-access-token:${{ steps.app_token.outputs.token }}@github.com/.insteadOf' https://github.com/
git config --global advice.detachedHead false
haxelib --global git haxelib https://github.com/FunkinCrew/haxelib.git
haxelib --global git hmm https://github.com/FunkinCrew/hmm.git
haxelib --global run hmm install -q
cd .haxelib/hxcpp/git/tools/hxcpp && haxe compile.hxml
haxelib --global fixrepo
haxelib --global list
pushd .haxelib/hxcpp/git/tools/hxcpp && haxe compile.hxml && popd
- if: ${{ matrix.target != 'html5' }}
name: Restore hxcpp cache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: /usr/share/hxcpp
key: haxe-hxcpp-${{ runner.os }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: haxe-hxcpp-${{ runner.os }}-${{ github.ref_name }}
- name: Restore lime rebuild cache
id: cache-lime
uses: actions/cache@v5
with:
path: .haxelib/lime/git/ndll/Linux64
key: haxe-lime-linux64-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}-${{ github.sha }}
restore-keys: haxe-lime-linux64-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}
- name: Setup lime
run: |
haxelib --always run lime setup
haxelib run lime rebuild hxcpp
- if: ${{ steps.cache-lime.outputs.cache-hit != 'true' }}
name: Rebuild lime
run: |
haxelib run lime rebuild cpp -64
git -C .haxelib/lime/git status || true
- name: Populate .env
run: |
touch .env
@@ -262,7 +285,7 @@ jobs:
timeout-minutes: 120
- name: Save build artifact to Github Actions
if: ${{ github.event.inputs.save-artifact }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: build-${{ matrix.target }}
path: export/release/${{matrix.target}}/bin/
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
steps:
- name: Cancel queued workflows for ${{ github.event.pull_request.head.ref }}
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
result-encoding: string
retries: 3
+1 -1
View File
@@ -27,4 +27,4 @@ jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/label-actions@v4
- uses: dessant/label-actions@v5
@@ -7,6 +7,11 @@ on:
types:
- opened
# Ensure only one task can execute for a given PR at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
queue: max
jobs:
# Apply `status: pending triage` to newly created pull requests
+5 -1
View File
@@ -13,6 +13,10 @@ name: "Pull Request Labeler"
on:
- pull_request_target
# Ensure only one task can execute for a given PR at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
queue: max
jobs:
# Apply labels to pull requests based on which files were edited
@@ -23,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set basic labels
uses: actions/labeler@v5
uses: actions/labeler@v6
with:
sync-labels: true
# Apply labels to pull requests based on how many lines were edited
+8
View File
@@ -17,6 +17,14 @@ NewgroundsCredentials.hx
.idea/
*.iml
# Dox output and types
docs/dox/output
docs/dox/Windows.xml
docs/dox/Mac.xml
docs/dox/iOS.xml
docs/dox/Linux.xml
docs/dox/Android.xml
# Mobile signing stuff
.apple/
.env
+7 -2
View File
@@ -80,13 +80,13 @@
{ "name": "html5", "enabled": true, "label": "HTML5" },
{ "name": "android", "enabled": true, "label": "Android" },
{ "name": "ios", "enabled": true, "label": "iOS" },
// Disabled targets
{ "name": "hl", "enabled": false, "label": "HashLink" },
{ "name": "air", "enabled": false },
{ "name": "electron", "enabled": false },
{ "name": "flash", "enabled": false },
{ "name": "neko", "enabled": false },
{ "name": "tvos", "enabled": false }
{ "name": "hl", "enabled": false }
],
"lime.defaultTargetConfiguration": "Windows / Debug",
"lime.targetConfigurations": [
@@ -144,6 +144,11 @@
"target": "windows",
"args": ["-debug", "-DLATENCY", "-DFEATURE_DEBUG_FUNCTIONS"]
},
{
"label": "Windows / Debug (No Asset Redirect)",
"target": "windows",
"args": ["-debug", "-DNO_REDIRECT_ASSETS_FOLDER"]
},
{
"label": "Windows / Debug (Waveform Test)",
"target": "windows",
+395 -25
View File
@@ -4,6 +4,375 @@ 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.8.7] - 2026-08-23
### Fixed
- [ANDROID] Fixed a crash when opening an FNFC chart file.
- [ANDROID] Fixed errors and crashes related to the lime backend.
- [ANDROID] Fixed a shader not displaying correctly in some places.
## [0.8.6] - 2026-08-12
### Added
- Added the ability to toggle Discord RPC statuses and hide song info.
- [LINUX] Added support for Wayland, which the game now defaults to. (Thanks Starexify!)
- Added the game version as a compilation flag for modders to access. ([e51ae10](https://github.com/FunkinCrew/Funkin/commit/e51ae1098a9392c7ec3a903543f3aa4fc4220da1)) - by @zxcksharks in [#7659](https://github.com/FunkinCrew/Funkin/pull/7659)
- Added a shouldBop property to HealthIconData to allow animated icons to bop. ([cc91faa](https://github.com/FunkinCrew/Funkin/commit/cc91faaccc63d2050270723bd49477f8b518ab6f)) - by @Starexify in [#6901](https://github.com/FunkinCrew/Funkin/pull/6901)
- Added album and sticker pack fields to the Chart Editor Metadata window. ([790e3fb](https://github.com/FunkinCrew/Funkin/commit/790e3fb097b7054e7cf4010d6b588264414d283a)) - by @Starexify in [#6266](https://github.com/FunkinCrew/Funkin/pull/6266)
### Changed
- [HTML5] The “Touch To Play” sprite now smoothly scales when hovered.
- Made some improvements to width/height and cliprect functionality for FunkinGroup.
- The Chart Editor now consistently exports chart data in the same order. (Thanks TechnikTil!)
- Discord RPC images can now be configured in the album and song data files.
- Discord RPC now pulls icons based on character icon data. ([bd23b5c](https://github.com/FunkinCrew/Funkin/commit/bd23b5c12f734eae529a8d2d2593fd1d6eb9a27b)) - by @7oltan in [#7643](https://github.com/FunkinCrew/Funkin/pull/7643)
- Forced animations for the player character now unmute the player's vocals. ([e0a6253](https://github.com/FunkinCrew/Funkin/commit/e0a625331010a2dddde639a24953dd88f25010b1)) - by @Lasercar in [#4314](https://github.com/FunkinCrew/Funkin/pull/4314)
- The Animation Editor now plays the Chart Editor theme music and click sounds. ([f42dcec](https://github.com/FunkinCrew/Funkin/commit/f42dcecab6966f77162308a0564af558616ea81b)) - by @JVNpixels in [#7556](https://github.com/FunkinCrew/Funkin/pull/7556)
### Fixed
- Made some niche fixes to Polymod.
- Argument count validation no longer crashes the game entirely in some instances. (Thanks Starexify!)
- The `cast` keyword no longer throws a parsing error. (Thanks gamerbross!)
- Every non-Windows platform is now case-insensitive. (Thanks TechnikTil!)
- Preprocessors that span the entire file no longer throw an error. (Thanks KoloInDaCrib!)
- Scripted class extending no longer breaks with multiple scripted layers. (Thanks TechnikTil!)
- Imports with module names (ex. `funkin.play.character.BaseCharacter.CharacterType​​`) no longer throw an import error. (Thanks NotHyper-474!)
- [iOS] Connecting a keyboard no longer freezes the game.
- The Darken blend mode no longer renders with black boxes, fixing the Boyfriend Freeplay DJ Dad animation.
- The Open File dialog now opens from the latest directory, not the root directory.
- The Chart Editor now exports charts with correct suffixes for vocal tracks.
- Clicking the Save Chart button now displays a notification in the Chart Editor.
- Disconnecting a controller while in the gamepad controls menu no longer crashes the game. ([6fe2089](https://github.com/FunkinCrew/Funkin/commit/6fe2089beac639124d3561d4c2c1af1ffb7dfe11)) - by @MrMadera in [#7214](https://github.com/FunkinCrew/Funkin/pull/7214)
- Hot-reloading and re-entering the Lag Adjustment menu no longer crashes the game. ([adbe5ba](https://github.com/FunkinCrew/Funkin/commit/adbe5ba7cb53f67363ec205c5e555744e69215de)) - by @AnimatingLegend in [#7304](https://github.com/FunkinCrew/Funkin/pull/7304)
- `onExit` is now properly called when exiting the game. ([90712bf](https://github.com/FunkinCrew/Funkin/commit/90712bf1e62a20d1201c3da15b4554720e9fff46)) - by @AnimatingLegend in [#7321](https://github.com/FunkinCrew/Funkin/pull/7321)
- Focusing into the game with 0 volume and Pause on Unfocus disabled no longer increases the volume. ([18f5e25](https://github.com/FunkinCrew/Funkin/commit/18f5e25496d2cb74fff24e490a95db29a1fb59e3)) - by @ahmed7p in [#7750](https://github.com/FunkinCrew/Funkin/pull/7750)
- Save Data prompts no longer allow scrolling the Options menu behind them. ([83bfccc](https://github.com/FunkinCrew/Funkin/commit/83bfccc10115b089f6b8d747c366c2be64c4335c)) - by @Starexify in [#7213](https://github.com/FunkinCrew/Funkin/pull/7213)
- Adjusted the Lag Adjustment overlay to fit the whole screen. ([27fd960](https://github.com/FunkinCrew/Funkin/commit/27fd960fb369b2baf3c3377fa317732bf80a5230)) - by @JVNpixels in [#7358](https://github.com/FunkinCrew/Funkin/pull/7358)
- Input latency is now calculated correctly when hitting a note late in the Lag Adjustment menu. ([de36ca8](https://github.com/FunkinCrew/Funkin/commit/de36ca87e8b95d8fe4d40d458c355baf52e4d94a)) - by @nykwono in [#7792](https://github.com/FunkinCrew/Funkin/pull/7792)
- Weeks with non-default variation songs no longer use default variation scripts. ([2a49681](https://github.com/FunkinCrew/Funkin/commit/2a4968115f0ed5e81d4209bedba3f8bf153aab6a)) - by @requazar in [#7586](https://github.com/FunkinCrew/Funkin/pull/7586)
- Scrolling Freeplay after the rank slam animation now properly updates the song preview. ([347f7cf](https://github.com/FunkinCrew/Funkin/commit/347f7cfecbe91fc06e71a502ee58a5d7859be5fc)) - by @AnimatingLegend in [#7230](https://github.com/FunkinCrew/Funkin/pull/7230)
- Earning a new rank no longer causes the song title to clip incorrectly. ([0b6198f](https://github.com/FunkinCrew/Funkin/commit/0b6198f23ad7a957d40eaaf6d4af9b976e6e1a36)) - by @KoloInDaCrib in [#7350](https://github.com/FunkinCrew/Funkin/pull/7350)
- Selecting a Freeplay song capsule no longer occasionally squashes the text. ([bdf51dc](https://github.com/FunkinCrew/Funkin/commit/bdf51dcd4392a7d99c9837bd3b56b4e6497cf207)) - by @Lasercar in [#6038](https://github.com/FunkinCrew/Funkin/pull/6038)
- The Freeplay backing image now respects modified alpha values. ([840c043](https://github.com/FunkinCrew/Funkin/commit/840c0431ecaf3004901bd09a346c126eb8e2f484)) - by @Luscious77 in [#7576](https://github.com/FunkinCrew/Funkin/pull/7576)
- Removed clipping from the OST Vol 1 album title sprite. ([90282d7](https://github.com/FunkinCrew/funkin.assets/commit/90282d78c6a326f1c1e05bec3f3638d3f0cd66a9)) - by @LeGooeyy in [funkin.assets#410](https://github.com/FunkinCrew/funkin.assets/pull/410)
- The Freeplay change character hint now updates consistently when a gamepad is connected. ([e0af5e2](https://github.com/FunkinCrew/Funkin/commit/e0af5e282e6cf2ad0a63dbf633eb325204fbd649)) - by @MrMadera in [#7409](https://github.com/FunkinCrew/Funkin/pull/7409)
- Character Select nametags no longer become stuck pixelated when switching between characters. ([a62e1c0](https://github.com/FunkinCrew/Funkin/commit/a62e1c08ab4a8cbe1f0bc790e4c228b5b64f0071)) - by @NotHyper-474 in [#7217](https://github.com/FunkinCrew/Funkin/pull/7217)
- Pressing a note with two different keybinds now properly penalizes health. ([d60fe07](https://github.com/FunkinCrew/Funkin/commit/d60fe0726f1cab3999a35ff497ba32e82afbd1b8)) - by @realvirtu in [#7744](https://github.com/FunkinCrew/Funkin/pull/7744)
- Input latency is now calculated correctly when hitting a note late. ([b97012a](https://github.com/FunkinCrew/Funkin/commit/b97012a10d54e222a3f370956d0e42f8d8eaab47)) - by @Lasercar in [#7367](https://github.com/FunkinCrew/Funkin/pull/7367)
- Conductor events are no longer dispatched when a substate is active. ([19610c4](https://github.com/FunkinCrew/Funkin/commit/19610c43099dfaf4a8b9ae70dc7f4b1833f420a9)) - by @KoloInDaCrib in [#6886](https://github.com/FunkinCrew/Funkin/pull/6886)
- Health icon angles now lerp at the proper rate. ([2bb5397](https://github.com/FunkinCrew/Funkin/commit/2bb5397c2b9e7fcc9d62670c6a86ebce64737f46)) - by @Starexify in [#7222](https://github.com/FunkinCrew/Funkin/pull/7222)
- Hold note covers no longer disappear when too many are on screen at once. ([f0a5188](https://github.com/FunkinCrew/Funkin/commit/f0a5188cb11cde3f6646254a39953e7b064dd7e9)) - by @realvirtu in [#7593](https://github.com/FunkinCrew/Funkin/pull/7593)
- The notestyle now properly falls back to the default notestyle in PlayState. ([ac10239](https://github.com/FunkinCrew/Funkin/commit/ac102396d71609b61f8864c2dad72b8d4b647dd1)) - by @NotHyper-474 in [#7721](https://github.com/FunkinCrew/Funkin/pull/7721)
- Using characters outside of PlayState no longer tries to create health icons. ([da1e8e4](https://github.com/FunkinCrew/Funkin/commit/da1e8e4664dfdd098794aa7187e15c85d020508c)) - by @zxcksharks in [#7646](https://github.com/FunkinCrew/Funkin/pull/7646)
- Pausing the game on the same frame a camera event is triggered no longer cancels the event. ([0e967eb](https://github.com/FunkinCrew/Funkin/commit/0e967ebefb61cb007cc84fc2032dc4a1d7c399a5)) - by @realvirtu in [#7472](https://github.com/FunkinCrew/Funkin/pull/7472)
- Pausing while a dialogue conversation is fading out now pauses the fade tween. ([c0a483f](https://github.com/FunkinCrew/Funkin/commit/c0a483f003ca901679e7a4a3fe5a9dfacd86ea15)) - by @ahmed7p in [#7359](https://github.com/FunkinCrew/Funkin/pull/7359)
- A-Bot's eyes now consistently follow the Focus Camera event. ([0de4f94](https://github.com/FunkinCrew/funkin.assets/commit/0de4f94e10f09f637dca2dedf2538d5ae45dcd97)) - by @ahmed7p in [funkin.assets#408](https://github.com/FunkinCrew/funkin.assets/pull/408)
- Doppelganger Pico's vocals are now fully muted after encountering an easter egg. ([09e3b50](https://github.com/FunkinCrew/funkin.assets/commit/09e3b5025268e53c5c9415e9d2c40122c5ec4493)) - by @trayfellow in [funkin.assets#401](https://github.com/FunkinCrew/funkin.assets/pull/401)
- The passing car in Week 4 stages no longer floats when the camera is zoomed out. ([baacbaa](https://github.com/FunkinCrew/funkin.assets/commit/baacbaa45469a5497e0ac4e35dc772214beef763)) - by @realvirtu in [funkin.assets#415](https://github.com/FunkinCrew/funkin.assets/pull/415)
- Spirit's icon no longer renders behind the health bar in some cases. ([4f96d2c](https://github.com/FunkinCrew/Funkin/commit/4f96d2c070c2768327c6fcd5983dd6a4458f61b3)) - by @NotHyper-474 in [#7676](https://github.com/FunkinCrew/Funkin/pull/7676)
- The Stress background tankmen now pause their flickering when the game is paused. ([25c7810](https://github.com/FunkinCrew/funkin.assets/commit/25c781024d4299c15c42a23d2ed788c9e34785fa)) - by @ahmed7p in [funkin.assets#405](https://github.com/FunkinCrew/funkin.assets/pull/405)
- Optimized the rimlight shader to improve performance in the Week 7 Erect stage. ([0e82016](https://github.com/FunkinCrew/Funkin/commit/0e8201623240ed189ce8517431e73eb6a0d8b50c)) - by @iLauncherDev in [#7517](https://github.com/FunkinCrew/Funkin/pull/7517)
- Selecting between events of different types while searching in the Events window no longer crashes the Chart Editor. ([05c81bc](https://github.com/FunkinCrew/Funkin/commit/05c81bc622fbe8eeaefbc685389c18d8944243b2)) - by @Infinite-SUDO67 in [#7767](https://github.com/FunkinCrew/Funkin/pull/7767)
- Selecting between notes with different notekinds while searching in the Notes window no longer crashes the Chart Editor. ([b42cd4b](https://github.com/FunkinCrew/Funkin/commit/b42cd4b6e17ac9bbff9934a69b10c7fbb2e6f5e6)) - by @kiryvajiravuth in [#7761](https://github.com/FunkinCrew/Funkin/pull/7761)
- Chart Editor dropdowns no longer lock focus onto them after selecting an item. ([86f2f44](https://github.com/FunkinCrew/Funkin/commit/86f2f44b468a25c060240911765a8b210867418b)) - by @VICK-sys in [#7528](https://github.com/FunkinCrew/Funkin/pull/7528)
- Health icons now consistently appear in the Chart Editor. ([1fce75f](https://github.com/FunkinCrew/Funkin/commit/1fce75feb99988a4757f620968f4ab53d68111c7)) - by @Starexify in [#7193](https://github.com/FunkinCrew/Funkin/pull/7193)
- Chart Editor Results Screen music no longer persists into gameplay when hot-reloading with F5. ([0b08668](https://github.com/FunkinCrew/Funkin/commit/0b086689e82c6fd6cac0d96b4cdca7b18543659d)) - by @AnimatingLegend in [#7126](https://github.com/FunkinCrew/Funkin/pull/7126)
- Chart Editor playtests now only carry over custom playback rates when "Use Editor Audio Settings" is enabled. ([7f8a1ab](https://github.com/FunkinCrew/Funkin/commit/7f8a1ab6d067db0b2cd7d16f75d08cc2bce6731d)) - by @NotHyper-474 in [#7483](https://github.com/FunkinCrew/Funkin/pull/7483)
- Packaged song scripts no longer create errors during Chart Editor playtests. ([b75add7](https://github.com/FunkinCrew/Funkin/commit/b75add7c59d338606b7004f5814e976aaa074a8f)) - by @ahmed7p in [#7470](https://github.com/FunkinCrew/Funkin/pull/7470)
- Saving a chart or metadata file through the Difficulty toolbox now saves with the correct file name. ([6aa8bc3](https://github.com/FunkinCrew/Funkin/commit/6aa8bc3ce93affbe69bf7b39300c62f60e912cce)) - by @NebulaStellaNova in [#7571](https://github.com/FunkinCrew/Funkin/pull/7571)
- The Chart Editor background now scales properly on widescreen resolutions. ([2e4115a](https://github.com/FunkinCrew/Funkin/commit/2e4115a33cee591f28433b92da4ead2e64da90fa)) - by @JVNpixels in [#7741](https://github.com/FunkinCrew/Funkin/pull/7741)
- The Stage Editor no longer crashes when loading in Texture Atlas props. ([e8d91e0](https://github.com/FunkinCrew/Funkin/commit/e8d91e0f1f6aff6a62b4946868f5dfe6d6b2d461)) - by @KoloInDaCrib in [#7674](https://github.com/FunkinCrew/Funkin/pull/7674)
- Folders in the mod folder without Polymod metadata no longer display an error. ([6ab6bc6](https://github.com/FunkinCrew/Funkin/commit/6ab6bc62e7bd81e218747ed4446089f04a938811)) - by @Starexify in [#7282](https://github.com/FunkinCrew/Funkin/pull/7282)
- Enforced the Polymod blacklist in ReflectUtil. ([66d191d](https://github.com/FunkinCrew/Funkin/commit/66d191d43102f75f672478bd2efd9c7e820c1c05)) - by @FuroYT in [#7005](https://github.com/FunkinCrew/Funkin/pull/7005)
- Blacklisted a class for security. ([3752232](https://github.com/FunkinCrew/Funkin/commit/3752232e3ab6ed0cb41445cb50729e74f338fa44)) - by @charlesisfeline in [#7512](https://github.com/FunkinCrew/Funkin/pull/7512)
## New Contributors for 0.8.6
* @moxie-coder made their first contribution in [#7187](https://github.com/FunkinCrew/Funkin/pull/7187)
* @ahmed7p made their first contribution in [#7470](https://github.com/FunkinCrew/Funkin/pull/7470)
* @iLauncherDev made their first contribution in [#7517](https://github.com/FunkinCrew/Funkin/pull/7517)
* @Luscious77 made their first contribution in [#7576](https://github.com/FunkinCrew/Funkin/pull/7576)
* @VICK-sys made their first contribution in [#7528](https://github.com/FunkinCrew/Funkin/pull/7528)
* @MRK2009 made their first contribution in [#7686](https://github.com/FunkinCrew/Funkin/pull/7686)
* @kiryvajiravuth made their first contribution in [#7761](https://github.com/FunkinCrew/Funkin/pull/7761)
* @Infinite-SUDO67 made their first contribution in [#7767](https://github.com/FunkinCrew/Funkin/pull/7767)
* @nykwono made their first contribution in [#7792](https://github.com/FunkinCrew/Funkin/pull/7792)
* @WizardMantis441 made their first contribution in [funkin.assets#413](https://github.com/FunkinCrew/funkin.assets/pull/413)
## [0.8.5] - 2026-04-06
### Fixed
- [ANDROID] Fixed various issues with visuals, controls, and gamepad functionality.
## [0.8.4] - 2026-03-26
### Added
- Added several new features to Polymod:
- Added FULL support for abstracts! (Previously, only `FlxColor` was supported)
- Added support for getting the code of a single character string (i.e `’h’.code`) (Thanks NotHyper-474!)
- Added support for import defaults (`import.hx`/`import.hxc`), allowing scripted classes with the same package to share imports. (Thanks KoloInDaCrib!)
- Added `scriptInit` and `listScriptClasses` functions to scripted classes. (Thanks KoloInDaCrib!)
- `.hx` files can now be parsed. (Thanks Starexify!)
- Added support for preprocessing (`#if`/`#else` syntax), allowing for platform-specific code to be implemented in an easier way. (Thanks KoloInDaCrib!)
- Added support for mod IDs. (Thanks Starexify!)
- Implemented `_merge` support for scripts. (Thanks KoloInDaCrib!)
- Please refer to the Cookbook to learn how to use this.
- Added widescreen scale properties to the Zoom Camera event in the Chart Editor to account for widescreen resolutions.
- Added a flipY field for Story Mode level props. ([48ed659](https://github.com/FunkinCrew/Funkin/commit/48ed65980005366371fda7a66c04f73bb5b86200)) - by @ExtraCode75 in [#6340](https://github.com/FunkinCrew/Funkin/pull/6340)
- Implemented working start and end times for Freeplay song previews. ([40eab2e](https://github.com/FunkinCrew/Funkin/commit/40eab2e4618ebb6dc67a06ef67df817920773c56)) - by @ADA-Funni in [#6725](https://github.com/FunkinCrew/Funkin/pull/6725)
- Added a new albumOSTName property to Freeplay album data to make the "OFFICIAL OST" text moddable. ([67d2a98](https://github.com/FunkinCrew/Funkin/commit/67d2a9811b5c92409bdc76e287c984d5777d8621)) - by @NotHyper-474 in [#6578](https://github.com/FunkinCrew/Funkin/pull/6578)
- Added an optional 'capsule' field to level data to display any week label on Freeplay capsules. ([528e9e4](https://github.com/FunkinCrew/Funkin/commit/528e9e4f03c40e59f3932d8b4c522b6eeb66783b)) - by @Trayfellow in [#7149](https://github.com/FunkinCrew/Funkin/pull/7149)
- Implemented ScriptedBaseFreeplayDJ, allowing modders to customize how custom Freeplay DJs are rendered. ([423ccfa](https://github.com/FunkinCrew/Funkin/commit/423ccfab98a29646e4998dacedaf403319d956ff)) - by @PurSnake in [#6806](https://github.com/FunkinCrew/Funkin/pull/6806)
- Added a new FunkinGroup class to make groups of sprites easier to modify. ([4f31600](https://github.com/FunkinCrew/Funkin/commit/4f316003af9a6ca46c77bf4971059e20543cbd7b)) - by @MightyTheArmiddilo in [#6758](https://github.com/FunkinCrew/Funkin/pull/6758)
- Added `Reflect.makeVarArgs` to allow modders to create functions with a variable number of arguments. ([3633df3](https://github.com/FunkinCrew/Funkin/commit/3633df3fdc6dc0af4f9886fcb1e1d4a8d2b8d5aa)) - by @Starexify in [#6738](https://github.com/FunkinCrew/Funkin/pull/6738)
- Added script event support for song events. ([15bef89](https://github.com/FunkinCrew/Funkin/commit/15bef89d71982c5685f4ce6f6d7e6e4d8321508c)) - by @KoloInDaCrib in [#4130](https://github.com/FunkinCrew/Funkin/pull/4130)
- Added a new Chart Editor event type: Set Target Bop Speed. ([1893f2b](https://github.com/FunkinCrew/Funkin/commit/1893f2b2f679d8a4d262052793dde24e94719ee6)) - by @roma-perec-bp in [#6769](https://github.com/FunkinCrew/Funkin/pull/6769)
- Added shortcuts to select all notes above or below the playhead in the Chart Editor. ([08b3af9](https://github.com/FunkinCrew/Funkin/commit/08b3af959d6657511bfe8418da545731050cb24a)) - by @Lasercar in [#4306](https://github.com/FunkinCrew/Funkin/pull/4306)
- Added the ability to view and edit the timing of a note or event through the Chart Editor context menu. ([a782b3f](https://github.com/FunkinCrew/Funkin/commit/a782b3f9e8498634babb864341fd1437bb2c01f6)) - by @Lasercar in [#4200](https://github.com/FunkinCrew/Funkin/pull/4200)
- Added an "Edit Note" option to the Chart Editor context menu that opens the Notes window. ([e710198](https://github.com/FunkinCrew/Funkin/commit/e710198afec9a0fe19effe4cd196ab3a247f4784)) - by @Honton129 in [#7010](https://github.com/FunkinCrew/Funkin/pull/7010)
- Added the ability to Ctrl-click on health icons in the Chart Editor to open character previews. ([011f154](https://github.com/FunkinCrew/Funkin/commit/011f1541b197fd4f962ab8a910cbd417f78c2d09)) - by @Trofem in [#7089](https://github.com/FunkinCrew/Funkin/pull/7089)
### Changed
- Upgraded the input handling system from SDL2 to SDL3!
- Added an “Unlocked Framerate” preference to Desktop platforms.
- The input system is now much more responsive and accurate down to the nanosecond.
- The game now properly supports more controllers and input devices.
- The game now shows popups when installed mods have issues, such as when the API version is incorrect.
- Unfocusing the game now reduces the game’s volume to 25% (down from 50%).
- The notekinds dropdown are no longer hardcoded in the Chart Editor.
- The Character Select key is now hidden in the Controls menu until a new character is unlocked. ([6c13444](https://github.com/FunkinCrew/Funkin/commit/6c134442118d3f5f61b9e3faa631512d210422fb)) - by @Lasercar in [#4882](https://github.com/FunkinCrew/Funkin/pull/4882)
- The Story Mode level score now displays with commas. ([04fffe8](https://github.com/FunkinCrew/Funkin/commit/04fffe8ade4c4b236d59a236f08534e8eede179f)) - by @JVNpixels in [#4965](https://github.com/FunkinCrew/Funkin/pull/4965)
- Freeplay capsule week labels are now softcoded and rendered using a font. ([48752e4](https://github.com/FunkinCrew/Funkin/commit/48752e444cc5f1b8cd0a3b579f843e9ab6580c46)) - by @KoloInDaCrib in [#5249](https://github.com/FunkinCrew/Funkin/pull/5249)
- The Freeplay change character hint now changes when a gamepad is connected. ([0f7859b](https://github.com/FunkinCrew/Funkin/commit/0f7859bfb6b829290804efab9d5c67fbdbec0903)) - by @MrMadera in [#6609](https://github.com/FunkinCrew/Funkin/pull/6609)
- Moved the Winter Horrorland intro cutscene logic into a script. ([9bbe73b](https://github.com/FunkinCrew/funkin.assets/commit/9bbe73b21ccbea29a5d5187709f91b4822bf7e31)) - by @mario64thane in [funkin.assets#63](https://github.com/FunkinCrew/funkin.assets/pull/63)
- Merged FlxFilteredSprite functionality into FunkinSprite. ([22736b2](https://github.com/FunkinCrew/Funkin/commit/22736b27da7d8de8b11ab6cc6c2a622e5579dccd)) - by @TechnikTil in [#7114](https://github.com/FunkinCrew/Funkin/pull/7114)
- Adjusted some wording in the Chart/Stage Editor backup window to be clearer. ([a607396](https://github.com/FunkinCrew/Funkin/commit/a607396d04f24388691ee23bd04022681ca54756)) - by @Marcosayfi in [#7071](https://github.com/FunkinCrew/Funkin/pull/7071)
### Fixed
- Conjoined string interpolation `$a$b` now parses properly in Polymod.
- Video cutscenes are no longer muted at volumes of 3 or lower.
- Video cutscenes no longer occasionally show glitches at the beginning.
- [MOBILE] Loading a cloud save from Newgrounds no longer carries over the volume level from Desktop.
- [HTML5] Scrolling the game out of view now pauses the game instead of allowing gameplay to continue processing.
- The Boyfriend Freeplay DJ new rank animation now transitions smoothly back to its idle animation.
- Hold notes now score much more consistently across different framerate values.
- The bricks in Week 7 stages are now better quality.
- Trimmed out the silent beat at the beginning of Ugh Erect.
- Camera bopping no longer stops at zoom values of 1.35x or higher.
- Charting many hold notes in a row no longer breaks audio handling.
- Adding collapsible frames in event schemas no longer crashes the game.
- Some event properties have been grouped under Advanced frames.
- Chart Editor dropdowns no longer refocus when a tooltip appears.
- Focus and Zoom Camera event durations now account for playback speed.
- [WINDOWS] Exiting the game no longer leaves it running as a background process. ([881aba3](https://github.com/FunkinCrew/Funkin/commit/881aba3b03a26764374441cab244cd2d360a30b9)) - by @AnimatingLegend in [#6885](https://github.com/FunkinCrew/Funkin/pull/6885)
- Story Mode now only shows difficulties that all of a level's songs have. ([365f8dc](https://github.com/FunkinCrew/Funkin/commit/365f8dcfea9569f2edba1ebfceb3d49819ad2b57)) - by @Starexify in [#7046](https://github.com/FunkinCrew/Funkin/pull/7046)
- The Girlfriend Story Mode prop now bops continuously when scrolling through levels. ([84b2d5b](https://github.com/FunkinCrew/Funkin/commit/84b2d5b48d9eb76c918fdba6987ccc1f5da76133)) - by @Redar13 in [#6830](https://github.com/FunkinCrew/Funkin/pull/6830)
- The Freeplay new rank slam animation now properly plays its glow effect. ([fcbce0a](https://github.com/FunkinCrew/Funkin/commit/fcbce0a66b75b0c1224c6a0e2907c170b71998ad)) - by @FuroYT in [#7015](https://github.com/FunkinCrew/Funkin/pull/7015)
- The Freeplay Random capsule no longer displays BPM and difficulty numbers. ([0ad2d50](https://github.com/FunkinCrew/Funkin/commit/0ad2d507efa9dcb577184e28bfd04091b3424bfb)) - by @Lasercar in [#4927](https://github.com/FunkinCrew/Funkin/pull/4927)
- Favoriting a song in Freeplay no longer breaks capsule text cycling. ([ce493a0](https://github.com/FunkinCrew/Funkin/commit/ce493a03c9ffb4c43c2c27885ed0fab0c1c3531d)) - by @realvirtu in [#7134](https://github.com/FunkinCrew/Funkin/pull/7134)
- Freeplay songs with invalid pixel icons no longer duplicate the icon from the previous song in the list. ([b3eb709](https://github.com/FunkinCrew/Funkin/commit/b3eb709f4ed535ed2544f3bb530ff3724e07be3f)) - by @FuroYT in [#7006](https://github.com/FunkinCrew/Funkin/pull/7006)
- A Freeplay clear percent of 100% now properly exits to the right when returning to the Main Menu. ([5974c1a](https://github.com/FunkinCrew/Funkin/commit/5974c1a48293f3185c5f249acb9130ebd6b35ae4)) - by @Trayfellow in [#7183](https://github.com/FunkinCrew/Funkin/pull/7183)
- Nudged the Freeplay backing image down by one pixel to align with the bottom of the screen. ([b8c2854](https://github.com/FunkinCrew/Funkin/commit/b8c2854007f36ac7a2b6897eead3f979e11f0ad7)) - by @SuperEric1 in [#6893](https://github.com/FunkinCrew/Funkin/pull/6893)
- Improved performance for songs that use a lot of events. ([3b27ec5](https://github.com/FunkinCrew/Funkin/commit/3b27ec5b66b2fa00d59a77f6ec07aff68e440860)) - by @KoloInDaCrib in [#7171](https://github.com/FunkinCrew/Funkin/pull/7171)
- Adjusted hit window logic to accurately reflect threshold values for all judgments. ([dcb5b3a](https://github.com/FunkinCrew/Funkin/commit/dcb5b3a9358a9bb126153b57aa2d38dc0684c39d)) - by @Rudyrue in [#7104](https://github.com/FunkinCrew/Funkin/pull/7104)
- Adjusted offsets for all health icons to be more consistent. ([83d8134](https://github.com/FunkinCrew/funkin.assets/commit/83d8134f9d0b3cf3b59e9e1d972fa1e200a98ba1)) - by @LeGooeyy in [funkin.assets#278](https://github.com/FunkinCrew/funkin.assets/pull/278)
- Hold notes no longer shift upward when hit early. ([d62c8af](https://github.com/FunkinCrew/Funkin/commit/d62c8af20c90ec3d6e4274aba8ddbfb378ab0256)) - by @realvirtu in [#7060](https://github.com/FunkinCrew/Funkin/pull/7060)
- The opponent no longer stops singing upon missing if Boyfriend has no vocals file. ([cea54e3](https://github.com/FunkinCrew/Funkin/commit/cea54e394c78544dd0ec0339721faaac140caa65)) - by @FuroYT in [#7007](https://github.com/FunkinCrew/Funkin/pull/7007)
- onPause script functions now properly trigger when pausing during a cutscene or dialogue. ([5a0b431](https://github.com/FunkinCrew/Funkin/commit/5a0b4310a2c39b033989e0e36b8f456bdac65a5b)) - by @MightyTheArmiddilo in [#6804](https://github.com/FunkinCrew/Funkin/pull/6804)
- Camera events now consistently pause when the Pause Menu is opened. ([e623439](https://github.com/FunkinCrew/Funkin/commit/e6234397f57d2af37035a0ff2504b8241e23949d)) - by @realvirtu in [#7145](https://github.com/FunkinCrew/Funkin/pull/7145)
- The Pause Menu global offset value now adjusts at the same rate across all framerates. ([348647f](https://github.com/FunkinCrew/Funkin/commit/348647f48629a24ee3bd2b759bbfc1bff168fb81)) - by @KolzeYT in [#7147](https://github.com/FunkinCrew/Funkin/pull/7147)
- Spirit's trail effect now renders consistently across all framerates. ([75506f7](https://github.com/FunkinCrew/Funkin/commit/75506f71a97d468f516a0232c8be5560afb0682e)) - by @KolzeYT in [#7179](https://github.com/FunkinCrew/Funkin/pull/7179)
- The sound tray now appears consistently and plays sound effects at the right volume. ([2b9906d](https://github.com/FunkinCrew/Funkin/commit/2b9906df29660057410d3054e897012896896d6a)) - by @Raltyro in [#7068](https://github.com/FunkinCrew/Funkin/pull/7068)
- The sticker transition now properly pauses when losing focus with Pause on Unfocus enabled. ([8a1d74b](https://github.com/FunkinCrew/Funkin/commit/8a1d74b82cceab97e777dc49e7a2117b8d27e59b)) - by @ComedyLost in [#7129](https://github.com/FunkinCrew/Funkin/pull/7129)
- [HTML5] Rimlight alt masks now render properly. ([0613e9d](https://github.com/FunkinCrew/Funkin/commit/0613e9d295179e66d30db3d2f6805870eac847d6)) - by @realvirtu in [#6900](https://github.com/FunkinCrew/Funkin/pull/6900)
- The Week 2 Erect stage lightning strike fade now pauses and cancels appropriately. ([cd05267](https://github.com/FunkinCrew/funkin.assets/commit/cd05267023859d04cc8920c787b8280682e5f0f5)) - by @ComedyLost in [funkin.assets#390](https://github.com/FunkinCrew/funkin.assets/pull/390)
- A-Bot (Dark)'s frame no longer renders as completely dark in Week 2 Erect. ([a142530](https://github.com/FunkinCrew/funkin.assets/commit/a142530cae6198ca17b560ff73e36d50f1582768)) - by @ComedyLost in [funkin.assets#368](https://github.com/FunkinCrew/funkin.assets/pull/368)
- Dying on the same frame as a lightning strike in Week 2 Erect no longer throws a script error. ([ef89bde](https://github.com/FunkinCrew/funkin.assets/commit/ef89bde19c397f15a53b0fda2f64ba93ff96f56f)) - by @KoloInDaCrib in [funkin.assets#363](https://github.com/FunkinCrew/funkin.assets/pull/363)
- Pico (Dark) and Nene (Dark) no longer throw script errors in debug editors. ([b16ce44](https://github.com/FunkinCrew/funkin.assets/commit/b16ce44beb43d4511c61418c824929fb4dfabb63)) - by @ComedyLost in [funkin.assets#367](https://github.com/FunkinCrew/funkin.assets/pull/367)
- Girlfriend's hair no longer falls when restarting the song in a Week 3 stage. ([ade80ab](https://github.com/FunkinCrew/funkin.assets/commit/ade80ab72915ddd47724c380bb41d6df4c1b79bd)) - by @AnimatingLegend in [funkin.assets#370](https://github.com/FunkinCrew/funkin.assets/pull/370)
- The camera transition to Results no longer reveals the edges of stage art in the Week 6 Erect stage. ([ecf4c54](https://github.com/FunkinCrew/funkin.assets/commit/ecf4c5458a2e1fadba7db31c3272cea485d22b2f)) - by @ComedyLost in [funkin.assets#383](https://github.com/FunkinCrew/funkin.assets/pull/383)
- Fine-tuned offsets for pixel characters. ([8b3c268](https://github.com/FunkinCrew/funkin.assets/commit/8b3c2680a6a966e81b62598e783c60f46355c759)) - by @CEliuxJV in [funkin.assets#376](https://github.com/FunkinCrew/funkin.assets/pull/376)
- Tankman's game over lines now properly play during game overs in Ugh (Pico Mix) and Guns (Pico Mix). ([b900208](https://github.com/FunkinCrew/funkin.assets/commit/b900208143f980adee25d70db247e0b176dd659c)) - by @hucks5 in [funkin.assets#373](https://github.com/FunkinCrew/funkin.assets/pull/373)
- Restarting during the mid-song animation in Stress (Pico Mix) now properly resets the characters' animations. ([2ca92de](https://github.com/FunkinCrew/funkin.assets/commit/2ca92de46eced3f53d305579704fcb7e8c051f3a)) - by @requazar in [funkin.assets#364](https://github.com/FunkinCrew/funkin.assets/pull/364)
- The rain shader now properly fades out with the transition to the Results Screen. ([a0caa41](https://github.com/FunkinCrew/Funkin/commit/a0caa41edcb26298e4f8c243a5eed0b4fe93fcf7)) - by @realvirtu in [#6776](https://github.com/FunkinCrew/Funkin/pull/6776)
- Exiting a Chart Editor playtest while using the pixel notestyle no longer crashes the game. ([6c1f380](https://github.com/FunkinCrew/Funkin/commit/6c1f3800dbc9b13fb4b409abce53c1dafc9bbe8f)) - by @Starexify and @KoloInDaCrib in [#7108](https://github.com/FunkinCrew/Funkin/pull/7108)
- Chart Editor Edit buttons are now appropriately disabled when nothing is selected. ([6b1fc03](https://github.com/FunkinCrew/Funkin/commit/6b1fc0372bca202d80f4ccf316580b13a5a80879)) - by @Lasercar in [#4386](https://github.com/FunkinCrew/Funkin/pull/4386)
- Undoing a Chart Editor event now plays the undo sound. ([f7fd7a5](https://github.com/FunkinCrew/Funkin/commit/f7fd7a57c36f0461f56c2ab627a17d752cb82320)) - by @realvirtu in [#6963](https://github.com/FunkinCrew/Funkin/pull/6963)
- The playback speed audio setting no longer rounds incorrectly upon reopening the Chart Editor. ([3b15873](https://github.com/FunkinCrew/Funkin/commit/3b15873fc7d0c20840c313f1d2cfed91014c664f)) - by @AnimatingLegend in [#7023](https://github.com/FunkinCrew/Funkin/pull/7023)
- The Chart Editor easing preview graph now properly displays tweens that exceed start/end values. ([7626700](https://github.com/FunkinCrew/Funkin/commit/7626700495743862caddbf50a7dafef51529a2a6)) - by @echolotl in [#7152](https://github.com/FunkinCrew/Funkin/pull/7152)
- The Chart Editor playbar head is no longer draggable during a playtest. ([ccb874e](https://github.com/FunkinCrew/Funkin/commit/ccb874e97a121859c26a8a71b394743d27f6ed37)) - by @ComedyLost in [#6987](https://github.com/FunkinCrew/Funkin/pull/6987)
- The Results Screen no longer shows up after a Chart Editor playtest with Bot Play enabled. ([786f19c](https://github.com/FunkinCrew/Funkin/commit/786f19c57d999dba9309cae28d912b080968670d)) - by @ComedyLost in [#7022](https://github.com/FunkinCrew/Funkin/pull/7022)
- The Osu!Mania Chart Editor importer no longer accepts non-Osu!Mania beatmaps. ([456b2ff](https://github.com/FunkinCrew/Funkin/commit/456b2ff6c4a127733120cef3d03d6102bdd7522f)) - by @FuroYT in [#6624](https://github.com/FunkinCrew/Funkin/pull/6624)
- Characters in the Stage Editor no longer fly away when clicking and dragging them. ([0389af2](https://github.com/FunkinCrew/Funkin/commit/0389af2202aa4dc6a21ce9b7eea95944bfaa6946)) - by @KoloInDaCrib in [#7002](https://github.com/FunkinCrew/Funkin/pull/7002)
- Characters with alternating idle animations now properly play danceLeft when pressing Space in the Animation Editor. ([05032e3](https://github.com/FunkinCrew/Funkin/commit/05032e3126eda78a2bbf70e8c975bcb04eed201b)) - by @ComedyLost in [#7056](https://github.com/FunkinCrew/Funkin/pull/7056)
- [LINUX] Paths are now properly sanitized as they are on other platforms. ([219143c](https://github.com/FunkinCrew/Funkin/commit/219143c02dcf65e68aec80701a82023ca0d70db6)) - by @NotHyper-474 in [#6395](https://github.com/FunkinCrew/Funkin/pull/6395)
- OpenFL and some Lime classes are now accessible to modders. ([56a56db](https://github.com/FunkinCrew/Funkin/commit/56a56dbfaa3f62a3f684df49c682f69a496e45f4)) - by @FuroYT in [#7115](https://github.com/FunkinCrew/Funkin/pull/7115)
- Sandboxed API classes can now be accessed by mods. ([03930a2](https://github.com/FunkinCrew/Funkin/commit/03930a29c3d8aa6a310147a7131c6b7cddefd475)) - by @MightyTheArmiddilo in [#6952](https://github.com/FunkinCrew/Funkin/pull/6952)
- Blacklisted some more classes for security.
- And even more fixes!
## New Contributors for 0.8.4
* @roma-perec-bp made their first contribution in [#6769](https://github.com/FunkinCrew/Funkin/pull/6769)
* @Redar13 made their first contribution in [#6830](https://github.com/FunkinCrew/Funkin/pull/6830)
* @SuperEric1 made their first contribution in [#6893](https://github.com/FunkinCrew/Funkin/pull/6893)
* @AnimatingLegend made their first contribution in [#7023](https://github.com/FunkinCrew/Funkin/pull/7023)
* @Marcosayfi made their first contribution in [#7071](https://github.com/FunkinCrew/Funkin/pull/7071)
* @Rudyrue made their first contribution in [#7104](https://github.com/FunkinCrew/Funkin/pull/7104)
* @KolzeYT made their first contribution in [#7147](https://github.com/FunkinCrew/Funkin/pull/7147)
* @echolotl made their first contribution in [#7152](https://github.com/FunkinCrew/Funkin/pull/7152)
* @mario64thane made their first contribution in [funkin.assets#63](https://github.com/FunkinCrew/funkin.assets/pull/63)
* @LeGooeyy made their first contribution in [funkin.assets#278](https://github.com/FunkinCrew/funkin.assets/pull/278)
* @requazar made their first contribution in [funkin.assets#364](https://github.com/FunkinCrew/funkin.assets/pull/364)
## [0.8.3] - 2026-02-23
### Fixed
- [HTML5] Hitting a can in 2hot no longer creates a script error. (Thanks NotHyper-474!)
- The game no longer consistently lag spikes during gameplay. ([823120c](https://github.com/FunkinCrew/Funkin/commit/823120cdef7bfbb2d3ec37c7085878fcbeebcb30)) - by @ACrazyTown in [#6970](https://github.com/FunkinCrew/Funkin/pull/6970)
## [0.8.2] - 2026-02-23
### Added
- Added 14 new blend modes, allowing the engine to render better visual effects.
- Added a PlayState parameter that mirrors notes during a song.
- Added preview graphs for Chart Editor event easing types. ([eea1265](https://github.com/FunkinCrew/Funkin/commit/eea12657b1d8131014a3fdc270c3f351fae6e851)) - by @PurSnake in [#6374](https://github.com/FunkinCrew/Funkin/pull/6374)
- Added the ability to mirror notes on the X and Y axes in the Chart Editor. ([fd0c2df](https://github.com/FunkinCrew/Funkin/commit/fd0c2df35ee8cda3f1566a297c4faec984d809bb)) - by @Lasercar in [#4372](https://github.com/FunkinCrew/Funkin/pull/4372)
- Added a deselect button and shortcut to the Stage Editor. ([a9f1d41](https://github.com/FunkinCrew/Funkin/commit/a9f1d41771f0c97fdd70d4d6c54087ac0e64ff38)) - by @Lasercar in [#5281](https://github.com/FunkinCrew/Funkin/pull/5281)
### Changed
- Made some improvements to Polymod:
- Added string interpolation support. (Thanks NotHyper-474!)
- Scripted classes can now extend nothing. (Thanks NotHyper-474!)
- Scripted classes can now extend other scripted classes. (Thanks KoloInDaCrib!)
- Tweaked some error messages to be more verbose.
- Added `scriptHas` and `staticScriptHas` functions to check if a script has a specific variable/function.
- The `is` operator is now more accurate to regular Haxe. (Thanks Starexify!)
- Static functions can now use static extensions (`using`s). (Thanks NotHyper-474!)
- `interface`s can now be properly parsed. (Thanks Starexify!)
- Optional fields and extensions can now be used in `typedef`s. (Thanks Starexify!)
- Added stricter checking for default/optional arguments in functions. (Thanks Starexify!)
- May be a breaking change for some scripts, so please update your scripts to account for this!
- Enums now have multiple arguments. (Thanks Starexify!)
- Basic types (e.g `String`, `Int`, `Bool`, etc.) can now be used with the `is` operator without having to import the type first.
- Tweaked charts for the following songs:
- Bopeebo (Pico Mix) [Normal/Hard] - Adjusted note timings and added a “hey” animation event in Sections 18, 26, and 27.
- Fresh Erect [Nightmare] - Added 2 notes where Boyfriend’s vocals echo.
- DadBattle Erect [Nightmare] - Added a missing jack note in Section 38, added holds to two notes in Section 63.
- DadBattle (Pico Mix) [all difficulties] - Adjusted timings for various notes in Sections 37-40 and 60.
- Spookeez Erect [Erect/Nightmare] - Adjusted many hold note lengths to better match vocals.
- Spookeez (Pico Mix) - Added one missing note to Section 14.
- South Erect [Erect/Nightmare] - Adjusted many hold note lengths to better match vocals.
- Pico [Easy] - Adjusted timings for one note each in Sections 36 and 38.
- Pico [Normal/Hard] - Adjusted timings for Boyfriend’s right notes to be a bit earlier in Sections 31-42.
- Pico [all difficulties] - Added a Focus Camera event on Girlfriend during the duet.
- Satin Panties Erect [Erect/Nightmare] - Split a hold note into two for Mom in Sections 14 and 18.
- High Erect [Erect/Nightmare] - Adjusted timing for one note each in Sections 25 and 41.
- M.I.L.F [Easy] - Adjusted timings for two notes in Section 73.
- M.I.L.F [Hard] - Changed one down note into an up note in Section 15 for consistency.
- Cocoa Erect [Nightmare] - Fixed one note not being a Mom notekind in Section 24, added holds to 2 notes in Section 67.
- Cocoa (Pico Mix) [all difficulties] - Adjusted timings for two notes in Section 15.
- Eggnog Erect [Erect/Nightmare] - Adjusted how a grace note is charted in Section 52, added 2 missing notes for Mom in Section 72, adjusted Camera Bop event in Section 63.
- Senpai (Pico Mix) [all difficulties] - Adjusted timing for one note in Section 10.
- Roses [Normal] - Adjusted timings for four notes in Sections 30, 32, 41, and 43.
- Thorns Erect [Erect] - Adjusted timings for two notes in Section 36, removed some double notes to differentiate the chart from Nightmare.
- Ugh Erect [Erect/Nightmare] - Adjusted some Zoom Camera events around Section 24.
- Guns (Pico Mix) [all difficulties] - Fixed many timing issues throughout the whole song.
- SPAGHETTI [Normal/Hard] - Added one note to match Boyfriend’s rapping.
- Darnell (BF Mix) [all difficulties] - Removed extra notes from Sections 49 and 50, adjusted various note timings throughout the song.
- Lit Up [Normal] - Added one missing note each in Sections 40 and 60.
- Lit Up (BF Mix) [Normal/Hard] - Adjusted timings for various grace notes in Sections 1, 52, 55, and 56.
- 2hot [Easy/Normal] - Recharted many sections to be more predictable.
- [macOS] Disabled high DPI to significantly improve performance on some displays.
- Improved the Lag Adjustment menu to better handle very large offsets.
- Chart Editor exporting now omits default values and orders values more consistently.
- Chart Editor playtests now processes all events before the starting position.
- Optimized the Week 2 Spooky Mansion stage background by using a texture atlas. ([2bdd5a7](https://github.com/FunkinCrew/funkin.assets/commit/2bdd5a713f0b5c7e945c457e2a4a92bdb367cc02)) - by @MaybeMaru and @Trayfellow in [funkin.assets#348](https://github.com/FunkinCrew/funkin.assets/pull/348)
- Added more default imports for mods. ([1620cf3](https://github.com/FunkinCrew/Funkin/commit/1620cf388973eab5d83e151eec28b2c8abc84eb1)) - by @Starexify in [#6706](https://github.com/FunkinCrew/Funkin/pull/6706)
- The Set Camera Bop event now supports decimal values for rate and offset at 0.25 precision. ([ffaba34](https://github.com/FunkinCrew/Funkin/commit/ffaba343258c4a0e5ee7e1bd7fa0e8138ae60bc1)) - by @KoloInDaCrib in [#6741](https://github.com/FunkinCrew/Funkin/pull/6741)
### Fixed
- Fixed some issues with Polymod:
- The super constructor for scripted classes can now accept more than 4 arguments. (Thanks NotHyper-474!)
- Functions can now accept more than 8 arguments. (Thanks NotHyper-474!)
- Script variables are no longer dropped early when passing them to a callback (ex. `FlxTimer`). (Thanks NotHyper-474!)
- Fix a memory leak that could happen if a script tried to reference an anonymous object with a lot of `StringMap`s. (Thanks NotHyper-474!)
- Properties (`get_`/`set_` functions) are now much more accurate to regular Haxe. (Thanks NotHyper-474!)
- Re-exported some assets to fix some issues:
- Re-exported all variations of Pico as texture atlases to optimize memory usage.
- Freeplay DJ Pico’s table sparks no longer persist when his gun is lifted.
- Pico (Blazin’)’s game over retry animation now properly displays its blend modes.
- Pico (Christmas) no longer shows several stray marks around his sprites.
- Nene (Christmas) no longer becomes slightly offset when her knife is raised.
- The running tankmen in Stress (Pico Mix) no longer tank the game’s performance.
- Daddy Dearest now properly holds his up pose.
- Monster (Christmas)’s hat no longer moves while he holds a pose.
- Darnell’s can in 2hot now shows a sparkling effect.
- [DESKTOP] Modded atlas characters with both .png and .astc spritesheets no longer crash the game.
- [DESKTOP] The game display no longer sometimes becomes offset from the window.
- [MOBILE] Selecting a song using touch controls when a keyboard is connected no longer disables the keyboard strumline layout.
- [ANDROID] Improved Freeplay scrolling behavior on high framerate displays.
- [WINDOWS] Chart Editor save dialog windows no longer freeze the game.
- The Chart Editor Results Screen playtest option now consistently shows the Results Screen after each playtest.
- Scrolling really quickly in Freeplay no longer crashes the game. ([76699b2](https://github.com/FunkinCrew/Funkin/commit/76699b235cd5b359bc34e6950cd05bbbb13918f8)) - by @ComedyLost in [#6962](https://github.com/FunkinCrew/Funkin/pull/6962)
- Fixed a memory leak in the Freeplay menu. ([910ba65](https://github.com/FunkinCrew/Funkin/commit/910ba650b0c1011802b151b85f4a9d8177ae95c7)) - by @KoloInDaCrib in [#6615](https://github.com/FunkinCrew/Funkin/pull/6615)
- Modded difficulty dots and graphics now render correctly in Freeplay. ([90b856d](https://github.com/FunkinCrew/Funkin/commit/90b856d88635ac4e5517e934298e3820b2e5f45c)) - by @ComedyLost in [#6205](https://github.com/FunkinCrew/Funkin/pull/6205)
- Freeplay capsules with long song names no longer display too far to the left during the new rank animation. ([17a914c](https://github.com/FunkinCrew/Funkin/commit/17a914c933592cb3ba79881ca6a8d900b8513cbc)) - by @realvirtu in [#6690](https://github.com/FunkinCrew/Funkin/pull/6690)
- Freeplay capsule BPM values ending in 1 now display with proper spacing. ([e5b4351](https://github.com/FunkinCrew/Funkin/commit/e5b43510dd810a74a7d06f7f02c52892d11d6f8b)) - by @realvirtu in [#6696](https://github.com/FunkinCrew/Funkin/pull/6696)
- The Freeplay pixel icon now properly plays its confirm animation when mashing the capsule. ([a56bc44](https://github.com/FunkinCrew/Funkin/commit/a56bc4462d1c49e8ec71462b9bd7ff338b743c93)) - by @realvirtu in [#6723](https://github.com/FunkinCrew/Funkin/pull/6723)
- [HTML5] Scrolling with the mouse now works properly in Story Mode and Freeplay. ([506d80b](https://github.com/FunkinCrew/Funkin/commit/506d80b287b969121dc3601714c2459cc71f7e55)) - by @realvirtu in [#6621](https://github.com/FunkinCrew/Funkin/pull/6621)
- Optimized rendering in the Character Select menu. ([2ecebf7](https://github.com/FunkinCrew/Funkin/commit/2ecebf79205a66b64148d64bbb3162c9fc073d85)) - by @MaybeMaru in [#6789](https://github.com/FunkinCrew/Funkin/pull/6789)
- [MOBILE] Tapping on a lock in Character Select now plays its reject animation. ([05148f0](https://github.com/FunkinCrew/Funkin/commit/05148f0e5dad4d60089e6074e616b583ba29a5e6)) - by @realvirtu in [#6779](https://github.com/FunkinCrew/Funkin/pull/6779)
- Hold note covers now follow when the strumline position is modified. ([77c6651](https://github.com/FunkinCrew/Funkin/commit/77c6651e245ea276b1bdf33e5d6732073dcb6037)) - by @MightyTheArmiddilo in [#6746](https://github.com/FunkinCrew/Funkin/pull/6746)
- The pause and game over screens no longer sometimes play the wrong character's themes. ([878644a](https://github.com/FunkinCrew/Funkin/commit/878644aee7ba425e482707b94b9f887ec23f6306)) - by @KoloInDaCrib in [#6812](https://github.com/FunkinCrew/Funkin/pull/6812)
- The game over camera focus point is now consistent, regardless of which animation was previously playing. ([18cceb4](https://github.com/FunkinCrew/Funkin/commit/18cceb4946a51fda0009d77baae1115437694415)) - by @KoloInDaCrib in [#6705](https://github.com/FunkinCrew/Funkin/pull/6705)
- Pico (Pixel) and other pixel characters now use RetroCameraFade as Boyfriend (Pixel) does. ([d1382aa](https://github.com/FunkinCrew/Funkin/commit/d1382aa985f97e3b40b0b629cb3d04301ebfb55e)) - by @afreetoplaynoob in [#6526](https://github.com/FunkinCrew/Funkin/pull/6526)
- [MOBILE] The back button can no longer exit during the Boyfriend fakeout death animation. ([9d06018](https://github.com/FunkinCrew/Funkin/commit/9d0601813e912de9e25a851ad9204a654316625a)) - by @ActualMandM in [#6917](https://github.com/FunkinCrew/Funkin/pull/6917)
- The song name text is now properly hidden at the beginning of the Results Screen animation. ([a5b15b9](https://github.com/FunkinCrew/Funkin/commit/a5b15b9424f16d8eadc7a92f1c355da647990c3a)) - by @NotHyper-474 and @Trayfellow in [#6931](https://github.com/FunkinCrew/Funkin/pull/6931)
- The sticker transition no longer covers the volume soundtray. ([616546d](https://github.com/FunkinCrew/Funkin/commit/616546d298a06c4135a32ffad41483be208552f1)) - by @realvirtu in [#6727](https://github.com/FunkinCrew/Funkin/pull/6727)
- Lightning now appears more regularly during South Erect and South (Pico Mix). ([9ca2092](https://github.com/FunkinCrew/funkin.assets/commit/9ca20929bc3dde6b07d74100c45fb45e48769c35)) - by @JackXson-Real in [funkin.assets#345](https://github.com/FunkinCrew/funkin.assets/pull/345)
- [HTML5] The city lights in the Week 3 stages now show up. ([603684f](https://github.com/FunkinCrew/funkin.assets/commit/603684ffb327f03d8216aaeaba143ca5f9cd77f0)) - by @realvirtu in [funkin.assets#342](https://github.com/FunkinCrew/funkin.assets/pull/342)
- The Week 3 Pico doppelganger cutscene background music no longer cuts off at the end. ([8ef58aa](https://github.com/FunkinCrew/funkin.assets/commit/8ef58aabdba8287d4c88808e2f0ecc0ac385b383)) - by @Trayfellow in [funkin.assets#349](https://github.com/FunkinCrew/funkin.assets/pull/349)
- The Story Mode cutscene before Stress now properly plays when viewed more than once. ([6ec45ec](https://github.com/FunkinCrew/funkin.assets/commit/6ec45ec82ca77188b1b2b9c58ada172f5c357103)) - by @NotHyper-474 in [funkin.assets#341](https://github.com/FunkinCrew/funkin.assets/pull/341)
- Darnell's can sound effects in 2hot no longer play twice with high offsets or when lagging. ([6315e25](https://github.com/FunkinCrew/funkin.assets/commit/6315e25eaaa8be4ca85e9b607f547595c699997a)) - by @JackXson-Real in [funkin.assets#354](https://github.com/FunkinCrew/funkin.assets/pull/354)
- [MOBILE] The cutscene after 2hot now properly accounts for different resolutions. ([dd3371a](https://github.com/FunkinCrew/Funkin/commit/dd3371a549f4e10f68f1a458f40ec1a342f07876)) - by @ActualMandM in [#6937](https://github.com/FunkinCrew/Funkin/pull/6937)
- Made the AttractState video skipping pie smoother. ([5a161b1](https://github.com/FunkinCrew/Funkin/commit/5a161b1d7342d7931950edf37554ce3a338736f9)) - by @PurSnake in [#6728](https://github.com/FunkinCrew/Funkin/pull/6728)
- The screenshot preview no longer breaks when changing states. ([dc78db8](https://github.com/FunkinCrew/Funkin/commit/dc78db8808a7ea205fe75eba006e4ec1c57a8190)) - by @Lasercar in [#6792](https://github.com/FunkinCrew/Funkin/pull/6792)
- Holding Ctrl and clicking on a hold note trail no longer crashes the Chart Editor (again). ([86ac336](https://github.com/FunkinCrew/Funkin/commit/86ac336d62a65fb420cdd6b1be739c3262d21159)) - by @Lasercar in [#6912](https://github.com/FunkinCrew/Funkin/pull/6912)
- Chart Editor tooltips no longer appear when hovering over a deleted note or event. ([091c18b](https://github.com/FunkinCrew/Funkin/commit/091c18bccd95b588ba0d4577a94d83acf5942417)) - by @KoloInDaCrib in [#6929](https://github.com/FunkinCrew/Funkin/pull/6929)
- Chart Editor vocal waveforms now render more accurately after BPM changes in the song. ([4e8f48d](https://github.com/FunkinCrew/Funkin/commit/4e8f48d5f0f1be4438c4ef9571137eaa35935f67)) - by @gamerbross in [#6833](https://github.com/FunkinCrew/Funkin/pull/6833)
- The Chart Editor vocal waveforms now display in the proper position regardless of the game's aspect ratio. ([1fb9040](https://github.com/FunkinCrew/Funkin/commit/1fb9040470432528a0441d7938d217e424ce27fd)) - by @Starexify in [#6193](https://github.com/FunkinCrew/Funkin/pull/6193)
- The second section number and divider now renders consistently in the Chart Editor. ([ac539bd](https://github.com/FunkinCrew/Funkin/commit/ac539bdf26ee7b5ecdcc52665c7c95287ef491c0)) - by @NotHyper-474 in [#6765](https://github.com/FunkinCrew/Funkin/pull/6765)
- The Chart Editor now saves the Show Results Screen setting. ([c893a73](https://github.com/FunkinCrew/Funkin/commit/c893a7320d72abd3743bc5c1ddeaecf073035eb1)) - by @MightyTheArmiddilo in [#6854](https://github.com/FunkinCrew/Funkin/pull/6854)
- Closing the game while in the Stage Editor no longer crashes the game. ([99cd4e2](https://github.com/FunkinCrew/Funkin/commit/99cd4e2cbd7fba87249b02b072a1e60f07c2c907)) - by @realvirtu in [#6775](https://github.com/FunkinCrew/Funkin/pull/6775)
- The onion skin now properly renders as transparent after changing characters in the Animation Editor. ([5c444f1](https://github.com/FunkinCrew/Funkin/commit/5c444f1109e5af04735a4383e577c69682b3713f)) - by @realvirtu in [#6545](https://github.com/FunkinCrew/Funkin/pull/6545)
- Blacklisted a class for security. ([3a113c2](https://github.com/FunkinCrew/Funkin/commit/3a113c270f92a6b14dfcda221124742437e1670a)) - by @charlesisfeline in [#6573](https://github.com/FunkinCrew/Funkin/pull/6573)
- Even more tiny fixes!
## [0.8.1] - 2026-01-04
### Added
@@ -20,7 +389,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.0] - 2025-12-31
## [0.8.0] - 2026-01-03
The LE SSERAFIM collab update!
@@ -83,7 +452,7 @@ The LE SSERAFIM collab update!
- Freeplay song previews now fade out before restarting. ([aaf5084](https://github.com/FunkinCrew/Funkin/commit/aaf5084fd9e9c2d3b7e823767a93db82ce908d86)) - by @JVNpixels in [#6094](https://github.com/FunkinCrew/Funkin/pull/6094)
- The game's volume is now reduced when unfocused without pausing. ([3040692](https://github.com/FunkinCrew/Funkin/commit/30406928522f88762eab4bbf571fedf1424f7569)) - by @PurSnake in [#6250](https://github.com/FunkinCrew/Funkin/pull/6250)
- Optimized the way the windows in Week 3 are handled. ([70d433d](https://github.com/FunkinCrew/funkin.assets/commit/70d433de3027badb39027d295d1b18d20a130741)) - by @CrusherNotDrip in [funkin.assets#291](https://github.com/FunkinCrew/funkin.assets/pull/291)
- Script create events now also run after hot-reloading with F5, rather than only during initialization. ([2f865a5](https://github.com/FunkinCrew/Funkin/commit/2f865a5c7f4d8712f1b1e0bc70cb910f4fed08dc)) - by @VirtuGuy in [#6084](https://github.com/FunkinCrew/Funkin/pull/6084)
- Script create events now also run after hot-reloading with F5, rather than only during initialization. ([2f865a5](https://github.com/FunkinCrew/Funkin/commit/2f865a5c7f4d8712f1b1e0bc70cb910f4fed08dc)) - by @realvirtu in [#6084](https://github.com/FunkinCrew/Funkin/pull/6084)
- Hot-reloading with F5 during a Chart Editor playtest no longer returns to the Chart Editor. ([c1988f1](https://github.com/FunkinCrew/Funkin/commit/c1988f1858344a78a82bf335774d986703cac942)) - by @KoloInDaCrib in [#6275](https://github.com/FunkinCrew/Funkin/pull/6275)
- Opening the Chart Editor during a song now places the playhead at the current song position. ([71b4a58](https://github.com/FunkinCrew/Funkin/commit/71b4a58cab821c3b5a530e3a2be6d73966faa2a6)) - by @KoloInDaCrib in [#6210](https://github.com/FunkinCrew/Funkin/pull/6210)
- The Easing property for Chart Editor events is now split into two separate dropdowns: type and direction. ([d1d77dd](https://github.com/FunkinCrew/Funkin/commit/d1d77dd85c3daed22ee954353fa41e81279ced3c)) - by @PurSnake in [#5612](https://github.com/FunkinCrew/Funkin/pull/5612)
@@ -112,7 +481,6 @@ The LE SSERAFIM collab update!
- [iOS] The navigation bar is no longer unlocked after watching an ad.
- [iOS] The “larger text” accessibility setting no longer causes the game to not fill the whole screen.
- [iOS] The game now displays error popups.
- [ANDROID] Keyboard detection and strumline positioning now work properly.
- [ANDROID] Taking a screenshot no longer pauses the game for a moment.
- The Title Screen no longer switches to Attract Mode while the Girlfriend’s Ringtone easter egg is playing.
- Holding Escape in the Main Menu no longer quickly closes the game.
@@ -144,21 +512,22 @@ The LE SSERAFIM collab update!
- Pause on Unfocus now properly applies to Chart Editor playtests.
- Unfocusing while the Chart Editor is playing audio now pauses the playback.
- Fixed a memory leak with the Freeplay backing card scrolling text. ([67846d6](https://github.com/FunkinCrew/Funkin/commit/67846d6c4bfd2f42e002fa129a51772f0717329d)) - by @FuroYT in [#5963](https://github.com/FunkinCrew/Funkin/pull/5963)
- Using a static pixel icon in Character Select no longer crashes the game. ([96f8ee8](https://github.com/FunkinCrew/Funkin/commit/96f8ee85e0c2281834b7334b87d1862003e5fa05)) - by @VirtuGuy in [#6171](https://github.com/FunkinCrew/Funkin/pull/6171)
- Using a static pixel icon in Character Select no longer crashes the game. ([96f8ee8](https://github.com/FunkinCrew/Funkin/commit/96f8ee85e0c2281834b7334b87d1862003e5fa05)) - by @realvirtu in [#6171](https://github.com/FunkinCrew/Funkin/pull/6171)
- A-Bot's visualizer no longer causes a memory leak during gameplay or in Character Select. ([6607645](https://github.com/FunkinCrew/Funkin/commit/6607645786ed8611436fa5f92a35027c2a64f1d0)) - by @FuroYT in [#5908](https://github.com/FunkinCrew/Funkin/pull/5908)
- The Credits menu no longer crashes when not using hardcoded credits. ([4366fbe](https://github.com/FunkinCrew/Funkin/commit/4366fbe51274438ad2bc190afcca42e37987386d)) - by @sphis-sinco in [#5982](https://github.com/FunkinCrew/Funkin/pull/5982)
- The game no longer lag spikes when Darnell throws his can in 2hot. ([a0bc6d6](https://github.com/FunkinCrew/funkin.assets/commit/a0bc6d61fde5799a7fc619b7fdea691b0d8bae05)) - by @KoloInDaCrib in [funkin.assets#313](https://github.com/FunkinCrew/funkin.assets/pull/313)
- Hold note covers no longer get permanently stuck playing after a lag spike. ([66882d9](https://github.com/FunkinCrew/Funkin/commit/66882d9677268396320ee003478a3e2627655755)) - by @KoloInDaCrib in [#6066](https://github.com/FunkinCrew/Funkin/pull/6066)
- Scrolling through Freeplay songs for the first time no longer stutters. ([cc486ad](https://github.com/FunkinCrew/Funkin/commit/cc486ad94b5e9806d18fb65165663fea0ce0d7b4)) - by @mikolka9144 in [#4851](https://github.com/FunkinCrew/Funkin/pull/4851)
- Re-implemented an error that appears when a video file does not exist. ([2ad5933](https://github.com/FunkinCrew/Funkin/commit/2ad593341f8bea8384646f4803dc8795a9efe32a)) - by @TechnikTil in [#6253](https://github.com/FunkinCrew/Funkin/pull/6253)
- [ANDROID] Keyboard detection and strumline positioning now work properly. ([5763ae5](https://github.com/FunkinCrew/Funkin/commit/5763ae5b728359c5639bbc578f15b65a16fa57b1)) - by @NotHyper-474 in [#6328](https://github.com/FunkinCrew/Funkin/pull/6328)
- The game now properly parses .json files beginning with a bracket. ([c7367ae](https://github.com/FunkinCrew/Funkin/commit/c7367ae33d7e11f57b821f7d5fbff39a3edc1604)) - by @NotHyper-474 in [#6164](https://github.com/FunkinCrew/Funkin/pull/6164)
- The Newgrounds logo no longer covers the intro text. ([28883fb](https://github.com/FunkinCrew/Funkin/commit/28883fb9ed025abf9f9aee2621f365cd6f4d8b6c)) - by @hucks5 in [#6196](https://github.com/FunkinCrew/Funkin/pull/6196)
- Exiting from the Save Data Options menu no longer exits the Options Menu as well. ([26b253d](https://github.com/FunkinCrew/Funkin/commit/26b253d8cac97f0dcd09a5ef233f7058cd26008e)) - by @VirtuGuy in [#6036](https://github.com/FunkinCrew/Funkin/pull/6036)
- Exiting from the Save Data Options menu no longer exits the Options Menu as well. ([26b253d](https://github.com/FunkinCrew/Funkin/commit/26b253d8cac97f0dcd09a5ef233f7058cd26008e)) - by @realvirtu in [#6036](https://github.com/FunkinCrew/Funkin/pull/6036)
- Numeric values in the Options Menu are now rounded to prevent near-zero precision errors. ([934bce7](https://github.com/FunkinCrew/Funkin/commit/934bce7bdc5780e09623d845eda97a27c0ad0ecf)) - by @Starexify in [#6225](https://github.com/FunkinCrew/Funkin/pull/6225)
- The Test/Offset Calibration menu no longer starts playing after exiting the Lag Adjustment menu. ([23a38f7](https://github.com/FunkinCrew/Funkin/commit/23a38f76f9c79c5fab5b9af5e2d98e51597e05a8)) - by @VioletSnowLeopard in [#6088](https://github.com/FunkinCrew/Funkin/pull/6088)
- [MOBILE] The Back button now fades out when entering a Week in Story Mode. ([1ebce74](https://github.com/FunkinCrew/Funkin/commit/1ebce748d4e3306b4464a7bf82fab56bcb427a62)) - by @VirtuGuy in [#6255](https://github.com/FunkinCrew/Funkin/pull/6255)
- [MOBILE] The Back button now fades out when entering a Week in Story Mode. ([1ebce74](https://github.com/FunkinCrew/Funkin/commit/1ebce748d4e3306b4464a7bf82fab56bcb427a62)) - by @realvirtu in [#6255](https://github.com/FunkinCrew/Funkin/pull/6255)
- The Freeplay difficulty can now only be changed in one direction at a time. ([95af46c](https://github.com/FunkinCrew/Funkin/commit/95af46cbf72291d9d3226df91ed17f1aa3d3839f)) - by @Starexify in [#6262](https://github.com/FunkinCrew/Funkin/pull/6262)
- Pico's backing card now renders properly in widescreen aspect ratios. ([aa29b3d](https://github.com/FunkinCrew/funkin.assets/commit/aa29b3dcc1ee2f8e89d2622c480b2e997410d57d)) - by @VirtuGuy in [funkin.assets#297](https://github.com/FunkinCrew/funkin.assets/pull/297)
- Pico's backing card now renders properly in widescreen aspect ratios. ([aa29b3d](https://github.com/FunkinCrew/funkin.assets/commit/aa29b3dcc1ee2f8e89d2622c480b2e997410d57d)) - by @realvirtu in [funkin.assets#297](https://github.com/FunkinCrew/funkin.assets/pull/297)
- The album titles in Freeplay are now positioned consistently. ([ed8cca4](https://github.com/FunkinCrew/funkin.assets/commit/ed8cca4694a098ae6aa56c4d2a231587edb9688c)) - by @Donothan73 in [funkin.assets#257](https://github.com/FunkinCrew/funkin.assets/pull/257)
- Health icons now bop independently from the framerate. ([8e6fa51](https://github.com/FunkinCrew/Funkin/commit/8e6fa51c27ceaa830efec06bb8a52e281a008255)) - by @PurSnake in [#6035](https://github.com/FunkinCrew/Funkin/pull/6035)
- The note resetting animation on song restart is now consistent between Downscroll and Upscroll. ([7b8d657](https://github.com/FunkinCrew/Funkin/commit/7b8d6577eddba568f20c3d23663dded054699090)) - by @FuroYT in [#6220](https://github.com/FunkinCrew/Funkin/pull/6220)
@@ -167,19 +536,19 @@ The LE SSERAFIM collab update!
- The path for a notestyle's countdown sound is now properly loaded as a sound instead of an image. ([dd5ea77](https://github.com/FunkinCrew/Funkin/commit/dd5ea7748b3b1878139998c209aa06db0fa05e0b)) - by @gamerbross in [#6232](https://github.com/FunkinCrew/Funkin/pull/6232)
- The Pause Menu theme no longer plays at maximum volume for a split second when pausing. ([6ba44d6](https://github.com/FunkinCrew/Funkin/commit/6ba44d6cb0c71deb29eb23b82b61f58b2e95193e)) - by @ComedyLost in [#6334](https://github.com/FunkinCrew/Funkin/pull/6334)
- The scrolling text in the Results Screen is now positioned consistently. ([200f798](https://github.com/FunkinCrew/Funkin/commit/200f7984379cb1bd911e49de92be312750893420)) - by @NotHyper-474 in [#6595](https://github.com/FunkinCrew/Funkin/pull/6595)
- The scrolling text in the Results Screen is now FPS-independent. ([8c43f6f](https://github.com/FunkinCrew/Funkin/commit/8c43f6f67a362bde4de4ad8dbd72966d7c4a9f60)) - by @VirtuGuy in [#6476](https://github.com/FunkinCrew/Funkin/pull/6476)
- The scrolling text in the Results Screen is now FPS-independent. ([8c43f6f](https://github.com/FunkinCrew/Funkin/commit/8c43f6f67a362bde4de4ad8dbd72966d7c4a9f60)) - by @realvirtu in [#6476](https://github.com/FunkinCrew/Funkin/pull/6476)
- The Results Screen theme now loops more smoothly. ([592bf1a](https://github.com/FunkinCrew/Funkin/commit/592bf1a9221d4dcef53ae421571eddf78ed631e4)) - by @FuroYT in [#6477](https://github.com/FunkinCrew/Funkin/pull/6477)
- Transition stickers now render properly with the window resized to any aspect ratio. ([4215b1c](https://github.com/FunkinCrew/Funkin/commit/4215b1c72e4391b2176014825885799b81dde2ba)) - by @PurSnake in [#6156](https://github.com/FunkinCrew/Funkin/pull/6156)
- Boyfriend now stands in the same position in the Week 3 and Week 3 Erect stages. ([d2d15f1](https://github.com/FunkinCrew/funkin.assets/commit/d2d15f114256125d53c6331b46415701ae291c1f)) - by @CEliuxJV in [funkin.assets#261](https://github.com/FunkinCrew/funkin.assets/pull/261)
- Pico's game over music now properly loops after his explosion death in 2hot. ([f1a1db0](https://github.com/FunkinCrew/Funkin/commit/f1a1db08347c3f9248fd16909cff06027297ad13)) - by @KoloInDaCrib in [#6216](https://github.com/FunkinCrew/Funkin/pull/6216)
- 2hot now smoothly transitions into the cutscene. ([462b1b6](https://github.com/FunkinCrew/funkin.assets/commit/462b1b6e6e9b622ad8fd15f15a1f39c7dffa4764)) - by @hucks5 in [funkin.assets#286](https://github.com/FunkinCrew/funkin.assets/pull/286)
- Nene now swings her legs during in-game cutscenes. ([6a5d9b2](https://github.com/FunkinCrew/funkin.assets/commit/6a5d9b265732d60da28083fb1c3d7b7b854edf63)) - by @hucks5 in [funkin.assets#289](https://github.com/FunkinCrew/funkin.assets/pull/289)
- Nene's 50 combo animation now renders its heart properly. ([bcd96ee](https://github.com/FunkinCrew/funkin.assets/commit/bcd96eeb78b9b03cf7b24dc956ac3bc36438193e)) - by @VirtuGuy in [funkin.assets#296](https://github.com/FunkinCrew/funkin.assets/pull/296)
- Nene's 50 combo animation now renders its heart properly. ([bcd96ee](https://github.com/FunkinCrew/funkin.assets/commit/bcd96eeb78b9b03cf7b24dc956ac3bc36438193e)) - by @realvirtu in [funkin.assets#296](https://github.com/FunkinCrew/funkin.assets/pull/296)
- A-Bot (Christmas) now properly looks at the opponent. ([f81cc16](https://github.com/FunkinCrew/funkin.assets/commit/f81cc16c8f99655f76b7e27ce221819798c9c94e)) - by @ComedyLost in [funkin.assets#279](https://github.com/FunkinCrew/funkin.assets/pull/279)
- Nene (Pixel) now raises and lowers her knife properly. ([1d9f50d](https://github.com/FunkinCrew/funkin.assets/commit/1d9f50d405f202e07efd883aeef5d6c1e9eaaa90)) - by @VirtuGuy in [funkin.assets#274](https://github.com/FunkinCrew/funkin.assets/pull/274)
- Nene (Pixel) now raises and lowers her knife properly. ([1d9f50d](https://github.com/FunkinCrew/funkin.assets/commit/1d9f50d405f202e07efd883aeef5d6c1e9eaaa90)) - by @realvirtu in [funkin.assets#274](https://github.com/FunkinCrew/funkin.assets/pull/274)
- Pico (Pixel)'s game over theme now plays at the right time. ([e8a4d24](https://github.com/FunkinCrew/funkin.assets/commit/e8a4d2472ca2dc28b03be05953dff3d7b5ec7433)) - by @JackXson-Real and @ComedyLost in [funkin.assets#288](https://github.com/FunkinCrew/funkin.assets/pull/288)
- Pico holding Nene's idle animation no longer lasts too long. ([3483345](https://github.com/FunkinCrew/funkin.assets/commit/348334583746ec45f1c6ab2c5e1715a67038cc5c)) - by @JackXson-Real in [funkin.assets#271](https://github.com/FunkinCrew/funkin.assets/pull/271)
- The tankmen in Stress no longer briefly appear behind the speakers when restarting. ([7f79ad8](https://github.com/FunkinCrew/funkin.assets/commit/7f79ad8c08d66fb909a9382de2c09f0430b756f1)) - by @VirtuGuy in [funkin.assets#298](https://github.com/FunkinCrew/funkin.assets/pull/298)
- The tankmen in Stress no longer briefly appear behind the speakers when restarting. ([7f79ad8](https://github.com/FunkinCrew/funkin.assets/commit/7f79ad8c08d66fb909a9382de2c09f0430b756f1)) - by @realvirtu in [funkin.assets#298](https://github.com/FunkinCrew/funkin.assets/pull/298)
- Encountering a Set Health Icon event during Minimal playtesting no longer crashes the Chart Editor. ([9f0a498](https://github.com/FunkinCrew/Funkin/commit/9f0a4988a3cc47581916a9750731bb7e63f168f3)) - by @charlesisfeline in [#6481](https://github.com/FunkinCrew/Funkin/pull/6481)
- Typing in Chart Editor text fields no longer triggers bound key functions. ([3b5e589](https://github.com/FunkinCrew/Funkin/commit/3b5e5893c01c2b56036e53626eaea8d41e70f640)) - by @MightyTheArmiddilo in [#6601](https://github.com/FunkinCrew/Funkin/pull/6601)
- Clicking between Chart Editor events no longer converts the second event's dropdown values into those of the first. ([c170c25](https://github.com/FunkinCrew/Funkin/commit/c170c256934ae316a735d38620ad5e24c2f15f4d)) - by @NotHyper-474 in [#6211](https://github.com/FunkinCrew/Funkin/pull/6211)
@@ -187,19 +556,19 @@ The LE SSERAFIM collab update!
- Placing a note and removing it no longer breaks the cursor in the Chart Editor. ([8cb5ed9](https://github.com/FunkinCrew/Funkin/commit/8cb5ed91baf50b6f78eefc2e50612a01195a2742)) - by @Lasercar in [#4237](https://github.com/FunkinCrew/Funkin/pull/4237)
- Playtesting in the Chart Editor now properly loads song variation scripts. ([055f620](https://github.com/FunkinCrew/Funkin/commit/055f62026ef44a928876d9065cc388da0905e9f1)) - by @PurSnake in [#6405](https://github.com/FunkinCrew/Funkin/pull/6405)
- Playtesting in the Chart Editor no longer sometimes moves on to another song like Story Mode. ([9497378](https://github.com/FunkinCrew/Funkin/commit/9497378600bad44639ff8b3fc92cb329052fd08a)) - by @KoloInDaCrib in [#6192](https://github.com/FunkinCrew/Funkin/pull/6192)
- The cursor is now hidden when playtesting through the Chart Editor. ([0471872](https://github.com/FunkinCrew/Funkin/commit/047187257b6712e61bf05fdebab33c7b3e9ac0f6)) - by @VirtuGuy in [#6137](https://github.com/FunkinCrew/Funkin/pull/6137)
- The cursor is now hidden when playtesting through the Chart Editor. ([0471872](https://github.com/FunkinCrew/Funkin/commit/047187257b6712e61bf05fdebab33c7b3e9ac0f6)) - by @realvirtu in [#6137](https://github.com/FunkinCrew/Funkin/pull/6137)
- The Chart Editor note moving sound no longer plays when dragging outside the grid. ([593456e](https://github.com/FunkinCrew/Funkin/commit/593456e53e02c53e71189fdb154e4a3e4f2b3092)) - by @amyspark-ng in [#4157](https://github.com/FunkinCrew/Funkin/pull/4157)
- The Chart Editor music now fades in after a period of silence when enabled. ([960d2f3](https://github.com/FunkinCrew/Funkin/commit/960d2f3cf166400c6fecee212b87961f3df10c2e)) - by @Lasercar in [#4148](https://github.com/FunkinCrew/Funkin/pull/4148)
- The Chart Editor Difficulty toolbox no longer displays the incorrect song name. ([dff2a1e](https://github.com/FunkinCrew/Funkin/commit/dff2a1e487dc20f86ef4f526a259083a7726ea6a)) - by @VirtuGuy in [#6547](https://github.com/FunkinCrew/Funkin/pull/6547)
- The Chart Editor Difficulty toolbox no longer displays the incorrect song name. ([dff2a1e](https://github.com/FunkinCrew/Funkin/commit/dff2a1e487dc20f86ef4f526a259083a7726ea6a)) - by @realvirtu in [#6547](https://github.com/FunkinCrew/Funkin/pull/6547)
- Chart Editor notifications now display a bit higher. ([9e645db](https://github.com/FunkinCrew/Funkin/commit/9e645db0074424ffb2de42b27afb3adaff55de62)) - by @MightyTheArmiddilo in [#6445](https://github.com/FunkinCrew/Funkin/pull/6445)
- The Yes and No text in the Chart Editor exit confirmation prompt buttons now always render properly. ([4c0d925](https://github.com/FunkinCrew/Funkin/commit/4c0d92507ae0b81a744d223e5292bf8d27013abd)) - by @NotHyper-474 in [#6173](https://github.com/FunkinCrew/Funkin/pull/6173)
- Exiting the Chart Editor now consistently saves your audio preferences. ([2f77ccf](https://github.com/FunkinCrew/Funkin/commit/2f77ccfc6e93fabef27d3e06447f9f6edd8e840d)) - by @VioletSnowLeopard in [#6127](https://github.com/FunkinCrew/Funkin/pull/6127)
- The Chart Editor and Stage Editor backup window now properly retrieves the most recently edited backup. ([a8dec0c](https://github.com/FunkinCrew/Funkin/commit/a8dec0cd7053f88865757f30a7d9f0ca5eb0fb02)) - by @Lasercar in [#6119](https://github.com/FunkinCrew/Funkin/pull/6119)
- The Chart Editor backup dialog no longer appears if the latest backup is deleted. ([bc1d36d](https://github.com/FunkinCrew/Funkin/commit/bc1d36ddeab81a790e3604598248a9b2fe869cac)) - by @KoloInDaCrib in [#6027](https://github.com/FunkinCrew/Funkin/pull/6027)
- Switching between Animation and Spritesheet mode no longer crashes the Animation Editor. ([a61016d](https://github.com/FunkinCrew/Funkin/commit/a61016d2dfc2ac6a50aae230969c036f0753cfaa)) - by @VirtuGuy in [#6114](https://github.com/FunkinCrew/Funkin/pull/6114)
- Switching between Animation and Spritesheet mode no longer crashes the Animation Editor. ([a61016d](https://github.com/FunkinCrew/Funkin/commit/a61016d2dfc2ac6a50aae230969c036f0753cfaa)) - by @realvirtu in [#6114](https://github.com/FunkinCrew/Funkin/pull/6114)
- The Animation Editor no longer displays a missing object icon next to the dropdown menus. ([b30ea36](https://github.com/FunkinCrew/Funkin/commit/b30ea36fcc982ce4ac0be9143fd4701e180fc684)) - by @KoloInDaCrib in [#6177](https://github.com/FunkinCrew/Funkin/pull/6177)
- The Animation Editor onion skin now properly accounts for character scale and offsets. ([a76a868](https://github.com/FunkinCrew/Funkin/commit/a76a868cb6a27c1c76d09177b90cf6df3df29d17)) - by @VirtuGuy in [#6123](https://github.com/FunkinCrew/Funkin/pull/6123)
- The debug cursor is now properly hidden when exiting the Animation Editor. ([f2f6b4c](https://github.com/FunkinCrew/Funkin/commit/f2f6b4c8591e1ab4a8c6f0ed998d6d25d7cc9f43)) - by @VirtuGuy in [#6112](https://github.com/FunkinCrew/Funkin/pull/6112)
- The Animation Editor onion skin now properly accounts for character scale and offsets. ([a76a868](https://github.com/FunkinCrew/Funkin/commit/a76a868cb6a27c1c76d09177b90cf6df3df29d17)) - by @realvirtu in [#6123](https://github.com/FunkinCrew/Funkin/pull/6123)
- The debug cursor is now properly hidden when exiting the Animation Editor. ([f2f6b4c](https://github.com/FunkinCrew/Funkin/commit/f2f6b4c8591e1ab4a8c6f0ed998d6d25d7cc9f43)) - by @realvirtu in [#6112](https://github.com/FunkinCrew/Funkin/pull/6112)
- Plenty more tiny fixes.
## New Contributors for 0.8.0
@@ -258,13 +627,13 @@ The LE SSERAFIM collab update!
- 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 Main Menu music now fades in consistently when exiting from Freeplay to the Title Screen. ([a10bbf6](https://github.com/FunkinCrew/Funkin/commit/a10bbf60acbbeadfb5a91930745ef4fd338b1a24)) - by @realvirtu 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)
- The bricks in Stress (Pico Mix) no longer move after restarting the song. ([9cfee03](https://github.com/FunkinCrew/Funkin/commit/9cfee0398a057567f80ad68ff6052964da63af09)) - by @realvirtu 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)
@@ -337,7 +706,7 @@ The LE SSERAFIM collab update!
- 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)
- Selecting a song in the Freeplay menu now plays a fade-out transition. ([705e6b3](https://github.com/FunkinCrew/Funkin/commit/705e6b330806c3157bca7301b1e43cd78acdb23a)) - by @realvirtu 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)
@@ -385,8 +754,8 @@ The LE SSERAFIM collab update!
- 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 Preferences menu camera now remembers its position when exiting and re-entering. ([3d88fbb](https://github.com/FunkinCrew/Funkin/commit/3d88fbb11fea2b52d399f37cb8154795329c31c2)) - by @realvirtu 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 @realvirtu 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)
@@ -404,7 +773,7 @@ The LE SSERAFIM collab update!
- 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)
- 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 @realvirtu 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)
@@ -418,12 +787,12 @@ The LE SSERAFIM collab update!
- 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)
- The Legacy Chart Importer now properly imports scroll speeds. ([2645d56](https://github.com/FunkinCrew/Funkin/commit/2645d56514dd1a27a050ff432c3cd4122f958e10)) - by @realvirtu 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)
- Pressing F4 in the Chart Editor now properly resets the window title. ([86e69cf](https://github.com/FunkinCrew/Funkin/commit/86e69cfbd1b1bd3daa49181b827fa813cb716703)) - by @realvirtu 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)
@@ -431,9 +800,10 @@ The LE SSERAFIM collab update!
## New Contributors for 0.7.4
* @Trofem made their first contribution in [#5476](https://github.com/FunkinCrew/Funkin/pull/5476)
* @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)
* @realvirtu 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)
+1 -1
View File
@@ -197,7 +197,7 @@ You can view the `funkin-assets` license here: (https://github.com/FunkinCrew/fu
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2020-2024 The Funkin' Crew Inc.
Copyright 2020-2026 The Funkin' Crew Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+1 -1
Submodule art updated: 2e68e371f8...429ab728b1
+1 -1
Submodule assets updated: 39d4b3fc95...724eba9de9
+30 -3
View File
@@ -9,6 +9,10 @@
"asset": "assets/preload/images/NOTE_assets.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/characters/darnell/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "assets/preload/images/NOTE_hold_assets.png",
"blocksize": "4x4"
@@ -41,6 +45,22 @@
"asset": "assets/shared/images/characters/sserafim/chaewon/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/characters/pico-dark/spritemap1.png",
"blocksize": "4x4"
},
{
"asset": "assets/shared/images/characters/pico/basic-animations/spritemap1.png",
"blocksize": "6x6"
},
{
"asset": "assets/shared/images/characters/pico/explosion-death/spritemap1.png",
"blocksize": "8x8"
},
{
"asset": "assets/shared/images/characters/pico/playable-animations/spritemap1.png",
"blocksize": "6x6"
},
{
"asset": "assets/shared/images/holdCoverBlue.png",
"blocksize": "4x4"
@@ -109,6 +129,10 @@
"asset": "assets/week1/image/erect/lights.png",
"blocksize": "6x6"
},
{
"asset": "assets/shared/images/characters/pico/death/spritemap1.png",
"blocksize": "6x6"
},
{
"asset": "assets/week1/images/erect/crowd.png",
"blocksize": "8x8"
@@ -127,6 +151,7 @@
}
],
"excludes": [
"assets/fonts/vcr-bmp.png",
"assets/preload/images/cursor/",
"assets/preload/images/fonts/",
"assets/preload/images/freeplay/",
@@ -134,8 +159,8 @@
"assets/preload/images/soundtray/",
"assets/preload/images/stageBuild/",
"assets/preload/images/storymenu/titles/",
"assets/preload/images/titleEnter.png",
"assets/preload/images/titleEnter_mobile.png",
"assets/preload/images/title-screen-text/spritemap1.png",
"assets/preload/images/title-screen-text-mobile/spritemap1.png",
"assets/preload/images/ui/popup/pixel/*",
"assets/shared/images/characters/abotPixel/*",
"assets/shared/images/characters/bfPixel.png",
@@ -177,6 +202,8 @@
"assets/week1/images/erect/orangeLight.png",
"assets/week2/images/erect/stairsDark.png",
"assets/week2/images/erect/stairsLight.png",
"assets/week6/"
"assets/week6/",
"assets/week7/images/bricksGround.png",
"assets/week7/images/erect/bricksGround.png"
]
}
+19 -17
View File
@@ -1,8 +1,8 @@
FROM ubuntu:noble
ARG haxe_version=4.3.6
ARG haxelib_version=4.1.0
ARG neko_version=2.4.0
ARG haxe_version=4.3.7
ARG haxelib_version=4.2.0
ARG neko_version=2.4.1
# prepare runner
ENV GITHUB_HOME="/github/home"
@@ -80,11 +80,13 @@ EOF
# Haxe native dependencies
RUN <<EOF
apt-fast install -y --no-install-recommends \
libc6-dev libffi-dev \
libx11-dev libxi-dev libxext-dev libxinerama-dev libxrandr-dev \
libgl-dev libgl1-mesa-dev \
build-essential \
libc6-dev libffi-dev libdbus-1-dev libudev-dev libgbm-dev \
libx11-dev libxi-dev libxext-dev libxinerama-dev libxrandr-dev libxcursor-dev libxss-dev \
libgl-dev libgl1-mesa-dev libglu1-mesa-dev libdrm-dev \
libasound2-dev libpulse-dev \
libvlc-dev libvlccore-dev
libvlc-dev libvlccore-dev \
gcc-multilib g++-multilib
EOF
# Janky libffi.6 fix
@@ -98,11 +100,11 @@ EOF
# neko
# https://github.com/HaxeFoundation/neko/releases/download/v2-3-0/neko-2.3.0-linux64.tar.gz
RUN <<EOF
#neko_url=$(curl https://api.github.com/repos/HaxeFoundation/neko/releases -fL \
# | jq '.[] | select(.name == "'"$neko_version"'")' \
# | jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
# | jq -r '.browser_download_url')
neko_url="https://geo.thei.rs/funkin/neko-2.4.1-linux64.tar.gz"
neko_url=$(curl https://api.github.com/repos/HaxeFoundation/neko/releases -fL \
| jq '.[] | select(.name == "'"$neko_version"'")' \
| jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
| jq -r '.browser_download_url')
#neko_url="https://geo.thei.rs/funkin/neko-2.4.1-linux64.tar.gz"
curl -fL "$neko_url" | tar -xz -C /usr/local
EOF
@@ -112,16 +114,16 @@ ln -s "$neko_path" /usr/local/neko
EOF
ENV NEKOPATH="/usr/local/neko"
ENV LD_LIBRARY_PATH="$NEKOPATH:$LD_LIBRARY_PATH"
ENV LD_LIBRARY_PATH="$NEKOPATH"
ENV PATH="$NEKOPATH:$PATH"
# haxe
# https://github.com/HaxeFoundation/haxe/releases/download/4.0.5/haxe-4.0.5-linux64.tar.gz
RUN <<EOF
#haxe_url=$(curl https://api.github.com/repos/HaxeFoundation/haxe/releases -fL \
# | jq '.[] | select(.name == "'"$haxe_version"'")' \
# | jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
# | jq -r '.browser_download_url')
haxe_url=$(curl https://api.github.com/repos/HaxeFoundation/haxe/releases -fL \
| jq '.[] | select(.name == "'"$haxe_version"'")' \
| jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
| jq -r '.browser_download_url')
haxe_url="https://geo.thei.rs/funkin/haxe-4.3.6-linux64.tar.gz"
curl -fL "$haxe_url" | tar -xz -C /usr/local
EOF
+409 -151
View File
@@ -1,4 +1,6 @@
{
"version": 1,
"exclude": {},
"defaultSeverity": "INFO",
"extendsConfigPath": "",
"numberOfCheckerThreads": 5,
@@ -6,113 +8,152 @@
"defineCombinations": [],
"checks": [
{
"props": {},
"comment": "If enabled, prevents using anonymous types inline without creating a typedef for them.",
"props": { "severity": "INFO" },
"type": "Anonymous"
},
{
"comment": "If enabled, mandates spacing around array access syntax.",
"props": {
"spaceBefore": false,
"spaceInside": false
"spaceInside": false,
"severity": "INFO"
},
"type": "ArrayAccess"
},
{
"props": {},
"comment": "If enabled, mandates array literals be defined with [] instead of 'new'.",
"props": { "severity": "WARNING" },
"type": "ArrayLiteral"
},
{
"comment": "If enabled, mandates specific syntax for the use of array literals.",
"props": {
"allowSingleArgParens": true,
"allowReturn": true,
"allowFunction": true,
"allowCurlyBody": true
"allowCurlyBody": true,
"enforceArrowForNonMemberFunctions": true,
"severity": "INFO"
},
"type": "ArrowFunction"
},
{
"props": {
"avoidIdentifiers": []
},
"comment": "Specify a list of variable and function names which are not allowed and should be renamed. Doesn't support regex.",
"props": { "avoidIdentifiers": [], "severity": "WARNING" },
"type": "AvoidIdentifier"
},
{
"props": {},
"comment": "If enabled, prevents imports like 'import flixel.*' from being used.",
"props": { "severity": "INFO" },
"type": "AvoidStarImport"
},
{
"props": {},
"comment": "If enabled, prevents ternary operators from being nested.",
"props": {
"severity": "INFO",
"maxDepth": 1
},
"type": "AvoidTernaryOperator"
},
{
"comment": "If enabled, prevents conditional compilation from crossing blocks. This prevents the case where conditional compilation could potentially create invalid syntax.",
"props": { "severity": "INFO" },
"type": "BlockBreakingConditional"
},
{
"comment": "Specifies a specific naming format for the parameter of a catch block.",
"props": {
"format": "^(e|t|ex|[a-z][a-z][a-zA-Z]+)$"
"format": "^(e|t|ex|[a-z][a-z][a-zA-Z]+)$",
"severity": "INFO"
},
"type": "CatchParameterName"
},
{
"comment": "If enabled, flags when large blocks of similar code should be extracted to a function.",
"props": {
"thresholdSimilar": 120,
"severityIdentical": "WARNING",
"thresholdIdentical": 60
"severity": "IGNORE",
"thresholdIdentical": 60,
"severityIdentical": "IGNORE"
},
"type": "CodeSimilarity"
},
{
"props": {},
"comment": "If enabled, flags Haxe code that is commented out. Unused code should be removed and accessed via version control later if needed.",
"props": { "severity": "WARNING" },
"type": "CommentedOutCode"
},
{
"comment": "If enabled, flags when conditional compilation blocks are not properly aligned. NOTE:Disabled because it's kinda broken.",
"props": {
"severity": "IGNORE",
"policy": "aligned",
"allowSingleline": true
"allowSingleline": true,
"severity": "IGNORE"
},
"type": "ConditionalCompilation"
},
{
"comment": "Specifies a specific naming format for static var identifiers.",
"props": {
"ignoreExtern": true,
"format": "^?:_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*$",
"tokens": ["INLINE", "NOTINLINE"]
"tokens": ["INLINE", "NOTINLINE", "NOTFINAL"],
"severity": "INFO"
},
"type": "ConstantName"
},
{
"comment": "Specifies a specific naming format for static final identifiers.",
"props": {
"ignoreExtern": true,
"format": "^[A-Z]([_A-Z0-9]+)*$",
"tokens": ["INLINE", "NOTINLINE", "FINAL"],
"severity": "INFO"
},
"type": "ConstantName"
},
{
"comment": "Calculates the complexity of methods using the McCabe metric, and throws warnings at certain thresholds. Indicates that a function should be refactored or split up.",
"props": {
"thresholds": [
{
"complexity": 20,
"severity": "WARNING"
},
{
"complexity": 25,
"severity": "ERROR"
}
{ "complexity": 20, "severity": "WARNING" },
{ "complexity": 25, "severity": "ERROR" }
],
"severity": "IGNORE"
},
"type": "CyclomaticComplexity"
},
{
"props": {},
"comment": "If enabled, the default case of a switch statement must be last.",
"props": { "severity": "INFO" },
"type": "DefaultComesLast"
},
{
"comment": "Specifies the format for doc-style comments ().",
"props": {
"startStyle": "twostars",
"endStyle": "onestar",
"lineStyle": "onestar",
"startStyle": "ignore"
"severity": "INFO"
},
"type": "DocCommentStyle"
},
{
"comment": "If enabled, prevents the use of the Dynamic type.",
"props": { "severity": "IGNORE" },
"type": "Dynamic"
},
{
"props": {},
"comment": "If enabled, ensures ~/.../ is used instead of 'new EReg()'",
"props": { "severity": "WARNING" },
"type": "ERegLiteral"
},
{
"comment": "If enabled, enforces specific syntax on empty blocks (require only one line, etc.)",
"props": {
"tokens": [
"CLASS_DEF",
@@ -129,11 +170,13 @@
"TRY",
"CATCH"
],
"option": "empty"
"option": "empty",
"severity": "IGNORE"
},
"type": "EmptyBlock"
},
{
"comment": "If enabled, flags when consecutive empty lines are used.",
"props": {
"requireEmptyLineAfterPackage": true,
"requireEmptyLineAfterInterface": true,
@@ -141,17 +184,18 @@
"allowEmptyLineAfterSingleLineComment": true,
"max": 1,
"requireEmptyLineAfterClass": true,
"allowEmptyLineAfterMultiLineComment": true
"allowEmptyLineAfterMultiLineComment": true,
"severity": "IGNORE"
},
"type": "EmptyLines"
},
{
"props": {
"enforceEmptyPackage": true
},
"comment": "If enabled, mandates the use of 'package;' on root level modules.",
"props": { "enforceEmptyPackage": true, "severity": "WARNING" },
"type": "EmptyPackage"
},
{
"comment": "If enabled, provides advanced checking for when consecutive empty lines are used.",
"props": {
"none": [],
"upto": [],
@@ -160,45 +204,61 @@
"max": 1,
"ignore": [],
"atleast": [],
"skipSingleLineTypes": true
"skipSingleLineTypes": true,
"severity": "IGNORE"
},
"type": "ExtendedEmptyLines"
},
{
"comment": "If enabled, mandates documentation comments for public fields.",
"props": {
"requireParams": true,
"fieldType": "BOTH",
"requireReturn": true,
"ignoreOverride": true,
"tokens": ["ABSTRACT_DEF", "CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF"],
"tokens": ["ABSTRACT_DEF", "CLASS_DEF", "INTERFACE_DEF"],
"modifier": "PUBLIC",
"excludeNames": ["new", "toString"]
"excludeNames": ["new", "toString"],
"severity": "INFO"
},
"type": "FieldDocComment"
},
{
"comment": "If enabled, mandates documentation comments for public fields.",
"props": {
"max": 1000,
"ignoreEmptyLines": true,
"severity": "IGNORE"
"requireParams": true,
"fieldType": "FUNCTIONS",
"requireReturn": true,
"ignoreOverride": true,
"tokens": ["ENUM_DEF"],
"modifier": "PUBLIC",
"excludeNames": ["new", "toString"],
"severity": "INFO"
},
"type": "FieldDocComment"
},
{
"comment": "If enabled, warns if files exceed a certain number of lines.",
"props": { "max": 1000, "ignoreEmptyLines": true, "severity": "IGNORE" },
"type": "FileLength"
},
{
"comment": "If enabled, requires modules match the casing of their file name.",
"type": "FileNameCase",
"props": {}
"props": { "severity": "WARNING" }
},
{
"comment": "If enabled, requires inline/static variables to be declared final.",
"type": "Final",
"props": {}
"props": { "severity": "IGNORE" }
},
{
"props": {
"option": "upperCase"
},
"comment": "If enabled, requires hexadecimal literals to be in upper case. 0xFFFFFF is valid and 0xffffff is invalid.",
"props": { "option": "upperCase", "severity": "WARNING" },
"type": "HexadecimalLiteral"
},
{
"comment": "If enabled, warns if a local variable or parameter shadows an existing field.",
"props": {
"ignoreSetter": true,
"ignoreFormat": "^(main|run)$",
@@ -207,21 +267,21 @@
"type": "HiddenField"
},
{
"props": {
"character": " ",
"severity": "IGNORE"
},
"comment": "If enabled, mandates indentation.",
"props": { "character": "", "severity": "IGNORE" },
"type": "Indentation"
},
{
"comment": "If enabled, mandates characters used for indentation.",
"props": {
"character": "space",
"severity": "INFO",
"severity": "IGNORE",
"ignorePattern": "^$"
},
"type": "IndentationCharacter"
},
{
"comment": "If enabled, warns about assignments performed within another expression, like 'if (a=b){}'",
"props": {
"ignoreReturnAssignments": true,
"severity": "WARNING"
@@ -229,161 +289,261 @@
"type": "InnerAssignment"
},
{
"comment": "If enabled, enforces that interfaces should not contain properties.",
"props": {
"allowProperties": false,
"allowMarkerInterfaces": true
"allowMarkerInterfaces": true,
"severity": "WARNING"
},
"type": "Interface"
},
{
"comment": "If enabled, enforces a newline before the left curly brace of a block.",
"props": {
"option": "nl",
"ignoreEmptySingleline": true,
"tokens": [
"CLASS_DEF",
"ENUM_DEF",
"ABSTRACT_DEF",
"TYPEDEF_DEF",
"INTERFACE_DEF",
"FUNCTION",
"FOR",
"IF",
"WHILE",
"SWITCH",
"TRY",
"CATCH",
"ARRAY_COMPREHENSION"
],
"severity": "INFO"
},
"type": "LeftCurly"
},
{
"comment": "If enabled, enforces the left curly brace occurs on the end of the line, without a newline.",
"props": {
"option": "eol",
"ignoreEmptySingleline": true,
"tokens": ["OBJECT_DECL"],
"severity": "IGNORE"
},
"type": "LeftCurly"
},
{
"comment": "If enabled, warns when lines of code exceed a certain length.",
"props": {
"max": 160,
"ignorePattern": "^(\\s*['\"][^'\"]*['\"].*)$"
"ignorePattern": "^(\\s*['\"][^'\"]*['\"].*)$",
"severity": "INFO"
},
"type": "LineLength"
},
{
"comment": "If enabled, mandates a specific naming convention for listener methods.",
"props": {
"listeners": ["addEventListener", "addListener", "on", "once"],
"format": "^_?[a-z][a-zA-Z0-9]*$"
"format": "^_?[a-z][a-zA-Z0-9]*$",
"severity": "IGNORE"
},
"type": "ListenerName"
},
{
"comment": "Specifies a specific naming format for local var variables.",
"props": {
"ignoreExtern": true,
"format": "^[a-z][a-zA-Z0-9]*$",
"tokens": []
"tokens": ["NOTFINAL"],
"severity": "INFO"
},
"type": "LocalVariableName"
},
{
"comment": "Specifies a specific naming format for local final variables.",
"props": {
"ignoreNumbers": [-1, 0, 1, 2],
"severity": "IGNORE"
"ignoreExtern": true,
"format": "^[A-Z][_A-Z0-9]*$",
"tokens": ["FINAL"],
"severity": "INFO"
},
"type": "LocalVariableName"
},
{
"comment": "Puts a warning on long numbers without separators. 1000000 is invalid and 1_000_000 is valid.",
"props": {
"severity": "INFO",
"decimalGroupSize": 3,
"fractionalGroupSize": -1,
"binaryGroupSize": 8,
"hexadecimalGroupSize": 8,
"decimalMinimum": 10000
},
"type": "LongNumber"
},
{
"comment": "If enabled, warns when unlabelled numeric values get used. Use named constants instead to improve code clarity.",
"props": { "ignoreNumbers": [-1, 0, 1, 2], "severity": "IGNORE" },
"type": "MagicNumber"
},
{
"comment": "Specifies a specific naming format for public abstract member fields.",
"props": {
"format": "^[A-Z][a-zA-Z0-9]*$",
"tokens": ["ABSTRACT"]
"format": "^[a-zA-Z][_a-zA-Z0-9]*$",
"tokens": ["PUBLIC", "ABSTRACT"]
},
"type": "MemberName"
},
{
"comment": "Specifies a specific naming format for private abstract member fields.",
"props": {
"format": "^[_a-zA-Z][a-z][a-zA-Z0-9]*$",
"tokens": ["ABSTRACT"]
"tokens": ["PRIVATE", "ABSTRACT"]
},
"type": "MemberName"
},
{
"comment": "Specifies a specific naming format for public class member fields.",
"props": {
"ignoreExtern": true,
"format": "^[_a-z][a-zA-Z0-9]*$",
"tokens": ["PUBLIC", "PRIVATE", "CLASS", "TYPEDEF"]
"format": "^[a-zA-Z][a-z][a-zA-Z0-9]*$",
"tokens": ["PUBLIC", "CLASS"]
},
"type": "MemberName"
},
{
"comment": "Specifies a specific naming format for private class member fields.",
"props": {
"format": "^[_a-zA-Z][_a-zA-Z0-9]*$",
"tokens": ["PRIVATE", "CLASS"]
},
"type": "MemberName"
},
{
"comment": "Specifies a specific naming format for enum member fields.",
"props": {
"format": "^[a-zA-Z][_a-zA-Z0-9]*$",
"tokens": ["PUBLIC", "ENUM"]
},
"type": "MemberName"
},
{
"comment": "Specifies a specific naming format for typedef member fields.",
"props": {
"format": "^[_a-zA-Z][a-z][a-zA-Z0-9]*$",
"tokens": ["TYPEDEF"]
},
"type": "MemberName"
},
{
"comment": "If enabled, enforces that modules should not exceed a certain number of methods.",
"props": {
"maxPrivate": 100,
"maxPublic": 100,
"maxTotal": 100
"maxTotal": 100,
"severity": "IGNORE"
},
"type": "MethodCount"
},
{
"props": {
"max": 50,
"ignoreEmptyLines": true,
"severity": "IGNORE"
},
"comment": "If enabled, enforces that methods should not exceed a certain number of lines of code, excluding empty lines.",
"props": { "max": 50, "ignoreEmptyLines": true, "severity": "IGNORE" },
"type": "MethodLength"
},
{
"comment": "Specifies a specific naming format for method names.",
"props": {
"ignoreExtern": true,
"format": "^[a-z][a-zA-Z0-9]*$",
"format": "^[a-z][_a-zA-Z0-9]*$",
"tokens": [],
"severity": "IGNORE"
"severity": "INFO"
},
"type": "MethodName"
},
{
"comment": "Specifies a specific order for modifiers on fields.",
"props": {
"modifiers": [
"OVERRIDE",
"OVERLOAD",
"PUBLIC_PRIVATE",
"STATIC",
"MACRO",
"OVERRIDE",
"ABSTRACT",
"EXTERN",
"INLINE",
"DYNAMIC",
"MACRO",
"FINAL"
],
"severity": "IGNORE"
"severity": "INFO"
},
"type": "ModifierOrder"
},
{
"comment": "If enabled, complains when a specific string literal is used in the same file multiple times. Use a named constant instead.",
"props": {
"minLength": 2,
"ignore": "^\\s+$",
"allowDuplicates": 5
"allowDuplicates": 5,
"severity": "IGNORE"
},
"type": "MultipleStringLiterals"
},
{
"props": {},
"comment": "If enabled, complains when a multiple variables are declared in a single expression. Use individual lines.",
"props": { "severity": "WARNING" },
"type": "MultipleVariableDeclarations"
},
{
"comment": "If enabled, mandates the use of braces on specific block types, unless they fit on a single line.",
"props": {
"allowSingleLineStatement": true,
"tokens": ["ELSE_IF", "WHILE", "DO_WHILE"]
"tokens": ["FUNCTION", "FOR", "IF", "IF_WITH_ELSE", "ELSE"],
"severity": "INFO"
},
"type": "NeedBraces"
},
{
"comment": "If enabled, mandates the use of braces on specific block types, and prevent them from being placed on a single line.",
"props": {
"max": 3,
"severity": "IGNORE"
"allowSingleLineStatement": false,
"tokens": ["IF_WITH_ELSE", "CATCH", "WHILE", "DO_WHILE", "ELSE_IF"],
"severity": "INFO"
},
"type": "NeedBraces"
},
{
"comment": "If enabled, complains when control flow statements are nested too deep (indicating high complexity).",
"props": { "max": 3, "severity": "IGNORE" },
"type": "NestedControlFlow"
},
{
"props": {
"max": 1,
"severity": "IGNORE"
},
"comment": "If enabled, complains when 'for' loops are nested too deep (indicating high complexity).",
"props": { "max": 1, "severity": "IGNORE" },
"type": "NestedForDepth"
},
{
"props": {
"max": 4
},
"comment": "If enabled, complains when 'if' statements are nested too deep (indicating high complexity).",
"props": { "max": 4, "severity": "IGNORE" },
"type": "NestedIfDepth"
},
{
"props": {
"max": 1
},
"comment": "If enabled, complains when try/catch statements are nested too deep (indicating high complexity).",
"props": { "max": 1, "severity": "INFO" },
"type": "NestedTryDepth"
},
{
"props": {
"option": "questionMark"
},
"comment": "If enabled, enforces ?value rather than value = null.",
"props": { "option": "questionMark", "severity": "INFO" },
"type": "NullableParameter"
},
{
"comment": "If enabled, enforces that operators should be surrounded by whitespace.",
"props": {
"oldFunctionTypePolicy": "none",
"unaryOpPolicy": "none",
@@ -401,6 +561,7 @@
"type": "OperatorWhitespace"
},
{
"comment": "If enabled, enforces that most operators should be after a newline rather than before.",
"props": {
"tokens": [
"+",
@@ -443,54 +604,52 @@
"type": "OperatorWrap"
},
{
"props": {
"tokens": ["="],
"option": "eol"
},
"comment": "If enabled, enforces that assignment operators should be before a newline rather than after.",
"props": { "tokens": ["="], "option": "eol" },
"type": "OperatorWrap"
},
{
"comment": "Specifies a specific naming format for method parameter names.",
"props": {
"ignoreExtern": true,
"format": "^(_|[a-z][a-zA-Z0-9]*$)",
"tokens": []
"tokens": [],
"severity": "INFO"
},
"type": "ParameterName"
},
{
"props": {
"max": 7,
"ignoreOverriddenMethods": false
},
"comment": "If enabled, complains when there are too many parameters on a method.",
"props": { "max": 7, "ignoreOverriddenMethods": false },
"type": "ParameterNumber"
},
{
"props": {
"severity": "WARNING"
},
"comment": "If enabled, complains when you make a property accessor method public.",
"props": { "severity": "WARNING" },
"type": "PublicAccessor"
},
{
"props": {
"prohibitMeta": false
},
"comment": "If enabled, complains when an @:access metadata is redundant.",
"props": { "prohibitMeta": false, "severity": "INFO" },
"type": "RedundantAccessMeta"
},
{
"props": {
"prohibitMeta": false
},
"comment": "If enabled, complains when an @:allow metadata is redundant.",
"props": { "prohibitMeta": false, "severity": "INFO" },
"type": "RedundantAllowMeta"
},
{
"comment": "If enabled, complains when an access modifier is redundant.",
"props": {
"enforcePrivate": false,
"enforcePublic": true,
"enforcePublicPrivate": false
"enforcePublicPrivate": false,
"severity": "WARNING"
},
"type": "RedundantModifier"
},
{
"comment": "If enabled, enforces that a return type is specified for all methods.",
"props": {
"enforceReturnTypeForAnonymous": false,
"allowEmptyReturn": true,
@@ -499,44 +658,67 @@
"type": "Return"
},
{
"props": {
"ignoreFormat": "^$",
"max": 2,
"severity": "IGNORE"
},
"comment": "If enabled, mandates a maximum number of 'return' statements in a method.",
"props": { "ignoreFormat": "^$", "max": 2, "severity": "IGNORE" },
"type": "ReturnCount"
},
{
"comment": "If enabled, enforces a specific placement for curly braces. TODO:Choose between Allman/K&R and enforce project-wide.",
"props": {
"option": "aloneorsingle",
"tokens": [
"CLASS_DEF",
"ENUM_DEF",
"ABSTRACT_DEF",
"TYPEDEF_DEF",
"INTERFACE_DEF",
"OBJECT_DECL",
"FUNCTION",
"FOR",
"IF",
"WHILE",
"SWITCH",
"TRY",
"CATCH",
"REIFICATION",
"ARRAY_COMPREHENSION"
],
"severity": "IGNORE"
},
"type": "RightCurly"
},
{
"comment": "Enforces specific whitespace around certain separators, such as commas and semicolons.",
"props": {
"commaPolicy": "after",
"semicolonPolicy": "after",
"allowTrailingComma": false,
"dotPolicy": "none"
"dotPolicy": "none",
"severity": "INFO"
},
"type": "SeparatorWhitespace"
},
{
"props": {
"tokens": [","],
"option": "eol"
},
"comment": "Enforces specific line wrapping for certain separators, such as commas and semicolons.",
"props": { "tokens": [","], "option": "eol" },
"type": "SeparatorWrap"
},
{
"props": {},
"comment": "If enabled, complains about overly complicated boolean expressions.",
"props": {
"severity": "WARNING",
"allowEqualsFalse": false
},
"type": "SimplifyBooleanExpression"
},
{
"props": {},
"comment": "If enabled, complains about overly complicated boolean return statements.",
"props": { "severity": "WARNING" },
"type": "SimplifyBooleanReturn"
},
{
"comment": "If enabled, enforce spacing in and around conditional statements and certain operators.",
"props": {
"spaceIfCondition": "should",
"spaceAroundBinop": true,
@@ -550,94 +732,171 @@
"type": "Spacing"
},
{
"comment": "Enforce a specific string literal style (either ' or \").",
"props": {
"policy": "onlySingle",
"allowException": true,
"severity": "IGNORE"
"severity": "INFO"
},
"type": "StringLiteral"
},
{
"comment": "If enabled, requires that switch conditions be wrapped in parenthesis.",
"props": {
"format": "^\\s*(TODO|FIXME|HACK|XXX|BUG)"
"policy": "require",
"severity": "INFO"
},
"type": "SwitchParentheses"
},
{
"comment": "Puts a warning on unresolved TODO/FIXME comments.",
"props": {
"format": "^\\s*(TODO|FIXME|HACK|XXX|BUG)",
"severity": "INFO"
},
"type": "TODOComment"
},
{
"props": {
"ignorePattern": "^$"
},
"comment": "Checks if there are any tabs in the middle of a line.",
"props": { "severity": "INFO" },
"type": "TabForAligning"
},
{
"props": {
"severity": "IGNORE"
},
"comment": "If enabled, complains whenever trace() gets used in code.",
"props": { "severity": "IGNORE" },
"type": "Trace"
},
{
"props": {},
"comment": "If enabled, complains about trailing commas at the end of array and object literals.",
"props": {
"severity": "INFO",
"enforceArrayComprehension": false,
"enforceArrayLiterals": false,
"enforceObjectLiterals": false
},
"type": "TrailingComma"
},
{
"comment": "If enabled, complains about trailing whitespaces at the end of lines.",
"props": { "severity": "INFO" },
"type": "TrailingWhitespace"
},
{
"type": "Type",
"props": {
"ignoreEnumAbstractValues": true
}
"comment": "If enabled, requires type be specified on member fields.",
"props": { "ignoreEnumAbstractValues": true, "severity": "INFO" },
"type": "Type"
},
{
"comment": "If enabled, mandates documentation comments on classes and interfaces.",
"props": {
"tokens": ["CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF", "TYPEDEF_DEF"]
"tokens": [
"CLASS_DEF",
"INTERFACE_DEF",
"TYPEDEF_DEF",
"ABSTRACT_DEF",
"ENUM_DEF"
],
"severity": "INFO"
},
"type": "TypeDocComment"
},
{
"comment": "Specifies a specific naming format for abstract types.",
"props": {
"ignoreExtern": true,
"format": "^[A-Z]+[a-zA-Z0-9]*$",
"tokens": []
"tokens": ["ABSTRACT"],
"severity": "WARNING"
},
"type": "TypeName"
},
{
"comment": "Specifies a specific naming format for class types.",
"props": {
"ignoreExtern": true,
"format": "^[A-Z]+[a-zA-Z0-9]*$",
"tokens": ["CLASS"],
"severity": "WARNING"
},
"type": "TypeName"
},
{
"comment": "Specifies a specific naming format for enum types.",
"props": {
"ignoreExtern": true,
"format": "^[A-Z]+[a-zA-Z0-9]*$",
"tokens": ["ENUM"],
"severity": "WARNING"
},
"type": "TypeName"
},
{
"comment": "Specifies a specific naming format for interface types.",
"props": {
"ignoreExtern": true,
"format": "^[A-Z]+[a-zA-Z0-9]*$",
"tokens": ["INTERFACE"],
"severity": "WARNING"
},
"type": "TypeName"
},
{
"comment": "Specifies a specific naming format for typedefs.",
"props": {
"ignoreExtern": true,
"format": "^[A-Z]+[a-zA-Z0-9]*$",
"tokens": ["TYPEDEF"],
"severity": "WARNING"
},
"type": "TypeName"
},
{
"props": {},
"comment": "If enabled, complains when a class with only static fields and values has a redundant constructor.",
"props": { "severity": "WARNING" },
"type": "UnnecessaryConstructor"
},
{
"props": {
"moduleTypeMap": {},
"ignoreModules": []
},
"comment": "If enabled, complains when a module contains unused imports. NOTE:Sometimes complains about required imports.",
"props": { "moduleTypeMap": {}, "ignoreModules": [], "severity": "INFO" },
"type": "UnusedImport"
},
{
"props": {
"severity": "WARNING"
},
"comment": "If enabled, complains when a local variable is unused.",
"props": { "severity": "WARNING" },
"type": "UnusedLocalVar"
},
{
"type": "VarTypeHint",
"comment": "If enabled, requires type hints for certain variables.",
"props": {
"typeHintPolicy": "enforce_all",
"ignoreEnumAbstractValues": true,
"severity": "IGNORE"
}
},
"type": "VarTypeHint"
},
{
"comment": "If enabled, complains when a class member variable is initialized at the class level rather than the constructor.",
"type": "VariableInitialisation",
"props": {
"allowFinal": false
"allowFinal": true,
"severity": "IGNORE"
}
},
{
"comment": "If enabled, mandates whitespace after certain tokens.",
"props": {
"tokens": [",", ";"],
"allowTrailingComma": false
"allowTrailingComma": false,
"severity": "INFO"
},
"type": "WhitespaceAfter"
},
{
"comment": "If enabled, mandates whitespace around certain tokens.",
"props": {
"tokens": [
"=",
@@ -672,11 +931,10 @@
"&=",
"^=",
"=>"
]
],
"severity": "INFO"
},
"type": "WhitespaceAround"
}
],
"exclude": {},
"version": 1
]
}
+5 -5
View File
@@ -12,7 +12,7 @@ Check [COMPILING.md](./COMPILING.md) if you haven’t done that yet.
setx ANDROID_HOME "C:\path\to\your\folder" /M
```
3. Download [Android Studio Command-line Tools](https://developer.android.com/studio#command-line-tools-only).
4. Extract the ZIP into your folder from step 1.
4. Extract the ZIP into your folder from step 0.
5. (Optional) Close and reopen the terminal if needed.
6. Run:
```bash
@@ -69,10 +69,10 @@ Check [COMPILING.md](./COMPILING.md) if you haven’t done that yet.
```
## iOS
Note that you can only build the game for iOS on a computer running MacOS.
Note that you can only build the game for iOS on a computer running macOS.
0. Build the game for desktop to make sure everything works. Check [COMPILING.md](./COMPILING.md).
1. Get Xcode from the app store on your MacOS Machine.
1. Get Xcode from the app store on your macOS Machine.
2. Download the iPhone SDK (First thing that pops up in Xcode)
3. Open up a terminal tab and run `lime test ios -xcode`
4. You will need to sign your own copy in order to run the game with a real iOS device! That requires an Apple Developer account, sorry!
@@ -81,11 +81,11 @@ Note that you can only build the game for iOS on a computer running MacOS.
### iOS Troubleshooting
- **A required plugin failed to load. Please ensure system content is up-to-date — try running 'xcodebuild -runFirstLaunch'.**
Make sure you have the iOS SDK isntalled, see Step 2.
Make sure you have the iOS SDK installed, see Step 2.
- **error: No Accounts: Add a new account in Accounts settings. (in target 'Funkin' from project 'Funkin')**
Open XCode, press CMD+, to open Settings, select Accounts, add an Apple ID.
Open Xcode, press CMD+, to open Settings, select Accounts, add an Apple ID.
- error: No Account for Team "Z7G7AVNGSH". Add a new account in Accounts settings or verify that your accounts have valid credentials.
+3 -2
View File
@@ -60,8 +60,8 @@ 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.8.1)
- without any mods
- the latest version of the game (currently v0.8.6, or v0.8.7 for Android) or a public playtest version (v0.9 Feature Preview builds)
- without any mods (unless the issue involves mods)
- on [Newgrounds](https://www.newgrounds.com/portal/view/770371) or downloaded from [itch.io](https://ninja-muffin24.itch.io/funkin)
## Rejected Features
@@ -86,6 +86,7 @@ Here's a list of commonly suggested features and the reasons why they won't be a
| Importing Charts from Psych Engine (and other mod content) | https://github.com/FunkinCrew/Funkin/issues/2586#issuecomment-2125733327 |
| Backwards Compatibility for Modding | https://github.com/FunkinCrew/Funkin/issues/3949#issuecomment-2608391329 |
| Lua Support | https://github.com/FunkinCrew/Funkin/issues/2643#issuecomment-2143718093 |
| Note Hitsounds | https://github.com/FunkinCrew/Funkin/pull/4112#issuecomment-5347549977 |
## Issue Types
Choose the issue template that best suits your needs!
+2 -3
View File
@@ -8,9 +8,7 @@ Most of this functionality is only available on debug builds of the game!
- `F3`: ***SCREENSHOT***: Takes a screenshot of the game and saves it to the local `screenshots` directory. Works outside of debug builds too!
- `F4`: ***EJECT***: Forcibly switch state to the Main Menu (with no extra transition). Useful if you're stuck in a level and you need to get out!
- `F5`: ***HOT RELOAD***: Forcibly reload the game's scripts and data files, then restart the current state. If any files in the `assets` folder have been modified, the game should process the changes for you! NOTE: Known bug, this does not reset song charts or song scripts, but it should reset everything else (such as stage layout data and character animation data).
- `CTRL-ALT-SHIFT-L`: ***FORCE CRASH***: Immediately crash the game with a detailed crash log and a stack trace. (Only works in the Main Menu on debug builds).
- `CTRL-SHIFT-L`: ***FORCE CRASH***: Immediately crash the game with a detailed crash log and a stack trace.
- `CTRL-ALT-SHIFT-L`: ***FORCE CRASH***: Immediately crash the game with a detailed crash log and a stack trace.
## **Play State**
- `H`: ***HIDE UI***: Makes the user interface invisible. Works in Pause Menu, great for screenshots.
@@ -27,6 +25,7 @@ Most of this functionality is only available on debug builds of the game!
- `P`: ***SWITCH TO PICO/BF***: Switch to Pico or BF (reopens Freeplay as the other character).
- `T`: ***TEST RANK ANIMATION***: Play the Gold Perfect rank animation on the currently selected song.
- `SHIFT-ACCEPT`: ***BOTPLAY MODE***: Start a song with Botplay mode enabled.
- `CTRL-ACCEPT`: ***MIRRORED MODE***: Start a song with mirrored notes enabled.
- `CTRL-Switch Song`: Play the first unlocked alternate instrumental as the song preview.
## **Title State**
+5
View File
@@ -0,0 +1,5 @@
# Install Dox
`haxelib install dox`
# To generate documentation
Run the script for your operating system, and then it will generate docs into `docs/dox/output/`
+4
View File
@@ -0,0 +1,4 @@
{
"name": "Funkin' Theme",
"author": "The Funkin' Crew Inc"
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,332 @@
#theme-toggle:focus {
outline: none;
}
.dark-theme {
background-color: #111 !important;
color: #ccc;
color-scheme: dark;
}
.dark-theme body {
background-color: #111 !important;
color: #ccc;
}
.dark-theme .navbar-inner {
background-color: #222 !important;
}
.dark-theme .brand {
color: #CCC !important;
}
.dark-theme .brand .img {
margin-top: -5px;
}
.dark-theme .well {
background-color: #222;
border: 1px solid #222;
}
.dark-theme .input-append .add-on,
.dark-theme .input-prepend .add-on {
background-color: #333;
border: 1px solid #333;
padding: 3px 5px;
text-shadow: 0 0 0 #000;
}
.dark-theme h1 {
color: #ccc;
}
.dark-theme a {
color: #0087ff;
}
.dark-theme a:hover,
.dark-theme a:focus {
color: #00b7ff;
}
.dark-theme input,
.dark-theme textarea {
background-color: #151515;
border: 1px solid #333;
transition: none;
}
.dark-theme .btn-group.open .btn.dropdown-toggle {
background-color: #202020;
}
.dark-theme .dropdown-menu {
background-color: #111;
}
.dark-theme .dropdown-menu>li>a {
color: #EEE;
}
.dark-theme .dropdown-menu>li>a:hover,
.dark-theme .dropdown-menu>li>a:focus,
.dark-theme .dropdown-submenu:hover>a,
.dark-theme .dropdown-submenu:focus>a {
color: #EEE;
background-color: #2f2f2f;
background-image: linear-gradient(to bottom, #262626, #2f2f2f);
}
.dark-theme .btn:focus,
.dark-theme .btn:hover {
background-position: 0 0;
}
.dark-theme .nav>li>a:hover,
.dark-theme .nav>li>a:focus {
background-color: #333;
}
.dark-theme .nav-list>.active>a {
background-color: #444;
}
.dark-theme .nav-list>.active>a.treeLink,
.dark-theme .nav-list>.active>a.treeLink:hover,
.dark-theme .nav-list>.active>a.treeLink:focus {
background: #269;
}
.dark-theme .btn {
color: #d5d5d5;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
background-color: #313131;
background-image: linear-gradient(to bottom, #313131, #282828);
border: 1px solid #424141;
border-bottom-color: #393939;
box-shadow: none;
}
.dark-theme .btn {
color: #d5d5d5;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
background-color: #313131;
background-image: linear-gradient(to bottom, #313131, #282828);
border: 1px solid #424141;
border-bottom-color: rgb(66, 65, 65);
border-bottom-color: #393939;
box-shadow: none;
}
.dark-theme .btn:focus,
.dark-theme .btn:hover {
color: #fff;
text-decoration: none;
}
.dark-theme .btn.active,
.dark-theme .btn:active {
background-image: none;
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.dark-theme .btn.disabled,
.dark-theme .btn[disabled] {
cursor: not-allowed;
opacity: 0.65;
box-shadow: none;
border-color: #393939;
}
.dark-theme .btn:focus {
color: #d5d5d5;
background-color: #313131;
border-color: #424141;
}
.dark-theme .btn:active:hover,
.dark-theme .btn:focus:hover {
color: #fff;
background-color: #313131;
border-color: #393939;
}
.dark-theme a.btn.disabled {
pointer-events: none;
}
.dark-theme .section.site-footer {
background: #111 !important;
}
.dark-theme .copyright>p {
color: #CCC !important;
}
.dark-theme .table th,
.dark-theme .table td {
border-bottom: 1px solid #222;
}
.dark-theme .table .fa {
color: #222;
margin-right: 5px;
}
.dark-theme .alert,
.dark-theme .alert h4 {
color: #ffc96c;
}
.dark-theme .availability {
color: #69b;
}
.dark-theme .section-availability {
color: #69b;
}
.dark-theme .alert {
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
}
.dark-theme .alert {
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
background-color: #332b00;
border: none;
}
.dark-theme hr {
border-top: none;
border-bottom: 1px solid #222;
}
.dark-theme .page-header {
border-bottom: 1px solid #222;
}
.dark-theme .section {
border-bottom: 1px solid #222;
}
.dark-theme .field+.field {
border-top: 1px solid #222;
}
.dark-theme code {
color: #ddd;
background-color: #111;
border: 1px solid #222;
}
.dark-theme pre {
background-color: #222;
border: 1px solid #333;
}
.dark-theme .example code {
color: #ddd;
background-color: transparent;
border: none;
}
.dark-theme pre code {
background-color: transparent;
}
.dark-theme pre.example::before {
color: #DDD;
background: #191919;
}
.dark-theme h3 code {
box-shadow: 0 0 15px rgb(20, 20, 20);
}
.dark-theme .label,
.dark-theme .badge {
color: #DDD;
background-color: #404040;
}
.dark-theme .label.label-meta {
background: #333379;
}
.dark-theme code .identifier {
color: #eff;
}
.dark-theme table.params {
border-left: 5px solid #222;
margin-left: 20px;
}
.dark-theme .table-bordered {
border: 1px solid #222;
}
.dark-theme table.params th {
background: #111;
}
.dark-theme .table-bordered th,
.dark-theme .table-bordered td {
border-left: 1px solid #222;
}
.dark-theme .indent {
border-left: 5px solid #222;
}
/* Types without links */
.dark-theme code .type {
color: #29e;
}
/* dark code examples (from try-haxe) */
.dark-theme code,
.dark-theme pre {
color: #DDD;
}
.dark-theme code a {
color: #29e
}
.dark-theme pre .type {
color: #DECB6B
}
.dark-theme pre .kwd {
color: #C792EA
}
.dark-theme pre .val {
color: #FF5370
}
.dark-theme div.pre .str,
.dark-theme pre .str,
.dark-theme pre .str .kwd,
.dark-theme pre .str .type,
.dark-theme pre .str .val {
color: #C3E88D
}
.dark-theme pre .cmt,
.dark-theme pre .cmt .kwd,
.dark-theme pre .cmt .str,
.dark-theme pre .cmt .type,
.dark-theme pre .cmt .val {
color: #545454
}
.dark-theme .last-modified {
color: #666
}
@@ -0,0 +1 @@
/** to be overridden in sub-themes */
@@ -0,0 +1,189 @@
nav.nav {
font-family: "Open Sans", sans-serif;
font-size: 16px;
margin: 0;
}
nav .fa {
color: #777;
margin-right: 5px;
}
body nav * {
line-height: 20px;
}
nav .navbar-inner {
background: #13110f;
border: 0;
border-radius: 0;
}
nav .navbar .nav {
margin: 0;
}
nav .dropdown-menu {
background: #2c2722;
font-size: 14px;
border-radius: 0px 0px 2px 2px;
padding: 10px 0px;
border: 1px solid #2c2722;
margin-top: -1px;
}
nav .navbar .nav>li>a {
padding: 14px 12px 15px 12px;
color: #ccc;
}
nav .dropdown-menu li a {
color: #b8b5b5;
padding: 3px 15px;
}
nav .divider {
background-color: transparent;
border-right: 1px solid #39332d;
margin: 5px 20px 5px 10px;
height: 39px;
}
nav .dropdown-menu .divider {
background-color: transparent;
border: 0;
border-bottom: 1px solid #39332d;
margin: 5px 0;
}
nav .navbar-inverse .nav .active>a,
nav .navbar-inverse .nav .active>a:hover,
nav .navbar-inverse .nav .active>a:focus,
nav .navbar-inverse .nav li.dropdown.open>.dropdown-toggle,
nav .navbar-inverse .nav li.dropdown.active>.dropdown-toggle,
nav .navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle {
color: #fff;
background-color: transparent;
background-image: none;
}
nav .navbar-inverse .nav .active>a:hover {
background: #39332d;
}
nav .dropdown-menu>.active>a,
nav .dropdown-menu>.active>a:hover,
nav .dropdown-menu>.active>a:focus {
font-weight: bold;
color: #fff;
background-image: none;
background: #39332d;
}
nav .dropdown-menu>li>a:hover,
.dropdown-menu>li>a:focus,
nav .dropdown-submenu:hover>a,
nav .dropdown-submenu:focus>a {
background: #39332d;
}
nav .navbar .nav>li>.dropdown-menu:after {
border-bottom-color: #2c2722;
}
/** MEDIA Q **/
@media (max-width: 979px) {
nav .navbar-fixed-top .navbar-inner,
nav .navbar-fixed-bottom .navbar-inner {
padding: 0px;
}
nav .navbar-fixed-top {
margin-bottom: 0;
}
}
/** SUB BRAND LOGOS **/
.navbar .brand.haxe-logo {
padding-right: 0;
margin: 3px 0 0 0px;
}
.navbar .brand.haxe-logo:hover {
opacity: .9;
}
.navbar .brand.haxe-logo:after {
content: " ";
position: absolute;
/* create arrow */
width: 0;
height: 0;
border-top: 22px solid transparent;
border-bottom: 22px solid transparent;
border-left: 7px solid #13110f;
/* same color as nav bar */
top: 0;
}
.navbar .brand.sub {
background: #39332d;
/* Old browsers */
background: -moz-linear-gradient(top, #39332d 50%, #2c2722 51%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%, #39332d), color-stop(51%, #2c2722));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #39332d 50%, #2c2722 51%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #39332d 50%, #2c2722 51%);
/* Opera 11.10+ */
background: -ms-linear-gradient(top, #39332d 50%, #2c2722 51%);
/* IE10+ */
background: linear-gradient(to bottom, #39332d 50%, #2c2722 51%);
/* W3C */
padding: 14px 20px 13px 20px;
margin: 0 10px 0 0;
font: bold 18px "arial black", "open sans";
line-height: 22px;
color: rgb(255, 255, 255);
}
.navbar .brand.sub:hover {
color: rgb(230, 230, 230);
background: #2c2722;
/* Old browsers */
}
.navbar .brand.sub:before {
content: "..";
/* two dots */
position: absolute;
margin-left: -33px;
margin-top: -28px;
line-height: 0px;
font: bold 40px "Open Sans", sans-serif;
letter-spacing: 0px;
color: #fff200;
}
/** SUB BRAND COLORS **/
.navbar .brand.sub.try:before {
color: #f89c0e;
}
.navbar .brand.sub.api:before {
color: #eedc16;
}
.navbar .brand.sub.lib:before {
color: #f1471d;
}
.navbar .brand.sub.ide:before {
color: #f89c0e;
}
@@ -0,0 +1,65 @@
/**
Code Highlighting
**/
html pre,
html pre code {
font-family: consolas, monospace;
white-space: pre;
overflow-x: auto;
}
code {
color: #333;
}
code a {
color: #08c;
}
pre {
color: #333;
margin: 15px 0;
padding: 0.5em;
}
pre .type {
color: #0086b3;
}
pre .kwd {
color: #00a;
}
pre .val {
color: #44a;
}
pre .str,
div.pre .str,
pre .str .kwd,
pre .str .val,
pre .str .type {
color: #a00;
}
pre .cmt {
color: #008800;
color: #998;
font-style: italic;
}
/* Make sure keywords inside comments are not highlighted*/
pre .cmt .kwd,
pre .cmt .str,
pre .cmt .val,
pre .cmt .type {
color: #998;
}
.last-modified {
color: #999;
}
.semantic {
display: none;
}
@@ -0,0 +1,43 @@
// highlighter adapted/modified from code.haxe.org
(function (console) { "use strict";
var EReg = function(r,opt) {
opt = opt.split("u").join("");
this.r = new RegExp(r,opt);
};
EReg.prototype = {
replace: function(s,by) {
return s.replace(this.r,by);
}
};
var Highlighter = function() { };
Highlighter.main = function() {
var _g = 0;
var _g1 = window.document.body.querySelectorAll("pre code");
while(_g < _g1.length) {
var el = _g1[_g];
++_g;
if(!Highlighter.hasClass(el,"highlighted")) {
el.innerHTML = Highlighter.syntaxHighlight(el.innerHTML);
el.className += " highlighted";
}
}
};
Highlighter.hasClass = function(el,className) {
return el.className.indexOf(className) != -1;
};
Highlighter.syntaxHighlight = function(html) {
var kwds = ["abstract","break","case","cast","catch","class","continue","default","do","dynamic","else","enum","extends","extern","false","final","for","function","if","implements","import","in","inline","interface","macro","new","operator","overload","override","package","private","public","return","static","switch","this","throw","true","try","typedef","untyped","using","var","while"];
var kwds1 = new EReg("\\b(" + kwds.join("|") + ")\\b","g");
var vals = ["null","true","false","this"];
var vals1 = new EReg("\\b(" + vals.join("|") + ")\\b","g");
var types = new EReg("\\b([A-Z][a-zA-Z0-9]*)\\b","g");
html = kwds1.replace(html,"<span class='kwd'>$1</span>");
html = vals1.replace(html,"<span class='val'>$1</span>");
html = types.replace(html,"<span class='type'>$1</span>");
html = new EReg("(\"[^\"]*\")","g").replace(html,"<span class='str'>$1</span>");
html = new EReg("(//.+?)(\n|$)","g").replace(html,"<span class='cmt'>$1</span>$2");
html = new EReg("(/\\*\\*?(.|\n)+?\\*?\\*/)","g").replace(html,"<span class='cmt'>$1</span>");
return html;
};
Highlighter.main();
})(typeof console != "undefined" ? console : {log:function(){}});
+319
View File
@@ -0,0 +1,319 @@
function createCookie(name, value) {
localStorage.setItem(name, value);
}
function readCookie(name) {
return localStorage.getItem(name);
}
function isDarkTheme() {
return document.querySelector("html").classList.contains("dark-theme");
}
function toggleTheme() {
const htmlTag = document.querySelector("html");
let isDark = isDarkTheme();
if (isDark) {
htmlTag.classList.remove("dark-theme");
} else {
htmlTag.classList.add("dark-theme");
}
isDark = isDarkTheme();
localStorage.theme = isDark ? "dark" : "light";
}
function toggleInherited(el) {
var toggle = $(el).closest(".toggle");
toggle.toggleClass("toggle-on");
if (toggle.hasClass("toggle-on")) {
$("i", toggle).removeClass("fa-folder").addClass("fa-folder-open");
} else {
$("i", toggle).addClass("fa-folder").removeClass("fa-folder-open");
}
return false;
}
function toggleCollapsed(el) {
var toggle = $(el).closest(".expando");
toggle.toggleClass("expanded");
if (toggle.hasClass("expanded")) {
$(toggle).find("i").first().removeClass("fa-folder").addClass("fa-folder-open");
} else {
$(toggle).find("i").first().addClass("fa-folder").removeClass("fa-folder-open");
}
updateTreeState();
return false;
}
function updateTreeState() {
var states = [];
$("#nav .expando").each(function (i, e) {
states.push($(e).hasClass("expanded") ? 1 : 0);
});
var treeState = JSON.stringify(states);
createCookie("treeState", treeState);
}
function setPlatform(platform) {
createCookie("platform", platform);
$("#select-platform").val(platform);
var styles = ".platform { display:none }";
var platforms = dox.platforms;
if (platform == "flash" || platform == "js") {
styles += ".package-sys { display:none; } ";
}
for (var i = 0; i < platforms.length; i++) {
var p = platforms[i];
if (platform == "sys") {
if (p != "flash" && p != "js") {
styles += ".platform-" + p + " { display:inherit } ";
}
}
else {
if (platform == "all" || p == platform) {
styles += ".platform-" + p + " { display:inherit } ";
}
}
}
if (platform != "flash" && platform != "js") {
styles += ".platform-sys { display:inherit } ";
}
$("#dynamicStylesheet").text(styles);
}
$(document).ready(function () {
$("#nav").html(navContent);
var treeState = readCookie("treeState");
$("#nav .expando").each(function (i, e) {
$("i", e).first().addClass("fa-folder").removeClass("fa-folder-open");
});
$(".treeLink").each(function () {
this.href = this.href.replace("::rootPath::", dox.rootPath);
});
if (treeState != null) {
var states = JSON.parse(treeState);
$("#nav .expando").each(function (i, e) {
if (states[i]) {
$(e).addClass("expanded");
$("i", e).first().removeClass("fa-folder").addClass("fa-folder-open");
}
});
}
$("head").append("<style id='dynamicStylesheet'></style>");
setPlatform(readCookie("platform") == null ? "all" : readCookie("platform"));
$("#search").on("input", function (e) {
searchQuery(e.target.value);
});
$(document).bind("keyup keydown", function (e) {
if (e.ctrlKey && e.keyCode == 80) { // ctrl + p
$("#search").focus();
return false;
}
return true;
});
function getItems() {
return $("#search-results-list a").toArray();
}
$("#search").bind("keyup", function (e) {
switch (e.keyCode) {
case 27: // escape
searchQuery("");
$("#search").val("")
$("#search").blur();
return false;
case 13: // enter
var items = getItems();
for (i = 0; i < items.length; i++) {
var item = $(items[i]);
if (item.hasClass("selected")) {
window.location = items[i].href;
break;
}
}
return false;
}
});
$("#search").bind("keydown", function (e) {
function mod(a, b) {
var r = a % b;
return r < 0 ? r + b : r;
}
function changeSelection(amount) {
var previousSelection = null;
var items = getItems();
for (i = 0; i < items.length; i++) {
var item = $(items[i]);
if (item.hasClass("selected")) {
item.removeClass("selected");
previousSelection = i;
break;
}
}
var newSelection = mod(previousSelection + amount, items.length);
$(items[newSelection]).addClass("selected");
items[newSelection].scrollIntoView(false);
}
switch (e.keyCode) {
case 38: // up
changeSelection(-1);
return false;
case 40: // down
changeSelection(1);
return false;
case 13: // enter
return false;
}
});
$("#select-platform").selectpicker().on("change", function (e) {
var value = $(":selected", this).val();
setPlatform(value);
});
$("#nav a").each(function () {
if (this.href == location.href) {
$(this.parentElement).addClass("active");
}
});
$("a.expand-button").click(function (e) {
var container = $(this).parent().next();
container.toggle();
$("i", this).removeClass("fa-folder-open")
.removeClass("fa-folder")
.addClass(container.is(":visible") ? "fa-folder-open" : "fa-folder");
return false;
});
// Because there is no CSS parent selector
$("code.prettyprint").parents("pre").addClass("example");
});
function searchQuery(query) {
$("#searchForm").removeAttr("action");
query = query.replace(/[&<>"']/g, "");
if (!query || query.length < 2) {
$("#nav").removeClass("searching");
$("#nav li").each(function (index, element) {
var e = $(element);
e.css("display", "");
});
$("#nav ul:first-child").css("display", "block");
$("#search-results-list").css("display", "none");
return;
}
var queryParts = query.toLowerCase().split(" ");
var listItems = [];
var bestMatch = 200;
$("#nav").addClass("searching");
$("#nav ul:first-child").css("display", "none");
$("#nav li").each(function (index, element) {
var e = $(element);
if (!e.hasClass("expando")) {
var content = e.attr("data_path");
var score = searchMatch(content, queryParts);
if (score >= 0) {
if (score < bestMatch) {
var url = dox.rootPath + e.attr("data_path").split(".").join("/") + ".html";
$("#searchForm").attr("action", url);
// best match will be form action
bestMatch = score;
}
var elLink = $("a", element);
// highlight matched parts
var elLinkContent = elLink.text().replace(new RegExp("(" + queryParts.join("|").split(".").join("|") + ")", "ig"), "<strong>$1</strong>");
var liStyle = (score == 0) ? ("font-weight:bold") : "";
listItems.push({ score: score, item: "<li style='" + liStyle + "'><a href='" + elLink.attr("href") + "'>" + elLinkContent + "</a></li>" });
}
}
});
if ($("#search-results-list").length == 0) {
// append to nav
$("#nav").parent().append("<ul id='search-results-list' class='nav nav-list'></ul>");
}
listItems.sort(function (x, y) { return x.score - y.score; }); // put in order
$("#search-results-list").css("display", "block").html(listItems.map(function (x) { return x.item; }).join(""));
// pre-select the first item
$("#search-results-list a").removeClass("selected");
$("#search-results-list a:first").addClass("selected");
}
function match(textParts, query) {
var queryParts = query.split(".");
if (queryParts.length == 1) {
var queryPart = queryParts[0];
for (var i = 0; i < textParts.length; ++i) {
var textPart = textParts[i];
if (textPart.indexOf(queryPart) > -1) {
// We don't want to match the same part twice, so let's remove it
textParts[i] = textParts[i].split(queryPart).join("");
return textPart.length - queryPart.length;
}
}
} else {
var offset = -1;
outer:
while (true) {
++offset;
if (queryParts.length + offset > textParts.length) {
return -1;
}
var scoreSum = 0;
for (var i = 0; i < queryParts.length; ++i) {
var queryPart = queryParts[i];
var textPart = textParts[i + offset];
var index = textPart.indexOf(queryPart);
if (index != 0) {
continue outer;
}
scoreSum += textPart.length - queryPart.length;
}
return scoreSum;
}
}
}
function searchMatch(text, queryParts) {
text = text.toLowerCase();
var textParts = text.split(".");
var scoreSum = 0;
for (var i = 0; i < queryParts.length; ++i) {
var score = match(textParts, queryParts[i]);
if (score == -1) {
return -1;
}
scoreSum += score + text.length;
}
return scoreSum;
}
function errorSearch() {
var errorURL = "";
if (!!window.location.pathname) {
errorURL = window.location.pathname;
} else if (!!window.location.href) {
errorURL = window.location.href;
}
if (!!errorURL) {
var searchTerm = errorURL.split("/").pop();
if (searchTerm.indexOf(".html") > -1) { searchTerm = searchTerm.split(".html").join(""); }
if (!!searchTerm) {
// update filter with search term
$("#search").val(searchTerm);
searchQuery(searchTerm);
}
}
}
File diff suppressed because one or more lines are too long
+527
View File
@@ -0,0 +1,527 @@
.main-content {
margin-top: 15px;
}
.dark {
background: rgb(20, 20, 25);
color: white;
}
.dark a {
color: white;
}
.dark a:hover {
color: rgb(200, 200, 200);
}
.dark blockquote {
border-left: 3px solid rgb(126, 126, 129);
}
.dark blockquote small {
color: white;
font-weight: bold;
}
.dark blockquote small:before {
display: none;
}
/* #nav { */
/* float: left; */
/* width: 250px; */
/* background: green; */
/* } */
/*#content .header { position:absolute; background:rgba(255,255,255,0.9); left:250px; right:15px; padding:0px 12px; border-bottom:1px solid #EEE;}*/
/*#content .body { padding-top:80px;}*/
.nav-list {
padding-right: 0;
}
.nav-list>li>a,
.nav-list .nav-header {
margin-right: 0;
}
.nav-list>li>a.treeLink {
padding-left: 20px;
}
.nav-list a {
overflow: hidden;
text-overflow: ellipsis;
font-size: 14px;
text-shadow: none !important;
}
.nav-list>.active>a.treeLink,
.nav-list>.active>a.treeLink:hover,
.nav-list>.active>a.treeLink:focus {
background: #999;
color: #fff;
}
.nav>li>a.selected,
.nav>li>a:hover {
background-color: #00000010;
}
.nav-list li i.fa {
height: 16px;
width: 16px;
color: rgb(200, 200, 200);
font-weight: normal;
font-size: 16px;
padding-right: 5px;
}
.viewsource {
float: right
}
/** Footer sitemap **/
footer {
font-size: 14px;
margin-top: auto;
}
.main-content {
margin-bottom: 40px;
}
.section.site-footer {
border-bottom: 0px;
}
.copyright {
padding: 6px;
overflow: hidden;
text-align: center;
margin: 40px 0;
}
.dark .copyright a {
color: #F48821;
}
/* .doc { margin-top:16px; } */
.toggle-hide {
display: block;
}
.toggle-show {
display: none;
}
.toggle-on .toggle-hide {
display: none !important;
}
.toggle-on .toggle-show {
display: block !important;
}
.related-types .toggle-hide {
padding-top: 4px;
}
/* #nav li { list-style-type: none; } */
#nav .expando>ul {
display: none;
}
#nav .expando.expanded>ul {
display: inherit;
}
/* #nav ul, #nav li li { margin-left: 10px; } */
#nav img {
padding-right: 4px;
}
#nav .pack {
display: none;
}
/* .nav .nav li { margin-left: 14px; } */
.dropdown {
padding: 0 9px;
}
#nav.searching .expando>ul {
display: inherit;
}
#nav.searching .expando>a {
display: none;
}
#nav.searching ul {
margin-left: 0px;
}
#nav.searching .pack {
display: inline;
}
#nav.searching .nav-list .nav-list {
padding-left: 0;
padding-right: 0;
}
.nav-header {
text-transform: none;
font-size: 14px;
color: #555;
text-shadow: none;
}
.availability {
color: #e48931;
font-size: 90%;
}
.section-availability {
color: #e48931;
}
h3 code {
background: none;
box-shadow: 0 0 15px rgb(240, 240, 240);
padding: 4px 8px;
white-space: inherit;
display: inline-block;
line-height: 1.5em;
margin-left: -10px;
}
h3 span.label,
.label-meta {
margin-right: 5px;
}
.label.label-meta {
background: #5959AC;
}
/* only show some specific whitelisted metadata */
.label-meta {
display: none;
}
.label-meta-callable,
.label-meta-commutative,
.label-meta-op,
.label-meta-arrayAccess,
.label-meta-resolve,
.label-meta-to,
.label-meta-from,
.label-meta-using,
.label-meta-forward,
.label-meta-forwardStatics {
display: inline;
}
.alert.alert-deprecated {
font-size: 90%;
margin-bottom: 10px;
padding: 4px 35px 4px 14px;
}
code {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
font-weight: normal;
color: #666;
background-color: #f7f7f9;
border: 1px solid #e1e1e8;
white-space: nowrap;
border-radius: 3px;
padding: 2px 4px;
font-size: 13px;
}
code .identifier {
font-family: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #002b36;
padding: 0 0 0 5px;
}
code .identifier,
code.type {
font-weight: bold;
}
/* code { background:#FDF6E3; color:#002b36; tab-size:4; } [> light <] */
code a {
text-decoration: none;
}
code a:hover {
text-decoration: underline;
}
/*code.dark { background:#272822; color:#F8F8F2; border:none; } */
code .type {
color: #268bd2;
}
/* code .keyword { color:#dc322f; } */
/* code .directive { color:#2aa198; } */
/* code .constant { color:#AE81FF; } */
/* code .comment { color:#75715E; } */
/* code .string { color:#E6DB74; } */
/* code .macro { color:#A6E22A; } */
/* code .inactive { color:#75715E; } */
/* .navbar-fixed-top { position: fixed; } */
/* .navbar-fixed-top .navbar-inner, */
/* .navbar-fixed-bottom .navbar-inner { padding: 0; } */
html,
body {
height: 100%;
margin: 0;
}
body {
margin: 0px;
padding: 0px;
font-size: 16px;
font-family: "Open Sans", sans-serif;
color: #1e1e1e;
line-height: 1.5;
display: flex;
flex-direction: column;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: "Source Sans Pro", sans-serif;
font-weight: 600;
word-wrap: break-word;
}
h1 {
font-size: 36px;
color: #171717;
}
h1 small {
font-size: 14px;
color: #999;
font-weight: normal;
}
h2 {
font-size: 30px;
}
h3 {
font-size: 24px;
}
h4 {
font-size: 20px;
}
h5,
h5 code {
font-size: 18px;
}
h6 {
font-size: 16px;
}
.sidebar-nav {
padding: 9px 0;
}
#explorer {
max-height: 70vh;
overflow-y: auto;
}
#searchForm {
padding: 0 9px;
margin-bottom: 10px;
}
#searchForm .control-group {
margin: 0;
}
.indent {
margin-left: 20px;
border-left: 5px solid #eeeeee;
padding-left: 20px;
}
table.params {
border-left: 5px solid #eeeeee;
margin-left: 20px;
}
table.params th {
background: #fcfcfc;
}
.doc-main {
margin-bottom: 40px;
}
.section {
border-bottom: 1px solid #eee;
}
.table p {
margin: 3px 0;
}
.table th,
.table td {
border-top: 0;
border-bottom: 1px solid #ccc;
}
.table a small {
color: #666;
}
.table .fa {
color: rgb(200, 200, 200);
margin-right: 5px;
}
.javadoc {
/* font-weight: normal; */
/* font-size: small; */
margin-top: 20px;
}
.inline-content * {
display: inline;
}
/**
* Stuff for input-block-level:
* http://stackoverflow.com/questions/13306670/bootstrap-prepended-and-appended-input-how-to-max-input-field-width
*/
.input-append.input-block-level,
.input-prepend.input-block-level {
display: table;
}
.input-append.input-block-level .add-on,
.input-prepend.input-block-level .add-on {
display: table-cell;
}
.input-append.input-block-level>input,
.input-prepend.input-block-level>input {
box-sizing: border-box;
/* use bootstrap mixin or include vendor variants */
-moz-box-sizing: border-box;
/* for Firefox */
-webkit-box-sizing: border-box;
/* for Firefox */
-ms-box-sizing: border-box;
/* for Firefox */
-o-box-sizing: border-box;
/* for Firefox */
display: table;
/* table-cell is not working well in Chrome for small widths */
min-height: inherit;
width: 100%;
}
.input-append.input-block-level>input {
border-right: 0;
}
.input-prepend.input-block-level>input {
border-left: 0;
}
.field {
padding-bottom: 10px;
}
.field+.field {
border-top: 1px solid #eee;
margin-top: 10px;
}
.fields {
margin-left: 40px;
}
.field-source {
margin-top: 15px;
visibility: hidden;
}
.field:hover .field-source {
visibility: inherit;
}
pre.example {
position: relative;
padding-top: 34.5px;
}
pre.example:before {
position: absolute;
top: -1px;
left: -1px;
content: "Example";
color: #999;
padding: 2px 6px;
background: #fff;
font-weight: bold;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-moz-border-radius: 4px 0;
-ms-border-radius: 4px 0;
-webkit-border-radius: 4px 0;
border-radius: 4px 0;
border: 1px solid rgba(0, 0, 0, 0.15);
}
.inherited-fields {
padding: 5px 20px;
margin-top: 1em;
background: #fcfcfc;
}
@media (max-width: 767px) {
.navbar-fixed-top,
.navbar-fixed-bottom,
.navbar-static-top {
margin-right: 0;
margin-left: 0;
}
.navbar .divider {
display: none;
}
.main-content {
margin-top: 0px;
}
}
@media (max-width: 979px) {
.main-content {
margin-top: 15px;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

+12
View File
@@ -0,0 +1,12 @@
::use 'main.mtt'::
<script type="text/javascript">
$(document).ready(errorSearch);
</script>
<h1><small>404</small> Page not found</h1>
<p>Page not found, sorry.</p>
::end::
@@ -0,0 +1,35 @@
::use 'main.mtt'::
<div class="page-header">
<span ::cond api.hasSourceLink(type):: class="viewsource">
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
</span>
<h1><small>::if api.isEnumAbstract(type)::enum ::end::abstract</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)::if !api.isCoreType(type)::($$printLinkedType(::type.athis::,::false::))::end::</h1>
$$printPackage(::type::)
<h4 ::cond (type.from != null || type.to != null)::>
::foreach t type.from::
::if t.field == null::
<small>::if(repeat.t.index==0)::from ::end::$$printLinkedType(::t.t::,::false::)::if((type.from.length!=1)&&(repeat.t.index<type.from.length-1))::, ::end::</small>
::end::
::end::
::foreach t type.to::
::if t.field == null::
<small>::if(repeat.t.index==0):: to ::end::$$printLinkedType(::t.t::,::false::)::if((type.to.length!=1)&&(repeat.t.index<type.to.length-1))::, ::end::</small>
::end::
::end::
</h4>
$$printModule(::type.module::)
$$printMeta(::type::)
$$printDeprecation(::type::)
$$printPlatforms(::type.platforms::,::true::)
</div>
<div class="body">
<div class="doc doc-main" ::cond type.doc != null::>
::raw type.doc::
</div>
::if type.impl != null::
$$printClassBody(::type.impl::)
::end::
</div>
::end::
+68
View File
@@ -0,0 +1,68 @@
::use 'main.mtt'::
<div class="page-header">
<span ::cond api.hasSourceLink(type):: class="viewsource">
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
</span>
<h1>
<small>::if type.isFinal::final ::end::::if type.isInterface::interface::else::class::end::</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)
</h1>
$$printPackage(::type::)
::if type.superClass != null::
<h4>
::set inheritedFields = api.getInheritedFields(type)::
<small>extends
::if (inheritedFields.types.length>0)::
::foreach t inheritedFields.types::
$$printLinkedPath(::t.path::,::null::,::false::)::if ((inheritedFields.types.length!=1)&&(repeat.t.index<(inheritedFields.types.length-1))):: &rsaquo; ::end::
::end::
::else::
$$printLinkedPath(::type.superClass.path::,::null::,::false::)
::end::
</small>
</h4>
::end::
<h4 ::cond (type.interfaces.length>0)::>
<small>::if type.isInterface::extends::else::implements::end::
::foreach i type.interfaces::
$$printLinkedPath(::i.path::,::i.params::,::false::)::if ((type.interfaces.length!=1)&&(repeat.i.index<(type.interfaces.length-1)))::, ::end::
::end::
</small>
</h4>
$$printModule(::type.module::)
<h4 ::cond subClasses !=null::>
<small>
::set title = "extended by "::
::set infos = subClasses::
::use "related_types.mtt"::::end::
</small>
</h4>
<h4 ::cond implementors !=null::>
<small>
::if type.isInterface::
::set title = "extended by "::
::else::
::set title = "implemented by "::
::end::
::set infos = implementors::
::use "related_types.mtt"::::end::
</small>
</h4>
$$printMeta(::type::)
$$printDeprecation(::type::)
$$printPlatforms(::type.platforms::,::true::)
</div>
<div class="body">
<div class="doc doc-main" ::cond type.doc != null::>
::raw type.doc::
</div>
$$printClassBody(::type::)
$$printInheritedFields(::type::)
</div>
::end::
@@ -0,0 +1,27 @@
::if (field.doc != null && field.doc != "<p></p>") || !field.isOverride::
<div class="field ::if (depth == 0 && api.isPlatform(name)) " platform platform-" + name else ""::">
::if source_url != null && field.line != null::
<a href="::source_url::#L::field.line::" class="field-source pull-right" target="_blank">
<i class="fa fa-eye"></i> View source
</a>
::end::
<a ::attr name field.name::></a>
<h3 class="anchor">$$printFieldSignature(::field::,::isStatic::,::type::)</h3>
::if field.overloads != null::
::foreach field field.overloads::
<h3 class="anchor">$$printFieldSignature(::field::,::isStatic::,::type::)</h3>
::end::
::end::
$$printDeprecation(::field::)
$$printFieldPlatforms(::field::)
::if field.doc != null::
<div class="doc">::raw field.doc::</div>
::end::
</div>
::end::
+56
View File
@@ -0,0 +1,56 @@
::if info.deprecated != null::
<div class="alert inline-content">
<strong>Deprecated</strong>: ::raw info.deprecated.doc::
</div>
::end::
::raw info.doc::
::if info.params.length > 0::
<p class="javadoc">Parameters:</p>
<table class="table table-bordered params">
::foreach param info.params::
<tr><th style="width:25%;"><code>::param.value::</code></th><td>::raw param.doc::</td></tr>
::end::
</table>
::end::
::if info.returns != null::
<p class="javadoc">Returns:</p>
<div class="indent inline-content">
::raw info.returns.doc::
</div>
::end::
::if info.throws.length > 0::
<p class="javadoc">Throws:</p>
<table class="table table-bordered params">
::foreach throws info.throws::
<tr class="indent"><th style="width:25%;"><code>::throws.value::</code></th><td>::raw throws.doc::</td></tr>
::end::
</table>
::end::
::if info.events.length > 0::
<p class="javadoc">Events:</p>
<table class="table table-bordered params">
::foreach event info.events::
<tr class="indent"><th style="width:25%;"><code>::event.value::</code></th><td>::raw event.doc::</td></tr>
::end::
</table>
::end::
::if info.since != null::
<div class="javadoc inline-content">
Available since ::raw info.since.doc::.
</div>
::end::
::if info.sees.length > 0::
<p class="javadoc">See also:</p>
<ul>
::foreach see info.sees::
<li><div class="inline-content">::raw see.doc::</div></li>
::end::
</ul>
::end::
+26
View File
@@ -0,0 +1,26 @@
::use 'main.mtt'::
<div class="page-header">
<span ::cond api.hasSourceLink(type):: class="viewsource">
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
</span>
<h1><small>enum</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)</h1>
$$printPackage(::type::)
$$printModule(::type.module::)
$$printMeta(::type::)
$$printDeprecation(::type::)
$$printPlatforms(::type.platforms::,::true::)
</div>
<div class="body">
<div class="doc doc-main" ::cond type.doc != null::>
::raw type.doc::
</div>
::if type.constructors.length > 0::
<h3 class="section">Values</h3>
<div class="fields">
::foreach ctor type.constructors::
::use "enum_field.mtt"::::end::
::end::
</div>
::end::
</div>
::end::
@@ -0,0 +1,19 @@
<div class="field">
<h3>
<code>
<a name="::ctor.name::" href="#::ctor.name::">
<span class="identifier">::ctor.name::</span>
</a>
::if ctor.args != null::
(::foreach arg ctor.args::::arg.name:::$$printLinkedType(::arg.t::,::false::)::if !repeat.arg.last::, ::end::::end::)
::end::
</code>
</h3>
$$printDeprecation(::ctor::)
$$printFieldPlatforms(::ctor::)
<div class="doc" ::cond ctor.doc != null::>
::raw ctor.doc::
</div>
</div>
@@ -0,0 +1 @@
@@ -0,0 +1,10 @@
<footer class="section site-footer" style="background:$$getHexValue(::themeColor::)">
<div class="container">
<div class="copyright">
<p ::cond api.isDefined("version")::>This documentation is generated for version ::api.getValue('version')::</p>
<p>&copy; ::api.config.date.getFullYear():: &nbsp;
<a ::cond api.isDefined("website"):: ::attr href api.getValue("website")::>The Funkin' Crew Inc</a>
</p>
</div>
</div>
</footer>
@@ -0,0 +1,36 @@
<head>
<meta charset='utf-8'/>
<link href="::api.config.rootPath::bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="::api.config.rootPath::bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet" />
<link href="::api.config.rootPath::bootstrap/css/bootstrap-select.min.css" rel="stylesheet" />
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700,700italic,400italic' rel='stylesheet' type='text/css'/>
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,600,600italic,400' rel='stylesheet' type='text/css'/>
<link href='https://netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css' rel='stylesheet' type='text/css' />
<script src="::api.config.rootPath::jquery-3.6.0.min.js"></script>
<script src="::api.config.rootPath::bootstrap/js/bootstrap.min.js"></script>
<script src="::api.config.rootPath::bootstrap/js/bootstrap-select.min.js"></script>
<link href="::api.config.rootPath::styles.css" rel="stylesheet" />
<link href="::api.config.rootPath::extra-styles.css" rel="stylesheet" />
<link href="::api.config.rootPath::haxe-nav.css" rel="stylesheet" />
<link href="::api.config.rootPath::dark-mode.css" rel="stylesheet" />
<script>var dox = {
rootPath: "::api.config.rootPath::",
platforms: [
::foreach pf api.config.platforms::
"::pf::"
::if !repeat.pf.last::,::end::
::end::
]
};</script>
<script src="::api.config.rootPath::nav.js"></script>
<script src="::api.config.rootPath::index.js"></script>
<link rel="icon" href="https://funkin.me/img/construction-icon.ico" type="image/x-icon"/>
<title>::api.currentPageName::::if api.config.pageTitle !=null:: - ::api.config.pageTitle::::end::</title>
::set description = api.getShortDesc(type)::
::set description = description.substr(3, description.length-7)::
<meta name="description" ::cond type.doc!=null && description.length>0:: content="::description::"/>
::use "extra-headers.mtt"::::end::
</head>
+336
View File
@@ -0,0 +1,336 @@
<macro name="printTypeParams(params)">
::if params.length > 0::
&lt;
::foreach param params::
<span class="type">::param::</span>
::if !repeat.param.last::, ::end::
::end::
&gt;
::end::
</macro>
<macro name="getHexValue(value)">::value.split("0x").join("#")::</macro>
<macro name="printPlatforms(platforms, useSeparator)">
::if (useSeparator && api.config.platforms.length>1)::<hr/>::end::
<p class="availability" ::cond (api.config.platforms.length>1)::>
<em>
Available on
::if platforms.length == api.config.platforms.length:: all platforms
::elseif platforms.length > 1:: ::platforms.join(", ")::
::else:: ::platforms.join("")::
::end::
</em>
</p>
</macro>
<macro name="printFieldPlatforms(field)">
::if field.platforms.length != type.platforms.length && field.platforms.length > 0 && field.platforms.length < api.config.platforms.length::
$$printPlatforms(::field.platforms::,::false::)
::end::
</macro>
<macro name="printLinkedPath(path, params, qualified)">
::if api.isKnownType(path)::
<a class="type" title="::api.getSentenceDesc(api.resolveType(path))::" ::attr href api.pathToUrl(path)::>
::if qualified::
::path::
::else::
::api.getPathName(path)::
::end::
</a>
::else::
<span class="type">::api.getPathName(path)::</span>
::end::
::if params != null && params.length > 0::
&lt;
::foreach param params::
$$printLinkedType(::param::,::qualified::)
::if !repeat.param.last::, ::end::
::end::
&gt;
::end::
</macro>
<macro name="printLinkedType(ctype, qualified)">
::switch ctype::
::case::Unknown
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
::case::
::if args[0].length != 1 || args[0][0].name != ""::(::end::
::foreach arg args[0]::
::if arg.name != ""::
::arg.name:::
::end::
$$printLinkedType(::arg.t::,::qualified::)
::if !repeat.arg.last::, ::end::
::end::
::if args[0].length != 1 || args[0][0].name != ""::)::end::
&nbsp;&#8209;&gt;&nbsp;
$$printLinkedType(::args[1]::,::qualified::)
::case::
{
::foreach field args[0]::
::field.name:::$$printLinkedType(::field.type::,::qualified::)
::if !repeat.field.last::, ::end::
::end::
}
::case::$$printLinkedPath(::"Dynamic"::,::null::,::qualified::)::if args[0] != null::&lt;$$printLinkedType(::args[0]::,::qualified::)&gt;::end::
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
::end::
</macro>
<macro name="printModule(module)">
<h4 ::cond module != null && module != "StdTypes"::><small>import <a ::attr href api.pathToUrl(module)::>::module::</a></small></h4>
</macro>
<macro name="printDeprecation(field)">
::if (field.meta != null)::
::foreach meta field.meta::
::if (meta.name == ":deprecated")::
<div class="alert alert-warning alert-deprecated">
<strong>Deprecated:</strong>
::if (meta.params != null && meta.params.length > 0)::
::foreach param meta.params::
::param::
::if !repeat.param.last::, ::end::
::end::
::end::
</div>
::end::
::end::
::end::
</macro>
<macro name="printMeta(field)">
::if (field.meta != null)::
::foreach meta field.meta::
::if (meta.name != ":deprecated")::::if false::<!--skip deprecation meta, see printDeprecation -->::end::
::set metaName = meta.name.substr(1)::
::set displayMetaName = "@" + meta.name::
<span class="label label-meta label-meta-::metaName::" title="::api.getMetaDesc(meta.name)::">::displayMetaName::
::if (meta.params != null && meta.params.length > 0)::(
::foreach param meta.params::
$$printMetaParam(::param::)
::if !repeat.param.last::,::end::
::end::
)::end::</span>
::end::
::end::
::end::
</macro>
<macro name="printMetaParam(param)">::if (param.substr(0,9) == "<![CDATA[")::::param.substr(9,param.length-3-9)::::else::::param::::end::</macro>
<macro name="printFieldSignature(field, isStatic, type)">
<code>
::if !field.isPublic::
<span class="label label-private">private</span>
::end::
$$printMeta(::field::)
::if isStatic::
<span class="label label-static">static</span>
::end::
::set fieldInfo = api.getFieldInfo(field)::
::if fieldInfo.modifiers.isOptional::
<span class="label label-optional">optional</span>
::end::
::if fieldInfo.modifiers.isFinal::
<span class="label label-final">final</span>
::end::
::if fieldInfo.modifiers.isDynamic::
<span class="label label-dynamic">dynamic</span>
::end::
::if fieldInfo.modifiers.isInline::
<span class="label label-inline">inline</span>
::end::
::switch fieldInfo.kind::
::switch field.set::
::case 1::
<span class="label">read only</span>
::end::
::switch field.get::
::case 1::
<span class="label">write only</span>
::end::
<a href="#::field.name::"><span class="identifier">::field.name::</span></a>:$$printLinkedType(::field.type::,::false::)$$printInitExpr(::field.expr::)
::case 2::
<a href="#::field.name::"><span class="identifier">::field.name::</span></a>
$$printTypeParams(::field.params::)(
::foreach arg args[0]::
<span style="white-space:nowrap">
::if arg.opt && (arg.value == null || arg.value == "null")::?::end::
::arg.name:::$$printLinkedType(::arg.t::,::false::)
::if arg.value != null && arg.value != "null":: = ::arg.value::::end::
::if !repeat.arg.last::,::end::
</span>
::if !repeat.arg.last:: ::end::
::end::
)
::if field.name != "new"::
:$$printLinkedType(::args[1]::,::false::)
::end::
::end::
</code>
</macro>
<macro name="printInitExpr(expr)">
<span ::cond expr != null::>
= ::expr::
</span>
</macro>
<macro name="printClassBody(type)">
::set showSection = false::
::foreach field type.statics::
::if !api.isMethod(field)::
::eval showSection = true::
::end::
::end::
::if showSection::
<h3 class="section">Static variables</h3>
<div class="fields">
::foreach field type.statics::
::set isStatic = true::
::if !api.isMethod(field)::
::use "class_field.mtt"::::end::
::end::
::end::
</div>
::end::
::set showSection = false::
::foreach field type.statics::
::if api.isMethod(field)::
::eval showSection = true::
::end::
::end::
::if showSection::
<h3 class="section">Static methods</h3>
<div class="fields">
::foreach field type.statics::
::set isStatic = true::
::if api.isMethod(field)::
::use "class_field.mtt"::::end::
::end::
::end::
</div>
::end::
::set showSection = false::
::foreach field type.fields::
::if field.name == "new" && api.isMethod(field)::
::eval showSection = true::
::end::
::end::
::if showSection::
<h3 class="section">Constructor</h3>
<div class="fields">
::foreach field type.fields::
::set isStatic = false::
::if field.name == "new" && api.isMethod(field)::
::use "class_field.mtt"::::end::
::end::
::end::
</div>
::end::
::set showSection = false::
::foreach field type.fields::
::if !api.isMethod(field)::
::eval showSection = true::
::end::
::end::
::if showSection::
<h3 class="section">Variables</h3>
<div class="fields">
::foreach field type.fields::
::set isStatic = false::
::if !api.isMethod(field)::
::use "class_field.mtt"::::end::
::end::
::end::
</div>
::end::
::set showSection = false::
::foreach field type.fields::
::if field.name != "new" && api.isMethod(field)::
::eval showSection = true::
::end::
::end::
::if showSection::
<h3 class="section">Methods</h3>
<div class="fields">
::foreach field type.fields::
::set isStatic = false::
::if field.name != "new" && api.isMethod(field)::
::use "class_field.mtt"::::end::
::end::
::end::
</div>
::end::
</macro>
<macro name="printInheritedFields(type)">
::if type.superClass != null::
::set inheritedFields = api.getInheritedFields(type)::
::set hasFields = inheritedFields.fields.keys().hasNext()::
::set hasMethods = inheritedFields.methods.keys().hasNext()::
<div class="inherited-fields well" ::cond hasFields || hasMethods::>
<h3 class="section" ::cond hasFields::>Inherited Variables</h3>
<div class="fields" ::cond hasFields::>
::set fields=inheritedFields.fields::
::foreach cl inheritedFields.types::
<h4 ::cond fields.get(cl).length>0::><a href="#" class="expand-button"><i class="fa fa-arrow-circle-o-right"></i></a> Defined by $$printLinkedPath(::cl.path::,::null::,::false::)</h4>
<div style="display:none">
::foreach field fields.get(cl)::
::set isStatic = false::
::set type=cl::
::use "class_field.mtt"::::end::
::end::
</div>
::end::
</div>
<h3 class="section" ::cond hasMethods::>Inherited Methods</h3>
<div class="fields" ::cond hasMethods::>
::set fields=inheritedFields.methods::
::foreach cl inheritedFields.types::
<h4 ::cond fields.get(cl).length>0::><a href="#" class="expand-button"><i class="fa fa-arrow-circle-o-right"></i></a> Defined by $$printLinkedPath(::cl.path::,::null::,::false::)</h4>
<div style="display:none">
::foreach field fields.get(cl)::
::set isStatic = false::
::if field.name != "new" ::
::set type=cl::
::use "class_field.mtt"::::end::
::end::
::end::
</div>
::end::
</div>
</div>
::end::
</macro>
<macro name="printPackage(type)">
::if type.path.indexOf(".", 0) >= 0::
::set packagePath = type.path.split(".").slice(0, -1).join(".")::
<h4><small>package <a ::attr href api.packageToUrl(packagePath)::>::packagePath::</a></small></h4>
::else::
<h4><small><a href="./">no package</a></small></h4>
::end::
</macro>
+73
View File
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<!-- use theme color or fallback -->
::set themeColor="0xFAFAFA"::
::if (api.isDefined("themeColor"))::::set themeColor=api.getValue("themeColor")::::end::
<!--use textcolor from settings, otherwise create a contrasting color to theme color-->
::set textColor="0xFFFFFF"::
::if (api.isDefined("textColor"))::::set textColor=api.getValue("textColor")::
::elseif (api.std.parseInt(themeColor) > 7829367)::::set textColor="0x000000"::::end::
::use "header.mtt"::::end::
<body>
<script>
/* Here to prevent flash of unstyled content */
let systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if ((!localStorage.theme && systemDarkMode) || localStorage.theme == "dark") {
document.body.style.backgroundColor = "#111";
document.body.style.opacity = "0";
document.addEventListener("DOMContentLoaded", function(event) {
toggleTheme();
document.body.style.backgroundColor = "";
document.body.style.opacity = "";
});
}
</script>
::use "topbar.mtt"::::end::
<div class="container main-content">
<div class="row-fluid">
<div class="span3">
<div class="well sidebar-nav">
<form class="form-search" id="searchForm">
<div class="input-prepend input-block-level">
<span class="add-on"><i class="fa fa-search"></i></span>
<input id="search" type="text" placeholder="Filter (Ctrl+P)" autocomplete="off"/>
</div>
</form>
<div class="dropdown" ::cond (api.config.platforms.length>1)::>
<select id="select-platform" class="selectpicker" title="Filter by platform" data-width="100%">
<option value="all" selected="selected">All Platforms</option>
::foreach i api.config.platforms::
<option>::i::</option>
::end::
</select>
</div>
</div>
<div class="well sidebar-nav" id="explorer">
<div id="nav"></div>
</div>
</div>
<div class="span9">::raw __content__::</div>
</div>
</div>
::use "footer.mtt"::::end::
<script src="::api.config.rootPath::highlighter.js"></script>
<link href="::api.config.rootPath::highlighter.css" rel="stylesheet" />
::if (api.isDefined("googleAnalytics"))::
::set trackingID=api.getValue("googleAnalytics")::
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=::trackingID::"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '::trackingID::');
</script>
::end::
</body>
</html>
+33
View File
@@ -0,0 +1,33 @@
<macro name="makeTree(tree,depth)">
::switch tree::
<li ::attr data_path api.getTreePath(tree)::>
::set pack = api.getTreePack(tree)::
<a class="treeLink" href="::api.getTreeUrl(tree)::" title=":: pack + "." + api.getTreeName(tree) ::">
::api.getTreeName(tree)::
::if pack != ""::
<span class="pack">&nbsp;-&nbsp;::pack::</span>
::end::
</a>
</li>
::case::
::set name = args[0]::
<li ::cond name.charAt(0) != "_"::
::attr class "expando " + if (depth == 0 && api.isPlatform(name)) "platform platform-" + name else if (depth == 0) "package-" + name else "" ::>
<a class="nav-header" href="#" onclick="return toggleCollapsed(this)">
<i class="fa fa-folder"></i>
::api.getTreeName(tree)::
</a>
<ul class="nav nav-list">
::foreach sub args[2]::
$$makeTree(::sub::,::depth + 1::)
::end::
</ul>
</li>
::end::
</macro>
var navContent='<ul class="nav nav-list">
::foreach tree root::
$$makeTree(::tree::,::0::)
::end::
</ul>
';
@@ -0,0 +1,37 @@
::use 'main.mtt'::
::use 'package_description.mtt'::::end::
<table class="table table-condensed">
<tbody>
<tr ::cond full != ""::>
<th style="width:200px;">
<i class="fa fa-folder-o"></i>
<a href="::api.packageToUrl(full.split(".").slice(0,-1).join("."))::" title="::full.split(".").slice(0,-1).join(".")::">..</a>
</th>
<td></td>
</tr>
::foreach tree subs::
::set name = api.getTreeName(tree)::
::set treeType = api.getTreeType(tree)::
<tr class="::treeType::" ::cond name.charAt(0) != "_"::>
::if (treeType=="package")::
<td colspan="2">
<i class="fa fa-folder-o"></i>
<a href="::api.getTreeUrl(tree)::" title="::full::.::name::">::name::</a>
</td>
::else::
<td style="width:200px;">
<a href="::api.getTreeUrl(tree)::" title="::full::.::name::">::name::</a>
</td>
<td>
::raw api.getTreeShortDesc(tree)::
</td>
::end::
</tr>
::end::
</tbody>
</table>
::end::
@@ -0,0 +1,2 @@
<h1>::api.currentPageName:: <small ::cond api.isDefined("version") && full == ""::>version ::api.getValue('version')::</small></h1>
<p ::cond api.isDefined("description")::>::api.getValue("description")::</p>
@@ -0,0 +1,4 @@
<span class="muted">::title::</span>
::foreach info infos::
$$printLinkedPath(::info.path::,::null::,::false::)::if !repeat.info.last::, ::end::
::end::
@@ -0,0 +1,23 @@
<style>
::raw "
.navbar .brand {
display: inline-block;
float: none;
text-shadow: 0 0 0 transparent;
}
"::
</style>
<nav class="nav">
<div class="navbar">
<div class="navbar-inner" style="background:$$getHexValue(::themeColor::); border-bottom:1px solid rgba(0,0,0,.09)">
<div class="container">
<a href="https://funkin.me/" class="brand"><img alt="The Funkin' Crew Inc main website" src="https://funkin.me/img/api/funkin-api-export.svg" width="150" height="50"/></a>
<a href="https://funkin.me/api-reference/" class="brand" style="color:$$getHexValue(::textColor::)">::if api.config.pageTitle!=null::::api.config.pageTitle::::else::API Documentation::end::</a>
<div class="brand">
<p>|</p>
</div>
<a href="https://funkin.me/cookbook/" class="brand" style="color:$$getHexValue(::textColor::)">Cookbook</a>
</div>
</div>
</div>
</nav>
@@ -0,0 +1,49 @@
::use 'main.mtt'::
<div class="page-header">
<span ::cond api.hasSourceLink(type):: class="viewsource">
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
</span>
<h1><small>typedef</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)</h1>
$$printPackage(::type::)
$$printModule(::type.module::)
$$printMeta(::type::)
$$printDeprecation(::type::)
$$printPlatforms(::type.platforms::,::true::)
</div>
<div class="body">
<div class="doc doc-main" ::cond type.doc != null::>
::raw type.doc::
</div>
::set multiplePlatforms = api.lambda.array(type.types).length > 1::
::foreach platform type.types.keys()::
::set platformType = type.types.get(platform)::
::if multiplePlatforms::
<h4 class="section section-availability">::platform::</h4>
::end::
::switch platformType::
::if !multiplePlatforms::<h3 class="section">Alias</h3>::end::
<div class="fields">
<div class="field">
<em>alias for </em><code>$$printLinkedType(::platformType::,::true::)</code>
</div>
</div>
::case 5::
::if !multiplePlatforms::<h3 class="section">Fields</h3>::end::
<div class="fields">
::switch platformType::
::case 5::
::if args[0].length == 0::
<em>empty structure</em>
::else::
::foreach field args[0]::
::use "class_field.mtt"::::end::
::end::
::end::
::end::
</div>
::end::
::end::
</div>
::end::
+42
View File
@@ -0,0 +1,42 @@
cd ../..
# ask for version
$version = Read-Host "Enter version (Will display on the website)"
# regenerate XML files?
$regenerateXml = Read-Host "Regenerate XML files? (y/n)"
if ($regenerateXml -eq "y") {
Write-Host "Regenerating XML files..."
echo "Generating docs for version $version..."
lime build linux -xml -cpp --no-output -Ddoc-gen
lime build windows -xml -cpp --no-output -Ddoc-gen
copy export\release\windows\types.xml docs\dox\Windows.xml
copy export\release\linux\types.xml docs\dox\Linux.xml
} else {
Write-Host "Skipping XML regeneration..."
}
# Then run dox
haxelib run dox `
-i .\docs\dox\ `
-o docs/dox/output `
--title "Funkin'" `
-theme "docs/dox/funkin-theme" `
-D version "$version" `
-D source-path "https://github.com/FunkinCrew/Funkin/tree/main/source" `
-D website "https://funkin.me/" `
-D description "Friday Night Funkin' API Reference" `
-in "funkin" `
-in "openfl" `
-in "lime" `
-in "flixel" `
-ex "funkin.ui.debug.*" `
-ex "funkin.macro.*" `
-ex "funkin.save.*" `
-ex "funkin.api.*" `
-ex "funkin.vis.*"
cd docs/dox
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
cd ../..
# ask for version
read -p "Enter version (Will display on the website): " version
# regenerate XML files?
read -p "Regenerate XML files? (y/n): " regenerateXml
if [ "$regenerateXml" == "y" ]; then
echo "Regenerating XML files..."
echo "Generating docs for version $version..."
lime build windows -xml -cpp --no-output -Ddoc-gen
lime build linux -xml -cpp --no-output -Ddoc-gen
cp export/release/linux/types.xml docs/dox/Linux.xml
cp export/release/windows/types.xml docs/dox/Windows.xml
else
echo "Skipping XML regeneration..."
fi
# Then run dox
haxelib run dox \
-i ./docs/dox/ \
-o docs/dox/output \
-theme "docs/dox/funkin-theme" \
--title "Funkin'" \
-D version "$version" \
-D source-path "https://github.com/FunkinCrew/Funkin/tree/main/source" \
-D website "https://funkin.me/" \
-D description "Friday Night Funkin' API Reference" \
-in "funkin" \
-in "openfl" \
-in "lime" \
-in "flixel" \
-ex "funkin.ui.debug.*" \
-ex "funkin.macro.*" \
-ex "funkin.save.*" \
-ex "funkin.api.*" \
-ex "funkin.vis.*"
cd docs/dox
+1 -1
View File
@@ -6,7 +6,7 @@
"name": "EliteMasterEric"
}
],
"api_version": "0.7.0",
"api_version": "0.8.0",
"mod_version": "1.0.0",
"license": "Apache-2.0"
}
+1 -1
View File
@@ -6,7 +6,7 @@
"name": "EliteMasterEric"
}
],
"api_version": "0.7.0",
"api_version": "0.8.0",
"mod_version": "1.0.0",
"license": "Apache-2.0"
}
+47 -36
View File
@@ -4,75 +4,91 @@
"name": "FlxPartialSound",
"type": "git",
"dir": null,
"ref": "26ed20b9c181a576f4cbe18ccdea38912c01476e",
"ref": "13a0949395250216b9b500ca0731b46841e46085",
"url": "https://github.com/FunkinCrew/FlxPartialSound.git"
},
{
"name": "astc-compressor",
"type": "git",
"dir": null,
"ref": "b7a91b3072dc16e785a9bde847f17ba0ef15dd47",
"ref": "6c0fa6f46d3547ca58859b6ede87e659018a7ff5",
"url": "https://github.com/KarimAkra/astc-compressor"
},
{
"name": "extension-admob",
"type": "git",
"dir": null,
"ref": "4c69bb43f1fb89fd6003dc98d2f3a9d75c5364b6",
"ref": "68fc73c4090c5765709597b68fbe87389f3548c0",
"url": "https://github.com/FunkinCrew/extension-admob"
},
{
"name": "extension-agesignals",
"type": "git",
"ref": "dd3f56ccbb313a43d40cba8826fca2b1ec7c7e5d",
"url": "https://github.com/FunkinCrew/extension-agesignals"
},
{
"name": "extension-androidtools",
"type": "haxelib",
"version": "2.2.2"
},
{
"name": "extension-haptics",
"name": "dox",
"type": "haxelib",
"version": "1.0.4"
"version": "1.6.0"
},
{
"name": "extension-haptics",
"type": "git",
"ref": "8978b34b437f943a0d164bd6b3d8b69bd0025081",
"url": "https://github.com/LimeExtensions/extension-haptics"
},
{
"name": "extension-iapcore",
"type": "haxelib",
"version": "1.0.4"
"type": "git",
"ref": "5fbb4a8e56ff0f4d8ffc71b561d57a367419ead8",
"url": "https://github.com/LimeExtensions/extension-iapcore"
},
{
"name": "extension-iarcore",
"type": "haxelib",
"version": "1.0.3"
"type": "git",
"ref": "a78e49fe69feecef9abcdbcfd08ccc510ed00c6c",
"url": "https://github.com/LimeExtensions/extension-iarcore"
},
{
"name": "extension-webviewcore",
"type": "git",
"dir": null,
"ref": "d13109450d65c40678244ca23b1aa88ac18d77e6",
"ref": "98c059722491b182ee932ff47c5d7b564c967165",
"url": "https://github.com/LimeExtensions/extension-webviewcore"
},
{
"name": "flixel",
"type": "git",
"dir": null,
"ref": "c8e79d2a42f9c11c639519ef2a6fd7ef2379a8aa",
"ref": "141f23c400c0508c76d5a09a143f5ce6790f8122",
"url": "https://github.com/FunkinCrew/flixel"
},
{
"name": "flixel-addons",
"type": "git",
"dir": null,
"ref": "6fa30b3f5209146c852c25f3d1003e08898083e2",
"ref": "7628435364c4a45440d1e5db656741b66a8cd2ec",
"url": "https://github.com/FunkinCrew/flixel-addons"
},
{
"name": "flixel-animate",
"type": "git",
"dir": null,
"ref": "c61476f4b3a3d225631ab3065e4e925a4b63c076",
"ref": "c5e3393c70b71a191f20fa902114cea92042e486",
"url": "https://github.com/MaybeMaru/flixel-animate"
},
{
"name": "format",
"type": "haxelib",
"version": "3.5.0"
"version": "3.8.0"
},
{
"name": "svg",
"type": "haxelib",
"version": "1.1.3"
},
{
"name": "funkin.vis",
@@ -88,6 +104,11 @@
"ref": "6409f3c6d1b4c52176813d3ede86c0d34e8af2c1",
"url": "https://github.com/FunkinCrew/grig.audio"
},
{
"name": "tink_core",
"type": "haxelib",
"version": "1.26.0"
},
{
"name": "hamcrest",
"type": "haxelib",
@@ -97,7 +118,7 @@
"name": "haxeui-core",
"type": "git",
"dir": null,
"ref": "088b153b35985f8e4419ef710057ebd5b3749513",
"ref": "998534fb830450ca1e60c47a9524af5730431145",
"url": "https://github.com/FunkinCrew/haxeui-core"
},
{
@@ -107,18 +128,10 @@
"ref": "100f2c96beab619cfe72c567a058c41c71e3e998",
"url": "https://github.com/haxeui/haxeui-flixel"
},
{
"name": "hscript",
"type": "git",
"dir": null,
"ref": "dcc6f822e0866ca4fda300ed23e99559260f7bf5",
"url": "https://github.com/FunkinCrew/hscript"
},
{
"name": "hxcpp",
"type": "git",
"dir": null,
"ref": "5932340d095a7eea8635fe4d1355f1c0efd0b3c2",
"ref": "0376e9b19af9a4d91f9d9afc131a358467856a10",
"url": "https://github.com/FunkinCrew/hxcpp"
},
{
@@ -153,13 +166,13 @@
{
"name": "hxvlc",
"type": "haxelib",
"version": "2.2.5"
"version": "2.3.0"
},
{
"name": "json2object",
"type": "git",
"dir": null,
"ref": "a7e4cef3d444bea8d8244d6e59ab82f5a593f597",
"ref": "dc945d58c1239a6ab6e37e0a6c128387193c9af5",
"url": "https://github.com/FunkinCrew/json2object"
},
{
@@ -175,30 +188,28 @@
{
"name": "lime",
"type": "git",
"dir": null,
"ref": "318253ea3a28a3299a167748912c40444f403777",
"ref": "268dacfb2609766e14bef9ea5b669e91501852d2",
"url": "https://github.com/FunkinCrew/lime"
},
{
"name": "newgrounds",
"type": "git",
"dir": null,
"ref": "b2b53cd0a5f030af74efd325732951cddbea8826",
"ref": "60162762e6ca65da011ffee7a6617f547ea5dff9",
"url": "https://github.com/FunkinCrew/Newgrounds"
},
{
"name": "openfl",
"type": "git",
"dir": null,
"ref": "a69a6e778816c6a57eba7a91bfb0b60295508e88",
"ref": "74a51908a116d6df74be1083e219abb9fa057636",
"url": "https://github.com/FunkinCrew/openfl"
},
{
"name": "polymod",
"type": "git",
"dir": null,
"ref": "9824bf4f00863c152d5afe3ac4bbcac173d80684",
"url": "https://github.com/larsiusprime/polymod"
"ref": "acfdc2e26722f20339a2bc0cc8cd7dd5fe0c6b5e",
"url": "https://github.com/FunkinCrew/polymod"
},
{
"name": "thx.core",
+535 -6
View File
@@ -1,30 +1,559 @@
{
"disableFormatting": false,
"emptyLines": {
"finalNewline": true,
"maxAnywhereInFile": 1,
"beforePackage": 0,
"afterPackage": 1,
"importAndUsing": {
"betweenImports": 0,
"betweenImportsLevel": "firstLevelPackage",
"beforeUsing": 1,
"beforeType": 1
},
"betweenTypes": 1,
"lineCommentsBetweenTypes": "one",
"lineCommentsBetweenFunctions": "one",
"betweenSingleLineTypes": 0,
"beforeRightCurly": "remove",
"afterLeftCurly": "remove",
"afterReturn": "remove",
"beforeBlocks": "remove",
"afterBlocks": "remove",
"enumAbstractEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenVars": 0,
"afterVars": 1,
"betweenFunctions": 1,
"existingBetweenFields": "remove"
},
"classEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenStaticVars": 0,
"afterStaticVars": 1,
"afterPrivateVars": 1,
"betweenVars": 0,
"afterVars": 1,
"afterStaticFunctions": 1,
"betweenStaticFunctions": 1,
"afterPrivateFunctions": 1,
"betweenFunctions": 1,
"existingBetweenFields": "remove"
},
"macroClassEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenStaticVars": 0,
"afterStaticVars": 1,
"afterPrivateVars": 1,
"betweenVars": 0,
"afterVars": 1,
"afterStaticFunctions": 1,
"betweenStaticFunctions": 1,
"afterPrivateFunctions": 1,
"betweenFunctions": 1,
"existingBetweenFields": "remove"
},
"externClassEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenVars": 0,
"afterVars": 0,
"betweenFunctions": 0,
"existingBetweenFields": "remove"
},
"abstractEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenStaticVars": 0,
"afterStaticVars": 1,
"afterPrivateVars": 1,
"betweenVars": 0,
"afterVars": 1,
"afterStaticFunctions": 1,
"betweenStaticFunctions": 1,
"afterPrivateFunctions": 1,
"betweenFunctions": 1,
"existingBetweenFields": "remove"
},
"interfaceEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenVars": 0,
"afterVars": 0,
"betweenFunctions": 0,
"existingBetweenFields": "remove"
},
"enumEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenFields": 0,
"existingBetweenFields": "remove"
},
"typedefEmptyLines": {
"beginType": 0,
"endType": 0,
"betweenFields": 0,
"existingBetweenFields": "remove"
},
"conditionalsEmptyLines": {
"afterIf": 0,
"beforeElse": 0,
"afterElse": 0,
"beforeEnd": 0,
"beforeError": 0,
"afterError": 0
},
"beforeDocCommentEmptyLines": "one",
"afterFieldsWithDocComments": "one",
"afterFileHeaderComment": 1,
"betweenMultilineComments": 0
},
"indentation": {
"conditionalPolicy": "aligned",
"character": " ",
"tabWidth": 2,
"trailingWhitespace": false,
"indentObjectLiteral": true,
"indentComplexValueExpressions": false,
"indentCaseLabels": true
},
"lineEnds": {
"lineEndCharacter": "auto",
"metadataType": "after",
"metadataVar": "forceAfterLast",
"metadataFunction": "forceAfterLast",
"metadataOther": "none",
"caseColon": "after",
"sharp": "after",
"leftCurly": "both",
"rightCurly": "both",
"emptyCurly": "noBreak",
"blockCurly": {
"emptyCurly": "break",
"leftCurly": "both",
"rightCurly": "both"
},
"anonFunctionCurly": {
"emptyCurly": "break",
"leftCurly": "both",
"rightCurly": "both"
},
"anonTypeCurly": {
"emptyCurly": "break",
"leftCurly": "both",
"rightCurly": "both"
},
"objectLiteralCurly": {
"emptyCurly": "break",
"leftCurly": "after",
"rightCurly": "both"
},
"leftCurly": "both",
"rightCurly": "both"
"typedefCurly": {
"emptyCurly": "break",
"leftCurly": "both",
"rightCurly": "both"
}
},
"sameLine": {
"ifBody": "same",
"elseBody": "next",
"ifElse": "next",
"doWhile": "next",
"elseIf": "same",
"ifElseSemicolonNextLine": true,
"expressionIf": "same",
"expressionIfWithBlocks": false,
"forBody": "same",
"comprehensionFor": "same",
"whileBody": "next",
"doWhileBody": "next",
"doWhile": "same",
"tryBody": "next",
"tryCatch": "next"
"catchBody": "next",
"tryCatch": "next",
"caseBody": "next",
"expressionCase": "next",
"expressionTry": "same",
"functionBody": "same",
"anonFunctionBody": "same",
"returnBody": "same",
"returnBodySingleLine": "same",
"untypedBody": "same"
},
"whitespace": {
"switchPolicy": "around"
}
"parenConfig": {
"metadataParens": {
"openingPolicy": "none",
"closingPolicy": "none",
"removeInnerWhenEmpty": true
}
},
"bracesConfig": {},
"bracketConfig": {
"arrayLiteralBrackets": {
"openingPolicy": "noneAfter",
"closingPolicy": "none",
"removeInnerWhenEmpty": true
},
"mapLiteralBrackets": {
"openingPolicy": "noneAfter",
"closingPolicy": "none",
"removeInnerWhenEmpty": true
},
"accessBrackets": {
"openingPolicy": "noneAfter",
"closingPolicy": "none",
"removeInnerWhenEmpty": true
},
"comprehensionBrackets": {
"openingPolicy": "none",
"closingPolicy": "none",
"removeInnerWhenEmpty": true
},
"unknownBrackets": {
"openingPolicy": "noneAfter",
"closingPolicy": "none",
"removeInnerWhenEmpty": true
}
},
"typeParamOpenPolicy": "none",
"typeParamClosePolicy": "none",
"typeExtensionPolicy": "after",
"commaPolicy": "onlyAfter",
"dotPolicy": "none",
"colonPolicy": "none",
"caseColonPolicy": "onlyAfter",
"objectFieldColonPolicy": "after",
"typeHintColonPolicy": "none",
"typeCheckColonPolicy": "around",
"ternaryPolicy": "around",
"semicolonPolicy": "onlyAfter",
"ifPolicy": "after",
"doPolicy": "after",
"whilePolicy": "after",
"forPolicy": "after",
"switchPolicy": "around",
"tryPolicy": "after",
"catchPolicy": "after",
"binopPolicy": "around",
"intervalPolicy": "none",
"arrowFunctionsPolicy": "around",
"functionTypeHaxe3Policy": "none",
"functionTypeHaxe4Policy": "around",
"compressSuccessiveParenthesis": true,
"formatStringInterpolation": true,
"addLineCommentSpace": true
},
"wrapping": {
"maxLineLength": 160,
"arrayMatrixWrap": "matrixWrapWithAlign",
"arrayWrap": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0,
"rules": [
{
"type": "noWrap",
"conditions": [
{
"cond": "itemCount <= n",
"value": 1
},
{
"cond": "totalItemLength <= n",
"value": 160
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "anyItemLength >= n",
"value": 32
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "itemCount >= n",
"value": 5
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "hasMultilineItems",
"value": 1
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "totalItemLength >= n",
"value": 160
}
]
}
]
},
"mapWrap": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0,
"rules": [
{
"type": "onePerLine",
"conditions": [
{
"cond": "anyItemLength >= n",
"value": 32
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "itemCount >= n",
"value": 5
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "hasMultilineItems",
"value": 1
}
]
},
{
"type": "onePerLine",
"conditions": [
{
"cond": "lineLength >= n",
"value": 160
}
]
}
]
},
"methodChain": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0,
"rules": [
{
"additionalIndent": 0,
"location": "afterLast",
"type": "onePerLine",
"conditions": [
{
"cond": "lineLength >= n",
"value": 160
}
]
}
]
},
"callParameter": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0,
"rules": [
{
"additionalIndent": 0,
"location": "afterLast",
"type": "onePerLine",
"conditions": [
{
"cond": "lineLength >= n",
"value": 160
}
]
}
]
},
"objectLiteral": {
"defaultWrap": "onePerLine",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"opBoolChain": {
"defaultWrap": "noWrap",
"defaultLocation": "beforeLast",
"defaultAdditionalIndent": 0,
"rules": [
{
"additionalIndent": 0,
"location": "beforeLast",
"type": "onePerLine",
"conditions": [
{
"cond": "lineLength >= n",
"value": 160
}
]
}
]
},
"opAddSubChain": {
"defaultWrap": "noWrap",
"defaultLocation": "beforeLast",
"defaultAdditionalIndent": 0,
"rules": [
{
"additionalIndent": 0,
"location": "beforeLast",
"type": "onePerLine",
"conditions": [
{
"cond": "lineLength >= n",
"value": 160
}
]
}
]
},
"implementsExtends": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"metadataCallParameter": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"anonFunctionSignature": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"anonType": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"casePattern": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"functionSignature": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"multiVar": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
},
"typeParameter": {
"defaultWrap": "noWrap",
"defaultLocation": "afterLast",
"defaultAdditionalIndent": 0
}
},
"excludes": [
"_Provide a list of regular expressions to exclude from formatting.",
".haxelib",
".git",
"node_modules"
]
}
+157 -200
View File
@@ -32,13 +32,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.8.1";
static final VERSION:String = "0.8.7";
/**
* 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 = 70;
static final BUILD_NUMBER:Int = 102;
/**
* The game's name. Used as the default window title.
@@ -105,15 +105,8 @@ class Project extends HXProject
//
/**
* The app's minimal Android SDK version.
* The app's lime Android java extensions.
*/
static final ANDROID_MINIMUM_SDK_VERSION:Int = 28;
/**
* The app's target Android SDK version.
*/
static final ANDROID_TARGET_SDK_VERSION:Int = 35;
static final ANDROID_EXTENSIONS:Array<String> = [
"funkin.extensions.CallbackUtil",
"funkin.extensions.FNFCExtension",
@@ -171,11 +164,7 @@ class Project extends HXProject
/**
* Asset path globs to exclude on platforms with `CENSOR_EXPLETIVES` disabled.
*/
static final EXCLUDE_ASSETS_UNCENSORED:Array<String> = [
"stressCutscene-censored.mp4",
"stressPicoCutscene-censored.mp4",
"darnellCutscene-censored.mp4"
];
static final EXCLUDE_ASSETS_UNCENSORED:Array<String> = ["stressCutscene-censored.mp4", "stressPicoCutscene-censored.mp4", "darnellCutscene-censored.mp4"];
//
// ASSET EMBEDDING
@@ -184,9 +173,7 @@ class Project extends HXProject
/**
* The songs whose audio files should be embedded inside the executable.
*/
static final EMBED_SONGS_AUDIO:Array<String> = [
"spaghetti"
];
static final EMBED_SONGS_AUDIO:Array<String> = ["spaghetti"];
//
// BUILD FLAGS
@@ -216,6 +203,13 @@ class Project extends HXProject
*/
static final EXCLUDE_ARMV7:FeatureFlag = "EXCLUDE_ARMV7";
/**
* `-DFORCE_BLEND_SHADER`
* If this flag is enabled, the game will force the use of shaders to render
* certain blend modes, even if the device supports the needed OpenGL extensions.
*/
static final FORCE_BLEND_SHADER:FeatureFlag = "FORCE_BLEND_SHADER";
/**
* `-DGITHUB_BUILD`
* If this flag is enabled, the game will use the configuration used by GitHub Actions
@@ -387,10 +381,16 @@ class Project extends HXProject
/**
* `-DFEATURE_MOBILE_WEBVIEW`
* If this feature flag is enabled, the user may sometimes be prompted to review the app on their respective store.
* If this feature flag is enabled, the game will be able to load WebViews, mainly needed for the Newgrounds impl.
*/
static final FEATURE_MOBILE_WEBVIEW:FeatureFlag = "FEATURE_MOBILE_WEBVIEW";
/**
* `-DFEATURE_MOBILE_AGESIGNALS`
* If this feature flag is enabled, the game will be able to use age singals.
*/
static final FEATURE_MOBILE_AGESIGNALS:FeatureFlag = "FEATURE_MOBILE_AGESIGNALS";
/**
* `-DFEATURE_NAUGHTYNESS`
* If this feature flag is enabled, naughtyness will be a toggleable option in the Options Menu.
@@ -534,19 +534,34 @@ class Project extends HXProject
{
super();
#if !target.unicode
if (isWindowsHost())
{
// Enable code page 65001 for unicode support
Sys.command("chcp 65001 > nul");
}
#end
envConfig = readEnvironmentFile("./.env");
flair();
displayTarget();
configureApp();
displayTarget();
configureOutputDir();
if (isRun() || isInstall())
{
// These commands dont really need much in order to run so to improve the speed, we return here.
return;
}
configureFeatureFlags();
configureCompileDefines();
configureIncludeMacros();
configureCustomMacros();
configureOutputDir();
configurePolymod();
configureHaxelibs();
configureASTCTextures();
@@ -577,7 +592,7 @@ class Project extends HXProject
buildHxCppTools();
}
if (!isDisplay())
if (!(isDisplay() || isCleanCommand()))
{
checkLibraries();
}
@@ -606,11 +621,6 @@ class Project extends HXProject
{
this.meta.title = isMobile() ? TITLE_MOBILE : TITLE;
// ios uses this character code instead of spaces...
// We don't have spaces in our title for mobile anymore
// But keeping incase anybody source-modding ever does add spaces
if (isIOS()) this.meta.title = ~/ /ig.replace(TITLE_MOBILE, "\u2002");
this.meta.version = VERSION;
this.meta.packageName = PACKAGE_NAME;
this.meta.company = COMPANY;
@@ -636,17 +646,6 @@ class Project extends HXProject
// Set the build number, required for publishing the game to mobile stores.
this.meta.buildNumber = Std.string(BUILD_NUMBER);
// These values are only used by the SWF target I think.
// this.app.path
// this.app.init
// this.app.swfVersion
// this.app.url
// These values are only used by... FIREFOX MARKETPLACE WHAT?
// this.meta.description = "";
// this.meta.companyId = COMPANY;
// this.meta.companyUrl = COMPANY;
// Configure the window.
// Automatically configure FPS.
this.window.fps = 60;
@@ -659,7 +658,7 @@ class Project extends HXProject
this.window.hardware = true;
this.window.vsync = false;
// force / allow high DPI
this.window.allowHighDPI = true;
this.window.allowHighDPI = !isMac();
if (isWeb())
{
@@ -691,8 +690,28 @@ class Project extends HXProject
this.excludeArchitectures.push(Architecture.ARMV7);
}
config.set("android.minimum-sdk-version", ANDROID_MINIMUM_SDK_VERSION);
config.set("android.target-sdk-version", ANDROID_TARGET_SDK_VERSION);
if (isRelease())
{
if (envConfig != null)
{
keystore = new Keystore();
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())
{
config.set("android.gradle-project-directory", "bin-bundle");
}
}
}
if (isIOS())
{
config.set("ios.non-exempt-encryption", "false");
config.set("ios.team-id", IOS_TEAM_ID);
config.set("ios.deployment", "16.0");
}
}
@@ -726,7 +745,6 @@ class Project extends HXProject
// case Platform.PS3:
// case Platform.PS4:
// case Platform.TIZEN:
// case Platform.TVOS:
// case Platform.VITA:
// case Platform.WEBOS:
// case Platform.WIIU:
@@ -738,42 +756,22 @@ class Project extends HXProject
switch (this.platformType)
{
case PlatformType.DESKTOP:
info('Platform Type: Desktop');
info('Target Platform Type: Desktop');
case PlatformType.MOBILE:
info('Platform Type: Mobile');
info('Target Platform Type: Mobile');
case PlatformType.WEB:
info('Platform Type: Web');
info('Target Platform Type: Web');
case PlatformType.CONSOLE:
info('Platform Type: Console');
info('Target Platform Type: Console');
default:
error('Unknown platform type (got ${platformType})');
}
// Print whether we are using HXCPP, HashLink, or something else.
// Print whether we are using HXCPP, JavaScript, or something else.
if (isWeb())
{
info('Target Language: JavaScript (HTML5)');
}
else if (isHashLink())
{
info('Target Language: HashLink');
}
else if (isNeko())
{
info('Target Language: Neko');
}
else if (isJava())
{
info('Target Language: Java');
}
else if (isNodeJS())
{
info('Target Language: JavaScript (NodeJS)');
}
else if (isCSharp())
{
info('Target Language: C#');
}
else if (isCPP())
{
info('Target Language: C++');
@@ -789,23 +787,13 @@ class Project extends HXProject
switch (arch)
{
case Architecture.X86:
info('Architecture: x86');
info('Target Architecture: x86');
case Architecture.X64:
info('Architecture: x64');
case Architecture.ARMV5:
info('Architecture: ARMv5');
case Architecture.ARMV6:
info('Architecture: ARMv6');
info('Target Architecture: x64');
case Architecture.ARMV7:
info('Architecture: ARMv7');
case Architecture.ARMV7S:
info('Architecture: ARMv7S');
info('Target Architecture: ARMv7');
case Architecture.ARM64:
info('Architecture: ARMx64');
case Architecture.MIPS:
info('Architecture: MIPS');
case Architecture.MIPSEL:
info('Architecture: MIPSEL');
info('Target Architecture: ARM64');
case null:
if (!isWeb())
{
@@ -813,7 +801,7 @@ class Project extends HXProject
}
else
{
info('Architecture: Web');
info('Target Architecture: Web');
}
default:
error('Unsupported architecture (got ${arch})');
@@ -855,14 +843,15 @@ class Project extends HXProject
// Should be true on mobile builds.
CENSOR_EXPLETIVES.apply(this, isMobile());
// Should be true on Android.
// Some Android devices support native blends, but it causes issues
// with other shaders, so we'll disable it for now.
FORCE_BLEND_SHADER.apply(this, isAndroid());
//
// 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));
@@ -872,8 +861,7 @@ class Project extends HXProject
FEATURE_POLYMOD_MODS.apply(this, true);
// Video playback should be enabled on desktop, web, and mobile.
// HXCPP has trouble with iOS simulator builds though...
FEATURE_VIDEO_PLAYBACK.apply(this, !(isIOSSimulator() || isHashLink()));
FEATURE_VIDEO_PLAYBACK.apply(this, true);
// Video subtitles only work via using hxvlc.
FEATURE_VIDEO_SUBTITLES.apply(this, FEATURE_VIDEO_PLAYBACK.isEnabled(this) && !isWeb());
@@ -908,13 +896,13 @@ class Project extends HXProject
// Should be true except on web builds (some asset stuff breaks it)
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.
FEATURE_SCREENSHOTS.apply(this, !(isWeb() || isMobile()));
// Should be true only on Desktop builds.
// Mobile has its own screenshot methods.
// Web has it disabled due to performance cost of `preserveDrawingBuffer`.
FEATURE_SCREENSHOTS.apply(this, isDesktop());
// Should be true except on MacOS and mobile builds.
// Dragging and dropping files onto the window doesn't work there.
FEATURE_FILE_DROP.apply(this, !(isMac() || isMobile()));
// Should be true except on mobile builds.
FEATURE_FILE_DROP.apply(this, !isMobile());
// Audio context issues only exist on web builds.
FEATURE_TOUCH_HERE_TO_PLAY.apply(this, isWeb());
@@ -924,10 +912,11 @@ class Project extends HXProject
FEATURE_TOUCH_CONTROLS.apply(this, isMobile());
// Should be true only on mobile release builds. Remember you can add the flag manually for testing.
FEATURE_MOBILE_ADVERTISEMENTS.apply(this, (isMobile() && isRelease() && !isIOSSimulator()) && envConfig != null);
FEATURE_MOBILE_IAP.apply(this, (isMobile() && isRelease() && !isIOSSimulator()) && envConfig != null);
FEATURE_MOBILE_IAR.apply(this, isMobile() && isRelease() && !isIOSSimulator());
FEATURE_MOBILE_ADVERTISEMENTS.apply(this, (isMobile() && isRelease()) && envConfig != null);
FEATURE_MOBILE_IAP.apply(this, (isMobile() && isRelease()) && envConfig != null);
FEATURE_MOBILE_IAR.apply(this, isMobile() && isRelease());
FEATURE_MOBILE_WEBVIEW.apply(this, isMobile() && FEATURE_NEWGROUNDS.isEnabled(this));
FEATURE_MOBILE_AGESIGNALS.apply(this, isMobile() && isRelease());
// The coveted ghost tapping feature.
// Essential on mobile but delayed on desktop.
@@ -958,16 +947,6 @@ class Project extends HXProject
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))
@@ -1016,6 +995,9 @@ class Project extends HXProject
*/
function configureCompileDefines()
{
// Add Funkin's version as a compilation flag so Polymod scripts can use it.
setHaxedef("funkin", VERSION);
// Enable OpenFL's error handler. Required for the crash logger.
setHaxedef("openfl-enable-handle-error");
@@ -1029,8 +1011,6 @@ class Project extends HXProject
setHaxedef("HXCPP_STACK_TRACE");
setHaxedef("hscriptPos");
setHaxedef("safeMode");
if (FEATURE_DEBUG_FUNCTIONS.isDisabled(this))
{
setHaxedef("FLX_NO_DEBUG"); // If we aren't using the Flixel debugger, strip it out.
@@ -1123,6 +1103,13 @@ class Project extends HXProject
// Ensure all flixel-animate classes are available at runtime.
addHaxeMacro("include('animate')");
// Ensure all openfl classes are available at runtime.
addHaxeMacro("include('openfl')");
// Ensure all lime classes are available at runtime.
// Explicitly ignore tools and internal packages.
addHaxeMacro("include('lime', true, ['lime.tools.*', 'lime._internal.*'])");
// Ensure all Flixel classes are available at runtime.
// Explicitly ignore packages which require additional dependencies.
addHaxeMacro("include('flixel', true, [ 'flixel.addons.editors.spine.*', 'flixel.addons.nape.*', 'flixel.system.macros.*', 'flixel.addons.tile.FlxRayCastTilemap' ])");
@@ -1133,8 +1120,9 @@ class Project extends HXProject
*/
function configureCustomMacros()
{
// This macro allows addition of new functionality to existing Flixel. -->
// These macros allow additions of new functionality to existing Flixel. -->
addHaxeMacro("addMetadata('@:build(funkin.util.macro.FlxMacro.buildFlxBasic())', 'flixel.FlxBasic')");
addHaxeMacro("addMetadata('@:build(funkin.util.macro.FlxMacro.buildFlxSprite())', 'flixel.FlxSprite')");
}
function configureOutputDir()
@@ -1158,22 +1146,6 @@ class Project extends HXProject
{
javaPaths.push(Path.join([SOURCE_DIR, 'funkin/external/android/java']));
if (isRelease())
{
if (envConfig != null)
{
keystore = new Keystore();
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())
{
config.set("android.gradle-project-directory", "bin-bundle");
}
}
// Custom android.application XML Children for the AndroidManifest
final modsFolderProvider:Xml = Xml.createElement('provider');
modsFolderProvider.set('android:authorities', '$PACKAGE_NAME.docprovider');
@@ -1218,21 +1190,12 @@ class Project extends HXProject
intentFilter.addChild(category);
}
final intentFilterDatas:Map<String, Array<String>> = [
"android:mimeType" => ["application/zip"],
// When this is added, it makes the game show up only when it's a FNFC file.
final intentFilterDatas:Map<String,
Array<String>> = ["android:mimeType" => ["application/zip"], // When this is added, it makes the game show up only when it's a FNFC file.
// But it also for some reason make it not show up at all in ZArchiver no matter what the file is...
// "android:host" => ["*"],
"android:scheme" => ["file", "content"],
// I think having all these makes it so the extension check would work even when the files has dots like "epic-song-v2.0.fnfc"
"android:pathPattern" => [
".*\\.fnfc",
".*\\..*\\.fnfc",
".*\\..*\\..*\\.fnfc",
".*\\..*\\..*\\..*\\.fnfc",
".*\\..*\\..*\\..*\\..*\\.fnfc"
]
];
"android:scheme" => ["file", "content"], // I think having all these makes it so the extension check would work even when the files has dots like "epic-song-v2.0.fnfc"
"android:pathPattern" => [".*\\.fnfc", ".*\\..*\\.fnfc", ".*\\..*\\..*\\.fnfc", ".*\\..*\\..*\\..*\\.fnfc", ".*\\..*\\..*\\..*\\..*\\.fnfc"]];
for (key => values in intentFilterDatas)
{
@@ -1269,10 +1232,6 @@ class Project extends HXProject
function configureIOS()
{
config.set("ios.non-exempt-encryption", "false");
config.set("ios.team-id", IOS_TEAM_ID);
config.set("ios.deployment", "16.0");
// launchStoryboard = new LaunchStoryboard();
// launchStoryboard.path = "./LaunchScreen.storyboard";
@@ -1325,7 +1284,6 @@ class Project extends HXProject
addHaxelib('flixel'); // Game engine
addHaxelib('flixel-addons'); // Additional utilities for Flixel
addHaxelib('hscript'); // Scripting
if (FEATURE_HAXEUI.isEnabled(this))
{
@@ -1342,15 +1300,13 @@ class Project extends HXProject
addHaxelib('thx.core'); // General utility library, "the lodash of Haxe"
addHaxelib('thx.semver'); // Version string handling
if (isDebug())
if (isDebug() && isCPP())
{
addHaxelib('hxcpp-debug-server'); // VSCode debug support
}
if (isDesktop() || isMobile() && !isHashLink() && FEATURE_VIDEO_PLAYBACK.isEnabled(this))
if ((isDesktop() || isMobile()) && FEATURE_VIDEO_PLAYBACK.isEnabled(this))
{
// hxvlc doesn't function on HashLink or non-desktop platforms
// It's also unnecessary if video playback is disabled
addHaxelib('hxvlc'); // Video playback
}
@@ -1409,12 +1365,20 @@ class Project extends HXProject
{
addHaxelib('extension-webviewcore'); // WebView Extension
}
if (FEATURE_MOBILE_AGESIGNALS.isEnabled(this))
{
addHaxelib('extension-agesignals'); // WebView Extension
}
}
function configureAssets()
{
// Delete the assets folder from the export folder before adding anything.
clearAssets();
if (!(isDisplay() || isCleanCommand()))
{
// Delete the assets folder from the export folder before adding anything.
clearAssets();
}
var exclude = EXCLUDE_ASSETS.concat(isWeb() ? EXCLUDE_ASSETS_WEB : EXCLUDE_ASSETS_NATIVE);
var shouldPreload = PRELOAD_ALL.isEnabled(this);
@@ -1500,8 +1464,6 @@ class Project extends HXProject
addAssetLibrary("sserafim", shouldEmbed, shouldPreload);
addAssetPath("assets/sserafim", "assets/sserafim", "sserafim", ["*"], exclude, shouldEmbed, "assets");
// Art asset library (where README and CHANGELOG pull from)
var shouldEmbedArt = false;
var shouldPreloadArt = false;
@@ -1528,7 +1490,7 @@ class Project extends HXProject
var exportPath:Null<String> = app.path ?? "";
// mac target uses `macos` for the export folder instead of `mac`
var platform:String = (!isMac() ? Std.string(this.target) : 'macos');
var platform:String = !isMac() ? Std.string(this.target) : 'macos';
var basePath:String = Path.join([exportPath, platform, "bin"]);
var assetsPath:String = "";
@@ -1548,6 +1510,10 @@ class Project extends HXProject
{
assetsPath = Path.join([basePath, "app", "src", "main", "assets", "assets"]);
}
else if (isIOS())
{
assetsPath = Path.join([exportPath, platform, '${this.app.file}', "assets", "assets"]);
}
else
{
return;
@@ -1646,14 +1612,10 @@ class Project extends HXProject
*/
function configureASTCTextures()
{
if (!(isDisplay() || isClean()))
if (!(isDisplay() && isCleanCommand()) && FEATURE_COMPRESSED_TEXTURES.isEnabled(this))
{
readASTCExclusion();
if (FEATURE_COMPRESSED_TEXTURES.isEnabled(this))
{
runASTCCompressor();
}
runASTCCompressor();
}
}
@@ -1759,31 +1721,6 @@ class Project extends HXProject
return this.target == Platform.IOS && this.targetFlags.exists("simulator");
}
public function isHashLink():Bool
{
return this.targetFlags.exists("hl");
}
public function isNeko():Bool
{
return this.targetFlags.exists("neko");
}
public function isJava():Bool
{
return this.targetFlags.exists("java");
}
public function isNodeJS():Bool
{
return this.targetFlags.exists("nodejs");
}
public function isCSharp():Bool
{
return this.targetFlags.exists("cs");
}
public function isCPP():Bool
{
return this.defines.exists("cpp");
@@ -1794,11 +1731,26 @@ class Project extends HXProject
return this.command == "display";
}
public function isClean():Bool
public function isCleanCommand():Bool
{
return this.command == "clean";
}
public function isCleanFlag():Bool
{
return this.targetFlags.exists("clean");
}
public function isRun():Bool
{
return this.command == "run";
}
public function isInstall():Bool
{
return this.command == "install";
}
public function isBuild():Bool
{
return this.command == "test" || this.command == "build";
@@ -2092,7 +2044,7 @@ class Project extends HXProject
@SuppressWarnings('checkstyle:Dynamic')
function checkLibraries():Void
{
var diffrentLibraries:Map<String, Array<String>> = new Map<String, Array<String>>();
var differentLibraries:Map<String, Array<String>> = new Map<String, Array<String>>();
var hmmData:Dynamic = haxe.Json.parse(sys.io.File.getContent(#if ios '../../../../../' + #end 'hmm.json'));
@@ -2113,11 +2065,11 @@ class Project extends HXProject
switch (library.type)
{
case 'haxelib':
diffrentLibraries.set(libraryName, [libraryDev, libraryCurrentCommitHash, library.version, 'haxelib']);
differentLibraries.set(libraryName, [libraryDev, libraryCurrentCommitHash, library.version, 'haxelib']);
case 'git':
if (libraryCurrentCommitHash != library.ref)
{
diffrentLibraries.set(libraryName, [libraryDev, libraryCurrentCommitHash, library.ref, 'git']);
differentLibraries.set(libraryName, [libraryDev, libraryCurrentCommitHash, library.ref, 'git']);
}
}
}
@@ -2128,18 +2080,18 @@ class Project extends HXProject
case 'haxelib':
if (library.version != libraryCurrentVersion)
{
diffrentLibraries.set(libraryName, ['', libraryCurrentVersion, library.version, 'haxelib']);
differentLibraries.set(libraryName, ['', libraryCurrentVersion, library.version, 'haxelib']);
}
case 'git':
if (libraryCurrentCommitHash != library.ref)
{
diffrentLibraries.set(libraryName, ['', libraryCurrentCommitHash, library.ref, 'git']);
differentLibraries.set(libraryName, ['', libraryCurrentCommitHash, library.ref, 'git']);
}
}
}
}
if (Lambda.count(diffrentLibraries) > 0)
if (Lambda.count(differentLibraries) > 0)
{
warn("Some libraries differ from the versions defined in hmm.json.".bold().yellow());
warn("To ensure consistency, it's recommended to stop the build and run `hmm reinstall [library]`.".bold().yellow());
@@ -2147,9 +2099,9 @@ class Project extends HXProject
Sys.println('');
for (libraryName in diffrentLibraries.keys())
for (libraryName in differentLibraries.keys())
{
var infos:Null<Array<String>> = diffrentLibraries.get(libraryName);
var infos:Null<Array<String>> = differentLibraries.get(libraryName);
if (infos == null) continue;
@@ -2160,9 +2112,8 @@ class Project extends HXProject
if (haxe.io.Path.isAbsolute(devPath))
{
Sys.println("- " + libraryName.replace(",", ".") + " (Development Build)".blue().bold());
Sys.println((" Path: " + haxe.io.Path.removeTrailingSlashes(devPath)).blue());
Sys.println("- " + libraryName.replace(",", ".") + " (Development Build)".bright_cyan());
Sys.println((" Path: " + haxe.io.Path.removeTrailingSlashes(devPath)).bright_blue());
}
else
{
@@ -2181,7 +2132,7 @@ class Project extends HXProject
{
var path = getLibraryCurrentFile(libraryName);
if (sys.FileSystem.exists(path)) return sys.io.File.getContent(path);
if (sys.FileSystem.exists(path)) return sys.io.File.getContent(path).trim();
return '';
}
@@ -2190,7 +2141,7 @@ class Project extends HXProject
{
var path = getLibraryDevFile(libraryName);
if (sys.FileSystem.exists(path)) return sys.io.File.getContent(path);
if (sys.FileSystem.exists(path)) return sys.io.File.getContent(path).trim();
return '';
}
@@ -2328,7 +2279,7 @@ class Project extends HXProject
*/
public function info(message:String):Void
{
if (!(isDisplay() || isClean()))
if (!(isDisplay() || isCleanCommand() || isRun() || isInstall()))
{
Sys.println(' INFO '.bold().bg_blue() + " " + message);
}
@@ -2339,7 +2290,7 @@ class Project extends HXProject
*/
public function warn(message:String):Void
{
if (!(isDisplay() || isClean()))
if (!(isDisplay() || isCleanCommand() || isRun() || isInstall()))
{
Sys.println(' WARNING '.bold().bg_yellow() + " " + message);
}
@@ -2485,8 +2436,14 @@ class Project extends HXProject
info('Compressing ASTC textures...');
var args:Array<String> = ['run', 'astc-compressor', 'compress-from-json'];
args = args.concat(['-json', './astc-compression-data.json']);
if (isCleanFlag())
{
args = args.concat(['-clean']);
}
Sys.command('haxelib', args);
info('Done compressing ASTC textures.');
+48
View File
@@ -0,0 +1,48 @@
package scripts;
using DateTools;
class Postbuild
{
static function main()
{
/* trace('creating NG zip');
var binFolder:String = 'export/release/html5/bin/';
var date = Date.now();
var outputName:String = 'NG-' + date.format("%Y%m%d--%H%M") + '.zip';
var out = sys.io.File.write(outputName);
var zip = new haxe.zip.Writer(out);
zip.write(getEntries(binFolder));
trace('Finished creating ZIP');
*/
}
static function getEntries(dir:String, entries:List<haxe.zip.Entry> = null, inDir:Null<String> = null)
{
if (entries == null) entries = new List<haxe.zip.Entry>();
if (inDir == null) inDir = dir;
for (file in sys.FileSystem.readDirectory(dir))
{
var path = haxe.io.Path.join([dir, file]);
if (sys.FileSystem.isDirectory(path)) getEntries(path, entries, inDir);
else
{
var bytes:haxe.io.Bytes = haxe.io.Bytes.ofData(sys.io.File.getBytes(path).getData());
var entry:haxe.zip.Entry = {
fileName: StringTools.replace(path, inDir, ""),
fileSize: bytes.length,
fileTime: Date.now(),
compressed: false,
dataSize: sys.FileSystem.stat(path).size,
data: bytes,
crc32: haxe.crypto.Crc32.make(bytes)
};
entries.push(entry);
}
}
return entries;
}
}
+181
View File
@@ -0,0 +1,181 @@
import haxe.Json;
import haxe.Log;
import haxe.macro.Compiler;
import sys.FileSystem;
import sys.io.File;
using StringTools;
#if !interp
package scripts;
// needs this thing to be run by interp, just for me lol!
#end
// general use of this!!
// if run in INTERP MODE:
// - scripts>haxe --main SongConverter --interp
// - song to convert: ../assets/preload/data/
// it will run through EVERY folder in there and convert the old songs to the new format!
// TODO make instructions for the C# script version!
class SongConverter
{
public static var VERSION:String = '0.1.0';
// TODO
// Update engine shit, to accomodate single file
static function main()
{
// trace(Compiler.get);
// trace(Compiler.getDefine('sysfsd'));
Sys.stdout().writeString('Please type directory you want to convert: ');
Sys.stdout().flush();
final input = Sys.stdin().readLine();
trace('Hello ${input}!');
/* Sys.stdout().writeString('What type of conversion do you need?\n\t0: Old charts to new chart\n\t1: new chart to .... new chart? lol\n>');
Sys.stdout().flush();
final deleteShitIDK = Std.parseInt(Sys.stdin().readLine());
trace(deleteShitIDK); */
var songCount:Int = 0;
for (fileThing in FileSystem.readDirectory('${input}/.'))
{
// trace(fileThing);
// trace(FileSystem.isDirectory(${input} + "/" + fileThing));
if (FileSystem.isDirectory(${input} + "/" + fileThing) && fileThing.toLowerCase() != 'smash')
{
trace('Formatting $fileThing');
formatSongs(fileThing, input);
songCount++;
}
}
trace('CONVERTED $songCount SONGS!!');
var timer:Int = 5;
while (timer > 0)
{
Sys.stdout().writeString('CLOSING IN $timer SECONDS!');
Sys.sleep(1);
Sys.print("\r");
timer -= 1;
}
}
public static function formatSongs(songName:String, root:String)
{
var existsArray:Array<Bool> = [];
var songMap:Map<String, Dynamic> = new Map();
var speedMap:Map<String, Dynamic> = new Map();
for (songFile in FileSystem.readDirectory('$root/$songName/'))
{
if (!songFile.endsWith('json') || !songFile.startsWith(songName)) continue; // ACCOMODATE FOR PICO SPEAKER EVENTUALLY!
var funnyFile:Dynamic = cast Json.parse(File.getContent('$root/$songName/$songFile'));
var songSplit:Array<String> = songFile.split('-');
var songShit:String = 'normal';
if (songSplit.length > 1)
{
if (songSplit[1] == 'new.json')
{
FileSystem.deleteFile('$root/$songName/$songFile');
trace('DELETEING $songFile');
continue;
}
songShit = songSplit[1].substr(0, songSplit[1].length - 5);
}
if (songShit != 'normal')
{
songMap[songShit] = funnyFile.song.notes;
speedMap[songShit] = funnyFile.song.speed;
}
else
{
//
if (funnyFile.song.notes is Array)
{
songMap[songShit] = funnyFile.song.notes[1];
speedMap[songShit] = funnyFile.song.speed[1];
}
else if (Type.typeof(funnyFile.song.notes) == TObject)
{
var dipshitMap:Map<String, Dynamic> = cast funnyFile.song.notes;
// songMap[songShit] = dipshitMap.get('normal');
}
else
{
songMap[songShit] = funnyFile.song.notes;
speedMap[songShit] = funnyFile.song.speed;
}
}
}
var fileNormal:Dynamic = cast Json.parse(File.getContent('$root/$songName/$songName.json'));
fileNormal.song.notes = songMap;
fileNormal.song.speed = speedMap;
fileNormal.song.hasDialogueFile = false;
fileNormal.song.stageDefault = getStage(songName);
fileNormal.version = 'FNF SongConverter $VERSION';
var daJson = Json.stringify(fileNormal, null, "\t");
// trace(daJson);
File.saveContent('$root/$songName/$songName.json', daJson);
}
static function noteCleaner(notes:Array<Dynamic>):Array<Dynamic>
{
var swagArray:Array<Dynamic> = [];
for (i in notes)
{
if (i.sectionNotes.length > 0) swagArray.push(i);
}
return swagArray;
}
/**
* Quicky lil function just for me formatting the old songs hehehe
*/
static function getStage(songName:String):String
{
switch (songName)
{
case 'spookeez' | 'monster' | 'south':
return "spooky";
case 'pico' | 'blammed' | 'philly':
return 'philly';
case "milf" | 'satin-panties' | 'high':
return 'limo';
case "cocoa" | 'eggnog':
return 'mall';
case 'winter-horrorland':
return 'mallEvil';
case 'senpai' | 'roses':
return 'school';
case 'thorns':
return 'schoolEvil';
case 'guns' | 'stress' | 'ugh':
return 'tank';
default:
return 'stage';
}
}
}
+99
View File
@@ -0,0 +1,99 @@
import csv
import re
import sys
import json
import subprocess
# This script imports a CSV file, and bulk updates the chart metadata files
#
# Requirements:
# python3 I believe
# and you need to have npm/npx, as we use that to run prettier to keep the same formatting
#
# Usage:
# In our Google Sheets, export as .csv file
#
# Then in here from within this directory, run:
# python3 sheetsToCharts.py path/to/csv/file.csv
#
# use from within this directory, as the paths to the chart metadata files are relative to this directory
# Get the command line argument, if one wasn't already provided
if len(sys.argv) < 2:
csv_file = input("Please provide the CSV file path: ")
else:
csv_file = sys.argv[1]
# Open the CSV file
with open(csv_file, 'r') as file:
reader = csv.reader(file)
# Which rows for each difficulty are we looking for
diff_rows = {}
# Iterate over each row in the CSV file
for idx, row in enumerate(reader):
# The first row has headers for the columns, stuff like "Easy - Difficulty", so we want
# to know which rows corresponde to which difficulty
if idx == 0:
pattern = r"\b(?:difficulty)\b"
diff_cols = []
diff_words = []
# Go through each column, and see if it includes the word "difficulty"
# then append the column index, and the first word of the column (usually what difficulty it is, "easy", "normal", "hard", etc.)
for colindex, column in enumerate(row):
txt = re.findall(pattern, column, flags=re.IGNORECASE)
if txt:
diff_cols.append(colindex)
diff_words.append(column.split()[0].lower())
# We then create a dictionary for use later, where the key is the difficulty, and the value is the column index
diff_rows = dict(zip(diff_words, diff_cols))
else:
# Some song title parsing, to match the filenames we used in for the chart files
song_title = row[1].lower() # we use lowercase for filenames, SOUTH -> south
song_title = song_title.replace(" ", "-") # usually we change spaces to dashes, PHILLY NICE -> philly-nice
song_title = song_title.replace(".", "") # M.I.L.F. -> milf
song_title = song_title.replace("'", "") # blazin' -> blazin
# we open the chart metadata json file for writing and reading ("r+")
with open(f"../../../assets/preload/data/songs/{song_title}/{song_title}-metadata.json", "r+") as chart_metadata_file:
json_data = json.load(chart_metadata_file) # load the file as a python data structure/dict
play_data = json_data["playData"] # we want to modify the "playData" section, as that holds the difficulty
# note to self, python equals(=) operator seems to create a reference for the variable,
# so modifying play_data will also modify json_data, so we can save json_data easily later
# if the chart metadata file doesn't already have a "ratings" dict/section, we create one here with 0 for each
if "ratings" not in play_data:
play_data["ratings"] = {'easy': 0, 'normal': 0, 'hard': 0}
ratings = play_data["ratings"]
# Now we go through our data from the csv file, and the data we kept from the columns there
# will be put into our new ratings var, if it exists
for diff, col in diff_rows.items():
if row[col] == "":
continue
if diff in ratings:
ratings[diff] = round(float(row[col])) # convert the string to a float, and then round it to nearest int
# Convert the python json_data dict back to a json string
json_output = json.dumps(json_data)
# Write the json string back to the file, and truncate the rest of the file
chart_metadata_file.seek(0)
chart_metadata_file.write(json_output)
chart_metadata_file.truncate()
chart_metadata_file.close()
# Bit hacky, but we simply run `npx prettier` using the same rules we use for FNF here
# essnetially running it via cli and passing in the songs folder and our prettier config file
# This should make the spacing and formatting consistent
command = "npx prettier ../../../assets/preload/data/songs --write --config ../../../.prettierrc.js"
subprocess.run(command, shell=True)
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
# Find all files in OGG format and execute ffmpeg to convert them to MP3
# Skips files that are already in MP3 format
find "../assets/" -name "*.ogg" -exec sh -c 'ffmpeg -n -i {} "${0%.*}.mp3"' {} \;
+218
View File
@@ -0,0 +1,218 @@
import requests
import sys
PROJECT_ID = 5582053
TEMPLATE = 'jQuery("#new-event-name").val("{event}"); jQuery("#save-new-event").click();'
EVENT_TEMPLATES = [
"start-game",
"watch-cartoon",
"open-credits",
"start-song_{songId}-{variation}",
"blueballs_{songId}-{variation}",
"complete-song_{songId}-{variation}",
"start-level_{levelId}",
"complete-level_{levelId}",
"earn-rank_{rankName}",
]
SONG_IDS = [
{ "songId": "tutorial", "variation": "default" },
{ "songId": "tutorial", "variation": "erect" },
{ "songId": "tutorial", "variation": "pico" },
{ "songId": "bopeebo", "variation": "default" },
{ "songId": "bopeebo", "variation": "erect" },
{ "songId": "bopeebo", "variation": "pico" },
{ "songId": "fresh", "variation": "default" },
{ "songId": "fresh", "variation": "erect" },
{ "songId": "fresh", "variation": "pico" },
{ "songId": "dadbattle", "variation": "default" },
{ "songId": "dadbattle", "variation": "erect" },
{ "songId": "dadbattle", "variation": "pico" },
{ "songId": "spookeez", "variation": "default" },
{ "songId": "spookeez", "variation": "erect" },
{ "songId": "spookeez", "variation": "pico" },
{ "songId": "south", "variation": "default" },
{ "songId": "south", "variation": "erect" },
{ "songId": "south", "variation": "pico" },
{ "songId": "monster", "variation": "default" },
{ "songId": "monster", "variation": "erect" },
{ "songId": "monster", "variation": "pico" },
{ "songId": "pico", "variation": "default" },
{ "songId": "pico", "variation": "erect" },
{ "songId": "pico", "variation": "pico" },
{ "songId": "philly-nice", "variation": "default" },
{ "songId": "philly-nice", "variation": "erect" },
{ "songId": "philly-nice", "variation": "pico" },
{ "songId": "blammed", "variation": "default" },
{ "songId": "blammed", "variation": "erect" },
{ "songId": "blammed", "variation": "pico" },
{ "songId": "satin-panties", "variation": "default" },
{ "songId": "satin-panties", "variation": "erect" },
{ "songId": "satin-panties", "variation": "pico" },
{ "songId": "high", "variation": "default" },
{ "songId": "high", "variation": "erect" },
{ "songId": "high", "variation": "pico" },
{ "songId": "milf", "variation": "default" },
{ "songId": "milf", "variation": "erect" },
{ "songId": "milf", "variation": "pico" },
{ "songId": "cocoa", "variation": "default" },
{ "songId": "cocoa", "variation": "erect" },
{ "songId": "cocoa", "variation": "pico" },
{ "songId": "eggnog", "variation": "default" },
{ "songId": "eggnog", "variation": "erect" },
{ "songId": "eggnog", "variation": "pico" },
{ "songId": "winter-horrorland", "variation": "default" },
{ "songId": "winter-horrorland", "variation": "erect" },
{ "songId": "winter-horrorland", "variation": "pico" },
{ "songId": "senpai", "variation": "default" },
{ "songId": "senpai", "variation": "erect" },
{ "songId": "senpai", "variation": "pico" },
{ "songId": "roses", "variation": "default" },
{ "songId": "roses", "variation": "erect" },
{ "songId": "roses", "variation": "pico" },
{ "songId": "thorns", "variation": "default" },
{ "songId": "thorns", "variation": "erect" },
{ "songId": "thorns", "variation": "pico" },
{ "songId": "ugh", "variation": "default" },
{ "songId": "ugh", "variation": "erect" },
{ "songId": "ugh", "variation": "pico" },
{ "songId": "guns", "variation": "default" },
{ "songId": "guns", "variation": "erect" },
{ "songId": "guns", "variation": "pico" },
{ "songId": "stress", "variation": "default" },
{ "songId": "stress", "variation": "erect" },
{ "songId": "stress", "variation": "pico" },
{ "songId": "darnell", "variation": "default" },
{ "songId": "darnell", "variation": "erect" },
{ "songId": "darnell", "variation": "bf" },
{ "songId": "lit-up", "variation": "default" },
{ "songId": "lit-up", "variation": "erect" },
{ "songId": "lit-up", "variation": "bf" },
{ "songId": "2hot", "variation": "default" },
{ "songId": "2hot", "variation": "erect" },
{ "songId": "2hot", "variation": "bf" },
{ "songId": "blazin", "variation": "default" },
{ "songId": "blazin", "variation": "erect" },
{ "songId": "blazin", "variation": "bf" },
]
LEVEL_IDS = [
"tutorial",
"week1",
"week2",
"week3",
"week4",
"week5",
"week6",
"week7",
"weekend1",
"week8",
]
RANKS = [
"PERFECT_GOLD",
"PERFECT",
"EXCELLENT",
"GREAT",
"GOOD",
"SHIT",
]
def formatEventSong(event):
result = []
for song in SONG_IDS:
result.append(event.format(
songId = song["songId"],
variation = song["variation"]
))
return result
def formatEventLevel(event):
result = []
for level in LEVEL_IDS:
result.append(event.format(
levelId = level
))
return result
def formatEventRank(event):
result = []
for rank in RANKS:
result.append(event.format(
rankName = rank
))
return result
def formatEvent(event):
if "{songId}" in event or "{variation}" in event:
return formatEventSong(event)
if "{levelId}" in event:
return formatEventLevel(event)
if "{rankName}" in event:
return formatEventRank(event)
return [event]
def createEvent(event):
print(TEMPLATE.format(event=event))
def main():
event_list = []
for event in EVENT_TEMPLATES:
event_list.extend(formatEvent(event))
# Filter out duplicates then sort alphabetically
event_list = list(set(event_list))
event_list.sort()
for event in event_list:
createEvent(event)
if __name__ == "__main__":
main()
#function sleep(ms) {
# console.log("sleeping for " + ms + "ms");
# return new Promise(resolve => setTimeout(resolve, ms));
#}
#async function example() {
# jQuery("#new-event-name").val("blueballs_blazin-erect"); jQuery("#save-new-event").click();
# await sleep(1000);
# jQuery("#new-event-name").val("blueballs_blazin-erect"); jQuery("#save-new-event").click();
# await sleep(1000);
#}
#example();
@@ -0,0 +1,11 @@
@echo off
color 0a
cd ..
@echo on
echo BUILDING GAME
lime build html5 -final
echo UPLOADING TO ITCH
butler push ./export/release/html5/bin ninja-muffin24/funkin-secret:html5
butler status ninja-muffin24/funkin-secret:html5
echo ITCH SHIT UPDATED LMAOOOOO
pause
+11
View File
@@ -0,0 +1,11 @@
@echo off
color 0a
cd ..
@echo on
echo BUILDING GAME
lime build html5 -debug
echo UPLOADING TO ITCH
butler push ./export/debug/html5/bin ninja-muffin24/funkin-secret:html5
butler status ninja-muffin24/funkin-secret:html5
echo ITCH SHIT UPDATED LMAOOOOO
pause
@@ -0,0 +1,15 @@
@echo off
color 0a
cd ..
@echo on
echo BUILDING GAME
lime build windows -final -clean
echo UPLOADING 64 BIT VERSION TO ITCH
butler push ./export/release/windows/bin ninja-muffin24/funkin:windows-64bit
lime build windows -final -32
echo UPLOADING 32 BIT VERSION TO ITCH
butler push ./export/release/windows/bin ninja-muffin24/funkin:windows-32bit
butler status ninja-muffin24/funkin:windows-32bit
butler status ninja-muffin24/funkin:windows-64bit
echo ITCH SHIT UPDATED LMAOOOOO
pause
@@ -0,0 +1,11 @@
@echo off
color 0a
cd ..
@echo on
echo BUILDING GAME
lime build windows -debug
echo UPLOADING 64 BIT VERSION TO ITCH
butler push ./export/debug/windows/bin ninja-muffin24/funkin:windows-secretBeta
butler status ninja-muffin24/funkin:windows-secretBeta
echo ITCH SHIT UPDATED LMAOOOOO
pause
@@ -0,0 +1,15 @@
@echo off
color 0a
cd ..
@echo on
echo BUILDING GAME
lime build windows -release
echo UPLOADING 64 BIT VERSION TO ITCH
butler push ./export/release/windows/bin ninja-muffin24/funkin:windows-64bit
lime build windows -release -32
echo UPLOADING 32 BIT VERSION TO ITCH
butler push ./export/release/windows/bin ninja-muffin24/funkin:windows-32bit
butler status ninja-muffin24/funkin:windows-32bit
butler status ninja-muffin24/funkin:windows-64bit
echo ITCH SHIT UPDATED LMAOOOOO
pause
@@ -0,0 +1,12 @@
@echo off
color 0a
cd ..
@echo on
echo BUILDING GAME
lime build html5 -final -Dng
echo ZIPPING
cd export
7z a -tzip -r swag release\html5\bin
start .
start https://www.newgrounds.com/projects/games/1528775
pause
@@ -0,0 +1,27 @@
@echo off
cd ..
@echo on
echo REBUILDING LIME FOR EXPORT (VERBOSE)
@echo off
color 0b
@echo on
lime rebuild windows -clean -v
@echo off
color 0a
@echo on
lime rebuild switch -clean -v
@echo off
color 0e
@echo on
lime rebuild tools -clean -v
echo HOPE AND PRAY...
@echo off
color 0a
@echo on
echo BUILDING GAME
lime build switch -final -clean -v
@echo off
color 0b
@echo on
echo NSP FILE CREATED
pause
+110
View File
@@ -0,0 +1,110 @@
// Highlight keyframes in flash
// drag .jsfl script in
// will export the layer info of the first(?) element it finds?
// maybe someone can extend this to add more depth / functionality!
// see FramesJSFLParser.hx and CharSelectGF.hx for sample implementation
function splitArrayIntoChunks(array, chunkSize) {
var result = [];
for (var i = 0; i < array.length; i += chunkSize) {
var chunk = array.slice(i, i + chunkSize);
result.push(chunk);
}
return result;
}
var isJson = false;
function addField(name, variable, end)
{
return (isJson) ? addFJson(name, variable, end) : addF(variable, end);
}
function addFJson(name, variable, end) {
return "\"" + name + "\": " + variable + ((!end) ? "," : "");
}
function addF(variable, end) {
return variable + ((end)? "" : " ");
}
fl.outputPanel.clear();
var timeline = fl.getDocumentDOM().getTimeline();
var daSelection = timeline.getSelectedFrames();
var splitArrays = splitArrayIntoChunks(daSelection, 3);
var uri = undefined;
if (fl.version.substring(4).split(",")[0] < 13)
{
var macFormat = "Folder|TEXT[*.||";
var winFormat = "Folder|*.||";
var previewArea = {};
uri = fl.browseForFileURL("save", "where to save files pick folder...", previewArea, macFormat, winFormat);
}
else
uri = fl.browseForFileURL("save", "where to save files pick folder..", "Folder(*.)", "*.");
for (var i = 0; i < splitArrays.length; i+=1)
{
var curLayerInfo = splitArrays[i];
var curLayerInd = curLayerInfo[0];
var curLayer = fl.getDocumentDOM().getTimeline().layers[curLayerInd];
var layerURI = uri;
var fileName = "";
var uris = uri.split("/");
fileName = uris[uris.length - 1];
FLfile.createFolder(layerURI);
var fileData = "{\n";
if (!isJson)
fileData = "";
var selectedFrames = curLayer.frames;
var sliceLength = curLayerInfo[2] - curLayerInfo[1];
selectedFrames =selectedFrames.slice(curLayerInfo[1],curLayerInfo[2]);
if (isJson)
fileData += "\"frames\": [";
for (var frameInd = curLayerInfo[1]; frameInd < curLayerInfo[2]; frameInd+=1)
{
if (isJson)
fileData += "\n{"
var curFrame = curLayer.frames[frameInd];
if (curFrame.isEmpty)
{
continue;
}
for (var elementInd = 0; elementInd < curFrame.elements.length; elementInd+=1)
{
var curElement = curFrame.elements[elementInd];
fileData += addField("x", curElement.left, false);
fileData += addField("y", curElement.top, false);
fileData += addField("alpha", (curElement.colorAlphaPercent == undefined) ? 100 : curElement.colorAlphaPercent, false);
fileData += addField("scaleX", curElement.scaleX, false);
fileData += addField("scaleY", curElement.scaleY, true);
if (frameInd != curLayerInfo[2] - 1)
fileData += "\n";
}
if (isJson)
fileData += "},";
}
if (isJson)
fileData += "]";
if (isJson)
fileData += "\n}";
FLfile.write(layerURI + "/" + fileName + ".txt", fileData);
}
+6
View File
@@ -0,0 +1,6 @@
# README
jsfl is a scripting format with javascript syntax, I believe it's old js (no `let`, idk the spec!)
Official Adobe JSFL docuementation
[https://github.com/AdobeDocs/developers-animatesdk-docs/tree/master](https://github.com/AdobeDocs/developers-animatesdk-docs/tree/master)
+120
View File
@@ -0,0 +1,120 @@
#!/bin/bash
set -e # Exit immediately if a command exits with a non-zero status
echo "Note! This should be run from the root of the main Funkin repo, after creating a universal macOS build!"
echo "This script will assist in codesigning the Funkin.app for macOS"
echo ""
TEAM_ID="Z7G7AVNGSH"
ISSUER_ID="5205caca-2a9b-4b5e-9390-1db124cf51f4"
DEVELOPER_CERT_NAME="Developer ID Application: The Funkin' Crew Incorporated ($TEAM_ID)"
APP_PATH="export/release/macosUniversal/Funkin.app"
# Check if app exists
if [ ! -d "$APP_PATH" ]; then
echo "Error: $APP_PATH does not exist! Please build the app first."
exit 1
fi
echo "Preparing/Checking the AuthKey"
team_key_path=~/.appstoreconnect/private_keys/
# Check if directory exists, if not, create it
if [ ! -d "$team_key_path" ]; then
echo "The directory $team_key_path does not exist! Creating it now."
mkdir -p "$team_key_path"
echo ""
echo "$team_key_path created, put the private key file in there (should be called 'AuthKey_XXXXXXX.p8')"
echo "Ask Cameron for the private key file!"
echo ""
fi
# wait for the user to put the file in the directory, if it's not there
while [ ! -f "${team_key_path}"AuthKey_*.p8 ]; do
echo "Waiting for the private key file to be placed in $team_key_path... (press Ctrl+C to exit)"
sleep 5
done
key_id=$(ls "$team_key_path" | grep -oE '[A-Z0-9]{10}' | head -n 1)
if [ -z "$key_id" ]; then
echo "Error: Could not extract key ID from the AuthKey file name"
exit 1
fi
echo "Found AuthKey with key id: $key_id"
key_path="${team_key_path}AuthKey_${key_id}.p8"
cd export/release/macosUniversal || { echo "Failed to change directory"; exit 1; }
echo "Ensuring properly formatted Entitlements.plist"
if [ ! -f "Funkin.app/Contents/Entitlements.plist" ]; then
echo "Error: Entitlements.plist not found"
exit 1
fi
plutil -convert xml1 Funkin.app/Contents/Entitlements.plist
plutil -convert xml1 Funkin.app/Contents/Info.plist
plutil -lint Funkin.app/Contents/Entitlements.plist
plutil -lint Funkin.app/Contents/Info.plist
echo "Entitlements.plist and Info.plist should be properly formatted..."
echo "Codesigning - Funkin.app"
# Check the keychain for the funkin crew certificate
echo "Checking for The Funkin' Crew certificate in the keychain..."
if ! security find-identity -p codesigning | grep -q "The Funkin' Crew Incorporated"; then
echo "The Funkin' Crew Developer ID Application certificate was not found in the keychain!"
echo "Download the certificate from:"
echo "https://developer.apple.com/account/resources/certificates/download/Z62SXF29U7"
exit 1
fi
echo "Codesigning - Funkin.app"
codesign --force --deep --timestamp --sign "$DEVELOPER_CERT_NAME" --options runtime Funkin.app || {
echo "Code signing failed"
exit 1
}
echo "Codesigning - Funkin.app done!"
# Debug info to see if the app is properly signed
codesign -vv --deep --strict Funkin.app || {
echo "Code signing verification failed"
exit 1
}
echo ""
echo "Zipping Funkin.app for notarization (using ditto)..."
# Check if Funkin.app.zip already exists, if so, delete it
if [ -f Funkin.app.zip ]; then
echo "Funkin.app.zip already exists, deleting it..."
rm -rf Funkin.app.zip
fi
ditto -c -k --keepParent Funkin.app Funkin.app.zip || {
echo "Failed to create zip file"
exit 1
}
echo "Funkin.app zipped, now sending to Apple for notarization..."
xcrun notarytool submit Funkin.app.zip --issuer "$ISSUER_ID" --key-id "$key_id" --key "$key_path" --wait || {
echo "Notarization submission failed"
exit 1
}
# Clean up zip file
rm -rf Funkin.app.zip
echo "Stapling Funkin.app"
xcrun stapler staple Funkin.app || {
echo "Stapling failed"
exit 1
}
echo "Code sign information!"
codesign -dv --verbose=4 Funkin.app
echo "Notarization information (stapler):"
xcrun stapler validate Funkin.app || {
echo "Stapler validation failed"
exit 1
}
cd ../../.. || { echo "Failed to return to original directory"; exit 1; }
echo "Notarization complete! Funkin.app is now codesigned and notarized!"
+20
View File
@@ -0,0 +1,20 @@
#!/bin/sh
echo "Note! This should be run from the root of the main Funkin repo, after creating a universal macOS build!"
echo "This script will assist in creating a universal build of Funkin.app for macOS"
echo ""
lime build mac -64 -release
cd export/release
rm -rf macosUniversal
mkdir macosUniversal
cp -r macos/bin/Funkin.app macosUniversal
cd ../..
lime build mac -arm64 -release
cd export/release
cp -r macos/bin/Funkin.app/Contents/MacOS/Funkin macosUniversal/Funkin.app/Contents/MacOS/FunkinArm
cp -r macos/bin/Funkin.app/Contents/MacOS/lime.ndll macosUniversal/Funkin.app/Contents/MacOS/limeArm.ndll
cd macosUniversal/Funkin.app/Contents/MacOS
mv Funkin Funkin64
mv lime.ndll lime64.ndll
lipo -create -output lime.ndll lime64.ndll limeArm.ndll
lipo -create -output Funkin Funkin64 FunkinArm
rm FunkinArm Funkin64 lime64.ndll limeArm.ndll
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
# Find all files in PNG format and execute oxipng to optimize file sizes
cd ../assets/ && oxipng -o 6 --strip safe --alpha {} **/*.png
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
# Resize each health icon to 512x512
find "../art/discord/" -name "icon-*.png" -exec sh -c 'ffmpeg -i {} -vf scale=512:512 "${0%.*}2.png"' {} \;
+34 -20
View File
@@ -11,6 +11,8 @@ import funkin.util.logging.CrashHandler;
import funkin.ui.debug.FunkinDebugDisplay;
import funkin.ui.debug.FunkinDebugDisplay.DebugDisplayMode;
import funkin.save.Save;
import funkin.FunkinMemory;
import funkin.audio.FunkinSound;
#if hxvlc
import hxvlc.util.Handle;
#end
@@ -87,11 +89,28 @@ class Main extends Sprite
removeEventListener(Event.ADDED_TO_STAGE, init);
}
#if (!html5 && !mobile)
// Force-kill the game to prevent background processing.
openfl.Lib.application.onExit.add((_) ->
{
// Dispose of cached audio and textures.
funkin.audio.FunkinSound.stopAllAudio(true, true);
funkin.FunkinMemory.purgeCache(true);
// Dispose of any assets still in the OpenFL cache, just incase.
openfl.Assets.cache.clear();
trace(' EXITING '.bold().bg_red() + ' Resources are disposed, Game is closing now.');
Sys.exit(0);
}, 99);
#end
// Manually crash the game when using a software renderer in order to give a nicer error message.
var context = stage.window.context.type;
if (context != WEBGL && context != OPENGL && context != OPENGLES)
{
var tech:String = #if web "WebGL" #elseif desktop "OpenGL" #else "OpenGL ES" #end;
var tech:String = #if web 'WebGL' #elseif desktop 'OpenGL' #else 'OpenGL ES' #end;
var requiredVersion:String = #if web '$tech 1.0 or newer' #elseif desktop '$tech 3.0 or newer' #else '$tech 2.0 or newer' #end;
var desc:String = 'Failed to initialize the $tech rendering context!\n\n';
#if web
@@ -136,7 +155,8 @@ class Main extends Sprite
#if hxvlc
// Initialize hxvlc's Handle here so the videos are loading faster.
Handle.initAsync(function(success:Bool):Void {
Handle.initAsync(function(success:Bool):Void
{
if (success)
{
trace(' HXVLC '.bold().bg_orange() + ' LibVLC instance initialized!');
@@ -148,16 +168,15 @@ class Main extends Sprite
});
#end
// Don't call anything from the preferences until the save is loaded!
#if web
// set this variable (which is a function) from the lime version at lime/_internal/backend/html5/HTML5Application.hx
// The framerate cap will more thoroughly initialize via Preferences in InitState.hx
funkin.Preferences.lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame");
#end
WindowUtil.setVSyncMode(funkin.Preferences.vsyncMode);
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash,
// Force a `FunkinCamera` to be the default camera.
// This allows the blend mode shader to work everywhere.
untyped FlxG.cameras = new funkin.graphics.FunkinCameraFrontEnd();
var framerate:Int = Preferences.unlockedFramerate ? 0 : Preferences.framerate;
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash,
(FlxG.stage.window.fullscreen || Preferences.autoFullscreen));
// FlxG.game._customSoundTray wants just the class, it calls new from
@@ -169,7 +188,7 @@ class Main extends Sprite
addChild(game);
#if FEATURE_DEBUG_FUNCTIONS
game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil());
#if !FLX_NO_DEBUG game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil()); #end
funkin.util.macro.ConsoleMacro.init();
#end
@@ -231,14 +250,7 @@ class Main extends Sprite
function repositionCounters(lerp:Bool):Void
{
// Calling this so it gets scaled based on the resolution of the game and device's resolution.
var scale:Float = Math.min(FlxG.stage.stageWidth / FlxG.width, FlxG.stage.stageHeight / FlxG.height);
#if android
scale = Math.max(scale, 1);
#else
scale = Math.min(scale, 1);
#end
final thypos:Float = Math.max(FullScreenScaleMode.notchSize.x, 10);
var scale:Float = Math.max(Math.min(FlxG.stage.stageWidth / FlxG.width, FlxG.stage.stageHeight / FlxG.height), 1);
if (debugDisplay != null)
{
@@ -246,13 +258,15 @@ class Main extends Sprite
if (FlxG.game != null)
{
final thypos:Float = Math.max(FullScreenScaleMode.notchSize.x, 10);
if (lerp)
{
debugDisplay.x = flixel.math.FlxMath.lerp(debugDisplay.x, FlxG.game.x + thypos, FlxG.elapsed * 3);
}
else
{
debugDisplay.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10;
debugDisplay.x = FlxG.game.x + thypos;
}
debugDisplay.y = FlxG.game.y + (3 * scale);
+5 -10
View File
@@ -36,12 +36,7 @@ class Postbuild
static function format(time:Float, decimals:Int = 1):String
{
var units = [
{name: "day", secs: 86400},
{name: "hour", secs: 3600},
{name: "minute", secs: 60},
{name: "second", secs: 1}
];
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;
@@ -49,13 +44,13 @@ class Postbuild
for (u in units)
{
var value:Float = (u.name == "second") ? Math.round(remaining * factor) / factor : Math.floor(remaining / u.secs);
var value:Float = (u.name == 'second') ? Math.round(remaining * factor) / factor : Math.floor(remaining / u.secs);
if (u.name != "second") remaining %= u.secs;
if (u.name != 'second') remaining %= u.secs;
if (value > 0 || (u.name == "second" && parts.length == 0)) parts.push('${value} ${u.name}${value == 1 ? "" : "s"}');
if (value > 0 || (u.name == 'second' && parts.length == 0)) parts.push('${value} ${u.name}${value == 1 ? "" : "s"}');
}
return parts.join(" ");
return parts.join(' ');
}
}
+4 -2
View File
@@ -2,6 +2,8 @@ package source; // Yeah, I know...
import sys.io.File;
using tools.AnsiUtil;
/**
* A script which executes before the game is built.
*/
@@ -12,13 +14,13 @@ class Prebuild
static function main():Void
{
var start:Float = Sys.time();
// Sys.println('[INFO] Performing pre-build tasks...');
// Sys.println(' INFO '.bold().bg_blue() + " Performing pre-build tasks...");
saveBuildTime();
var end:Float = Sys.time();
var duration:Float = end - start;
// Sys.println('[INFO] Finished pre-build tasks in $duration seconds.');
// Sys.println(' INFO '.bold().bg_blue() + ' Finished pre-build tasks in $duration seconds.');
}
static function saveBuildTime():Void
+39 -48
View File
@@ -1,4 +1,4 @@
/*
/**
* Pulled from Tracey profiler PR
* @see https://github.com/HaxeFoundation/haxe/pull/11772
*/
@@ -6,7 +6,7 @@
package cpp.vm.tracy;
#if (!HXCPP_TRACY)
#error "This class cannot be used without -D HXCPP_TRACY"
#error 'This class cannot be used without -D HXCPP_TRACY'
#end
enum abstract PlotFormatType(cpp.UInt8) from cpp.UInt8 to cpp.UInt8
{
@@ -19,68 +19,68 @@ enum abstract PlotFormatType(cpp.UInt8) from cpp.UInt8 to cpp.UInt8
extern class Native_TracyProfiler
{
/**
Mark a frame. Call this at the end of each frame loop.
**/
* Mark a frame. Call this at the end of each frame loop.
*/
@:native('::__hxcpp_tracy_framemark')
public static function frameMark():Void;
/**
Mark a named frame. Allows creating multiple frame sets for different timing categories.
Each unique name creates a separate frame set in the Tracy timeline.
**/
* Mark a named frame. Allows creating multiple frame sets for different timing categories.
* Each unique name creates a separate frame set in the Tracy timeline.
*/
@:native('::__hxcpp_tracy_framemark_named')
public static function frameMarkNamed(_name:String):Void;
/**
Mark the start of a discontinuous frame. Use for periodic work with gaps.
Must be paired with frameMarkEnd() using the same name.
**/
* Mark the start of a discontinuous frame. Use for periodic work with gaps.
* Must be paired with frameMarkEnd() using the same name.
*/
@:native('::__hxcpp_tracy_framemark_start')
public static function frameMarkStart(_name:String):Void;
/**
Mark the end of a discontinuous frame. Use for periodic work with gaps.
Must be paired with frameMarkStart() using the same name.
**/
* Mark the end of a discontinuous frame. Use for periodic work with gaps.
* Must be paired with frameMarkStart() using the same name.
*/
@:native('::__hxcpp_tracy_framemark_end')
public static function frameMarkEnd(_name:String):Void;
/**
Print a message into Tracy's log.
**/
* Print a message into Tracy's log.
*/
@:native('::__hxcpp_tracy_message')
public static function message(_msg:String, ?_color:Int = 0x000000):Void;
/**
Tracy can collect additional information about the profiled application,
which will be available in the trace description.
This can include data such as the source repository revision,
the application’s environment (dev/prod), etc.
**/
* Tracy can collect additional information about the profiled application,
* which will be available in the trace description.
* This can include data such as the source repository revision,
* the application’s environment (dev/prod), etc.
*/
@:native('::__hxcpp_tracy_message_app_info')
public static function messageAppInfo(_info:String):Void;
/**
Plot a named value to tracy. This will generate a graph in the profiler for you.
**/
* Plot a named value to tracy. This will generate a graph in the profiler for you.
*/
@:native('::__hxcpp_tracy_plot')
public static function plot(_name:String, _val:cpp.Float32):Void;
/**
Configure how values are plotted and displayed.
**/
* Configure how values are plotted and displayed.
*/
@:native('::__hxcpp_tracy_plot_config')
public static function plotConfig(_name:String, _format:PlotFormatType, ?_step:Bool = false, ?_fill:Bool = false, ?_color:Int = 0x000000):Void;
/**
Set a name for the current thread this function is called in. Supply an optional groupHint so threads become grouped in Tracy's UI.
**/
* Set a name for the current thread this function is called in. Supply an optional groupHint so threads become grouped in Tracy's UI.
*/
@:native('::__hxcpp_tracy_set_thread_name_and_group')
public static function setThreadName(_name:String, ?_groupHint:Int = 1):Void;
/**
Create a custom named scoped zone in your code.
**/
* Create a custom named scoped zone in your code.
*/
@:native('HXCPP_TRACY_ZONE')
public static function zoneScoped(_name:String):Void;
}
@@ -89,44 +89,35 @@ extern class Native_TracyProfiler
class Cppia_TracyProfiler
{
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMark)
public static function frameMark()
Native_TracyProfiler.frameMark();
public static function frameMark() Native_TracyProfiler.frameMark();
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMarkNamed)
public static function frameMarkNamed(_name:String)
Native_TracyProfiler.frameMarkNamed(_name);
public static function frameMarkNamed(_name:String) Native_TracyProfiler.frameMarkNamed(_name);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMarkStart)
public static function frameMarkStart(_name:String)
Native_TracyProfiler.frameMarkStart(_name);
public static function frameMarkStart(_name:String) Native_TracyProfiler.frameMarkStart(_name);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMarkEnd)
public static function frameMarkEnd(_name:String)
Native_TracyProfiler.frameMarkEnd(_name);
public static function frameMarkEnd(_name:String) Native_TracyProfiler.frameMarkEnd(_name);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.message)
public static function message(_msg:String, ?_color:Int = 0x000000)
Native_TracyProfiler.message(_msg, _color);
public static function message(_msg:String, ?_color:Int = 0x000000) Native_TracyProfiler.message(_msg, _color);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.messageAppInfo)
public static function messageAppInfo(_info:String)
Native_TracyProfiler.messageAppInfo(_info);
public static function messageAppInfo(_info:String) Native_TracyProfiler.messageAppInfo(_info);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.plot)
public static function plot(_name:String, _val:Float)
Native_TracyProfiler.plot(_name, _val);
public static function plot(_name:String, _val:Float) Native_TracyProfiler.plot(_name, _val);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.plotConfig)
public static function plotConfig(_name:String, _format:PlotFormatType, ?_step:Bool = false, ?_fill:Bool = false, ?_color:Int = 0x000000)
Native_TracyProfiler.plotConfig(_name, _format, _step, _fill, _color);
public static function plotConfig(_name:String, _format:PlotFormatType, ?_step:Bool = false, ?_fill:Bool = false,
?_color:Int = 0x000000) Native_TracyProfiler.plotConfig(_name, _format, _step, _fill, _color);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.setThreadName)
public static function setThreadName(_name:String, ?_groupHint:Int = 1)
Native_TracyProfiler.setThreadName(_name, _groupHint);
public static function setThreadName(_name:String, ?_groupHint:Int = 1) Native_TracyProfiler.setThreadName(_name, _groupHint);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.zoneScoped)
public static function zoneScoped(_name:String)
Native_TracyProfiler.zoneScoped(_name);
public static function zoneScoped(_name:String) Native_TracyProfiler.zoneScoped(_name);
}
typedef TracyProfiler = Cppia_TracyProfiler;
+13 -7
View File
@@ -362,7 +362,7 @@ class Conductor
static function get_instance():Conductor
{
if (Conductor._instance == null) set_instance(new Conductor());
if (Conductor._instance == null) throw "Could not initialize singleton Conductor!";
if (Conductor._instance == null) throw 'Could not initialize singleton Conductor!';
return Conductor._instance;
}
@@ -381,7 +381,9 @@ class Conductor
/**
* The constructor.
*/
public function new() {}
public function new()
{
}
/**
* Forcibly defines the current BPM of the song.
@@ -847,7 +849,7 @@ class Conductor
* @param type The type of length to return. Either "step", "beat", or "measure" works, along with their first character.
* @return The length of a step/beat/measure in milliseconds.
*/
public function getTypeLengthAtMs(ms:Float, type:String = "beat"):Float
public function getTypeLengthAtMs(ms:Float, type:String = 'beat'):Float
{
if (timeChanges.length == 0) return 0;
var wantedTimeChange:SongTimeChange = timeChanges[0];
@@ -866,10 +868,14 @@ class Conductor
var wantedBeatLengthMs:Float = ((Constants.SECS_PER_MIN / wantedTimeChange.bpm) * Constants.MS_PER_SEC) * (4 / wantedTimeChange.timeSignatureDen);
return switch (type.toLowerCase())
{
case "measure", "m": wantedBeatLengthMs * wantedTimeChange.timeSignatureNum;
case "beat", "b": wantedBeatLengthMs;
case "step", "s": wantedBeatLengthMs / Constants.STEPS_PER_BEAT;
default: wantedBeatLengthMs;
case 'measure', 'm':
wantedBeatLengthMs * wantedTimeChange.timeSignatureNum;
case 'beat', 'b':
wantedBeatLengthMs;
case 'step', 's':
wantedBeatLengthMs / Constants.STEPS_PER_BEAT;
default:
wantedBeatLengthMs;
}
}
+131 -100
View File
@@ -12,7 +12,7 @@ import lime.app.Promise;
/**
* Handles caching of textures and sounds for the game.
* TODO: Remove this once Eric finishes the memory system.
* I did this hello, this can be improved later on and I have ideas on how, but for now this functions well enough. -Zack
*/
@:nullSafety
class FunkinMemory
@@ -20,13 +20,10 @@ class FunkinMemory
static var permanentCachedTextures:Map<String, FlxGraphic> = [];
static var currentCachedTextures:Map<String, FlxGraphic> = [];
static var previousCachedTextures:Map<String, FlxGraphic> = [];
// waow
static var permanentCachedSounds:Map<String, Sound> = [];
static var currentCachedSounds:Map<String, Sound> = [];
static var previousCachedSounds:Map<String, Sound> = [];
static var purgeFilter:Array<String> = ["/week", "/characters", "/charSelect", "/results"];
static var purgeFilter:Array<String> = ['/week', '/characters', '/charSelect', '/results'];
/**
* Caches textures that are always required.
@@ -37,42 +34,42 @@ class FunkinMemory
for (file in allImages)
{
if (!(file.endsWith(".png") #if FEATURE_COMPRESSED_TEXTURES || file.endsWith(".astc") #end)
|| file.contains("chart-editor")
|| !file.contains("ui/"))
if (!(file.endsWith('.png') #if FEATURE_COMPRESSED_TEXTURES || file.endsWith('.astc') #end)
|| file.contains('chart-editor')
|| !file.contains('ui/'))
{
continue;
}
file = file.replace(" ", ""); // Handle stray spaces.
file = file.replace(' ', ''); // Handle stray spaces.
if (file.contains("shared") || Assets.exists('shared:$file', AssetType.IMAGE))
if (file.contains('shared') || Assets.exists('shared:$file', AssetType.IMAGE))
{
file = 'shared:$file';
}
permanentCacheTexture(file);
}
permanentCacheTexture(Paths.image("healthBar"));
permanentCacheTexture(Paths.image("menuDesat"));
permanentCacheTexture(Paths.image("notes", "shared"));
permanentCacheTexture(Paths.image("noteSplashes", "shared"));
permanentCacheTexture(Paths.image("noteStrumline", "shared"));
permanentCacheTexture(Paths.image("NOTE_hold_assets"));
permanentCacheTexture(Paths.image('healthBar'));
permanentCacheTexture(Paths.image('menuDesat'));
permanentCacheTexture(Paths.image('notes', 'shared'));
permanentCacheTexture(Paths.image('noteSplashes', 'shared'));
permanentCacheTexture(Paths.image('noteStrumline', 'shared'));
permanentCacheTexture(Paths.image('NOTE_hold_assets'));
// dude
permanentCacheTexture(Paths.image("fonts/bold", null));
permanentCacheTexture(Paths.image("fonts/default", null));
permanentCacheTexture(Paths.image("fonts/freeplay-clear", null));
permanentCacheTexture(Paths.image('fonts/bold', null));
permanentCacheTexture(Paths.image('fonts/default', null));
permanentCacheTexture(Paths.image('fonts/freeplay-clear', null));
var allSounds:Array<String> = Assets.list(AssetType.SOUND);
for (file in allSounds)
{
if (!file.endsWith(".ogg") || !file.contains("countdown/")) continue;
if (!file.endsWith('.ogg') || !file.contains('countdown/')) continue;
file = file.replace(" ", "");
file = file.replace(' ', '');
if (file.contains("shared") || Assets.exists('shared:$file', AssetType.SOUND))
if (file.contains('shared') || Assets.exists('shared:$file', AssetType.SOUND))
{
file = 'shared:$file';
}
@@ -80,26 +77,29 @@ class FunkinMemory
permanentCacheSound(file);
}
permanentCacheSound(Paths.sound("cancelMenu"));
permanentCacheSound(Paths.sound("confirmMenu"));
permanentCacheSound(Paths.sound("screenshot"));
permanentCacheSound(Paths.sound("scrollMenu"));
permanentCacheSound(Paths.sound("soundtray/Voldown"));
permanentCacheSound(Paths.sound("soundtray/VolMAX"));
permanentCacheSound(Paths.sound("soundtray/Volup"));
permanentCacheSound(Paths.music("freakyMenu/freakyMenu"));
permanentCacheSound(Paths.music("offsetsLoop/offsetsLoop"));
permanentCacheSound(Paths.music("offsetsLoop/drumsLoop"));
permanentCacheSound(Paths.sound("missnote1", "shared"));
permanentCacheSound(Paths.sound("missnote2", "shared"));
permanentCacheSound(Paths.sound("missnote3", "shared"));
permanentCacheSound(Paths.sound('cancelMenu'));
permanentCacheSound(Paths.sound('confirmMenu'));
permanentCacheSound(Paths.sound('screenshot'));
permanentCacheSound(Paths.sound('scrollMenu'));
permanentCacheSound(Paths.sound('soundtray/Voldown'));
permanentCacheSound(Paths.sound('soundtray/VolMAX'));
permanentCacheSound(Paths.sound('soundtray/Volup'));
permanentCacheSound(Paths.music('freakyMenu/freakyMenu'));
permanentCacheSound(Paths.music('offsetsLoop/offsetsLoop'));
permanentCacheSound(Paths.music('offsetsLoop/drumsLoop'));
permanentCacheSound(Paths.sound('missnote1', 'shared'));
permanentCacheSound(Paths.sound('missnote2', 'shared'));
permanentCacheSound(Paths.sound('missnote3', 'shared'));
}
/**
* Clears the current texture and sound caches.
* @param callGarbageCollector Whether to call the system's garbage collector after purging.
*/
public static inline function purgeCache(callGarbageCollector:Bool = false):Void
{
trace(' CLEARING CACHE '.bg_bright_lilac().bold() + ' Disposing all cached textures, assets and sounds...');
preparePurgeTextureCache();
purgeTextureCache();
preparePurgeSoundCache();
@@ -111,16 +111,6 @@ class FunkinMemory
///// TEXTURES /////
/**
* Determine whether the texture with the given key is cached.
* @param key The key of the texture to check.
* @return Whether the texture is cached.
*/
public static function isTextureCached(key:String):Bool
{
return FlxG.bitmap.get(key) != null;
}
/**
* Ensures a texture with the given key is cached.
* @param key The key of the texture to cache.
@@ -173,30 +163,6 @@ class FunkinMemory
currentCachedTextures = permanentCachedTextures.copy();
}
/**
* 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);
@@ -209,7 +175,7 @@ class FunkinMemory
/**
* Prepares the cache for purging unused textures.
*/
public inline static function preparePurgeTextureCache():Void
public static inline function preparePurgeTextureCache():Void
{
previousCachedTextures = currentCachedTextures.copy();
@@ -237,7 +203,7 @@ class FunkinMemory
continue;
}
if (graphicKey.contains("fonts")) continue;
if (graphicKey.contains('fonts')) continue;
var graphic:Null<FlxGraphic> = previousCachedTextures.get(graphicKey);
if (graphic != null)
@@ -261,7 +227,7 @@ class FunkinMemory
{
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
if (obj == null || (obj.persist && permanentCachedTextures.exists(key)) || key.contains("fonts"))
if (obj == null || (obj.persist && permanentCachedTextures.exists(key)) || key.contains('fonts'))
{
continue;
}
@@ -281,35 +247,69 @@ class FunkinMemory
}
}
/**
* Forces the GPU to load and upload a FlxGraphic.
* @param graphic The graphic to force render.
*/
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();
}
/**
* Determine whether the texture with the given key is cached.
* @param key The key of the texture to check.
* @return Whether the texture is cached.
*/
public static function isTextureCached(key:String):Bool
{
return FlxG.bitmap.get(key) != null
&& (permanentCachedTextures.exists(key) || currentCachedTextures.exists(key) || previousCachedTextures.exists(key));
}
///// NOTE STYLE //////
/**
* Caches all assets for the given note style.
* @param style The note style to cache.
*/
public static function cacheNoteStyle(style:NoteStyle):Void
{
// TODO: Texture paths should fall back to the default values.
cacheTexture(Paths.image(style.getNoteAssetPath() ?? "note"));
cacheTexture(style.getHoldNoteAssetPath() ?? "noteHold");
cacheTexture(Paths.image(style.getStrumlineAssetPath() ?? "strumline"));
cacheTexture(Paths.image(style.getSplashAssetPath() ?? "noteSplash"));
cacheTexture(Paths.image(style.getNoteAssetPath() ?? 'note'));
cacheTexture(style.getHoldNoteAssetPath() ?? 'noteHold');
cacheTexture(Paths.image(style.getStrumlineAssetPath() ?? 'strumline'));
cacheTexture(Paths.image(style.getSplashAssetPath() ?? 'noteSplash'));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(LEFT) ?? "LEFT"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(RIGHT) ?? "RIGHT"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(UP) ?? "UP"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(DOWN) ?? "DOWN"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(LEFT) ?? 'LEFT'));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(RIGHT) ?? 'RIGHT'));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(UP) ?? 'UP'));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(DOWN) ?? 'DOWN'));
// cacheTexture(Paths.image(style.buildCountdownSpritePath(THREE) ?? "THREE"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(TWO) ?? "TWO"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(ONE) ?? "ONE"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(GO) ?? "GO"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(TWO) ?? 'TWO'));
cacheTexture(Paths.image(style.buildCountdownSpritePath(ONE) ?? 'ONE'));
cacheTexture(Paths.image(style.buildCountdownSpritePath(GO) ?? 'GO'));
cacheSound(style.getCountdownSoundPath(THREE) ?? "THREE");
cacheSound(style.getCountdownSoundPath(TWO) ?? "TWO");
cacheSound(style.getCountdownSoundPath(ONE) ?? "ONE");
cacheSound(style.getCountdownSoundPath(GO) ?? "GO");
cacheSound(style.getCountdownSoundPath(THREE) ?? 'THREE');
cacheSound(style.getCountdownSoundPath(TWO) ?? 'TWO');
cacheSound(style.getCountdownSoundPath(ONE) ?? 'ONE');
cacheSound(style.getCountdownSoundPath(GO) ?? 'GO');
cacheTexture(Paths.image(style.buildJudgementSpritePath("sick") ?? 'sick'));
cacheTexture(Paths.image(style.buildJudgementSpritePath("good") ?? 'good'));
cacheTexture(Paths.image(style.buildJudgementSpritePath("bad") ?? 'bad'));
cacheTexture(Paths.image(style.buildJudgementSpritePath("shit") ?? 'shit'));
cacheTexture(Paths.image(style.buildJudgementSpritePath('sick') ?? 'sick'));
cacheTexture(Paths.image(style.buildJudgementSpritePath('good') ?? 'good'));
cacheTexture(Paths.image(style.buildJudgementSpritePath('bad') ?? 'bad'));
cacheTexture(Paths.image(style.buildJudgementSpritePath('shit') ?? 'shit'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(0) ?? '0'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(1) ?? '1'));
@@ -325,6 +325,10 @@ class FunkinMemory
///// SOUND //////
/**
* Caches a sound with the given key.
* @param key The key of the sound to cache.
*/
public static function cacheSound(key:String):Void
{
if (currentCachedSounds.exists(key)) return;
@@ -339,23 +343,40 @@ class FunkinMemory
}
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound == null) return;
if (sound == null)
{
return;
}
else
{
currentCachedSounds.set(key, sound);
}
}
/**
* Permanently caches a sound with the given key.
* @param key The key of the sound to cache.
*/
public static function permanentCacheSound(key:String):Void
{
if (permanentCachedSounds.exists(key)) return;
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound == null) return;
if (sound == null)
{
return;
}
else
{
permanentCachedSounds.set(key, sound);
}
if (sound != null) currentCachedSounds.set(key, sound);
}
/**
* Prepares the cache for purging unused sounds.
*/
public static function preparePurgeSoundCache():Void
{
previousCachedSounds = currentCachedSounds.copy();
@@ -391,10 +412,10 @@ class FunkinMemory
previousCachedSounds.remove(key);
}
}
Assets.cache.clear("songs");
Assets.cache.clear("music");
Assets.cache.clear('songs');
Assets.cache.clear('music');
// Felt lazy.
var key = Paths.music("freakyMenu/freakyMenu");
var key = Paths.music('freakyMenu/freakyMenu');
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound != null)
{
@@ -405,6 +426,9 @@ class FunkinMemory
///// MISC /////
/**
* Clears all Freeplay assets from memory.
*/
public static inline function clearFreeplay():Void
{
var keysToRemove:Array<String> = [];
@@ -412,8 +436,8 @@ class FunkinMemory
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
if (!key.contains("freeplay")) continue;
if (permanentCachedTextures.exists(key) || key.contains("fonts")) continue;
if (!key.contains('freeplay')) continue;
if (permanentCachedTextures.exists(key) || key.contains('fonts')) continue;
keysToRemove.push(key);
}
@@ -436,6 +460,9 @@ class FunkinMemory
purgeSoundCache();
}
/**
* Clears all sticker assets from memory.
*/
public static inline function clearStickers():Void
{
var keysToRemove:Array<String> = [];
@@ -443,8 +470,8 @@ class FunkinMemory
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
if (!key.contains("stickers")) continue;
if (permanentCachedTextures.exists(key) || key.contains("fonts")) continue;
if (!key.contains('stickers')) continue;
if (permanentCachedTextures.exists(key) || key.contains('fonts')) continue;
keysToRemove.push(key);
}
@@ -464,6 +491,10 @@ class FunkinMemory
}
}
/**
* Sends a trace with fancy ANSI colors.
* @param message The message to log.
*/
static function log(message:String):Void
{
trace(' MEMORY '.bg_bright_lilac().bold() + ' ${message}');
+13 -16
View File
@@ -49,20 +49,19 @@ abstract Tallies(RawTallies)
{
public function new()
{
this =
{
combo: 0,
missed: 0,
shit: 0,
bad: 0,
good: 0,
sick: 0,
totalNotes: 0,
totalNotesHit: 0,
maxCombo: 0,
score: 0,
isNewHighscore: false
}
this = {
combo: 0,
missed: 0,
shit: 0,
bad: 0,
good: 0,
sick: 0,
totalNotes: 0,
totalNotesHit: 0,
maxCombo: 0,
score: 0,
isNewHighscore: false
}
}
}
@@ -83,9 +82,7 @@ typedef RawTallies =
var good:Int;
var sick:Int;
var maxCombo:Int;
var score:Int;
var isNewHighscore:Bool;
/**
+101 -74
View File
@@ -10,7 +10,6 @@ import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.system.debug.log.LogStyle;
import flixel.util.FlxColor;
import funkin.graphics.FunkinSprite;
import funkin.data.dialogue.ConversationRegistry;
import funkin.data.dialogue.DialogueBoxRegistry;
import funkin.data.dialogue.SpeakerRegistry;
@@ -20,6 +19,7 @@ import funkin.data.freeplay.style.FreeplayStyleRegistry;
import funkin.data.notestyle.NoteStyleRegistry;
import funkin.data.song.SongRegistry;
import funkin.data.stickers.StickerRegistry;
import funkin.play.event.SongEventHelper;
import funkin.data.event.SongEventRegistry;
import funkin.data.stage.StageRegistry;
import funkin.data.story.level.LevelRegistry;
@@ -66,7 +66,7 @@ class InitState extends FlxState
/**
* Perform a bunch of game setup, then immediately transition to the title screen.
*/
public override function create():Void
override public function create():Void
{
// Setup a bunch of important Flixel stuff.
setupShit();
@@ -124,6 +124,11 @@ class InitState extends FlxState
funkin.mobile.util.WebViewUtil.init();
#end
#if FEATURE_MOBILE_AGESIGNALS
// Setup AgeSignals
funkin.mobile.util.AgeSignalsUtil.init();
#end
#if android
// Setup Callback util.
funkin.external.android.CallbackUtil.init();
@@ -136,9 +141,11 @@ class InitState extends FlxState
#if mobile
// Setup Mobile FNFC launcher.
funkin.mobile.util.FNFCUtil.init();
funkin.mobile.util.FNFCProvider.init();
#end
SongEventHelper.generateEaseGraphsBitmaps();
// This ain't a pixel art game! (most of the time)
FlxSprite.defaultAntialiasing = true;
@@ -185,7 +192,8 @@ class InitState extends FlxState
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));
FlxG.signals.gameResized.add(function(width:Int, height:Int) {
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,
@@ -196,10 +204,12 @@ class InitState extends FlxState
// 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() {
FlxG.signals.focusLost.add(function()
{
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
FlxG.signals.focusGained.add(function() {
FlxG.signals.focusGained.add(function()
{
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
#end
@@ -215,9 +225,13 @@ class InitState extends FlxState
// DISCORD API SETUP
//
#if FEATURE_DISCORD_RPC
DiscordClient.instance.init();
if (Preferences.enabledDiscordRPC)
{
DiscordClient.instance.init();
}
lime.app.Application.current.onExit.add(function(exitCode) {
lime.app.Application.current.onExit.add(function(exitCode)
{
DiscordClient.instance.shutdown();
});
#end
@@ -230,7 +244,9 @@ class InitState extends FlxState
// ANDROID SETUP
//
#if android
FlxG.android.preventDefaultKeys = [flixel.input.android.FlxAndroidKey.BACK];
FlxG.android.preventDefaultKeys = [
flixel.input.android.FlxAndroidKey.BACK
];
#end
//
@@ -302,22 +318,38 @@ class InitState extends FlxState
}
#if FEATURE_LOST_FOCUS_VOLUME
@:noCompletion var _lastFocusVolume:Null<Float>;
@:noCompletion
var _lastFocusVolume:Null<Float>;
function onLostFocus()
function onLostFocus():Void
{
if (FlxG.sound.muted || FlxG.sound.volume == 0 || FlxG.autoPause) return;
_lastFocusVolume = FlxG.sound.volume;
FlxG.sound.volume *= Constants.LOST_FOCUS_VOLUME_MULTIPLIER;
}
function onGainFocus()
{
if (FlxG.sound.muted || FlxG.autoPause) return;
if (_lastFocusVolume != null) FlxG.sound.volume = _lastFocusVolume;
}
#end
function onGainFocus():Void
{
#if !mobile
if (Preferences.unlockedFramerate)
{
FlxG.updateFramerate = 0;
FlxG.drawFramerate = 0;
}
else
{
FlxG.updateFramerate = Preferences.framerate;
FlxG.drawFramerate = Preferences.framerate;
}
#end
#if FEATURE_LOST_FOCUS_VOLUME
if (FlxG.sound.muted || FlxG.sound.volume == 0 || FlxG.autoPause) return;
if (_lastFocusVolume != null) FlxG.sound.volume = _lastFocusVolume;
#end
}
/**
* Start the game.
*
@@ -359,37 +391,34 @@ class InitState extends FlxState
FlxG.switchState(() -> new funkin.ui.debug.stage.StageBuilderState());
#elseif RESULTS
// -DRESULTS
FlxG.switchState(() -> new funkin.play.ResultState(
{
storyMode: true,
title: "Cum Song Erect by Kawai Sprite",
songId: "cum",
characterId: "pico",
difficultyId: "hard",
isNewHighscore: true,
scoreData:
{
score: 1_234_567,
tallies:
{
sick: 130,
good: 60,
bad: 69,
shit: 69,
missed: 69,
combo: 69,
maxCombo: 69,
totalNotesHit: 140,
totalNotes: 240
}
// 2400 total notes = 7% = LOSS
// 275 total notes = 69% = NICE
// 240 total notes = 79% = GOOD
// 230 total notes = 82% = GREAT
// 210 total notes = 91% = EXCELLENT
// 190 total notes = PERFECT
},
}));
FlxG.switchState(() -> new funkin.play.ResultState({
storyMode: true,
title: 'Cum Song Erect by Kawai Sprite',
songId: 'cum',
characterId: 'pico',
difficultyId: 'hard',
isNewHighscore: true,
scoreData: {
score: 1_234_567,
tallies: {
sick: 130,
good: 60,
bad: 69,
shit: 69,
missed: 69,
combo: 69,
maxCombo: 69,
totalNotesHit: 140,
totalNotes: 240
}
// 2400 total notes = 7% = LOSS
// 275 total notes = 69% = NICE
// 240 total notes = 79% = GOOD
// 230 total notes = 82% = GREAT
// 210 total notes = 91% = EXCELLENT
// 190 total notes = PERFECT
},
}));
#elseif ANIMDEBUG
// -DANIMDEBUG
FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState());
@@ -407,15 +436,13 @@ class InitState extends FlxState
function startGameNormally():Void
{
var params:CLIParams = CLIUtil.processArgs();
trace('Command line args: ${params}');
if (params.chart.shouldLoadChart)
{
#if FEATURE_CHART_EDITOR
FlxG.switchState(() -> new ChartEditorState(
{
fnfcTargetPath: params.chart.chartPath,
}));
FlxG.switchState(() -> new ChartEditorState({
fnfcTargetPath: params.chart.chartPath,
}));
#else
FlxG.switchState(() -> new TitleState());
#end
@@ -423,10 +450,9 @@ class InitState extends FlxState
else if (params.stage.shouldLoadStage)
{
#if FEATURE_STAGE_EDITOR
FlxG.switchState(() -> new StageEditorState(
{
fnfsTargetPath: params.stage.stagePath,
}));
FlxG.switchState(() -> new StageEditorState({
fnfsTargetPath: params.stage.stagePath,
}));
#else
FlxG.switchState(() -> new TitleState());
#end
@@ -441,9 +467,9 @@ class InitState extends FlxState
}
else
{
// FlxG.sound.cache(Paths.music('freakyMenu/freakyMenu'));
#if mobile
funkin.mobile.util.FNFCUtil.onFNFCOpen.add(function(fnfcFile:String) {
funkin.mobile.util.FNFCProvider.onFNFCOpen.add(function(fnfcFile:String)
{
flixel.tweens.FlxTween.globalManager.clear();
flixel.util.FlxTimer.globalManager.clear();
@:nullSafety(Off)
@@ -456,7 +482,7 @@ class InitState extends FlxState
FlxG.switchState(() -> new ChartPlaytestMenu(fnfcFile));
});
final fnfcFile = funkin.mobile.util.FNFCUtil.queryFNFC();
final fnfcFile = funkin.mobile.util.FNFCProvider.queryFNFC();
if (fnfcFile != null)
{
trace('launching FNFC from $fnfcFile');
@@ -517,11 +543,10 @@ class InitState extends FlxState
}
@:nullSafety(Off) // Cannot unify?
LoadingState.loadPlayState(
{
targetSong: songData,
targetDifficulty: difficultyId,
});
LoadingState.loadPlayState({
targetSong: songData,
targetDifficulty: difficultyId,
});
}
/**
@@ -560,11 +585,10 @@ class InitState extends FlxState
}
@:nullSafety(Off)
LoadingState.loadPlayState(
{
targetSong: targetSong,
targetDifficulty: difficultyId,
});
LoadingState.loadPlayState({
targetSong: targetSong,
targetDifficulty: difficultyId,
});
}
@:nullSafety(Off) // Meh, remove when flixel.system.debug.log.LogStyle is null safe
@@ -573,7 +597,7 @@ class InitState extends FlxState
//
// FLIXEL DEBUG SETUP
//
#if FEATURE_DEBUG_FUNCTIONS
#if (FEATURE_DEBUG_FUNCTIONS && !FLX_NO_DEBUG)
trace('Initializing Flixel debugger...');
#if !debug
@@ -592,7 +616,8 @@ class InitState extends FlxState
// Adds a red button to the debugger.
// This pauses the game AND the music! This ensures the Conductor stops.
FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFFCC2233), function() {
FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFFCC2233), function()
{
if (FlxG.vcr.paused)
{
FlxG.vcr.resume();
@@ -619,7 +644,8 @@ class InitState extends FlxState
// Adds a blue button to the debugger.
// This skips forward in the song.
FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFF2222CC), function() {
FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFF2222CC), function()
{
FlxG.game.debugger.vcr.onStep();
for (snd in FlxG.sound.list)
@@ -636,7 +662,8 @@ class InitState extends FlxState
// This big obnoxious white button is for MOBILE, so that you can press it
// easily with your finger when debug bullshit pops up during testing lol!
#if mobile
FlxG.debugger.addButton(LEFT, new BitmapData(200, 200), function() {
FlxG.debugger.addButton(LEFT, new BitmapData(200, 200), function()
{
FlxG.debugger.visible = false;
// Make errors and warnings less annoying.
+20 -21
View File
@@ -107,7 +107,7 @@ class Paths implements ConsoleClass
return getPath('data/$key.json', TEXT, library);
}
public static function srt(key:String, ?library:String, ?directory:String = "data/"):String
public static function srt(key:String, ?library:String, ?directory:String = 'data/'):String
{
return getPath('$directory$key.srt', TEXT, library);
}
@@ -181,10 +181,10 @@ class Paths implements ConsoleClass
public static function getAnimateAtlas(key:String, ?library:String, settings:AtlasSpriteSettings):FlxAnimateFrames
{
var assetLibrary:String = library ?? "";
var graphicKey:String = "";
var assetLibrary:String = library ?? '';
var graphicKey:String = '';
if (assetLibrary != "")
if (assetLibrary != '')
{
graphicKey = Paths.animateAtlas(key, assetLibrary);
}
@@ -193,19 +193,18 @@ class Paths implements ConsoleClass
graphicKey = Paths.animateAtlas(key);
}
var validatedSettings:AtlasSpriteSettings =
{
swfMode: settings?.swfMode ?? false,
cacheOnLoad: settings?.cacheOnLoad ?? false,
filterQuality: settings?.filterQuality ?? MEDIUM,
spritemaps: settings?.spritemaps ?? null,
metadataJson: settings?.metadataJson ?? null,
cacheKey: settings?.cacheKey ?? null,
uniqueInCache: settings?.uniqueInCache ?? false,
onSymbolCreate: settings?.onSymbolCreate ?? null,
applyStageMatrix: settings?.applyStageMatrix ?? false,
useRenderTexture: settings?.useRenderTexture ?? false
};
var validatedSettings:AtlasSpriteSettings = {
swfMode: settings?.swfMode ?? false,
cacheOnLoad: settings?.cacheOnLoad ?? false,
filterQuality: settings?.filterQuality ?? MEDIUM,
spritemaps: settings?.spritemaps ?? null,
metadataJson: settings?.metadataJson ?? null,
cacheKey: settings?.cacheKey ?? null,
uniqueInCache: settings?.uniqueInCache ?? false,
onSymbolCreate: settings?.onSymbolCreate ?? null,
applyStageMatrix: settings?.applyStageMatrix ?? false,
useRenderTexture: settings?.useRenderTexture ?? false
};
// Validate asset path.
if (!Assets.exists('${graphicKey}/Animation.json'))
@@ -230,8 +229,8 @@ class Paths implements ConsoleClass
enum abstract PathsFunction(String)
{
var MUSIC;
var INST;
var VOICES;
var SOUND;
public var MUSIC;
public var INST;
public var VOICES;
public var SOUND;
}
+7 -5
View File
@@ -21,7 +21,6 @@ class PlayerSettings
public static var player1(default, null):PlayerSettings;
@:nullSafety(Off)
public static var player2(default, null):PlayerSettings;
public static var onAvatarAdd(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
public static var onAvatarRemove(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
@@ -45,9 +44,12 @@ class PlayerSettings
{
return switch (id)
{
case 1: player1;
case 2: player2;
default: null;
case 1:
player1;
case 2:
player2;
default:
null;
};
}
@@ -98,7 +100,7 @@ class PlayerSettings
*/
function new(id:Int)
{
trace('loading player settings for id: $id');
trace('Loading player settings for id: $id');
this.id = id;
this.controls = new Controls('player$id', None);
+100 -45
View File
@@ -8,6 +8,9 @@ import funkin.save.Save;
import funkin.util.WindowUtil;
import funkin.util.HapticUtil.HapticsMode;
import funkin.ui.debug.FunkinDebugDisplay.DebugDisplayMode;
#if FEATURE_DISCORD_RPC
import funkin.api.discord.DiscordClient;
#end
/**
* A core class which provides a store of user-configurable, globally relevant values.
@@ -41,12 +44,23 @@ class Preferences
{
#if web
return 60;
#elseif mobile
var refreshRate:Int = FlxG.stage.window.displayMode.refreshRate;
if (refreshRate < 60) refreshRate = 60;
return refreshRate;
#else
var save:Save = Save.instance;
save.options.framerate = value;
Save.system.flush();
FlxG.updateFramerate = value;
FlxG.drawFramerate = value;
if (!unlockedFramerate)
{
FlxG.updateFramerate = value;
FlxG.drawFramerate = value;
}
return value;
#end
}
@@ -69,13 +83,13 @@ class Preferences
static function set_naughtyness(value:Bool):Bool
{
#if NO_FEATURE_NAUGHTYNESS
value = false;
#end
return false;
#else
var save:Save = Save.instance;
save.options.naughtyness = value;
Save.system.flush();
return value;
#end
}
/**
@@ -146,19 +160,23 @@ class Preferences
{
#if NO_FEATURE_DEBUG_DISPLAY
return DebugDisplayMode.Off;
#end
#else
return Save?.instance?.options?.debugDisplay ?? 'Off';
#end
}
static function set_debugDisplay(value:DebugDisplayMode):DebugDisplayMode
{
#if NO_FEATURE_DEBUG_DISPLAY
return DebugDisplayMode.Off;
#else
if (value != Save.instance.options.debugDisplay) setDebugDisplayMode(value);
var save = Save.instance;
save.options.debugDisplay = value;
Save.system.flush();
return value;
#end
}
/**
@@ -190,13 +208,13 @@ class Preferences
static function get_hapticsMode():HapticsMode
{
var value = Save?.instance?.options?.hapticsMode ?? "All";
var value = Save?.instance?.options?.hapticsMode ?? 'All';
return switch (value)
{
case "None":
case 'None':
HapticsMode.NONE;
case "Notes Only":
case 'Notes Only':
HapticsMode.NOTES_ONLY;
default:
HapticsMode.ALL;
@@ -210,11 +228,11 @@ class Preferences
switch (value)
{
case HapticsMode.NONE:
string = "None";
string = 'None';
case HapticsMode.NOTES_ONLY:
string = "Notes Only";
string = 'Notes Only';
default:
string = "All";
string = 'All';
};
var save:Save = Save.instance;
@@ -253,18 +271,23 @@ class Preferences
{
#if mobile
return false;
#end
#else
return Save?.instance?.options?.autoPause ?? true;
#end
}
static function set_autoPause(value:Bool):Bool
{
#if mobile
return false;
#else
if (value != Save.instance.options.autoPause) FlxG.autoPause = value;
var save:Save = Save.instance;
save.options.autoPause = value;
Save.system.flush();
return value;
#end
}
/**
@@ -314,35 +337,42 @@ class Preferences
static function get_vsyncMode():lime.ui.WindowVSyncMode
{
var value = Save?.instance?.options?.vsyncMode ?? "Off";
#if (mobile || web)
return lime.ui.WindowVSyncMode.OFF;
#else
var value = Save?.instance?.options?.vsyncMode ?? 'Off';
return switch (value)
{
case "Off":
case 'Off':
lime.ui.WindowVSyncMode.OFF;
case "On":
case 'On':
lime.ui.WindowVSyncMode.ON;
case "Adaptive":
case 'Adaptive':
lime.ui.WindowVSyncMode.ADAPTIVE;
default:
lime.ui.WindowVSyncMode.OFF;
};
#end
}
static function set_vsyncMode(value:lime.ui.WindowVSyncMode):lime.ui.WindowVSyncMode
{
#if (mobile || web)
return lime.ui.WindowVSyncMode.OFF;
#else
var string;
switch (value)
{
case lime.ui.WindowVSyncMode.OFF:
string = "Off";
string = 'Off';
case lime.ui.WindowVSyncMode.ON:
string = "On";
string = 'On';
case lime.ui.WindowVSyncMode.ADAPTIVE:
string = "Adaptive";
string = 'Adaptive';
default:
string = "Off";
string = 'Off';
};
WindowUtil.setVSyncMode(value);
@@ -351,48 +381,75 @@ class Preferences
save.options.vsyncMode = string;
Save.system.flush();
return value;
#end
}
public static var unlockedFramerate(get, set):Bool;
static function get_unlockedFramerate():Bool
{
#if (mobile || web)
return false;
#else
return Save?.instance?.options?.unlockedFramerate ?? false;
#end
}
static function set_unlockedFramerate(value:Bool):Bool
{
#if (mobile || web)
return false;
#else
if (value != Save.instance.options.unlockedFramerate)
{
#if web
toggleFramerateCap(value);
#end
}
var save:Save = Save.instance;
save.options.unlockedFramerate = value;
Save.system.flush();
return value;
#end
}
#if web
// We create a haxe version of this just for readability.
// We use these to override `window.requestAnimationFrame` in Javascript to uncap the framerate / "animation" request rate
// Javascript is crazy since u can just do stuff like that lol
public static var enabledDiscordRPC(get, set):Bool;
public static function unlockedFramerateFunction(callback, element)
static function get_enabledDiscordRPC():Bool
{
var currTime = Date.now().getTime();
var timeToCall = 0;
var id = js.Browser.window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
return id;
return Save?.instance?.options?.enabledDiscordRPC ?? true;
}
// Lime already implements their own little framerate cap, so we can just use that
// This also gets set in the init function in Main.hx, since we need to definitely override it
public static var lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame");
static function set_enabledDiscordRPC(value:Bool):Bool
{
#if FEATURE_DISCORD_RPC
toggleDiscordRPC(value);
#end
var save:Save = Save.instance;
save.options.enabledDiscordRPC = value;
Save.system.flush();
return value;
}
#if FEATURE_DISCORD_RPC
public static function toggleDiscordRPC(enable:Bool)
{
if (DiscordClient.instance == null) return;
if (enable)
{
DiscordClient.instance.init();
if (DiscordClient.presenceParamsCache != null)
{
DiscordClient.instance.setPresence(DiscordClient.presenceParamsCache);
}
}
else
{
DiscordClient.instance.shutdown();
}
}
#end
/**
@@ -484,9 +541,7 @@ class Preferences
setDebugDisplayMode(Preferences.debugDisplay);
setDebugDisplayBGOpacity(Preferences.debugDisplayBGOpacity / 100);
#if web
toggleFramerateCap(Preferences.unlockedFramerate);
#end
#if mobile
// Apply the allowScreenTimeout setting.
@@ -496,21 +551,21 @@ class Preferences
static function toggleFramerateCap(unlocked:Bool):Void
{
#if web
var framerateFunction = unlocked ? unlockedFramerateFunction : lockedFramerateFunction;
untyped js.Syntax.code("window.requestAnimationFrame = framerateFunction;");
#if !(mobile || web)
FlxG.drawFramerate = unlocked ? 0 : framerate;
FlxG.updateFramerate = unlocked ? 0 : framerate;
#end
}
public static function setDebugDisplayMode(mode:DebugDisplayMode):Void
{
if (FlxG.game.parent.contains(Main.debugDisplay)) FlxG.game.parent.removeChild(Main.debugDisplay);
if (FlxG.game.contains(Main.debugDisplay)) FlxG.game.removeChild(Main.debugDisplay);
if (mode == DebugDisplayMode.Off) return;
Main.debugDisplay.isAdvanced = (mode == DebugDisplayMode.Advanced);
FlxG.game.parent.addChild(Main.debugDisplay);
FlxG.game.addChild(Main.debugDisplay);
}
static function setDebugDisplayBGOpacity(value:Float):Void
+26 -25
View File
@@ -8,25 +8,36 @@ import hxdiscord_rpc.Types.DiscordRichPresence;
import hxdiscord_rpc.Types.DiscordUser;
import sys.thread.Thread;
@:build(funkin.util.macro.EnvironmentMacro.build())
@:nullSafety
/**
* Handles integration with the Discord Rich Presence API.
*/
@:build(funkin.util.macro.EnvironmentMacro.build()) @:nullSafety
class DiscordClient
{
@:envField
static final DISCORD_CLIENT_ID:Null<String>;
/**
* The current instance of the singleton Discord client.
*/
public static var instance(get, never):DiscordClient;
static var _instance:Null<DiscordClient> = null;
static function get_instance():DiscordClient
{
if (DiscordClient._instance == null) _instance = new DiscordClient();
if (DiscordClient._instance == null) throw "Could not initialize singleton DiscordClient!";
if (DiscordClient._instance == null) throw 'Could not initialize singleton DiscordClient!';
return DiscordClient._instance;
}
var handlers:DiscordEventHandlers;
/**
* Latest passed parameters for the presence.
*/
public static var presenceParamsCache:Null<DiscordClientPresenceParams>;
private function new()
{
trace(' DISCORD '.bold().bg_blue() + ' Initializing event handlers...');
@@ -44,13 +55,13 @@ class DiscordClient
if (!hasValidCredentials())
{
FlxG.log.warn("Tried to initialize Discord connection, but credentials are invalid!");
FlxG.log.warn('Tried to initialize Discord connection, but credentials are invalid!');
return;
}
@:nullSafety(Off)
{
Discord.Initialize(DISCORD_CLIENT_ID, cpp.RawPointer.addressOf(handlers), false, "");
Discord.Initialize(DISCORD_CLIENT_ID, cpp.RawPointer.addressOf(handlers), false, '');
}
createDaemon();
@@ -61,7 +72,7 @@ class DiscordClient
*/
static function hasValidCredentials():Bool
{
return !(DISCORD_CLIENT_ID == null || DISCORD_CLIENT_ID == "" || (DISCORD_CLIENT_ID != null && DISCORD_CLIENT_ID.contains(" ")));
return !(DISCORD_CLIENT_ID == null || DISCORD_CLIENT_ID == '' || (DISCORD_CLIENT_ID != null && DISCORD_CLIENT_ID.contains(' ')));
}
var daemon:Null<Thread> = null;
@@ -93,6 +104,8 @@ class DiscordClient
public function setPresence(params:DiscordClientPresenceParams):Void
{
presenceParamsCache = params;
var presence:DiscordRichPresence = new DiscordRichPresence();
// Presence should always be playing the game.
@@ -102,35 +115,33 @@ class DiscordClient
presence.largeImageText = "Friday Night Funkin'";
// State should be generally what the person is doing, like "In the Menus" or "Pico (Pico Mix) [Freeplay Hard]"
presence.state = cast(params.state, Null<String>) ?? "";
presence.state = cast(params.state, Null<String>) ?? '';
// Details should be what the person is specifically doing, including stuff like timestamps (maybe something like "03:24 elapsed").
presence.details = cast(params.details, Null<String>) ?? "";
presence.details = cast(params.details, Null<String>) ?? '';
// The large image displaying what the user is doing.
// This should probably be album art.
// IMPORTANT NOTE: This can be an asset key uploaded to Discord's developer panel OR any URL you like.
presence.largeImageKey = cast(params.largeImageKey, Null<String>) ?? "album-volume1";
presence.largeImageKey = cast(params.largeImageKey, Null<String>) ?? 'album-volume1';
// TODO: Make this use the song's album art.
// presence.largeImageKey = "icon";
// presence.largeImageKey = "https://f4.bcbits.com/img/a0746694746_16.jpg";
// The small inset image for what the user is doing.
// This can be the opponent's health icon?
// NOTE: Like largeImageKey, this can be a URL, or an asset key.
presence.smallImageKey = cast(params.smallImageKey, Null<String>) ?? "";
presence.smallImageKey = cast(params.smallImageKey, Null<String>) ?? '';
// NOTE: In previous versions, this showed as "Elapsed", but now shows as playtime and doesn't look good
// presence.startTimestamp = time - 10;
// presence.endTimestamp = time + 30;
final button1:DiscordButton = new DiscordButton();
button1.label = "Play on Web";
button1.label = 'Play on Web';
button1.url = Constants.URL_NEWGROUNDS;
presence.buttons[0] = button1;
final button2:DiscordButton = new DiscordButton();
button2.label = "Download";
button2.label = 'Download';
button2.url = Constants.URL_ITCH;
presence.buttons[1] = button2;
@@ -138,6 +149,7 @@ class DiscordClient
}
// TODO: WHAT THE FUCK get this pointer bullfuckery out of here
private static function onReady(request:cpp.RawConstPointer<DiscordUser>):Void
{
trace(' DISCORD '.bold().bg_blue() + ' Client has connected!');
@@ -166,17 +178,6 @@ class DiscordClient
trace(' DISCORD '.bold().bg_blue() + ' Client has received an error! ($errorCode) "${cast (message, String)}"');
}
// public var type(get, set):DiscordActivityType;
// public var state(get, set):String;
// public var details(get, set):String;
// public var startTimestamp(get, set):Int;
// public var endTimestamp(get, set):Int;
// public var largeImageKey(get, set):String;
// public var largeImageText(get, set):String;
// public var smallImageKey(get, set):String;
// public var smallImageText(get, set):String;
//
//
// public var partyId(get, set)
// public var partySize(get, set)
// public var partyMax(get, set)

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