|
| 1 | +# Integrate |
| 2 | + |
| 3 | +A library for mod loading into serialisable registries. |
| 4 | + |
| 5 | +## Terminology |
| 6 | + |
| 7 | +- A _registry_ is a data structure for holding case-insensitive key-value pairs. Simply, it matches names to objects, without caring about capitalisation. They are instances of `Integrate.Registry`. |
| 8 | +- *Registry name*s are string locations of an item in a _registry_. |
| 9 | +- *Constructible object*s are basic objects with a `type` property, holding a _registry name_ of a class. |
| 10 | +- _Content_ refers to any constructible object with a registry name, defined by the mod. Any content is an instance of `Integrate.Content`. |
| 11 | +- A _mod_ is a directory of files, each one adding _content_. |
| 12 | +- A _content file_ is a JSON file holding a _constructible object_. |
| 13 | + |
| 14 | +## Example (JS) |
| 15 | + |
| 16 | +_Adding Integrate mods to your project_ |
| 17 | + |
| 18 | +```js |
| 19 | +//Import Integrate |
| 20 | +import * as Integrate from "../integrate.js"; |
| 21 | +//"Game" Setup |
| 22 | +Integrate.types.add("entity", class Entity {}); |
| 23 | +Integrate.types.add("block", class Block {}); |
| 24 | +Integrate.types.add("item", class Item {}); |
| 25 | + |
| 26 | +//Modloader Setup |
| 27 | +let content = new Integrate.Registry(); |
| 28 | +Integrate.addModdableRegistry(content, "content"); |
| 29 | +Integrate.setPrefix(true); |
| 30 | + |
| 31 | +//Tests |
| 32 | +Integrate.add("./mod").then(() => content.forEach(x => console.log(Integrate.construct(x)))); |
| 33 | +``` |
| 34 | + |
| 35 | +On load, logs: |
| 36 | + |
| 37 | +``` |
| 38 | +> Block {type: "block", width: 20, height: 20, health: 200} |
| 39 | +``` |
| 40 | + |
| 41 | +## Example (Directory) |
| 42 | + |
| 43 | +_The directory structure for Integrate mods_ |
| 44 | + |
| 45 | +``` |
| 46 | +(mod root) |
| 47 | + |-> mod.json |
| 48 | + |-> definition file |
| 49 | + |=> (content) |
| 50 | +``` |
| 51 | + |
| 52 | +### mod.json |
| 53 | + |
| 54 | +Holds the basic information for the mod: |
| 55 | + |
| 56 | +```json |
| 57 | +{ |
| 58 | + "name": "example", |
| 59 | + "displayName": "Example Mod", |
| 60 | + "definitions": "./definitions.json", |
| 61 | + "tagline": "Basic mod to show functionality.", |
| 62 | + "description": "This mod exists only to show functionality of the modloader, and is not intended to be played with in any game. It is purely for demonstrative purposes.", |
| 63 | + "author": "LightningLaser8", |
| 64 | + "version": "v0.1.0" |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +`name` defines the _mod identifier_ - a string used to differentiate this mod's content form another's. |
| 69 | +`displayName` defines the name shown, both in info and possibly other parts of the program. |
| 70 | +`tagline` defines a _short_ description of the mod, usually a single line. |
| 71 | +`description` defines a longer description, which can be multiple lines, and should describe the type of content, or the premise of the mod. |
| 72 | +`author` defines the name that should be shown to have made the mod. |
| 73 | +`version` defines the _mod's version_, should be used to detect updated mods in saves, for example. |
| 74 | + |
| 75 | +`definitions` gives the path _from the mod.json file_ to the dfinition file. |
| 76 | + |
| 77 | +### Definition File |
| 78 | + |
| 79 | +This is the most important file in any Integrate mod, defining paths and registry names of _content_. |
| 80 | + |
| 81 | +```json |
| 82 | +[ |
| 83 | + { |
| 84 | + "path": "./wall.json", |
| 85 | + "name": "wall", |
| 86 | + "registry": "content" |
| 87 | + } |
| 88 | +] |
| 89 | +``` |
| 90 | + |
| 91 | +It consists of a _single array_, each entry being an object with these three properties: |
| 92 | +`path` defining the _relative location_ of the _content file_ being described. |
| 93 | +`name` being the _registry name_ of this content. |
| 94 | +`registry` being optional, defining the registry this content will be added to. By default, this will be `"content"`. **This registry does not exist by default, and will throw errors if not defined.** |
| 95 | + |
| 96 | +### Content Files |
| 97 | + |
| 98 | +These describe the actual content itself, not metadata. |
| 99 | + |
| 100 | +```json |
| 101 | +{ |
| 102 | + "type": "block", |
| 103 | + "width": 20, |
| 104 | + "height": 20, |
| 105 | + "health": 200 |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +`type` is mandatory, it defines the _registry name_ of the class this object will be an instance of. |
| 110 | +`width`, `height` and `health` are specific to this type, and are not necessary in content files. They are properties of the class stored at `"block"` in the Registry `Integrate.types`. |
| 111 | + |
| 112 | +## Interface |
| 113 | + |
| 114 | +Integrate has several functions to customise modloading, which are documented here. |
| 115 | + |
| 116 | +### Integrate.add() |
| 117 | + |
| 118 | +`Integrate.add()` loads, constructs and implements a mod all in one go. |
| 119 | + |
| 120 | +```ts |
| 121 | +Integrate.add(path: string): void |
| 122 | +``` |
| 123 | + |
| 124 | +`path` is the relative path from the current window location to the mod's _root directory_, **not** the mod.json. |
| 125 | + |
| 126 | +### Integrate.load() |
| 127 | + |
| 128 | +`Integrate.load()` loads a mod from a path, and returns the `Integrate.Mod` object. |
| 129 | + |
| 130 | +```ts |
| 131 | +Integrate.load(path: string): Integrate.Mod |
| 132 | +``` |
| 133 | + |
| 134 | +`path` is the relative path from the current window location to the mod's _root directory_, **not** the mod.json. |
| 135 | +Returns an `Integrate.Mod` object, holding all the info about the imported mod. Once loaded, this object is all that's needed. |
| 136 | + |
| 137 | +### Integrate.addModdableRegistry() |
| 138 | + |
| 139 | +`Integrate.addModdableRegistry()` adds a registry to the list of modifiable registries. This list defines which registries mods can add content to. |
| 140 | + |
| 141 | +```ts |
| 142 | +Integrate.addModdableRegistry(reg: Integrate.Registry, name: string): void |
| 143 | +``` |
| 144 | + |
| 145 | +`reg` is the `Integrate.Registry` (or similar implementing the same methods) to allow modification of. |
| 146 | +`name` is the string that this registry will be referred to by. |
| 147 | + |
| 148 | +### Integrate.setPrefix() |
| 149 | + |
| 150 | +`Integrate.setPrefix()` changes whether or not mod content's registry names should be prefixed with the mod's `name`. |
| 151 | + |
| 152 | +```ts |
| 153 | +Integrate.setPrefix(value: boolean): void |
| 154 | +``` |
| 155 | + |
| 156 | +`value` is the new Boolean value of this flag. `true` means prefixes on, `false` means prefixes off. By default this is `false`. |
| 157 | + |
| 158 | +### Integrate.setInfoOutput() |
| 159 | + |
| 160 | +`Integrate.setInfoOutput()` changes the way Integrate shows status messages. |
| 161 | + |
| 162 | +```ts |
| 163 | +Integrate.setInfoOutput(func: (info: string) => void): void |
| 164 | +``` |
| 165 | + |
| 166 | +`func` callback for each status message. THe parameter `info` contains the message, as a string. By default, this function is `console.log`. |
| 167 | + |
| 168 | +### Integrate.types |
| 169 | +`Integrate.types` is an `Integrate.Registry` holding all types mod content can be an instance of. |
| 170 | +```ts |
| 171 | +Integrate.types: Integrate.Registry |
| 172 | +``` |
| 173 | + |
| 174 | +### Integrate.construct() |
| 175 | +`Integrate.construct()` is a helpful function that combines `Integrate.Registry.create()` and `Integrate.Registry.construct` for mod content. |
| 176 | +```ts |
| 177 | +Integrate.construct(object: object | string, defaultType: class): object |
| 178 | +``` |
| 179 | +`object` is either a constructible object, or a registry name of one in any moddable registry. |
| 180 | +`defaultType` is an optional parameter defining a fallback type for if the constructible has no `type` property. |
| 181 | + |
| 182 | +## Classes |
| 183 | + |
| 184 | +### Integrate.Content |
| 185 | + |
| 186 | +```ts |
| 187 | +class Content { |
| 188 | + registry: string; |
| 189 | + name: string; |
| 190 | + constructible: object; |
| 191 | + JSON: string; |
| 192 | + implement() {}: void |
| 193 | + create() {}: object |
| 194 | +} |
| 195 | +``` |
| 196 | + |
| 197 | +`registry` Name of the registry this content is to be added to. |
| 198 | +`name` Name of this content in registry. |
| 199 | +`constructible` The JSON serialisable constructible object used to create instances of this content. |
| 200 | +`JSON` The JSON equivalent of the constructible. |
| 201 | +`implement()` Adds this content to its designated registry. |
| 202 | +`create()` Returns a constructed instance of this content directly. |
| 203 | + |
| 204 | +### Integrate.Mod |
| 205 | + |
| 206 | +```ts |
| 207 | +class Mod { |
| 208 | + displayName: string; |
| 209 | + name: string; |
| 210 | + version: string; |
| 211 | + author: string; |
| 212 | + tagline: string; |
| 213 | + description: string; |
| 214 | + content: Content[]; |
| 215 | +} |
| 216 | +``` |
| 217 | + |
| 218 | +`displayName` Display name of the mod. |
| 219 | +`name` Internal ID for the mod. Used for registry items. |
| 220 | +`version` Mod version. |
| 221 | +`author` Who made this mod. |
| 222 | +`tagline` Short, one-line description of the mod. |
| 223 | +`description` Longer description of the mod. |
| 224 | +`content` Array of all content in this mod. |
| 225 | + |
| 226 | +### Integrate.Registry |
| 227 | + |
| 228 | +```ts |
| 229 | +/** |
| 230 | + * Data structure for holding **unique, case-insensitive** key-value pairs. |
| 231 | + */ |
| 232 | +class Registry { |
| 233 | + get size() {}: number; |
| 234 | + add(name: string, item: any) {}: void; |
| 235 | + has(name: string) {}: boolean; |
| 236 | + get(name: string) {}: object; |
| 237 | + create(name: string, registry: Integrate.Registry, defaultType: class) {}: object; |
| 238 | + construct(object: object, defaultType: class) {}: object; |
| 239 | + rename(name: string, newName: string) {}: void; |
| 240 | + alias(name: string, as: string) {}: void; |
| 241 | + forEach(func: (item, name: string) => void) {}: void; |
| 242 | + nameOf(item: any) {}: string | null; |
| 243 | +} |
| 244 | +``` |
| 245 | + |
| 246 | +`size` Returns the size of the registry. |
| 247 | +`add()` Adds an item to registry. |
| 248 | +`has()` Checks for an item in registry. |
| 249 | +`get()` Gets an item from registry name. |
| 250 | +`create()` Constructs an item from registry. Note that this only works with objects. The parameter `registry` should be the registry holding all types, such as `Integrate.types`. |
| 251 | +`construct()` Constructs an item using a type from registry. Note that this only works with object entries. |
| 252 | +`rename()` Renames a registry item. Neither parameter is case-sensitive. |
| 253 | +`alias()` Adds another registry item with the same content as the specified one. |
| 254 | +`forEach()` Executes a function for each element in the registry. |
| 255 | +`nameOf()` Searches the registry for any entries with matching content. Equivalence follows `===` rules. |
0 commit comments