Prerequesites:
- Everest installed
- Git
- Visual Studio 2015 or newer with the .NET Framework 4.5.2 Targeting Pack
And either:
- Visual Studio Code
- Iodine for Visual Studio Code
Or:
- JetBrains Rider
Create a new project for your mod, and change directories to it:
\> dotnet new sln -o ExampleMod
\> cd ExampleMod
Initialize your mod as a Git repository so you can add Everest:
\ExampleMod\> git init
\ExampleMod\> git submodule add https://github.com/EverestAPI/Everest.git
Let's add Everest into our solution:
\ExampleMod\> dotnet sln add .\Everest\Celeste.Mod.mm\Celeste.Mod.mm.csproj
Create a new Class Library in F# for your Mod:
\ExampleMod\> dotnet new classlib -lang "F#" -o ExampleMod
There should now be an ExampleMod.fsproj
under the new folder ExampleMod
. Let's take a look at it:
\ExampleMod\> bat .\ExampleMod\ExampleMod.fsproj
───────┬────────────────────────────────────────────────────────────────────────────────────────────
│ File: .\ExampleMod\ExampleMod.fsproj
───────┼────────────────────────────────────────────────────────────────────────────────────────────
1 │ <U+FEFF><Project Sdk="Microsoft.NET.Sdk">
2 │
3 │ <PropertyGroup>
4 │ <TargetFramework>netstandard2.0</TargetFramework>
5 │ </PropertyGroup>
6 │
7 │ <ItemGroup>
8 │ <Compile Include="Library.fs" />
9 │ </ItemGroup>
10 │
11 │ </Project>
We need to edit this file to add the Everest imports, like so:
\ExampleMod\> bat .\ExampleMod\ExampleMod.fsproj
───────┬────────────────────────────────────────────────────────────────────────────────────────────
│ File: .\ExampleMod\ExampleMod.fsproj
───────┼────────────────────────────────────────────────────────────────────────────────────────────
1 │ <U+FEFF><?xml version="1.0" encoding="utf-8"?>
2 │ <Project Sdk="Microsoft.NET.Sdk">
3 │ <PropertyGroup>
4 │ <TargetFramework>net452</TargetFramework>
5 │ </PropertyGroup>
6 │ <ItemGroup>
7 │ <Reference Include="Celeste">
8 │ <HintPath>..\Everest\lib-stripped\Celeste.exe</HintPath>
9 │ <Private>False</Private>
10 │ </Reference>
11 │ <Reference Include="FNA">
12 │ <HintPath>..\Everest\lib-stripped\FNA.dll</HintPath>
13 │ <Private>False</Private>
14 │ </Reference>
15 │ <Reference Include="Steamworks.NET">
16 │ <HintPath>..\Everest\lib-stripped\Steamworks.NET.dll</HintPath>
17 │ <Private>False</Private>
18 │ </Reference>
19 │ <Reference Include="System" />
20 │ <Reference Include="System.Xml" />
21 │ <Reference Include="YamlDotNet">
22 │ <HintPath>..\Everest\lib\YamlDotNet.dll</HintPath>
23 │ <Private>False</Private>
24 │ </Reference>
25 │ </ItemGroup>
26 │ <ItemGroup>
27 │ <ProjectReference Include="..\Everest\Celeste.Mod.mm\Celeste.Mod.mm.csproj">
28 │ <Name>Celeste.Mod.mm.csproj</Name>
29 │ </ProjectReference>
30 │ </ItemGroup>
31 │ <ItemGroup>
32 │ <Compile Include="Library.fs" />
33 │ </ItemGroup>
34 │ </Project>
Let's add it to our solution:
\ExampleMod\> dotnet sln add .\ExampleMod\ExampleMod.fsproj
Next, let's replace Library.fs
:
\ExampleMod\> bat .\ExampleMod\Library.fs
───────┬────────────────────────────────────────────────────────────────────────────────────────────
│ File: .\ExampleMod\Library.fs
───────┼────────────────────────────────────────────────────────────────────────────────────────────
1 │ <U+FEFF>namespace ExampleMod
2 │
3 │ module Say =
4 │ let hello name =
5 │ printfn "Hello %s" name
with something that gets loaded as a mod:
\ExampleMod\> bat .\ExampleMod\Library.fs
───────┬────────────────────────────────────────────────────────────────────────────────────────────
│ File: .\ExampleMod\Library.fs
───────┼────────────────────────────────────────────────────────────────────────────────────────────
1 │ <U+FEFF>namespace Celeste.Mod.Example
2 │
3 │ open Celeste.Mod
4 │
5 │ type ExampleModule() =
6 │ inherit EverestModule()
7 │ override this.Load() = ()
8 │ override this.Unload() = ()
Now, we should be able to build our project:
\ExampleMod\> dotnet build
This should build ExampleMod.dll
.
Lastly, we need our everest.yaml
, which should start out like:
\ExampleMod\> bat everest.yaml
───────┬────────────────────────────────────────────────────────────────────────────────────────────
│ File: everest.yaml
───────┼────────────────────────────────────────────────────────────────────────────────────────────
1 │ - Name: ExampleMod
2 │ Version: 0.0.1
3 │ DLL: ExampleMod.dll
4 │ Dependencies:
5 │ - Name: Everest
6 │ Version: 1.1908.0
Replacing 1908
with the build of Everest installed.
To use the mod, navigate to your Mods
folder (which should already exist from Everest) under your Celeste folder and create a new folder ExampleMod
. You're going to want to copy over the following files into this folder:
\ExampleMod\ExampleMod\bin\Debug\net452\ExampleMod.dll
\ExampleMod\ExampleMod\bin\Debug\net452\ExampleMod.pdb
\ExampleMod\ExampleMod\bin\Debug\net452\FSharp.Core.dll
\ExampleMod\everest.yaml
The folder should look like this:
When you boot up Everest, if you go to Mod Options → Enable or Disable Mods, you should see ExampleMod
listed.
You should now be able to open \ExampleMod\
in VSCode or Rider. Select ExampleMod.sln
in the Iodine prompt at the top after VSCode loads the folder, or select ExampleMod.sln
in the "Open Solution" dialog in Rider. Any additional non-programming steps (adding resources, etc) should work the same way as in C# projects.
TODO:
- Document adding packages.