diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b1885a3..6f8ad01 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -39,20 +39,20 @@ jobs: - name: Download Flash uses: robinraju/release-downloader@v1.5 with: - repository: hjfod/flash + repository: geode-sdk/flash latest: true fileName: "flash.exe" tarBall: false zipBall: false out-file-path: "" - + - name: Create dist directory run: | mkdir dist - + - name: Build docs with Flash run: | - cd dist + cd dist ./../flash.exe -i ../geode -o . - name: Setup Pages diff --git a/assets/Set_Env_Var.png b/assets/Set_Env_Var.png new file mode 100644 index 0000000..44bd6d8 Binary files /dev/null and b/assets/Set_Env_Var.png differ diff --git a/cpp/declarations.md b/cpp/declarations.md index 52638b7..1f33df1 100644 --- a/cpp/declarations.md +++ b/cpp/declarations.md @@ -16,7 +16,7 @@ int someFunction(int a, int b); class SomeClass; ``` -These are also known as **forward declarations**. They are telling the compiler that you a symbol will exists, but you will only define it later on. +These are also known as **forward declarations**. They are telling the compiler that a symbol will exist, but you will only define it later on. Forward declarations are most useful (and also necessary) when dealing with symbols that depend on each other, for example functions that call each other: @@ -84,7 +84,23 @@ void sayHi() { } ``` -Of course, this example is quite simple, and not what most commonly causes headaches for new modders. The most common source of ODR problems is due to headers. +Another important thing to note about ODR is that **it applies across all source files**. That is, if you have two different source files: + +```cpp +// hi.cpp +void sayHi() { + std::cout << "Hi mom!" << std::endl; +} + +// hello.cpp +void sayHi() { + std::cout << "Hello mom!" << std::endl; +} +``` + +**This will also be considered an ODR violation.** Any definition of a C++ symbol in a source file is (usually) automatically visible to all other files, so the compiler will notice you have defined a function in multiple different sources and won't be able to decide which one to use. + +However, you will most likely rarely encounter ODR due to source files; rather, the most common source of ODR problems is due to headers. Say you have the following header, `hi.hpp`: diff --git a/cpp/index.md b/cpp/index.md index e4d4f0a..274bac6 100644 --- a/cpp/index.md +++ b/cpp/index.md @@ -1,3 +1,7 @@ +--- +order: 999 +--- + # C++ Tutorials This is a collection of tutorials for C++, ranging from basic language features to compiler-specific UB. This is intended as **supplemental** material for GD modders who are new to modding and C++ - **it should not be regarded as a full tutorial**. To learn C++, you should seek more information from sites such as [W3Schools](https://www.w3schools.com/cpp/default.asp) and [learncpp](https://www.learncpp.com/). diff --git a/faq.md b/faq.md deleted file mode 100644 index f4f3dc7..0000000 --- a/faq.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: FAQ -description: Answers to common questions about Geode -icon: info -style: qna ---- - -# Frequently Asked Questions - -## How do I install Geode? - -You can install Geode from [the Official Homepage](https://geode-sdk.org). If you're looking to develop your own mods using Geode, see [Installation](/installation.md). - -## I already have Mega Hack / QuickLdr / GDHM, how do I migrate? - -The Geode installer should detect and remove old mod loaders automatically. You can then reinstall your mods through the in-game Download page, if they are available. - -## How do I use Mega Hack with Geode? - -Absolute has said the next major release of Mega Hack (v8) will be available on Geode. The current version [won't work alongside Geode](#how-do-i-load-dll-mods), so you will have to wait for v8 to be released. - -## How do I load .DLL mods? - -Geode does not support loading old .DLL mods. Geode will most likely not work if installed alongside another mod loader either. Check if the mods you want to install are available as Geode mods. - -## Why doesn't Geode support .DLL mods? - -Short answer: Because if it did support it, people would complain about everything crashing. - -Geode introduces, among a lot of other features, a brand new hooking framework that is incompatible with older mods, which often use MinHook. As such, loading older mods while Geode is loaded will likely cause issues. On top of the hooking framework, Geode also shuffles a lot of UIs around internally, which is fine for Geode mods but will completely break older mods. - -## When will [insert mod name] get ported? - -Depends on the developer. If they're just porting the existing codebase with no changes, porting might only take a day. However, most mods such as BetterEdit and TextureLdr are getting extra features added while being ported, and as such will take longer. Follow the developer's social medias to see if they post progress updates. - -Once a mod has been ported, you can find it on the in-game Download page. - -## Help! The game crashed! - -Please send the latest crashlog from `geode/crashlogs` to us [on Github issues](https://github.com/geode-sdk/geode/issues/new/choose). diff --git a/geode/creating.md b/geode/creating.md deleted file mode 100644 index 72f1416..0000000 --- a/geode/creating.md +++ /dev/null @@ -1,53 +0,0 @@ -# Creating a new Mod - -These are instructions to create an empty mod. - -## Prerequisites: - - * [CMake](https://cmake.org/download/) (minimum v3.21) - * A supported C++ compiler ([clang](https://releases.llvm.org/) on MacOS, [MSVC](https://visualstudio.microsoft.com/downloads/) on Windows) - * [Geode CLI](https://github.com/geode-sdk/cli) (**Make sure you [add the CLI](/geode/installcli) to your path environment variable**) - * [git](https://git-scm.com/downloads) - -## Creating the mod - -You can easily create a mod using the [Geode CLI](/geode/installcli), by simply running this command in a terminal / command prompt and answering the prompts that follow. -``` -geode new -``` - -This will clone a template mod which you can then start editing to do whatever you want. - -## Building - -To build a mod, you can either do it [manually](#manually) or [with Visual Studio Code](#recommended-setup-using-vs-code). - -**IMPORTANT**: You will not be able to build a mod if you do not have [set up the SDK for developers](/installation). \ -Make sure the `GEODE_SDK` enviroment variable works. - -### Manually - -```bash -# Configure (for Windows) -cmake -B build -A win32 -# Configure (for MacOS) -cmake -B build - -# And then build -cmake --build build --config Release -``` - -### Recommended Setup using VS Code - -1. Make sure you have the [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) and [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) extensions for VS Code - -2. Open up the directory of your mod in VS Code (hint: you can do this from the command line with `code `) - -3. Press F1 to open the Command Palette and run `CMake: Configure` - 3.1 If you're on **Windows** make sure to select an x86/32-bit generator, for example - - `Visual Studio Community 2022 Release - x86` - - `Visual Studio Community 2022 Release - amd64_x86` - -4. Open up the Command Palette again and run `CMake: Select Variant` (select either `Release` or `RelWithDebInfo`) - -If you have the CMake Tools extension, you can simply press the `Build` button on the bottom bar or use the hotkey `F7`. diff --git a/geode/index.md b/geode/index.md deleted file mode 100644 index 695d975..0000000 --- a/geode/index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Geode ---- - -These pages are a collection of information about the Geode framework itself. diff --git a/geode/installcli.md b/geode/installcli.md deleted file mode 100644 index df83eb8..0000000 --- a/geode/installcli.md +++ /dev/null @@ -1,38 +0,0 @@ -# Installing Geode CLI - -Geode CLI is the command-line interface for working with Geode, intended mainly for developers. It comes with many important tools such as packaging mods into `.geode` files, creating spritesheets, creating bitmap fonts, etc.. The CLI is required for compiling the Geode loader, and is extremely helpful for working with your own mods, as it automatically packages all the resources into a `.geode` file and installs it to GD. - -## Downloading CLI - -## Latest Release - -You can find the latest release of CLI on the [Release page on its repo](https://github.com/geode-sdk/cli). - -## Building from source - -You can build the CLI yourself using [Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html). Clone the git repo using `git clone https://github.com/geode-sdk/cli` and then run `cargo build` to build it. If you encounter errors, [let us know through GitHub issues](https://github.com/geode-sdk/cli/issues). - -## Adding CLI to PATH (on Windows) - -> :warning: Note: this section is for Windows. - -In order for the CLI to be accessible from anywhere on your computer, it needs to be added to your `PATH` environment variable. If you know what that means, you know how to do it; otherwise, follow these steps: - -1. Select the CLI executable in File Explorer, Shift + Right-Click it and select `Copy as Path` - -2. Search `Edit the system environment variables` on Windows search. Alternatively, you can open up Control Panel and search for it, then select `Edit the system environment variables` or **to skip straight to step 3 select `Edit environment variables for your account`**. - -3. Click `Environment Variables...` - -4. In the top `User variables` section, select the `Path` variable and click `Edit` - -5. Now click `New` and paste the path of the CLI executable you copied at Step 1. **Remove the `\geode.exe` from the end;** the path has to point to the _directory_ with Geode CLI, not the CLI itself. - -6. Click OK to close the environment variable windows. - -## Making sure it works - -1. Open up Windows search and open `cmd` or `powershell` - -2. Type `geode` and hit Enter. If CLI was installed correctly, you should see the CLI help displaying its version and commands. - diff --git a/getting-started/cpp-stuff.md b/getting-started/cpp-stuff.md new file mode 100644 index 0000000..e7502bf --- /dev/null +++ b/getting-started/cpp-stuff.md @@ -0,0 +1,37 @@ +--- +title: 1.1. Required C++ Tools +order: 2 +--- + +# Required C++ Tools +To be able to use the Geode SDK, you **will** need at least the following: +* [A C++ compiler](#compiler) +* [CMake](https://cmake.org/download/) +* [git](https://git-scm.com/downloads) + +## Compiler +To use the Geode SDK, and in turn make Geometry Dash mods, you will need either: +* [Visual Studio](#windows) on Windows +* [clang](#macos) on MacOS +* [A secret third thing](#linux) on Linux + +### Windows +From the [Visual Studio](https://visualstudio.microsoft.com/downloads/) website, you can download the Visual Studio IDE along with the compiler. If you want **just** the compiler, look for *Build Tools for Visual Studio* further down in the page. + +After launching the installer, look for **Desktop development with C++**. You may choose other features, but you **will** need at least ***MSVC*** and ***Windows SDK*** installed. + +Once its installed, you should now have a working C++ compiler installed that is suited for GD mod development. + +### MacOS + +Install [brew](https://brew.sh/) if you don't already have it, and then run: +```bash +brew install llvm +``` + +### Linux +Linux is a bit more complicated, as obviously there's no linux release of GD (yet). Of course, you can run the Windows version of GD through software like [wine](https://www.winehq.org/) quite well, which is probably what you're already doing. + +Because of that, this guide will set you up to [cross-compile](https://en.wikipedia.org/wiki/Cross_compiler) windows Geode mods from linux. + +We recommend reading this gist: [linux-win-cross.md](https://gist.github.com/matcool/abb65ee59ded3766717c673014c3a2a7) for up to date information on how to cross compile. \ No newline at end of file diff --git a/getting-started/create-mod.md b/getting-started/create-mod.md new file mode 100644 index 0000000..677a20f --- /dev/null +++ b/getting-started/create-mod.md @@ -0,0 +1,46 @@ +--- +title: 3. Creating and building a new mod +order: 5 +--- + +# Creating a new mod +After all that setup, you can now create your first mod! + +To do this, open up a terminal where you want to create your project and run: +```bash +geode new +``` +Follow the given prompts and afterwards you should have a new folder containing the code for your mod. + +## Files + +You may notice the project already comes with a few files. Lets go over them: +- `CMakeLists.txt` - This is the main file for your CMake project. +- `about.md` - Here you can write a very long description page for your mod, in markdown. Think of it as a README for your mod! This file is technically optional, but highly recommended. +- `logo.png` - This is the icon for your mod, which shows up in-game. This file is technically optional, but highly recommended. +- `mod.json` - This json file contains all the metadata about your mod, such as name, version, custom resources, settings, etc. [See this page for detailed info](/mods/configuring) + +If you plan on releasing your mod, **please** edit the about.md and logo.png files! + +The source code for your mod can be found inside the `src` folder. + +## Additional Files +Geode will also look for these special files within your mod folder: +- `changelog.md` - Lists all of the changes between versions to the mod; [see detailed info](/mods/md-files) +- `support.md` - Is free-form info about how to show support to the developer of the mod; [see detailed info](/mods/md-files) + +# Build +Now, to build your mod you have a few options: \ +If youre using an IDE such as Clion, VScode or Visual Studio, head over to the [IDE Setup](/getting-started/ide-setup) page. + +Otherwise if you want to build your mods manually from the command line you can do that by simply running these commands in your mod's folder: +```bash +# Configure CMake (WINDOWS) +cmake -B build -A win32 + +# Configure CMake (Other platforms) +cmake -B build + +# Build the project +cmake --build build --config RelWithDebInfo +``` \ No newline at end of file diff --git a/getting-started/geode-cli.md b/getting-started/geode-cli.md new file mode 100644 index 0000000..e383c85 --- /dev/null +++ b/getting-started/geode-cli.md @@ -0,0 +1,66 @@ +--- +title: 1.2. Geode CLI +order: 3 +--- + +# Geode CLI +The Geode SDK has its own command line utility program to aid in many tasks involved in mod, such as asset packing, font generation, managing the SDK, etc. + +# Installation + +* [Windows](#windows) +* [MacOS](#macos) +* [Linux](#linux) + +## Windows +(Recommended) You can use [scoop](https://scoop.sh/) to easily install the cli by doing: +```bash +scoop install https://geode-sdk.org/geode-sdk-cli.json +``` + +If you don't have scoop, you can follow the installation instructions on their page: +[https://scoop.sh](https://scoop.sh) + +--- + +Otherwise, you can manually install it by: +1. Download the latest windows release over at [GitHub](https://github.com/geode-sdk/cli/releases/latest) +1. Extract the `geode.exe` into some folder on your computer +1. Select the CLI executable in File Explorer, Shift + Right-Click it and select `Copy as Path` +1. Search `Edit the system environment variables` on Windows search. Alternatively, you can open up Control Panel and search for it, then select `Edit the system environment variables` or **to skip straight to step 6 select `Edit environment variables for your account`**. +1. Click `Environment Variables...` +1. In the top `User variables` section, select the `Path` variable and click `Edit` +1. Now click `New` and paste the path of the CLI executable you copied at Step 1. **Remove the `\geode.exe` from the end;** the path has to point to the _directory_ with Geode CLI, not the CLI itself. +1. Click OK to close the environment variable windows. + +--- + +After either way of installing it, you should now be able to run `geode --version` in your cmd and see a version number! + +It is recommended that you [set up a profile now](#profile-setup). + +## MacOS + +You can easily install the CLI via [brew](https://brew.sh) +```bash +brew install geode-sdk/geode/geode-cli +``` + +It is recommended that you [set up a profile now](#profile-setup). + +## Linux + +We provide prebuilt linux binaries in the CLI releases page, which you can find here: \ +[https://github.com/geode-sdk/cli/releases/latest](https://github.com/geode-sdk/cli/releases/latest) + +Since this is different per distro, you must figure out how to add this binary to your path for CMake to find it. + +Once you figure that out, it is recommended that you [set up a profile now](#profile-setup). + + +# Profile Setup + +A profile is just an instance of Geometry Dash. It's a good idea to set up one up for CLI so your mods can be automatically installed post build. + +To setup a new profile, simply run the `geode config setup` command on your terminal. + diff --git a/getting-started/ide-setup.md b/getting-started/ide-setup.md new file mode 100644 index 0000000..4655172 --- /dev/null +++ b/getting-started/ide-setup.md @@ -0,0 +1,50 @@ +--- +title: 3.1. IDE Setup +order: 6 +--- + +# IDE Setup + +If youre using some IDE you may want to do a few things for your Geode projects. + +* [Visual Studio Code](#visual-studio-code) +* [Visual Studio](#visual-studio) +* [Clion](#clion) + +# Visual Studio Code + +For VSCode, we recommend a few extensions: +- `C/C++` on Windows +- `clangd` on MacOS +- `CMake Tools` +- `Geode` + +None of these extensions are "required", but they will make your experience much better. + +There are a few steps you should follow to get proper intellisense (you should only need to do these once per project, ideally): + + + +1. With VSCode open on your project, press **F1** and run `CMake: Select a Kit`. This will bring up a list of installed compilers on your machine. +![Image showing a bunch of compilers CMake detected in VS Code](/assets/win_compilers.png)\ +On **Windows**, you should go with a Visual Studio compiler that is either `x86` or `amd64_x86`. Note that there is also an `x86_amd64` compiler - you don't want to pick that one!\ +\ +On **Mac**, you should go with Clang. + + * If you're on **Windows**, press **F1** again and run `CMake: Select Variant`. +![Image showing available build types on Windows: Debug, Release, MinSizeRel, and RelWithDebInfo](/assets/win_relwithdebinfo.png)\ +You should go with either `RelWithDebInfo` (recommended at least for development) or `Release`. + +2. On **Windows**, register CMake as the **Configuration Provider** for the C++ extension by running `C/C++: Edit Configurations (UI)`.\ +\ +Scroll down to **Advanced** options, and set the Configuration Provider as `ms-vscode.cmake-tools`. +![Image showing the "C/C++: Edit Configurations (UI)" command being run in VS Code](/assets/win_usecmake.png) + +Now if you run `CMake: Configure`, assuming you have Geode properly installed, the include errors should go away. + +If the errors still persist, try building the mod with `CMake: Build`. If the build is successful but the errors don't disappear, try restarting VS Code. + +# Visual Studio +TODO +# Clion +TODO \ No newline at end of file diff --git a/getting-started/index.md b/getting-started/index.md new file mode 100644 index 0000000..36fdb90 --- /dev/null +++ b/getting-started/index.md @@ -0,0 +1,8 @@ +--- +title: Getting Started +order: 1 +--- + +# Getting Started + +Please read through this chapter in order, starting in [Prerequisites](/getting-started/prerequisites.md). \ No newline at end of file diff --git a/getting-started/prerequisites.md b/getting-started/prerequisites.md new file mode 100644 index 0000000..d0dc787 --- /dev/null +++ b/getting-started/prerequisites.md @@ -0,0 +1,11 @@ +--- +title: 1. Prerequisites +order: 1 +--- + +# Prerequisites +Before you get started with developing with the Geode SDK, there are a few prerequisites that you should know about! +* Prior C++ knowledge is **HIGHLY** recommended. We do not intend in helping you at C++ from the very basics. +* Installing [Geode](https://geode-sdk.org/install/) itself! you want to test your own mods dont you? + +It is recommended that you follow the tutorials on this chapter in order. \ No newline at end of file diff --git a/getting-started/sdk.md b/getting-started/sdk.md new file mode 100644 index 0000000..27a3cbe --- /dev/null +++ b/getting-started/sdk.md @@ -0,0 +1,50 @@ +--- +title: 2. Setting up the SDK +order: 4 +--- + +# Setting up the SDK +To install the SDK we will be using the CLI installed on the previous step. + +To download the sdk, you can simply run the command: +```bash +geode sdk install +``` +This *should* set the `GEODE_SDK` enviroment variable, which can you test after reopening your terminal: +```bash +# on windows +echo %GEODE_SDK% + +# elsewhere +echo $GEODE_SDK +``` + +If that command prints out the path you installed the SDK to, then it has worked correctly. + +To develop mods, you should also download the prebuilt binaries for Geode, which you can do by running this command: +```bash +geode sdk install-binaries +``` + +## Updating +You will need to manually update your local SDK every once in a while, which you do by running this command: +```bash +geode sdk update +``` + +Every time you update the SDK, you should update its prebuilt binaries too. +```bash +geode sdk install-binaries +``` + +--- + +You can also switch to the **nightly** version, which uses the latest commit. +```bash +geode sdk update nightly +``` + +Or to go back to stable: +```bash +geode sdk update stable +``` \ No newline at end of file diff --git a/getting-started/what-next.md b/getting-started/what-next.md new file mode 100644 index 0000000..41e1f00 --- /dev/null +++ b/getting-started/what-next.md @@ -0,0 +1,28 @@ +--- +title: 4. What next? +order: 7 +--- + +# What next? + +idk! Its difficult to guide you on what to do next, as you can do pretty much anything :-) + +## Geode Features + +Modding in Geode is for the most part the same as traditional modding, however there are a few things where it differs. Here are a list of Geode-specific concepts you might like to familiarize yourself with: + + * [Hooking with `$modify`](/tutorials/modify.md) and [adding fields](/tutorials/fields.md) + * [Using sprites and other resources](/mods/resources.md) + * [Settings](/mods/settings.md) and [saving data](/mods/savedata.md) + * [String IDs](/tutorials/nodetree.md) and [Layouts](/tutorials/layouts.md) + * [Events](/tutorials/events.md) + * [Using dependencies](/mods/dependencies.md) + * [Publishing mods](/mods/publishing.md) + +See also [our tutorial](/tutorials/migrating.md) for porting traditional mods to Geode. + +The [Tutorials](/tutorials) category in general is a great source for information about working with Geode mods. + +## Working with cocos + +If you haven't written GD mods before, see [the Handbook](/handbook/chap0.md) for a tutorial \ No newline at end of file diff --git a/handbook/index.md b/handbook/index.md index 60c43d9..8969adc 100644 --- a/handbook/index.md +++ b/handbook/index.md @@ -1,3 +1,7 @@ +--- +order: 4 +--- + # Handbook This handbook is a tutorial on how to mod GD, starting from the very basics and covering everything from hooking to reverse engineering. It has been written for newcomers with the expectation of now previous game modding experience, however C++ and general programming experience are assumed. diff --git a/handbook/vol1/chap1_1.md b/handbook/vol1/chap1_1.md index 111832f..8e4a727 100644 --- a/handbook/vol1/chap1_1.md +++ b/handbook/vol1/chap1_1.md @@ -25,7 +25,7 @@ Almost every platform GD is on has some sort of **dynamic library support**. On > :information_source: There is one platform that doesn't have dynamic library support: iOS (unless jailbroken). Modding on iOS without jailbreaking requires basically baking all the mods you want into a premodified game, like [iCreate](https://icreate.pro/) has done, but a general mod loader like Geode will likely never see iOS support unless some major changes to the OS happen first. -> :green_book: If you are interested in **learning more about binary injection**, [the Wikipedia article on DLL injection](https://en.m.wikipedia.org/wiki/DLL_injection) is a pretty good place to start. +> :green_book: If you are interested in **learning more about binary injection**, [the Wikipedia article on DLL injection](https://en.wikipedia.org/wiki/DLL_injection) is a pretty good place to start. Usually, the first custom dynamic library we make GD load is a mod loader; that is, a mod whose purpose is to load other mods. This is because the methods we use for injection are not easily scalable, but once we have our one library running, we can invent much simpler ways of loading more of them. For example, on Windows, loading a library from another library that you control is as simple as calling the `LoadLibrary` function. This can also be done an arbitary number of times within our initial library, so we can for example automatically find all the .DLL files in some directory and load them. This is how old 2.1 mod loaders such as **Mega Hack v7** used to work: they would search for all of the `.dll` files in a predefined folder like `extensions` and call `LoadLibrary` on them. diff --git a/handbook/vol1/chap1_2.md b/handbook/vol1/chap1_2.md index 4440b8d..3eeadb8 100644 --- a/handbook/vol1/chap1_2.md +++ b/handbook/vol1/chap1_2.md @@ -52,7 +52,7 @@ int addTwoHook(int a, int b) { A hook **always has the signature [[Note 1]](#notes) as the function being hooked**. This means that we couldn't hook `addTwo` with something that takes two strings. Likewise, the return type has to be the same; if `addTwo` returns an `int`, so does our hook. -This is the basic premise of hooking: when the function you're hooking is called, the first thing you do is hop into your own code, and then hop back into the original once you're finished. The function that contains your own code is called a **detour**, and the funtion being hooked is called the **original**. +This is the basic premise of hooking: when the function you're hooking is called, the first thing you do is hop into your own code, and then hop back into the original once you're finished. The function that contains your own code is called a **detour**, and the function being hooked is called the **original**. However, the code above is **actually misleading**. It would be more accurate to say that hooking does this: diff --git a/handbook/vol1/chap1_6.md b/handbook/vol1/chap1_6.md index 7f38fe9..c8de014 100644 --- a/handbook/vol1/chap1_6.md +++ b/handbook/vol1/chap1_6.md @@ -138,7 +138,7 @@ That's it. As previously stated, this is [quite close to the standard node desig > :warning: It should be noted that not all layer's `init` functions have the same signature, and `$modify` requires the signature to **exactly match** in order to create a hook. Unfortunately, due to implementation problems, it also (currently) doesn't tell you if your signature is wrong, so you may find yourself scratching your head as to why your mod isn't working, only to realize the signature of `init` is off. Check [GeometryDash.bro](https://github.com/geode-sdk/geode/blob/main/bindings/GeometryDash.bro) to make sure the signature of your hook is correct! -Now we are at an interesting point; we know how to hook to hook functions, we know what function from a layer to hook in order to modify it, and we know how to work with nodes. So, let's tie all of this together! Only 7 chapters in, [it's time for **Hello, World!**](/handbook/vol1/chap1_7.md) +Now we are at an interesting point; we know how to hook functions, we know what function from a layer to hook in order to modify it, and we know how to work with nodes. So, let's tie all of this together! Only 7 chapters in, [it's time for **Hello, World!**](/handbook/vol1/chap1_7.md) ## Notes diff --git a/index.md b/index.md index 7209d6f..7fa8155 100644 --- a/index.md +++ b/index.md @@ -4,14 +4,14 @@ **Geode** is a [Geometry Dash](https://store.steampowered.com/app/322170/Geometry_Dash/) mod loader and modding SDK with a modern approach towards mod development. Unlike previous mod loaders, which merely inject the DLLs and let devs handle the rest, Geode aims to be a more comprehensive project, which manages loaded mods & hooks itself. Geode has been built to ensure performance, compatibility, portability and ease of use. For devs, Geode means easy development and portability; for end users, Geode means an uniform and easy experience using mods. +> :warning: These docs are intended for **developers** looking to use Geode. If you're someone who would just like to use mods, [see our homepage](https://geode-sdk.org/install). + ## Why Geode? The main goal of Geode is to **end mod incompatability**. Traditional modding leads very easily to compatability problems, many of which Geode attempts to address with better solutions. On top of this, and perhaps more interestingly, **Geode provides much better ergonomics for modding**. Instead of having to deal with calling conventions, trampolines, manually setting hooks (likely in another source file), you can have all the code relevant to hooks in a [nice, clean, readable syntax](/tutorials/modify.md) contained within a single source file. -See [What is Geode](/whatisgeode.md) for more detailed information about why you should use Geode. - ## Help, Contributing, Etc. If you need help using Geode or would like to contribute, feel free to join our [Discord Server](https://discord.gg/9e43WMKzhp). @@ -20,11 +20,7 @@ Alternatively, if you hate joining Discord servers to work with a framework, you ## Getting Started -See [Installation](/installation) for instructions on how to install the Geode SDK on your computer. - -See [Creating a new mod](/geode/creating) for instructions on how to make your first mod. - -See [Building](/source/building) for instructions on how to build Geode itself from scratch on your computer. +See [Getting Started](/getting-started) for a step by step tutorial on getting started with Geode SDK. See [Handbook](/handbook/chap0) for a beginner-friendly tutorial series on using Geode and GD Modding in general (WIP!!). @@ -36,12 +32,6 @@ See [Handbook](/handbook/chap0) for a beginner-friendly tutorial series on using -### Libraries - - * [Cocos2d-x](https://github.com/cocos2d/cocos2d-x/tree/cocos2d-x-2.2.3) - * [FMOD](https://www.fmod.com/) - * [fmt](https://fmt.dev/latest/index.html) - ### Special Thanks * [NachoBIT](https://github.com/TheNachoBIT) diff --git a/installation.md b/installation.md deleted file mode 100644 index da2991b..0000000 --- a/installation.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Installation -icon: download -description: Instructions for installing Geode -order: 0 ---- - -# Installing Geode - -## For Users - -Geode is currently available on **Windows** and **MacOS**; Android and iOS support is planned in the future. - -Geode is installed using **its own installer**. You can find the latest version [on the Geode homepage](https://geode-sdk.org) or [on GitHub](https://github.com/geode-sdk/installer/releases/latest). - -You can uninstall Geode from the installer aswell incase you want to play vanilla GD, or if you want to switch versions. - -You can also [install the files manually](#installing-geode-manually), should the installer not work. - -> :warning: Please note that Geode is **incompatible with all other mod loaders and mods**. We're porting stuff like Mega Hack and BetterEdit over, but don't expect their old releases to work. - -## Installing Geode Manually - -In most cases, you should be fine by using the installer for installing Geode. However, shenanigans can make it difficult at times for the installer to do it's job properly as of writing this. To get around it, you can simply drop the Geode files into the Geometry Dash folder following the instructions below. - -1. Download the most recent .zip release of Geode. You can get any of the releases **including betas** [from here](https://github.com/geode-sdk/geode/releases). It should contain several files, the v1.0.0-beta.18 release being shown below for example: - -(Older and/or newer releases including v0.6.1 or earlier may have slightly different files, but that's fine. You just need something similar to this.) - -![Image of the files in the .zip, listed in this order: 1. Geode.dll, 2. Geode.lib, 3. Geode.pdb, 4. GeodeBootstrapper.dll, 5. XInput9_1_0.dll.](/assets/GeodeFilesExample.png) - -2. Find your Geometry Dash folder. For Windows, it should be stored in `C:\Program Files (x86)\Steam\steamapps\common\Geometry Dash`. For MacOS, it should be stored in `/Library/Application Support/Steam/steamapps/common/Geometry Dash`. The `Library` directory is usually hidden, so using the Finder is ideal. Another easier way to find it is through Steam by right clicking Geometry Dash>Manage>Browse Local Files. - -![Image showing the easier method shown above](/assets/BrowseLocalFilesForGD.png) - -3. Extract all of the files from the Geode .zip folder into the Geometry Dash folder so that all the files from the .zip are on the same level as the Geometry Dash executable. - -Then launch the game. - -## Installing Geode SDK (for Developers) - -### Prerequisites - - * [CMake](https://cmake.org/download/) (minimum v3.13.4, prefer latest) - * A supported C++ compiler ([MSVC](https://visualstudio.microsoft.com/downloads/) for Windows, [clang](https://releases.llvm.org/) for MacOS) - * [git](https://git-scm.com/downloads) - -1. Install [Geode CLI](https://github.com/geode-sdk/cli/releases/latest) [(Instructions)](/geode/installcli) - * Unzip the download file somewhere, and [add the directory with geode.exe to your user's PATH variable](/geode/installcli#adding-cli-to-path-on-windows). You may need to restart your command line after adding the directory to your path. - -2. Install Geode to GD. This means using [the installer](#installing-geode) or [installing it manually](#installing-geode-manually) - -3. Run `geode sdk install` to install the SDK (You can provide an argument to `geode sdk install ` if you want to install somewhere other than the default path) - * The installation should automatically set the `GEODE_SDK` environment variable to point to the SDK on Windows. You might need to restart your terminal or IDE, or even have to restart your computer. If it still doesn't work then you'll have to set it manually, as it is required. - -4. Run `geode config setup` from the command line to set up a profile - -5. Run `geode sdk install-binaries` to install prebuilt binaries, or [build Geode yourself](/source/building.md) - * You can pick whether you want the `nightly` or `stable` branch of Geode. `nightly` is the latest commit of the `main` branch, and contains all of the latest and greatest features but may also feature crashes and possibly not even compile, whereas `stable` is the latest released version. Use `geode sdk update nightly` or `geode sdk update stable` to switch between the two branches. - -6. All done :) See the [instructions for creating a mod](/geode/creating.md). - diff --git a/mods/configuring.md b/mods/configuring.md index 4b79151..6467116 100644 --- a/mods/configuring.md +++ b/mods/configuring.md @@ -46,7 +46,7 @@ The name of the mod's developer. Should be a single name, like "HJfod" or "Alk". ### `description` -A short description of the mod. Should only be a single sentence; for longer descriptions, see [about.md](/mods/description.md). +A short description of the mod. Should only be a single sentence; for longer descriptions, see [about.md](/mods/md-files.md). ### `repository` diff --git a/mods/index.md b/mods/index.md index dc68148..cb44c86 100644 --- a/mods/index.md +++ b/mods/index.md @@ -1,7 +1,8 @@ --- description: A collection of tutorials for working with Geode mods +order: 3 --- -# Mods +# Geode Mods These are a collection of tutorials for working with Geode mods; how to setup your developer environment, how to add settings, dependencies, etc. diff --git a/mods/description.md b/mods/md-files.md similarity index 79% rename from mods/description.md rename to mods/md-files.md index c00de43..0093e53 100644 --- a/mods/description.md +++ b/mods/md-files.md @@ -1,44 +1,46 @@ ---- -title: Mod description -description: How to use about.md in a Geode mod ---- - -# `about.md` - -Geode mods can specify a long, free-form description typeset using Markdown by including a file named `about.md` at the root of their project. See [the MDTextArea class](/classes/geode/MDTextArea) for information on what features of Markdown are supported. - -## Example - -```md -# My Awesome Mod - -This is my awesome mod, that does **all** the awesome stuff! - -If you like this mod, please check [my other mod](mod:my.other-mod)! - -## Credits - -[Join my Discord](https://discord.gg/K9Kuh3hzTC)! Thanks to [Hu Tao](https://www.youtube.com/watch?v=8oap-n_OEgc) for helping with the mod! -``` - -# `changelog.md` - -You may also provide a markdown file that contains a changelog for your mod. In future updates, Geode may use this file to show release notes for the mod. - -```md -# v1.1.0 - - * Removed Herobrine - -# v1.0.1 - - * Fixed bugs - -# v1.0.0 - - * Initial release -``` - -# `support.md` - -You may also provide a markdown file that contains free-form information about how to support you, the mod's developer. This may include things like Patreon links, PayPal links, catgirl picture donation links, anything you wish to say! +--- +title: Special Markdown Files +description: How to use about.md and other Markdown files in a Geode mod +--- + +# `about.md` + +Geode mods can specify a long, free-form description typeset using Markdown by including a file named `about.md` at the root of their project. See [the MDTextArea class](/classes/geode/MDTextArea) for information on what features of Markdown are supported. + +This file is similar to a README, however **it's intended for people who use the mod**; you should also keep a README for developers interested in building / contributing to your mod. + +## Example + +```md +# My Awesome Mod + +This is my awesome mod, that does **all** the awesome stuff! + +If you like this mod, please check [my other mod](mod:my.other-mod)! + +## Credits + +[Join my Discord](https://discord.gg/K9Kuh3hzTC)! Thanks to [Hu Tao](https://www.youtube.com/watch?v=8oap-n_OEgc) for helping with the mod! +``` + +# `changelog.md` + +You may also provide a markdown file that contains a changelog for your mod. In future updates, Geode may use this file to show release notes for the mod. + +```md +# v1.1.0 + + * Removed Herobrine + +# v1.0.1 + + * Fixed bugs + +# v1.0.0 + + * Initial release +``` + +# `support.md` + +You may also provide a markdown file that contains free-form information about how to support you, the mod's developer. This may include things like Patreon links, PayPal links, catgirl picture donation links, anything you wish to say! diff --git a/mods/savedata.md b/mods/savedata.md index 00c775b..ce27882 100644 --- a/mods/savedata.md +++ b/mods/savedata.md @@ -6,7 +6,7 @@ Settings are covered [in their own tutorial](/mods/settings.md) - **this tutoria Unlike settings, save data does not need to be declared in `mod.json`, or anywhere else for that matter. Save data is automatically brought to life when you set it for the first time. Save data is, as the name implies, saved when the game is closed, and its previous state loaded back up the next time the game is opened. -You can save any type of value as long as it implements `json::Serialize` (see the [STL container implementations](https://github.com/geode-sdk/json/blob/main/include/json/stl_serialize.hpp) for an example). +You can save any type of value as long as it implements `matjson::Serialize` (see the [STL container implementations](https://github.com/geode-sdk/json/blob/main/include/matjson/stl_serialize.hpp) for an example). ## Setting & getting save data @@ -22,16 +22,16 @@ struct MyCustomSaveData { }; template<> -struct json::Serialize { - static MyCustomSaveData from_json(json::Value const& value) { +struct matjson::Serialize { + static MyCustomSaveData from_json(matjson::Value const& value) { return MyCustomSaveData { .x = value["x"].as_int(), .y = value["y"].as_int() }; } - static json::Value to_json(MyCustomSaveData const& value) { - auto obj = json::Object(); + static matjson::Value to_json(MyCustomSaveData const& value) { + auto obj = matjson::Object(); obj["x"] = value.x; obj["y"] = value.y; return obj; diff --git a/mods/settings.md b/mods/settings.md index 19f1d87..8a62db3 100644 --- a/mods/settings.md +++ b/mods/settings.md @@ -128,11 +128,11 @@ class MySettingValue : public SettingValue { // you are free to do whatever! public: - bool load(json::Value const& json) override { + bool load(matjson::Value const& json) override { // load the value of the setting from json, // returning true if loading was succesful } - bool save(json::Value& json) const override { + bool save(matjson::Value& json) const override { // save the value of the setting into json, // returning true if saving was succesful } diff --git a/mods/vscode.md b/mods/vscode.md deleted file mode 100644 index b02bb28..0000000 --- a/mods/vscode.md +++ /dev/null @@ -1,31 +0,0 @@ -# Fixing VS Code Errors - -Here are a couple of common errors people have experienced using Geode in VS Code and how to fix them. - -## Include file `` not found - -![Image showing VS Code C++ extension unable to find Geode headers](/assets/include_path_error.png) - -VS Code's C++ extension can't figure out the include path on its own. It is recommended to use the [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) extension, as it can automatically provide the includes through CMake, though it needs some setting up. - -First, once you have the CMake Tools extension installed, open up your Geode mod, press **F1** and run `CMake: Select a Kit`. This will bring up a list of installed compilers on your machine. - -![Image showing a bunch of compilers CMake detected in VS Code](/assets/win_compilers.png) - -On Windows, you should go with a Visual Studio compiler that is either `x86` or `amd64_x86`. Note that there is also an `x86_amd64` compiler - you don't want to pick that one! - -On Mac, you should go with Clang. - -If you're on Windows, press **F1** again and run `CMake: Select Variant`. - -![Image showing available build types on Windows: Debug, Release, MinSizeRel, and RelWithDebInfo](/assets/win_relwithdebinfo.png) - -You should go with either `RelWithDebInfo` (recommended at least for development) or `Release`. - -Now register CMake as the **Configuration Provider** for the C++ extension by running `C/C++: Edit Configurations (UI)` (you can also pick the JSON option if you know what you are doing). - -![Image showing the "C/C++: Edit Configurations (UI)" command being run in VS Code](/assets/win_usecmake.png) - -Scroll down to **Advanced** options, and set the Configuration Provider as `ms-vscode.cmake-tools`. - -Now if you run `CMake: Configure`, assuming you have Geode properly installed, the include errors should go away. diff --git a/quickstart.md b/quickstart.md deleted file mode 100644 index 83e67e9..0000000 --- a/quickstart.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -icon: play ---- - -# Quick Start for Using Geode to Make Mods - -1. [Install Geode SDK](/installation) - -2. [Install Geode CLI](/geode/installcli) - -3. [Install Geode VS Code extension](https://marketplace.visualstudio.com/items?itemName=GeodeSDK.geode) - -4. [Follow the Handbook if you're new](/handbook/chap0.md), or [check out the tutorials for Geode-specific modding](/tutorials/index.md) diff --git a/source/building.md b/source/building.md deleted file mode 100644 index 1f943bc..0000000 --- a/source/building.md +++ /dev/null @@ -1,40 +0,0 @@ -# Building - -These are instructions for building the [Geode Loader](https://github.com/geode-sdk/geode). For building your own mods, see [Getting Started](/starting). - -## Prerequisites: - - * [CMake](https://cmake.org/download/) (minimum v3.13.4) - * A supported C++ compiler ([clang](https://releases.llvm.org/)/[MSVC](https://visualstudio.microsoft.com/downloads/)) - * [Geode CLI](https://github.com/geode-sdk/cli) - * [git](https://git-scm.com/downloads) - -## Quick instructions (for thigh-high programmers) - -1. `git clone --recursive https://github.com/geode-sdk/geode.git` - -2. `cmake -B build -T host=x64 -A win32` - -3. `cmake --build build --config Release` - -## Recommended way (for normal people) - -1. Install [VS Code](https://code.visualstudio.com/) - -2. Install the [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) and [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) extensions for VS Code - -3. Open up the command line and navigate to any directory where you'd like to build the loader - -4. `git clone https://github.com/geode-sdk/geode --recursive` - -5. Open up the directory in VS Code - -6. Press F1 to open the Command Palette and run `CMake: Configure` (make sure to select an x86 generator, for example `Visual Studio Community 2019 Release - amd64_x86`. Note that for Visual Studio generators, the second number is the target architecture, which must be x86.) - -7. Open up the Command Palette again and run `CMake: Select Variant` (select either `Release` or `RelWithDebInfo`). This may also be done through the bottom status bar. There should be a button that displays `Debug`. Click on this and change it to the option in the dropdown that displays `Release` - -8. Click `Build` on the bottom status bar or run `CMake: Build` - -9. If building was succesful, you can move the files from `bin/nightly` to your Geometry Dash folder (move the contents of resources to `/geode/resources/geode.loader`) - - diff --git a/source/index.md b/source/index.md index bd7112a..f9d7ab6 100644 --- a/source/index.md +++ b/source/index.md @@ -1,5 +1,6 @@ --- title: Source +order: 5 --- These pages contain info about the Geode codebase itself. \ No newline at end of file diff --git a/source/indexrules.md b/source/indexrules.md index 0624ae6..0b81df2 100644 --- a/source/indexrules.md +++ b/source/indexrules.md @@ -64,8 +64,10 @@ However, if your mod is closed source, you will have to send it source code priv In general, all Lead Geode Devs can add new mods to the index. However, in practice, for most mods you should ask **HJfod** for mods available on Windows and **alk** or **Camila** for mods on MacOS. For cross-platform mods, ask anyone. - * HJfod (Windows) | HJfod#1795 - * Pie (Windows) | pie#1593 - * Mat (Windows) | Mat#7533 - * Alk (MacOS) | alk1m123#3076 - * Camila (MacOS) | camila314#4124 + * HJfod (Windows) | hjfod + * Pie (Windows) | poweredbypie + * Mat (Windows) | mat.4 + * fig (Windows) | figmentboy + * ConfiG (Windows) | cgytrus + * Alk (MacOS) | alk1m123 + * Camila (MacOS) | camila314 diff --git a/tutorials/events.md b/tutorials/events.md new file mode 100644 index 0000000..ead1650 --- /dev/null +++ b/tutorials/events.md @@ -0,0 +1,159 @@ +# Events + +For most things in GD, such as `CCTextInputNode`, GD and Cocos2d-x use a **delegate-based event system**, where you install a delegate on the target class, and the delegate receives events via overridden virtual functions. This system works fine for most situations, but is often quite clumsy to use and runs into a few important issues: you have to manually deal with removing the delegate if the target class outlives the delegate, and more importantly, you can only have one delegate per target. + +As an alternative to this system, Geode introduces **events**. Events are essentially just small messages broadcast across the whole system: instead of having to install a single delegate, an unlimited number of classes can listen for events. The target that emits the events does not need to have any knowledge of its consumers; it just broadcasts events, and any receivers there are can handle them. + +Events are primarily interacted with through three classes: [`Event`](/classes/geode/Event), [`EventListener`](/classes/geode/EventListener), and [`EventFilter`](/classes/geode/EventFilter). `Event` is the base class for the events that are being broadcast; `EventListener` listens for events, and it uses an `EventFilter` to decide which events to listen to. Let's explore how they work through **an example**. + +Consider a system where one mod introduces a **drag-and-drop API** to Geode, so the user can just drag files over the GD window. Now, this mod itself probably won't know how to handle every single file type ever; instead, it exposes an API so other mods can handle actually dealing with different file types. However, using a delegate-based system here would be quite undesirable - there is definitely more than one file type in existence. While the mod could just have a list of delegates instead of a single one, those delegates have to manually deal with telling the mod to remove themselves from the list when they want to stop listening for events. + +Instead, the drag-and-drop API should leveradge the Geode event system by first defining a new type of event based on the `Event` base class: + +```cpp +using namespace geode::prelude; + +class DragDropEvent : public Event { +public: + using Files = std::vector; + +protected: + Files m_files; + CCPoint m_location; + +public: + DragDropEvent(Files const& files, CCPoint const& location); + + Files getFiles() const; + CCPoint getLocation() const; +}; +``` + +Now, the drag-and-drop mod can post new events by simple creating a `DragDropEvent` and calling `post` on it. + +```cpp +void handleFilesDroppedOnWindow(...) { + ... + + DragDropEvent(...).post(); +} +``` + +That's all - the drag-and-drop mod can now rest assured that any mod expecting drag-and-drop events has received them. + +Let's see how that listening part goes, through an example mod that expects [GDShare](https://github.com/hjfod/GDShare-mod) level files and imports them: + +```cpp +using namespace geode::prelude; + +$execute { + new EventListener>(+[](DragDropEvent* ev) { + for (auto& file : ev->getFiles()) { + if (file.extension() == ".gmd") { + handleGMDImport(file); + + // This stops event propagation, marking the file as handled. + // Stopping propagation is usually not needed, and shouldn't be + // done by default, however sometimes you want to stop other + // listeners from dealing with the event - such as here, where + // importing the same file twice would be undesirable + return ListenerResult::Stop; + } + } + // Propagate this event down the chain; aka, let other listeners see + // the event + return ListenerResult::Propagate; + }); +} +``` + +This is all the mod needs to do to set up a **global listener** - one that exists for the entire duration of the mod. Now, whenever a `DragDropEvent` is posted, the mod catches it and can do whatever it wants with it. + +This code also uses the default templated `EventFilter` class, which just checks if an event is right type and then calls the callback if that is the case, stopping propagation if the callback requests it to do so. However, we sometimes also want to create custom filters. + +For example, let's say another mod wants to use the drag-and-drop API, but instead of always listening for events, it wants to have a specific node in the UI that the user should drop files over. In this case, the listener should only exist while the node exists, and only accept events if it's over the node. We could of course deal with this in the global callback, however we can simplify our code by creating a custom filter that handles accepting the event. We can also include the file types to listen for in the filter itself, simplifying our code even further. + +We can create a custom `EventFilter` by inheriting from it: + +```cpp +using namespace geode::prelude; + +class DragDropOnNodeFilter : public EventFilter { +protected: + CCNode* m_target; + std::unordered_set m_filetypes; + +public: + // The callback does not need to return ListenerResult nor take the whole + // DragDropEvent as a parameter - if the callback is called, then we know + // the event was over the node and the file types were correct already + using Callback = void(std::vector const&); + + ListenerResult handle(MiniFunction fn, DragDropEvent* event); + DragDropOnNodeFilter(CCNode* target, std::unordered_set const& types); +}; +``` + +For the implementation of `handle`, we need to check that the event occurred on top of the target node: + +```cpp +ListenerResult DragDropOnNodeFilter::handle(MiniFunction fn, DragDropEvent* event) { + // Check if the event happened over the node + if (m_target->boundingBox().containsPoint(event->getLocation())) { + // Filter out only file types we can accept + std::vector valid; + for (auto& file : event->getFiles()) { + if (m_filetypes.contains(file.extension().string())) { + valid.push(file); + } + } + fn(valid); + // Mark dropped files as handled + return ListenerResult::Stop; + } + // Otherwise let other listeners handle it + return ListenerResult::Propagate; +} +``` + +Now, to install an event listener on a specific node, we have two options. If the node is our own class, we can just add it as a class member: + +```cpp +class DragDropNode : public CCNode { +protected: + EventListener m_listener = { + // You can bind member functions as event listeners too! + this, &DragDropNode::onDrop, + // The filter requires some args so we have to explicitly construct it + DragDropOnNodeFilter(this, { ".gmd", ".gmd2", ".lvl" }) + }; + + void onDrop(std::vector const& files) { + // Handle dropped files + } +}; +``` + +When `DragDropNode` is destroyed, the listener is automatically destroyed and unregistered aswell, so you don't need to do anything else. + +However, using a member function is not always possible. For example, if you're hooking a class, [event listeners don't work in fields](/tutorials/fields.md#note-about-addresses); or if you want to listen for events on an existing node whose class you don't control. + +In these cases, there exists a Geode-specific helper called [`CCNode::addEventListener`](/classes/cocos2d/CCNode#addEventListener). You can use this to **add event listeners to any node** - including existing ones by GD! + +```cpp +auto dragDropNode = CCNode::create(); +dragDropNode->template addEventListener( + [dragDropNode](auto const& files) { + // Handle dropped files + }, + { ".gmd", ".gmd2", ".lvl" } +); +``` + +`addEventListener` is meant only for events that are have a target node - it assumes that the first parameter of the filter's constructor takes `this` as the argument. Other parameters to the filter's constructor, such as the file types here, can be passed as the rest of the argument list to `addEventListener`. + +Any event listener added with `addEventListener` is automatically destroyed aswell when the node is destroyed. You can also provide a string ID for the event listener as the first argument to `addEventListener`, and then manually remove the listener later using [`removeEventListener`](/classes/cocos2d/CCNode#removeEventListener). + +## Dispatched events + +There also exist special types of events called **dispatch events** - these are intended for use within optional dependencies. See [the tutorial on dependencies](/mods/dependencies.md#events) for more information. diff --git a/tutorials/fields.md b/tutorials/fields.md index a4b91c7..db51361 100644 --- a/tutorials/fields.md +++ b/tutorials/fields.md @@ -50,5 +50,7 @@ class $modify(PlayerObject) { }; ``` -\* Fields are constructed and destructed in a different address than they exist normally (yes I know ub but we kinda need the space optimization), so if you have a class that depends on the value of this inside the constructor/destructor, I would recommend using `std::unique_ptr` to contain the said object. One such example would be Geode's events, since they are registered to a global map in their constructor. +## Note about addresses + +> :warning: Fields are constructed and destructed in a different address than they exist normally (required for space optimization), so **if you have a class that depends on the address of `this` inside the constructor/destructor**, use `std::unique_ptr` to contain the said object. One such example would be Geode's events, since they are registered to a global map in their constructor. diff --git a/tutorials/index.md b/tutorials/index.md index b4114a9..ccf8b20 100644 --- a/tutorials/index.md +++ b/tutorials/index.md @@ -1,3 +1,7 @@ +--- +order: 2 +--- + # Modding Tutorials These are a collection of **tutorials** and **information** for using making Geometry Dash mods using the Geode framework. These are focused on general modding tips & Geode-specific features. diff --git a/tutorials/memory.md b/tutorials/memory.md index 0eeb72d..4afc9b4 100644 --- a/tutorials/memory.md +++ b/tutorials/memory.md @@ -33,7 +33,7 @@ auto node = CCNode::create(); node->release(); ``` -You can think of `retain` and `release` like the following: `retain` tells Cocos2d "Hey, I'm still using this object, please don't free it!", and `release` tells it "Okay, you can free the memory now!" +You can think of `retain` and `release` like the following: `retain` tells Cocos2d "Hey, I'm still using this object, please don't free it!", and `release` tells it "Okay, I don't need this object anymore!" In practice, if you have to do manual memory management, you likely won't be using the `retain` and `release` functions directly and instead use the `CC_SAFE_RETAIN` and `CC_SAFE_RELEASE` macros: diff --git a/usagein10steps.md b/usagein10steps.md deleted file mode 100644 index 0ee9fff..0000000 --- a/usagein10steps.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Using Geode -icon: play ---- - -# Top 10 Geode Concepts - -This is a quick overview of the **most major concepts in Geode**. Some of these are familiar from other modding toolkits, but some are Geode-specific! - -## 1. Mods - -The central concept in Geode is - quite obviously - the mods. In Geode, these come in the form of `.geode` files - ZIP files that contain all of the mods assets, including platform-specific binaries, resources, and info about the mod, with the most important one being **mod.json**. It is a file that has all the basic information about the mod - its name, developer, a description, and other things you might expect. The most important thing in this file is the **mod ID** - a short human-readable piece of text that uniquely identifies this mod. This ID is used by other mods to check if this mod is loaded, by the loader to see if this mod has updates available, and in every situation where a reference to this mod is needed. - -At runtime, every mod also has associated with it an instance of the [Mod](/classes/geode/Mod) class - which the current mod can access by doing `Mod::get()`, and through which everything from placing hooks to patching addresses to saving settings is done. - -## 2. Loader - -Of course, there has to be something to load the mods, and for that there is the **Geode loader** - an instance of the [Loader](/classes/geode/Loader) class. The loader is the central manager in Geode - it manages all mods, and deals with setting up everything, like crashlogs, resources, etc.. - -## 3. Codegen & Headers - -As Geode's goal is to be cross-platform, its set of GD headers has to be carefully crafted to include definitions for all platforms. For this reason, Geode uses codegen to generate its headers. Another benefit of this is that if Geode is missing a function you need, **adding new bindings is really easy** - you just have to add it to [your local copy of Geode's GeometryDash.bro](https://github.com/geode-sdk/geode/blob/main/bindings/GeometryDash.bro), the file Geode uses to codegen all of its GD bindings. - -## 4. CLI - -To help work with Geode mods, Geode comes with [its own command-line tool called Geode CLI](https://github.com/geode-sdk/cli). The CLI handles things like installing & updating the Geode SDK and packaging `.geode` files - and to that end has a lot of really useful functionality. For example, if you want to include resources or custom fonts in your mod, all you have to do is specify them in your **mod.json** and Geode CLI will automatically package all of them for you - no need to mess around with TexturePacker or related tools! - -## 5. Hooks - -In order for mods to do something, they need to place hooks. If you are new to modding and don't know what that is, [check out the handbook](/handbook/chap0.md). For experienced modders, the way you place hooks in Geode is -```cpp -// this magical syntax is basically just the entry point, like int main() -$on_mod(Loaded) { - Mod::get()->addHook( - reinterpret_cast(base::get() + address), - &myAwesomeHook, - "My awesome hook!", - tulip::hook::TulipConvention::Thiscall - ); -} -``` -However, as this is quite verbose and having to manually specify all of your hooks kinda blows, Geode comes with incredibly magical syntactic sugar known as **`$modify`**: -```cpp -class $modify(TargetLayer) { - bool functionToHook(...) { - // TargetLayer::functionToHook is now hooked! no other code necessary - } -}; -``` - -## 6. Events - -In order for mods to communicate with each other, the traditional way to do it is by linking to the other mod. While this is still possible in Geode, what if you would like to have an optional dependency - as in, only do stuff related to another mod if it is loaded? For this, the main mechanism Geode introduces are called **events**. Events are basically what their name suggests - you can post events to other mods, and listen for events. Events include things like **mods being loaded**, **settings being edited**, etc.. - -These are somewhat reminiscent of **delegates** in Cocos2d and GD - however, as events are based on string IDs, can be applied to any existing class, can have any number of listeners, and can transmit any data, they are much more powerful. - -## 7. Node IDs - -Every mod has to interact with GD's UI in some way, and this will eventually result in the modder asking themselves the eternal question - how do I add my button next to this other button in the UI? Traditionally, the only way to do this has been to traverse the node tree using the absolute indices of child nodes - that is, getting the 3rd child of this menu, then the 5th child of that, then so on and so forth. **This breaks incredibly easily**, as the moment there is any disruption to the amount of children in a node, mods get thrown off. - -As this is really common in mods and also one of the most common sources of incompatabilities, Geode provides a much better alternative - **node IDs**. With IDs, instead of getting the 3rd child of a layer, you can just do `this->getChildByID("the-button-im-looking-for")`. This is much more consistent, as you can be pretty much certain that this will never fail - and you don't have to write any sort of property-based node lookup code to verify that is the case! - -On top of this, node IDs also enable other mods to safely rewamp scenes without fear of breaking other mods - if you want to make a mod that changes the layout of [MenuLayer](/classes/MenuLayer), all you have to make sure is that all of the node IDs are still there, and you can rest assured that other mods will work - assuming they aren't using absolute child indices for some reason. - - - -## 8. Index - -Geode comes with an in-game list, from where users can download & update mods at the click of a button. Once your awesome mod is ready for publishing, you should [submit it to the Geode index so it appears on the list](https://github.com/geode-sdk/mods). This way, you don't have to worry about setting up servers to distribute your mods and explain how to install your mod to users - we will handle that for you :) - -## 9. Developer Tools - -Geode's development aid is not limited to just the framework and CLI - Geode also has [its own VS Code extension](https://marketplace.visualstudio.com/items?itemName=GeodeSDK.geode) that comes with a bunch of useful tools for working with GD mods, and [a developer tools mod](https://github.com/geode-sdk/DevTools) for inspecting layers in-game. - -## 10. Docs - -One final minor goal of Geode is to **spread modding knowledge more**. GD modding has long been plagued by a lack of tutorials, documentation, and examples - and we want to change that. The goal of Geode docs is not only to explain how Geode works, but to act as a learning resource for GD modding in general, so that future modders won't have to learn everything by themselves through trial-and-error like we did. To that end, we have automated documentation for all GD and Cocos2d classes here on the docs site, tutorials for common things like [making popups](/tutorials/popup.md) and [creating buttons](/tutorials/buttons.md), and [a handbook that teaches everything there is to know about GD modding from the ground up](/handbook/chap0.md). - -If you are interested in trying Geode out for yourself, see [Installation](/installation.md) for installation instructions, and [Quick Start](/quickstart.md) for getting started with developing mods for Geode. diff --git a/whatisgeode.md b/whatisgeode.md deleted file mode 100644 index 7492200..0000000 --- a/whatisgeode.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -icon: help-circle -description: An explanation of what Geode is ---- - -# What is Geode? - -![A screenshot of a bug, where the mods BetterEdit and GDShare are conflicting, with a button added by GDShare being misplaced as a result](/assets/BetterEdit_GDShare_bug.png) - -> This is an image of two popular mods, GDShare and BetterEdit, infamously conflicting with each other, with the result being misplaced buttons and a lot of disgruntled developers. A huge percentage, if not a majority of all bugs reported in GD mods are caused by **hook conflicts**, **direct node tree access**, and other **mod incompatabilities**. **This is what Geode has been made to solve.** - - * Geode's main goal is to **make using mods less of a pain**; installing mods is simple, and things just work out-of-the-box with no need to mess around with load order. - - * Geode is also **a complete framework**. Instead of having to add `gd.h`, `cocos-headers`, and `MinHook` to every project every single time, Geode has all of the GD and Cocos2d headers in one package, along with a bunch of utilities that make modding simpler. - - * Geode does not impose any limits on what mods you can make; all of the basics, like hooking, creating UI, and the meat of how the mod works are still all the same. **All Geode does is reduce the amount of boilerplate you have to write**, and provide a lot of utilities to ensure your mod works together with other mods. - - * Geode does not load traditional `.DLL` mods; instead, it loads mods packaged as `.geode` files. This does mean that **by default, Geode will not load any old mods**. However, we do plan on making a mod that lets you load old DLLs (and you can also technically install Geode alongside another mod loader, however this will likely break!); with the caveat **that older mods are very likely going to break in many ways**. This is an unfortunate result of the fact that **Geode can only ensure mods built for it work**. Older mods by nature can not be made compatible with each other. - - * We're working on porting as many older mods over to Geode as we can, as that is the only way we can ensure stability. Luckily, this also provides us a golden opportunity to fix long-standing bugs and improve the mods - **BetterEdit**, **TextureLdr**, **GDShare**, **Run Info**, and more will have new, much better versions in Geode. If there's a mod you'd like to see ported to Geode, [do let us know](https://discord.gg/9e43WMKzhp). - - * **In short, it is to GD what Forge / Fabric are to Minecraft.**