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.txtfile from the session where the bug was encountered (located in your Celeste install folder, with previous sessions stored in theLogHistorysubfolder).
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-detailswhere 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.
Once everything is ready, for it to get merged it will need to get reviewed by at least 2 members of the Everest team. Once that has happened, there is a 3 day last-call window in which any concerns can be brought up before it is merged. If nothing is blocking the pull request, it'll get merged once the 3 day window is over.
If a pull request would be merged within 3 days of a planned release, it will have to be merged after it, to ensure it has enough time to be tested before being released. The date of the next release can be found in the Milestones section.
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.Modderor 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.GotoNextinstead ofTryGotoNextwhere possible, and implementing additional checks whenTryGotoNextis 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, theinheritdoctag should be used for members that would otherwise override vanilla docs, and theorigdoctag 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.