Skip to content

Commit

Permalink
docs(readme): update instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
Curve committed May 2, 2023
1 parent da01daa commit 0c343b6
Showing 1 changed file with 86 additions and 45 deletions.
131 changes: 86 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,22 @@ The installation of chalchiu is fairly simple:
* Locate your Game Folder
> e.g. `C:/GOG Games/Coromon/`
* Rename the `CoronaLabs.Corona.Native.dll` to `orig.dll`
> **Warning**
> This should only be done when you install chalchiu for the **first time**!
> **Ignore this step when updating!**
* Place the `CoronaLabs.Corona.Native.dll` found in the latest [Release](https://github.com/Curve/chalchiu/releases) into the same game directory

* Download the zip file from the latest [Release](https://github.com/Curve/chalchiu/releases) and unpack all files into the game directory
* Your Game Folder should now roughly look like this
> Please note that some files have been omitted
```
📂 C:/GOG Games/Coromon
├── coromon.exe
├── CoronaLabs.Corona.Native.dll
├── corona-plugins
├── iphlpapi.dll
├── libeay32.dll
├── lua.dll
├── mods
├── ...
```
* Start the Game, the following things should happen:
* A Log File named `chalchiu.txt` is created
* A Log File named `chalchiu.log` is created
* A Folder named `mods` is created in the game directory
* Your Game Window Title includes information about the loaded mods

Expand All @@ -48,27 +55,33 @@ The installation of chalchiu is fairly simple:

You can find some example mods in the [examples](./examples/) folder.

A `dump_modules` mod is also included, which will dump all modules loaded by the game into the log.
A `debug` mod is also included, which will dump all modules loaded by the game into the log.
This is especially useful when you don't want to unpack the precompiled lua scripts the game uses, as just having information on the game modules is often enough to get started.

## Writing a Mod

Creating a mod is fairly simple.
All you need to do is create a folder for your mod and place an `init.lua` inside of it.

There are two types of mods, `hooks` and `scripts`, `hooks` are ran once a specified module is loaded, and `scripts` will just be run when loaded.
The `init.lua` **is the only file that is explicitly loaded** by chalchiu.
You can however use `require` to load any files from the same directory your mod resides in.

Regardless of wether or not your mod is a `hook` or a `script`, the following basic structure is required:
You are expected to return a table containing some information about your mod from your `init.lua`.

<table>
<tr>
<td>Basic Structure</td>
<td>(Example) init.lua</td>
</tr>
<tr>
<td>

```lua
require("hooks") -- Will load the `hooks.lua` residing in the same directory

return {
name = 'Name', -- The name of your mod
author = '....', -- Who wrote the mod?
version = '....', -- Current version of your mod
description = '....', -- The description of your mod
}
```
Expand All @@ -77,61 +90,89 @@ return {
</tr>
</table>

Now, depending on what type of mod you wan't to write, the following fields are required:
## Utilities

* `hook`
* target
> The module you plan to intercept / modify
* hook
> The callback function that is ran once the specified module is loaded.
> The loaded `module` will be passed as the first parameter
There are some utilities you can use from within your mod.

* `script`
* `script`
> The function to be run on load
### Hooks

Hooks are an essential part of mods, as they allow you to modify modules loaded by the game as well as allowing you to dictate when a certain piece of code is run.

> **Warning**
> The filename under which you save your mod is **important!**
> Lua files in the `mods` directory will **only be loaded if** their filename ends on `mod.lua`
Hooks in chalchiu allow you to intercept lua `require` calls, which allows you to e.g. modify the original table and replace certain game logic with your own.

### Example Mod
All you need is the name of a `module` you want to hook. _(To get a list of modules you can use the [debug mod](examples/debug/))_

<table>
<tr>
<td>example_mod.mod.lua</td>
<td>Registering a hook</td>
</tr>
<tr>
<td>

```lua
return {
name = 'Name', -- The name of your mod
description = '....', -- The description of your mod
hooks.add("module.to.hook", function(table)
-- `table` is the original table that would've been returned

target = 'classes.modules.playerCurrency', -- The module we want to intercept, can be obtained through the `dump_modules` mod.
hook = function (table)
-- We now have full access to the module table
local original = table.onLoadSaveslotData -- Save the original function

-- Now we overwrite the `onLoadSaveslotData` function with our own, so that we can modify the amount of gold the player is holding.
table.onLoadSaveslotData = function(self, data)
data.gold = 2^52
return original(self, data)
end
end
}
-- You can now fully alter the table, and e.g. overwrite some function:
table["max"] = table["min"]
end)
```

</td>
</tr>
</table>

### Detours

The `detour` function allows you place a detour on any lua function and are often used together with [hooks](#hooks).

Detours can be useful for many things, e.g. modifying the players money when a save game is loaded.

<table>
<tr>
<td>Example Detour</td>
</tr>
<tr>
<td>

```lua
hooks.add("classes.localPlayer", function(table)
detour(table, "getMoney", function(original, self, ...)
-- `original` refers to the "original" (i.e. non detoured version) of the function
local originalMoney = original(self, ...)
return originalMoney * 1000
end)
end)
```

</td>
</tr>
</table>

### Globals

Every mod is loaded in its own lua environment, thus it does not have write access to the global lua table.

## Caveats
If you need explicit write access to the global table, you can use the `globals` variable, which refers to the global lua table used by the game.

> Most of the time you will not need this, however this can sometimes be useful, e.g. when you want to require one of the games files.
<table>
<tr>
<td>Simple Demonstration</td>
</tr>
<tr>
<td>

```lua
local not_math = require("math") -- This will fail as it will look for a `math.lua` inside of your mod!
local math = globals.require("math") -- This will load the same math as used by the game
```

</td>
</tr>
</table>

* When trying to `require` local files *(i.e. files you distribute along side the mod)*, you will have to use `req` instead of lua's built-in `require`.
* Using `req` may only work appropriately when called from inside the `hook` / `script` callback

</p>
</details>

0 comments on commit 0c343b6

Please sign in to comment.