forked from EverestAPI/EverestAPI.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodstruct.html
More file actions
259 lines (245 loc) · 13.6 KB
/
Copy pathmodstruct.html
File metadata and controls
259 lines (245 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Mod Structure | Everest </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Mod Structure | Everest ">
<meta name="generator" content="docfx 2.31.0.0">
<meta name="description" content="How should the files in your mod be structured? What formats are supported? This page lists some common mod structure information.">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
<meta property="docfx:rel" content="../">
<meta property="docfx:newtab" content="true">
<meta property="og:type" content="article">
<meta property="og:title" content="Mod Structure">
<meta property="og:site_name" content="Everest"><meta property="og:description" content="How should the files in your mod be structured? What formats are supported? This page lists some common mod structure information.">
<meta name="author" content="Everest Team">
<meta property="og:locale" content="en_US">
<link rel="canonical" href="https://everestapi.github.io/"><meta property="og:url" content="https://everestapi.github.io/">
<meta property="og:image" content="https://everestapi.github.io/logo.png">
<meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://everestapi.github.io/logo.png"><meta name="twitter:site" content="@everestapi"><meta name="twitter:creator" content="@everestapi">
</head>
<body data-spy="scroll" data-target="#affix">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../">
<img id="logo" src="../logo-small.png" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div class="container body-content">
<div id="search-results">
<div class="search-list"></div>
<div class="sr-items"></div>
<ul id="pagination"></ul>
</div>
</div>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="">
<h1 id="mod-structure">Mod Structure</h1>
<hr>
<!-- TODO: Get > [!PREREQUISITES] working -->
<div class="PREREQUISITES">
<h5>PREREQUISITES</h5>
<p>
<li>Everest: <a href="/">Website</a></li>
<li>Zipping software, f.e. 7zip: <a href="http://7-zip.org/">Website</a></li>
</p>
</div>
<hr>
<h2 id="formats">Formats</h2>
<p><strong>Everest currently supports the following formats:</strong></p>
<ul>
<li>Mod <code>.zip</code>s: Best used when using other's mods or when uploading your mod somewhere.</li>
<li>Mod subdirectories: Best used for prototyping mods on your own machine.</li>
</ul>
<p>A mod can't contain "submods", unless a code mod loads the "submods" dynamically.</p>
<p>All files in a mod <code>.zip</code> must be on the top level (root) and visible when just opening the <code>.zip</code> file. <code>YourMod.zip</code> shouldn't contain another <code>YourMod</code> folder.</p>
<div class="NOTE"><h5>Note</h5><p>A code mod can dynamically load external mod content and mod assemblies.<br>Dynamically loaded mods aren't restricted by the above formats, but rather by how the "supporting" mod loads them.<br>The following file layout still applies to dynamically loaded mods.</p>
</div>
<h2 id="file-layout">File Layout</h2>
<p>Mods can contain custom content, both overrides / replacements (when supported) and new content. The content paths match the originals as close as possible.</p>
<p>Mods must contain a <a href="#metadata"><code>everest.yaml</code> metadata file.</a></p>
<p><strong>The following content mappings are supported out of the box:</strong></p>
<ul>
<li><code>Graphics/Atlases/*.png</code>: Replace or add textures.<ul>
<li>Supports <code>.meta</code> definition files.</li>
<li><code>Graphics/Atlases/Gui/title.png</code><ul>
<li>Atlas: <code>Gui</code></li>
<li>Texture: <code>title</code></li>
</ul>
</li>
<li><code>Graphics/Atlases/Gameplay/scenery/sign.png</code><ul>
<li>Atlas: <code>characters</code></li>
<li>Texture: <code>scenery/sign</code></li>
</ul>
</li>
</ul>
</li>
<li><code>Maps/*.bin</code>: Add new maps.<ul>
<li>Supports <code>.meta</code> definition files.</li>
<li>Replacing vanilla maps not supported.</li>
<li><code>Maps/Author/LevelSet/1-Name.bin</code><ul>
<li>Default SID (String ID): <code>Author/LevelSet/1-Name</code></li>
<li>Default LevelSet: <code>Author/LevelSet</code></li>
<li>Default Name: <code>1-Name</code></li>
</ul>
</li>
</ul>
</li>
<li><code>Dialog/*.txt</code>: Add new texts.<ul>
<li>Only contains the texts belonging to the mod.</li>
<li>Multiple mods are allowed to occupy the same path. F.e. two mods can contain their own <code>Dialog/English.txt</code> files.</li>
<li>Replacing existing texts not supported.</li>
<li><code>Dialog/English.txt</code> is always used when a dialog key cannot be found in another language.</li>
</ul>
</li>
<li><code>Audio/*.bank</code> + <code>Audio/*.guids.txt</code>: Add new FMOD audio banks containing custom / replacement events.<ul>
<li>Works with new banks created in the <a href="https://www.fmod.com/download#demos">Celeste FMOD project</a></li>
<li>Requires manually exported <code>GUIDs.txt</code>, renamed to <code>your bank name.guids.txt</code></li>
<li>To replace the game's events, assign any modified events to your new mod bank. Please avoid overriding the game's original banks.</li>
</ul>
</li>
</ul>
<p><strong>With a few exceptions, each file path can only be occupied by one file.</strong></p>
<ul>
<li>If mod #1 contains <code>Graphics/Atlases/Gui/title.png</code> and <code>Graphics/Atlases/Gui/title.meta.yaml</code>, it overrides the texture shipped with Celeste.</li>
<li>If an additional mod #2 contains <code>Graphics/Atlases/Gui/title.png</code>, it overrides the texture shipped with #1. The meta definitions of #1 still apply.</li>
</ul>
<p>All "supported" mod content can be loaded with the usual Celeste methods. For example, a texture in an atlas can be accessed with the matching atlas.</p>
<p>All "unsupported" mod content can be loaded by codemods via <a href="/api/Celeste.Mod.Everest.Content.html#Celeste_Mod_Everest_Content_Get_System_String_System_Boolean_"><code>Everest.Content.Get*</code> (usage)</a>.</p>
<p>For content inside of <code>.zip</code>s and subdirectories, all mod content is directly contained in the <code>.zip</code> / subdirectory. For example, the mod <code>.zip</code> should directly contain a <code>Maps</code> directory. The <code>Maps</code> directory should not be in a <code>Content</code> subdirectory.</p>
<p>For content in form of embedded resources inside of <code>.dlls</code>, all mod content requires a <code>Content\</code> path prefix Embedded resources normally don't have logical file paths in the traditional sense - the C# compiler mangles the filepath into something C#-friendly. <strong>To fix content embedded into .dlls, set a logical name for all <code>Content\</code> <code><EmbeddedResource></code>s in your <code>.csproj</code>:</strong></p>
<pre><code class="lang-xml"><EmbeddedResource Include="Content\Dialog\English.txt">
<LogicalName>Content\Dialog\English.txt</LogicalName>
</EmbeddedResource>
</code></pre><p>Additionally, for embedded resources, the C# compiler requires filepaths with <code>\</code> as the directory separator, but the content is accessed with <code>/</code> as the directory separator. <strong>Everest replaces all <code>\</code> symbols with <code>/</code> symbols in embedded resource paths at runtime.</strong></p>
<h2 id="metadata">Metadata</h2>
<p>The <code>everest.yaml</code> file in your mod contains a list of all "module" names (ID), version, (optional) DLL paths and any dependencies.</p>
<p>If you've got no mod DLLs, leave that field out. If you've got multiple modules in separate DLLs, list them separately.</p>
<p><strong>The version should match the <a href="https://semver.org/">semver (semantic versioning) format</a>:</strong></p>
<ul>
<li>The MAJOR version must match to prevent breakages caused by API changes (f.e. API removals).</li>
<li>The MINOR version must rise with each backwards-compatible API change (f.e. API additions). If the mod depends on a new version but an older version is installed, the mod won't load.</li>
<li>The PATCH version isn't checked.</li>
</ul>
<p>Adding a dependency to a mod with version <code>0.0.*</code> ignores the above checks at your own risk.</p>
<h2 id="examples">Examples</h2>
<h3 id="code-mod">Code Mod</h3>
<p><strong>File list:</strong></p>
<ul>
<li><code>everest.yaml</code></li>
<li><code>GhostMod.dll</code></li>
<li><code>GhostNetMod.dll</code></li>
</ul>
<p><strong>Embedded resources:</strong></p>
<ul>
<li><code>Content\Dialog\English.txt</code>: Mod option texts.</li>
</ul>
<p><strong>Metadata:</strong></p>
<pre><code class="lang-yaml">- Name: GhostMod
Version: 1.2.1
DLL: GhostMod.dll
Dependencies:
- Name: Everest
Version: 1.0.0
- Name: GhostNetMod
Version: 1.3.4
DLL: GhostNetMod.dll
Dependencies:
- Name: Everest
Version: 1.0.0
- Name: GhostMod
Version: 1.2.1
</code></pre><ul>
<li>The mod will load with Everest <code>1.0+.*</code>, meaning <code>1.0.*</code>, <code>1.1.*</code>, <code>1.2.*</code>, ...</li>
<li>The mod won't load with Everest older than <code>1.0.0</code>.</li>
<li>The mod won't load with Everest <code>2.*.*</code>, <code>3.*.*</code>, <code>4.*.*</code> or similar. The API has changed in a way that could break the mod.</li>
</ul>
<h3 id="level-mod">Level Mod</h3>
<p><strong>File list:</strong></p>
<ul>
<li><code>everest.yaml</code></li>
<li><code>Dialog/English.txt</code>: LevelSet and chapter names.</li>
<li><code>Maps/Cruor-Secret.bin</code>: A-side map binary.</li>
<li><code>Maps/Cruor-Secret.meta.yaml</code>: Chapter metadata. Always the <code>.meta</code> of the A-side binary.</li>
<li><code>Maps/Cruor-Secret-B.bin</code>: B-side map binary. The A-side / chapter <code>.meta</code> links to this.</li>
<li><code>Graphics/Atlases/Gui/areas/secret.png</code>, <code>secret_back.png</code>: The chapter selection screen icon and its backside (when flipping).</li>
<li><code>Graphics/Atlases/Gameplay/decals/cruor-secret/*.png</code>: Any decals used by the A-side or B-side map <code>.bin</code>s.</li>
<li><code>Graphics/Atlases/Ending-Cruor-Secret-1/*.png</code>, ...: Chapter completion screen textures. The chapter <code>.meta</code> links to this.</li>
</ul>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
<li>
<a href="https://github.com/EverestAPI/EverestAPI.github.io/blob/docfx/tutorials/modstruct.md/#L1" class="contribution-link">Improve this Doc</a>
</li>
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
Baked with 🍓 by the Everest Team
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>