mirror of
https://github.com/izzy2lost/Ghostship.git
synced 2026-10-26 11:45:44 -07:00
87 lines
3.5 KiB
Markdown
87 lines
3.5 KiB
Markdown
# **Harbour Masters C Mod Template**
|
|
|
|
A streamlined template for creating C-based mods for games utilizing the libultraship engine (e.g., Super Mario 64 PC ports).
|
|
|
|
This template utilizes a Unity Build (amalgamation) pipeline. It allows you to write clean, modular C code organized across multiple directories, and automatically compiles them down into a single, portable mod.c file. This single-file output is perfectly formatted for dynamic compilation and loading via TCC (Tiny C Compiler) or for easy distribution.
|
|
|
|
## **🌟 Features**
|
|
|
|
* **Automated Amalgamation:** Uses a custom Python script hooked into CMake to safely merge all your .c and .h files, preventing redefinition errors.
|
|
* **Cross-Platform Exports:** Includes HM_API macros to handle the exact ABI export rules so the engine's dynamic linker can always find your ModInit function.
|
|
* **Event Hooking:** Includes a working boilerplate for tapping into the engine's event system (e.g., GameFrameUpdate, RenderGamePost).
|
|
|
|
## **📂 Directory Structure**
|
|
|
|
```
|
|
├── CMakeLists.txt # The build configuration
|
|
├── include/
|
|
│ └── mod.h # Core macros (MOD_INIT, MOD_EXIT, HM_API)
|
|
├── src/
|
|
│ └── demo.c # Your actual mod logic and event listeners
|
|
└── output/
|
|
├── dist/ # The final c files goes here after building
|
|
├── build.gen # The list of how to build the mod (auto-generated)
|
|
└── manifest.json # Metadata for the mod loader
|
|
```
|
|
|
|
## **🚀 Getting Started**
|
|
|
|
### **Prerequisites**
|
|
|
|
* **CMake** (3.10 or higher)
|
|
* **Python 3** (used for the amalgamation step)
|
|
* The libultraship source headers available in your parent directory structure.
|
|
|
|
### **Building the Mod**
|
|
|
|
We use an out-of-source build to keep the working directory clean. The CMake script will automatically grab all files in the src/ directory and generate the single mod.c in the output/ folder.
|
|
|
|
1. Open your terminal in the project root.
|
|
2. Create a build directory and configure the project:
|
|
```Bash
|
|
mkdir build
|
|
cd build
|
|
cmake ..
|
|
```
|
|
|
|
3. Run the build process:
|
|
```Bash
|
|
cmake --build .
|
|
```
|
|
|
|
4. Your fully amalgamated mod will be available at output/mod.c, ready to be packaged alongside manifest.json.
|
|
|
|
## **🛠️ Writing Your Mod**
|
|
|
|
### **The Entry and Exit Points**
|
|
|
|
Every mod requires an entry point so the engine knows how to initialize it. Use the provided macros from mod.h:
|
|
|
|
```C
|
|
#include "mod.h"
|
|
|
|
MOD_INIT() {
|
|
// Called when the mod is dynamically loaded.
|
|
// Register your engine listeners here.
|
|
}
|
|
|
|
MOD_EXIT() {
|
|
// Called when the mod is unloaded or the game closes.
|
|
// Unregister your listeners and free memory here.
|
|
}
|
|
```
|
|
|
|
### **Hooking into Engine Events**
|
|
|
|
The template includes a demo.c file showing how to hook into the engine's game loop.
|
|
|
|
* **GameFrameUpdate**: Ideal for gameplay logic (e.g., modifying gMarioState).
|
|
* **RenderGamePost**: Ideal for drawing custom UI (e.g., using print_text_centered).
|
|
|
|
Make sure to store your ListenerIDs globally so you can properly unregister them in MOD_EXIT().
|
|
|
|
### **⚠️ Important Note on Unity Builds (Amalgamation)**
|
|
|
|
Because all of your .c files are ultimately merged into a single mod.c file, everything shares the same global scope.
|
|
|
|
* **Use static:** If you write a helper function that should only be used internally, **always** prefix it with static. This ensures it won't accidentally collide with functions of the same name in the game engine or other mods once loaded into memory. |