Contributions are very welcome and greatly appreciated! Make sure to join the Celeste Community Discord for any help you need.
If you are planning on contributing code to Everest, it is recommended to create a fork of the main repo to develop on. Once you have a fork, clone it to your machine and follow the instructions here to build and install it.
These are guidelines for some of the different types of contributions you can make to Everest.
Make sure bug reports have enough information to be reproduced easily!
That means:
- Steps to reproduce.
- Description of the bug (expected behaviour vs actual behaviour).
log.txt
file from the session where the bug was encountered (located in your Celeste install folder, with previous sessions stored in theLogHistory
subfolder).
When submitting ideas or feature requests, consider carefully whether the feature would be more suited for a code mod.
Features for Everest should match at least one of the following criteria:
- Adds features for code mods.
- Specific to the Everest project.
- Not possible to achieve through a code mod.
When making a pull request, please note the following guidelines:
- Branch name: use a descriptive name for your branch, following the format of
action-target-details
where possible. - Description: explain what your pull request changes and why.
- Credits: if your modifications are in response to a request or issue, link to it or otherwise provide a "paper trail".
- Testing: if you are submitting a bugfix, describe the issue thouroughly and provide recreation steps, especially if it is not an existing issue.
- Response: when you submit a pull request, you are responsible for making sure any questions and change requests on it are answered in a timely manner.
These are explanations and guidelines for how to make changes to the Everest source code.
Content added must not change the functionality of the base game, or change any public facing API.
While many mods also make use of non-public code it is not as important to maintain backwards compatibility for it.
New features should only be added to improve or un-hardcode vanilla features, especially for general use in code mods (f.e. StrawberryRegistry, CustomNPC, Custom Events).
Gameplay mechanics, entities, and other features not present in the base game are usually better suited for a mod, although some exceptions will be made on a case by case basis.
As with in adding content, patches must not change the functionality of the base game, or change any public API.
Everest uses MonoMod to patch Celeste, which allows for classes and members to be modified. For an explanation of how the MonoMod patcher works, see the MonoMod GitHub
There are two ways to modify Vanilla code, depending on the scope of what is being modified:
Adding a class with the same name as an existing one, and prefixing it with patch_
will direct MonoMod to apply it as a patch onto the original class.
By default, any methods that are patched are preserved by MonoMod with an orig_
prefix, and can be referenced in the patched method:
public extern void orig_DoThing(int val);
public void DoThing(int val) {
int newVal = Transform(val);
orig_DoThing(newVal);
}
There are a few attributes that can be applied to members of the class with different effects:
[MonoModIgnore]
ignore this member, do not patch it except for MonoMod custom attributes.[MonoModConstructor]
treat this method as a constructor - why this is needed.[MonoModReplace]
replace this method entirely, do not generate anorig_
method.
Code mods were previously created with Everest as a git submodule, which meant that any additions from Everest in patch_
classes were not available to those mods at build time.
The recommended practice has since been updated to build against a patched version of Celeste, making Ext
classes relatively obsolete.
In most cases, new patch_
members should not be added to their associated Ext
class, and new Ext
classes should not be created.
Exceptions are made when the Ext
class contains significant additions that are not within the scope of the original class (ex: TextMenuExt
).
Existing Ext
classes will also be kept in the following cases:
- An associated
patch_
class member was not made public (ex:patch_Audio.CheckFmod
) - Useful extension methods are defined (ex:
AreaDataExt.ToKey
)
ℹ️ The recommended practices for MonoModRules have recently been changed as described in this PR.
Everest uses MonoModRules to directly modify the IL code of vanilla methods.
Some guidelines for using them are as follows:
-
Patches and Attribute definitions should be located in the
Celeste.Mod.mm/Patches/
folder alongside their associatedpatch_
class.- If a patch is used across multiple files, it can be moved into the main MonoModRules file.
-
When using types or methods in an IL patch, they must be imported as a reference through
MonoModRule.Modder
or by association with an already imported type. -
While in code mods it is often preferred to fail safe when patching, if an Everest patch does not work it should fail hard to prevent broken builds from reaching end-users.
This means usingILCursor.GotoNext
instead ofTryGotoNext
where possible, and implementing additional checks whenTryGotoNext
is necessary. -
Primitive arrays and switch statements with more than 6 cases are not usable due to compiler optimizations.
Due to the nature of modding, there are situations where the C# compiler will generate a warning that isn't possible to fix. In this situation you can add the following preprocessor directive to the top of the file:
#pragma warning disable [Warning Number] // Add a comment with the warning description
Warnings can be disabled for a specific block of code by surrounding it with pragma warning disable
and pragma warning enable
.
Documentation takes the form of comments, xmldoc, guides, and references.
- Comments should be added as needed to code, to help other developers and maintainers understand what it does and why it is necessary.
- XMLDoc (in-line code docs that show up in IDEs) are recommended to help modders out.
Vanilla types and members should be documented in
lib-stripped/Celeste.xml
. When adding xmldoc to modded or patched members, theinheritdoc
tag should be used for members that would otherwise override vanilla docs, and theorigdoc
tag can be added toorig_
members to warn users against using them. - Guides and References are kept in a number of locations, the most prominent being the Everest Wiki. Anything new for use in mods should be included there, with bonus points for adding an example in the Reference Mod, if appropriate.