Skip to content

V5#1

Merged
BlueWitherer merged 2 commits intomainfrom
v5
Feb 20, 2026
Merged

V5#1
BlueWitherer merged 2 commits intomainfrom
v5

Conversation

@BlueWitherer
Copy link
Copy Markdown
Member

No description provided.

@BlueWitherer BlueWitherer merged commit 35ebb3e into main Feb 20, 2026
6 checks passed
@BlueWitherer BlueWitherer deleted the v5 branch February 20, 2026 14:37
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @BlueWitherer, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a major internal overhaul of the "Horrible Ideas" mod, primarily driven by the upgrade to Geode SDK v5 and a commitment to modern C++ practices. The core changes involve a complete refactoring of how mod options are registered and managed, shifting from a monolithic list to a more modular, file-specific registration approach. The event system has been modernized to align with Geode's latest event architecture, and keybind management has been integrated directly into the mod. These updates aim to improve maintainability, leverage new SDK features, and ensure compatibility with the latest Geometry Dash versions.

Highlights

  • Geode SDK v5 Upgrade: The mod has been updated to be compatible with Geode SDK version 5.0.0-beta.3 and Geometry Dash version 2.2081, including the C++23 standard.
  • Refactored Option Management: The internal system for registering and managing 'horrible options' has been significantly refactored, moving from a centralized static list to a decentralized registration macro (REGISTER_HORRIBLE_OPTION) within individual hook files.
  • Modernized Event System: The custom event system (OptionEvent, OptionEventV2, CategoryEvent) has been updated to leverage Geode's GlobalEvent and Event classes, simplifying event handling and listener registration.
  • Internal Keybind Handling: The dependency on the external geode.custom-keybinds mod has been removed, and keybinds are now managed internally within the mod, with a new key-popup setting.
  • Code Modernization: Various C++ features have been updated, including making several classes final, replacing virtual ~ClassName() with ~ClassName(), using geode::Function instead of std::function, and replacing CC_SAFE_DELETE with delete.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • CMakeLists.txt
    • Updated C++ standard from 20 to 23.
  • README.md
    • Updated keybind customization instructions to reflect internal handling.
  • about.md
    • Updated keybind customization instructions to reflect internal handling.
  • include/Events.hpp
    • Refactored OptionEvent and OptionEventFilter to use geode::GlobalEvent.
    • Removed cocos2d.h include.
  • include/Horrible.hpp
    • Made OptionManager final.
    • Removed PImpl pattern, moving m_options and m_categories directly into the class.
    • Updated registerCategory and registerOption parameters.
    • Changed setOption to use geode::ZStringView.
    • Added [[nodiscard]] to getters.
    • Introduced REGISTER_HORRIBLE_OPTION macro.
  • include/Option.hpp
    • Made Option struct final.
  • include/OptionalAPI.hpp
    • Refactored OptionEventV2 and OptionEventFilterV2 to use geode::Event.
    • Made OptionManagerV2 final.
    • Updated setOption parameter.
  • mod.json
    • Updated Geode SDK version to 5.0.0-beta.3 and GD version to 2.2081.
    • Removed geode.custom-keybinds dependency.
    • Added a new key-popup keybind setting.
  • src/Keybinds.cpp
    • Removed the file, as keybind handling is now internal.
  • src/Utils.hpp
    • Removed the horrible::key namespace, which previously defined option IDs.
  • src/classes/Options.hpp
    • Updated set and doesCategoryExist parameters to use geode::ZStringView.
  • src/classes/src/Jumpscares.cpp
    • Modified downloadLevel calls to include an additional 0 parameter.
  • src/classes/ui/MathQuiz.hpp
    • Made MathQuiz and Richard classes final.
    • Changed virtual ~ to ~.
    • Updated setCallback to use geode::Function.
  • src/classes/ui/RandomAd.hpp
    • Made RandomAd class final.
    • Changed Popup<> to Popup.
    • Renamed setup() to init().
  • src/classes/ui/SpamChallenge.hpp
    • Changed SpamChallenge class to final.
    • Changed virtual ~ to ~.
    • Updated setCallback to use geode::Function.
  • src/classes/ui/src/MathQuiz.cpp
    • Updated constructor initialization.
    • Replaced std::function with geode::Function.
    • Updated switch statements with [[fallthrough]].
    • Replaced CC_SAFE_DELETE with delete.
  • src/classes/ui/src/RandomAd.cpp
    • Updated init() method to call Popup::init().
    • Replaced CC_SAFE_DELETE with delete.
  • src/classes/ui/src/SpamChallenge.cpp
    • Updated constructor initialization.
    • Replaced std::function with geode::Function.
    • Replaced CC_SAFE_DELETE with delete.
  • src/hooks/Achievement.cpp
    • Added Horrible.hpp include.
    • Defined and registered achieve option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/Dementia.cpp
    • Defined and registered dementia option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/GJBaseGameLayer/FakeCrash.cpp
    • Defined and registered fake_crash option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/GJBaseGameLayer/RandomNoJump.cpp
    • Defined and registered no_jump option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/GJBaseGameLayer/TimewarpJump.cpp
    • Defined and registered timewarp_jump option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/Mock.cpp
    • Defined and registered mock option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
    • Updated option ID references.
  • src/hooks/Parry.cpp
    • Added a commented-out id constant and Option definition, indicating potential future use or a disabled feature.
  • src/hooks/Placebo.cpp
    • Defined and registered placebo option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Adverts.cpp
    • Defined and registered ads option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/PlayLayer/BlackScreen.cpp
    • Defined and registered black_screen option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/BlinkingIcon.cpp
    • Defined and registered blinking_icon option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Confetti.cpp
    • Defined and registered confetti option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/PlayLayer/CrashGame.cpp
    • Defined and registered crash_death option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Earthquake.cpp
    • Defined and registered earthquake option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/FakeDeath.cpp
    • Defined and registered death option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Flipped.cpp
    • Defined and registered flipped option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/ForceLevels.cpp
    • Defined and registered grief and congregation options using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Freeze.cpp
    • Defined and registered freeze option using REGISTER_HORRIBLE_OPTION.
    • Moved FPS capping logic from FreezeFPS.cpp into this file.
  • src/hooks/PlayLayer/FreezeFPS.cpp
    • Removed the file.
  • src/hooks/PlayLayer/Friends.cpp
    • Defined and registered friends option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Gambler.cpp
    • Defined and registered gambler option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Health.cpp
    • Defined and registered health option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references and ID for health bar.
  • src/hooks/PlayLayer/Math.cpp
    • Defined and registered math_quiz option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/PlayLayer/Motivation.cpp
    • Defined and registered motivation option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/PlayLayer/Oxygen.cpp
    • Defined and registered oxygen option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references and ID for oxygen bar.
  • src/hooks/PlayLayer/Pause.cpp
    • Defined and registered pauses option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/RandomMirror.cpp
    • Defined and registered random_mirror option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayLayer/Spam.cpp
    • Defined and registered spam option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/PlayLayer/UpsideDown.cpp
    • Defined and registered upside_down option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/ClickSpeed.cpp
    • Defined and registered click_speed option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/DoubleJump.cpp
    • Defined and registered double_jump option using REGISTER_HORRIBLE_OPTION.
    • Removed OptionEventFilter listener.
  • src/hooks/PlayerObject/Gravity.cpp
    • Defined and registered gravity option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/OnIce.cpp
    • Defined and registered ice_level option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/RandomIcon.cpp
    • Defined and registered random_icon option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/RandomSpeed.cpp
    • Defined and registered random_speed option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/SizeChanger.cpp
    • Defined and registered size_changer option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/Sleepy.cpp
    • Defined and registered sleepy option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/hooks/PlayerObject/Sticky.cpp
    • Defined and registered sticky option using REGISTER_HORRIBLE_OPTION.
    • Updated option ID references.
  • src/include/Horrible.cpp
    • Removed OptionEvent and OptionEventFilter implementations.
    • Refactored OptionManager to remove PImpl and update parameter types.
    • Updated OptionManagerV2 methods.
  • src/main.cpp
    • Removed the static defOpts vector and its registration loop.
    • Updated listenForSettingChanges to use typed versions and listenForKeybindSettingPresses.
    • Changed floating button parent from SceneManager to OverlayManager.
  • src/menu/OptionCategoryItem.hpp
    • Made CategoryEvent a geode::Event struct.
    • Made OptionCategoryItem final.
    • Removed virtual ~.
    • Updated init and create parameters.
  • src/menu/OptionItem.hpp
    • Made OptionItem final.
    • Removed virtual ~.
    • Updated init and create parameters.
  • src/menu/OptionMenuButton.hpp
    • Made OptionMenuButton final.
    • Removed virtual ~.
  • src/menu/OptionMenuPopup.hpp
    • Made OptionMenuPopup final.
    • Changed Popup<> to Popup.
    • Removed OptionEventFilter and CategoryEventFilter listeners.
    • Removed virtual ~.
    • Renamed setup() to init().
  • src/menu/SettingV3.hpp
    • Made HorribleSettingV3 and HorribleSettingNodeV3 final.
    • Updated parse parameters to ZStringView.
    • Added noexcept to some methods.
    • Removed virtual ~.
  • src/menu/src/OptionCategoryItem.cpp
    • Removed CategoryEvent and CategoryEventFilter implementations.
    • Updated OptionCategoryItem constructor, init parameters, and event sending.
  • src/menu/src/OptionItem.cpp
    • Updated OptionItem constructor, init parameters, and internal field names.
    • Added OptionEvent sending on toggle.
  • src/menu/src/OptionMenuButton.cpp
    • Updated OptionMenuButton constructor and internal field names.
  • src/menu/src/OptionMenuPopup.cpp
    • Updated OptionMenuPopup constructor, init method, internal field names, and event handling.
    • Moved filterOptions logic into Impl class.
  • src/menu/src/SettingV3.cpp
    • Updated HorribleSettingV3::parse parameters.
    • Updated HorribleSettingNodeV3 constructor.
    • Updated button creation to directly call menu::open().
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/multi-platform.yml
Activity
  • No specific activity was recorded for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors a large portion of the codebase to align with Geode v5 APIs and best practices, utilizing GlobalEvent and the REGISTER_HORRIBLE_OPTION macro to enhance clarity and maintainability. No security vulnerabilities were identified. However, a critical regression was introduced by removing option event listeners in hook files, causing many hooks to cache the option's enabled state at initialization without updating it. This issue needs to be addressed across all affected hooks, in addition to a couple of minor potential issues.

Comment on lines 45 to 59
switch (m_impl->m_operation) {
case MathOperation::Addition:
m_impl->m_correctAnswer = m_impl->m_numFirst + m_impl->m_numSecond;
break;
default: [[fallthrough]];

case MathOperation::Subtraction:
m_impl->m_correctAnswer = m_impl->m_numFirst - m_impl->m_numSecond;
break;
case MathOperation::Addition:
m_impl->m_correctAnswer = m_impl->m_numFirst + m_impl->m_numSecond;
break;

case MathOperation::Multiplication:
m_impl->m_correctAnswer = m_impl->m_numFirst * m_impl->m_numSecond;
break;
case MathOperation::Subtraction:
m_impl->m_correctAnswer = m_impl->m_numFirst - m_impl->m_numSecond;
break;

default:
break;
case MathOperation::Multiplication:
m_impl->m_correctAnswer = m_impl->m_numFirst * m_impl->m_numSecond;
break;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using default: [[fallthrough]]; here could lead to subtle bugs if the MathOperation enum is extended in the future. An unhandled case would silently fall through to the Addition case. The previous implementation with default: break; was safer. It would be even better to not have a default case at all, so the compiler can warn about unhandled enum values.

Suggested change
switch (m_impl->m_operation) {
case MathOperation::Addition:
m_impl->m_correctAnswer = m_impl->m_numFirst + m_impl->m_numSecond;
break;
default: [[fallthrough]];
case MathOperation::Subtraction:
m_impl->m_correctAnswer = m_impl->m_numFirst - m_impl->m_numSecond;
break;
case MathOperation::Addition:
m_impl->m_correctAnswer = m_impl->m_numFirst + m_impl->m_numSecond;
break;
case MathOperation::Multiplication:
m_impl->m_correctAnswer = m_impl->m_numFirst * m_impl->m_numSecond;
break;
case MathOperation::Subtraction:
m_impl->m_correctAnswer = m_impl->m_numFirst - m_impl->m_numSecond;
break;
default:
break;
case MathOperation::Multiplication:
m_impl->m_correctAnswer = m_impl->m_numFirst * m_impl->m_numSecond;
break;
};
switch (m_impl->m_operation) {
case MathOperation::Addition:
m_impl->m_correctAnswer = m_impl->m_numFirst + m_impl->m_numSecond;
break;
case MathOperation::Subtraction:
m_impl->m_correctAnswer = m_impl->m_numFirst - m_impl->m_numSecond;
break;
case MathOperation::Multiplication:
m_impl->m_correctAnswer = m_impl->m_numFirst * m_impl->m_numSecond;
break;
// No default case to get compiler warnings for unhandled enum values.
// MathOperation::Geometry is not handled here.
};

Comment on lines 106 to 120
switch (m_impl->m_operation) {
case MathOperation::Addition:
operation = "+";
break;
default: [[fallthrough]];

case MathOperation::Subtraction:
operation = "-";
break;
case MathOperation::Addition:
operation = "+";
break;

case MathOperation::Multiplication:
operation = "x";
break;
case MathOperation::Subtraction:
operation = "-";
break;

default:
operation = "?";
case MathOperation::Multiplication:
operation = "x";
break;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the previous switch statement, using default: [[fallthrough]]; can hide potential bugs if the MathOperation enum is extended. The previous implementation which handled the default case by setting operation = "?" was more robust. It's generally better to either handle all enum cases explicitly or have a default that asserts or logs an error.

Suggested change
switch (m_impl->m_operation) {
case MathOperation::Addition:
operation = "+";
break;
default: [[fallthrough]];
case MathOperation::Subtraction:
operation = "-";
break;
case MathOperation::Addition:
operation = "+";
break;
case MathOperation::Multiplication:
operation = "x";
break;
case MathOperation::Subtraction:
operation = "-";
break;
default:
operation = "?";
case MathOperation::Multiplication:
operation = "x";
break;
};
switch (m_impl->m_operation) {
case MathOperation::Addition:
operation = "+";
break;
case MathOperation::Subtraction:
operation = "-";
break;
case MathOperation::Multiplication:
operation = "x";
break;
default:
// This case should ideally not be reached with the current logic,
// but it's safer to handle it.
operation = "?";
break;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant