Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 127 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,131 @@
# ccloader3

A mod loader for the game CrossCode by Radical Fish Games.

[![Build Status](https://travis-ci.com/dmitmel/ccloader3.svg?branch=master)](https://travis-ci.com/dmitmel/ccloader3)

A temporary repository for _The Third Version of [CCLoader](https://github.com/CCDirectLink/CCLoader)_. Project is currently under construction. I promise, **there will be documentation here**.
A temporary repository for _The Third Version of [CCLoader](https://github.com/CCDirectLink/CCLoader)_.
Project is currently under construction. I promise, [**there will be documentation here**](doc/).

## Features

- Support for overriding assets, like images, sounds, music and JSON data.
- Support for patching existing JSON data assets, like maps.
- Support for mod dependencies, allowing a mod to use other mods.
- Provides multiple hook points during startup where mods can inject code.
- Provides a GUI to enable or disable mods in the CrossCode settings.
- Provides advanced settings, configurable via a JSON config file.
- Provides a debug console even for the NW.js release bundled with the game.

## Installation

TODO

## Usage

Once CCLoader v3 is installed, the game will automatically use it.
Mods must be installed in the `assets/mods` directory.
To disable CCLoader v3, replace `package.json` with the one from the original game.

## How it works

CCLoader v3 starts by trying to load the optional configuration file named
`ccloader-user-config.js` in the main directory.
This file is optional, but if present, it provides ways to [override the default
configuration through code](doc/UserConfig.md).

It then begins its search for mods. By default, it will look for them in
the `assets/mods` directory.
Each mod must be in a subdirectory.
The name of the subdirectory isn't important, but it must contain a
[`ccmod.json` file](doc/CcmodFile.md).
For backward compatibility with CCLoader v2 mods, a `package.json` file is also
recognised with the old format.
Subdirectories that do not have one of the two files are ignored.

It will then attempt to resolve each mod dependencies to ensure that they
are present, while ignoring mods disabled by the user. It will also determine
the order in which mods will be loaded. The dependencies of a mod are always
loaded before the mod itself.

It then proceeds through these [loading phases](doc/LoadingStages.md):

1. Recreate the HTML DOM of the game
2. Load the main class of the mods, if any.
3. Execute the mods' `preload` stage. It is named as such because it happens
before the game code is loaded. The `preload` stage of each mod and all
further stages are executed in the order in which mods are loaded.
4. Load the game code without executing its entry point. This will load the
ImpactJS dependency injection framework, and define all ImpactJS modules
provided by the game, without initializing them.
5. Execute the mods' `postload` stage. Mods can make use of the ImpactJS
dependency injection and the class injection support to modify the game
before it is started. See the ImpactJS documentation for details. Note
that mods should define their module inline and not in separate files.
6. Start the game, by first indicating to ImpactJS that the DOM is ready, and
then invoking the `startCrossCode()` entry point. This will initialize a
large part of the game which will start loading resources.
7. Execute the mods' `prestart` stage.
8. Wait for the game to finish loading all its resources.
9. Execute the mods' `poststart` stage.
10. Allow the game to continue.

## Modloader API

CCLoader v3 also provides global objects that mods can use at any time:
the `modloader` object and `ccmod` object.

### window.modloader

This provides some access to the internal state of the modloader.
It contains the public fields:
```
// Name of the modloader
name: string = "ccloader",
// Version of the modloader.
version: string = "3.x.x",
// Version of the game.
gameVersion: semver.SemVer,
// Hotfix version of the game.
// If gameVersion is "1.3.0" and gameVersionHotfix is 4, then the complete
// game version is 1.3.0-4.
gameVersionHotfix: number,
// A map from mod ids to the Mod object of each mod. This map contains all
// detected mods, including mods that are not loaded.
installedMods: Map<string, Mod>,
// A map from mod ids to the Mod object of each mod. This map only contains
// mods that are loaded or will be loaded.
installedMods: Map<string, Mod>,
// Object used to store wether mods are enabled by the user or not.
modDataStorage: ModDataStorage
```

Mods do not usually need to use it. See the
[detailed documentation](doc/ModloaderAPI.md) for details.

### window.ccmod

This contains a so-called "standard library" for mods, providing various
utilities:
```
// Name of the implementor of the standard library.
implementor: string = "ccloader",
// Name of the implementation of the standard library.
implementation: string = "runtime",
// Provides path manipulation utilities, like nodejs's 'path' module.
paths: PathModule,
// Various javascript utilities.
utils: UtilsModule
// A nodejs-compatible require() that searchs relative to your mod directory.
// Not availlable if the game is run via a browser instead of NW.js
// To load your own code, it is recommended to use import() instead
require: (id: string) : mod
// Provide utilities to run functions as soon as impactjs is initialized
impactInitHooks: ImpactModuleHooksModule,
// Provides utilities to run callback as soon as a impactjs module is loaded
impactModuleHooks: ImpactModuleHooksModule,
// Provides utilities to load resources or dynamically patch them
resources: ResourcesModule
```

See the [detailed documentation for the ccmod API](doc/ccmodAPI.md) for details.
73 changes: 73 additions & 0 deletions doc/UserConfig.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
CCLoader v3 will look for a file named `ccloader-user-config.js` inside
the game root directory (the one containing `package.json` and
`tool.config.json`).

This file should export a default function with two parameters as follow:
```
export default function(config, context) {
// modify config here
}
```

`context` only contains two fields: `modloaderName` and `modloaderVersion`.
They are equal to `modloader.name` and `modloader.version` respectively, except
`modloader` is not available in this function.


`config` comes with the following modifiable members:
- `gameAssetsDir : string`: Where CCLoader v3 will load assets.
The default is `assets/`.
- `modsDir : string[]`: List of directories where CCLoader v3 will search mods.
The default is `["assets/mods/"]`
- `stylesheetURLs : string[]`,
List of stylesheet URLs to reference in the constructed DOM.
The default value of `stylesheetURLs` contains the same URLs that are
referenced in the original `assets/node-webkit.html` HTML file from the game,
but in the following order:
```
['impact/page/css/ui-darkness/jquery-ui-1.10.2.custom.min.css',
'impact/page/css/style.css',
'game/page/game-base.css']
```
It is recommended to not rely on this order or index, as it may be updated
as the game evolves.

- `scriptURLs : string[]`: List of javascript files to put in `<script>` tags
in the constructed DOM. This list should not contain the game's main code,
as it is handled separately.
Likewise for `stylesheetURLs`, the default values are unchanged from the
game, but are in the following order:
```
['impact/page/js/aes.js',
'impact/page/js/seedrandom.js',
'impact/page/js/jquery-1.11.1.min.js',
'impact/page/js/jquery-ui-1.10.2.custom.min.js',
'game/page/game-base.js',
'impact/page/js/options.js']
```

- `gameScriptURL: string`: URL to the game's main code. The default is
`js/game.compiled.js`. Note that this code in hooked into by CCLoader v3 in
various ways.

- `impactConfig: Record<string, unknown>`: Contains global variables used by
ImpactJS and/or by the game. The default are the same as in the original
`assets/node-webkit.html`:
```
{IG_GAME_SCALE: 2,
IG_GAME_CACHE: 0,
IG_ROOT: '',
IG_WIDTH: 568,
IG_HEIGHT: 320,
IG_HIDE_DEBUG: false,
IG_SCREEN_MODE_OVERRIDE: 2,
IG_WEB_AUDIO_BGM: false,
IG_FORCE_HTML5_AUDIO: false,
LOAD_LEVEL_ON_GAME_START: null,
IG_GAME_DEBUG: false,
IG_GAME_BETA: false}
```

- `onGameDOMCreated: async () : void`: A (possibly async) function that
CCLoader v3 will call after recreating the DOM, but before loading the
stylesheets and scripts.