-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
329 lines (313 loc) · 18.4 KB
/
index.html
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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Best practices | ReachVariantTool Documentation</title>
<base href="../" />
<link rel="stylesheet" href="resources/main.css" />
<!-- <link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/dark.min.css"> -->
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
<script src="highlightjs-rvt-script/dist/rvt-script.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<noscript>
<link rel="stylesheet" href="resources/noscript.css" />
</noscript>
<script src="resources/head.js"></script>
</head>
<body>
<nav id="sidebar">
<ul>
<li><a href="index.html">Index</a></li>
<li>
<a>Main Window</a>
<ul>
<li>
<a href="editor/main_window/index.html">Multiplayer</a>
<ul>
<li><a href="editor/main_window/metadata.html">Metadata</a></li>
<li><a href="editor/main_window/options-general.html">General Settings</a></li>
<li><a href="editor/main_window/options-respawn.html">Respawn Settings</a></li>
<li><a href="editor/main_window/options-social.html">Social Settings</a></li>
<li><a href="editor/main_window/options-map.html">Map and Game Settings</a></li>
<li data-dont-default-collapse>
<a href="editor/main_window/options-team.html">Team Settings</a>
<ul>
<li><a href="editor/main_window/options-team-specific.html">Individual Team Settings</a></li>
</ul>
</li>
<li data-dont-default-collapse>
<a href="editor/main_window/options-loadout.html">Loadout Settings</a>
<ul>
<li><a href="editor/main_window/options-loadout-specific.html">Individual Loadout Settings</a></li>
</ul>
</li>
<li><a href="editor/main_window/options-megalo.html">Script-Specific Settings</a></li>
<li><a href="editor/main_window/option-visibility.html">Option Visibility</a></li>
<li><a href="editor/main_window/tu1.html">Title Update Settings</a></li>
<li><a href="editor/main_window/traits.html">(all player traits)</a></li>
<li><a href="editor/main_window/forge.html">Forge Settings</a></li>
</ul>
</li>
<li>
<a href="editor/main_window_ff/index.html">Firefight</a>
<ul>
<li><a href="editor/main_window_ff/metadata.html">Metadata</a></li>
<li>
<a href="editor/main_window_ff/scenario.html">Firefight Settings</a>
<ul>
<li><a href="editor/main_window_ff/lives.html">Player Lives</a></li>
<li><a href="editor/main_window_ff/options-respawn.html">Respawn Settings</a></li>
<li><a href="editor/main_window_ff/round.html">Round Settings</a></li>
<li><a href="editor/main_window_ff/bonus-wave.html">Bonus Wave Settings</a></li>
<li><a href="editor/main_window_ff/custom-skull.html">Custom Skulls</a></li>
</ul>
</li>
<li>
<a>Other Settings</a>
<ul>
<li><a href="editor/main_window_ff/options-general.html">General Settings</a></li>
<li><a href="editor/main_window_ff/options-social.html">Social Settings</a></li>
<li data-dont-default-collapse>
<a href="editor/main_window_ff/options-team.html">Team Settings</a>
<ul>
<li><a href="editor/main_window_ff/options-team-specific.html">Individual Team Settings</a></li>
</ul>
</li>
<li data-dont-default-collapse>
<a href="editor/main_window_ff/options-loadout.html">Loadout Settings</a>
<ul>
<li><a href="editor/main_window_ff/options-loadout-specific.html">Individual Loadout Settings</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="editor/main_window_ff/traits.html">(all player traits)</a></li>
<li><a href="editor/main_window_ff/traits-wave.html">(all wave traits)</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="editor/script_window/index.html">Script Window</a>
<ul>
<li><a href="editor/script_window/meta-strings.html">Metadata Strings</a></li>
<li>
<a href="editor/script_window/string-table.html">All Other Strings</a>
<ul>
<li><a href="editor/script_window/string-localization.html">Localization</a></li>
</ul>
</li>
<li><a href="editor/script_window/forge-labels.html">Forge Labels</a></li>
<li><a href="editor/script_window/map-permissions.html">Map Permissions</a></li>
<li><a href="editor/script_window/player-rating-parameters.html">Player Rating Parameters</a></li>
<li><a href="editor/script_window/required-object-types.html">Required Object Types</a></li>
<li><a href="editor/script_window/script-options.html">Scripted Options</a></li>
<li><a href="editor/script_window/script-traits.html">Scripted Traits</a></li>
<li><a href="editor/script_window/script-stats.html">Scripted Stats</a></li>
<li><a href="editor/script_window/script-widgets.html">Scripted Widgets</a></li>
<li><a href="editor/script_window/gametype-code.html">Gametype Code</a></li>
</ul>
</li>
<li>
<a href="script/syntax.html">Scripting Language</a>
<ul>
<li><a href="script/alias.html">Aliases</a></li>
<li><a href="script/events.html">Events</a></li>
<li><a href="script/for.html">For-each-loops</a></li>
<li><a href="script/if.html">If-/alt-statements</a></li>
<li><a href="script/operators.html">Operators</a></li>
<li><a href="script/string-special-chars.html">Special string characters</a></li>
<li><a href="script/enum.html">User-defined enums</a></li>
<li><a href="script/function.html">User-defined functions</a></li>
<li><a href="script/snippets.html">Useful code snippets</a></li>
<li><a href="script/declare.html">Variable declarations</a></li>
<li><a href="script/best-practices.html">Best practices</a></li>
</ul>
</li>
<li>
<a href="script/api/index.html">Script API reference</a>
<ul>
<li data-dont-default-collapse>
<a>Namespaces</a>
<ul>
<li><a href="script/api/ns_unnamed.html">Content not in any namespace</a></li>
<li><a href="script/api/ns_enums.html">enums</a></li>
<li><a href="script/api/ns_game.html">game</a></li>
<li><a href="script/api/ns_global.html">global</a></li>
</ul>
</li>
<li data-dont-default-collapse>
<a>Types</a>
<ul>
<li data-dont-default-collapse>
<a>Variables</a>
<ul>
<li><a href="script/api/number.html">Number</a></li>
<li><a href="script/api/object.html">Object</a></li>
<li><a href="script/api/player.html">Player</a></li>
<li><a href="script/api/team.html">Team</a></li>
<li><a href="script/api/timer.html">Timer</a></li>
</ul>
</li>
<li data-dont-default-collapse>
<a>Misc</a>
<ul>
<li><a href="script/api/bool.html">Bool</a></li>
<li><a href="script/api/engine-icon.html">Engine Icon</a></li>
<li><a href="script/api/forge-label.html">Forge Label</a></li>
<li><a href="script/api/format-string.html">Format String</a></li>
<li><a href="script/api/incident.html">Incident</a></li>
<li><a href="script/api/object-type.html">Object Type</a></li>
<li><a href="script/api/player-set.html">Player Set</a></li>
<li><a href="script/api/player-traits.html">Player Traits</a></li>
<li><a href="script/api/sound.html">Sound</a></li>
<li><a href="script/api/variant-string-id.html">Variant ID</a></li>
<li><a href="script/api/waypoint-icon.html">Waypoint Icon</a></li>
<li><a href="script/api/widget.html">Widget</a></li>
<li><a href="script/api/widget-icon.html">Widget Icon</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a>Concepts</a>
<ul>
<li><a href="concepts/bipeds-and-items.html">Bipeds and items</a></li>
<li><a href="concepts/firefight.html">Firefight</a></li>
</ul>
</li>
</ul>
</nav>
<main>
<h1>Best practices</h1>
<p>
When writing scripts, there are a number of things you can do to make things easier for yourself and others.
</p>
<h2>Back up your original source code</h2>
<p>
Megalo is a <dfn>compiled</dfn> language. This means that the game variants that you save will not include the full and exact script code that you wrote; rather, they include a pre-processed copy of the code, which <i>Halo: Reach</i> can quickly
read and execute. Aliases, code comments, and similar <em>are not saved</em>, and if you lose them, they
<em>cannot be recovered by decompiling.</em>
</p>
<p>
You should keep your own copies of the source code that you write, separately from the game variant files that you save, so that you don't lose your code comments and other informative content.
</p>
<h2>Use aliases everywhere</h2>
<p>
When working with Megalo, you'll find yourself juggling several variables, particularly "temporary" variables that only need to hold information very briefly as part of some task. My approach to this is to alias all of my variables at the top of the script,
with names specifically marking the temporary ones.
</p>
<pre>
<code class="language-rvt-script">
--
-- I use names like these for my temporary variables:
--
alias temp_int_00 = global.number[0]
alias temp_int_01 = global.number[1]
alias temp_obj_00 = global.object[0]
--
-- Variables that need to remain "pristine" throughout a single game tick, or across
-- multiple game ticks, get more meaningful names:
--
alias sudden_death_enabled = global.number[2] -- set this to 1 when you want Sudden Death to be active, or 0 otherwise
alias announced_sudden_death = global.number[3] -- only announce the start of Sudden Death once
-- I usually define names like the ones above at the start of the script file.
--
-- Aliases can be block-scoped, so when you're using a temporary variable for something,
-- you can give it a specific name.
--
for each object with label "goal" do
alias current_biped = temp_obj_00
alias distance = temp_int_00
--
for each player do
current_biped = current_player.biped
if current_biped != no_object then
distance = current_biped.get_distance_to(current_object)
if distance < 10 then
--
-- ...
--
end
end
end
end</code></pre>
<p>
Aliases are also good for script options, so that you can reorder them within your gametype without having to change option indices all over the code. I prefer to put these aliases near the start of the code:
</p>
<pre>
<span class="keyword">alias</span> opt_leader_points = script_option[0]
<span class="keyword">alias</span> opt_kill_points = script_option[1]</pre>
<p>
And of course, it's also useful to do that for script traits, script widgets, and the indices of unnamed Forge labels:
</p>
<pre>
<code class="language-rvt-script">
alias current_biped = current_player.biped
for each object with label "Test String" do
for each player do
--This is test code to experiment with syntax highlighting
if current_object.is_of_type(spartan) and current_object == current_player.biped then
current_object.place_at_me(spartan, none, none, 0, 0, 0, none)
global.object[0] = current_player.biped
current_player.number[0] = current_biped.health
current_player.score = script_stat[0]
end
end
end
</code>
</pre>
<pre>
<span class="keyword">alias</span> leader_traits = script_traits[0]
<span class="keyword">alias</span> ui_turn_clock = script_widget[0]
<span class="keyword">alias</span> all_jetpacks = 1
<span class="keyword">for</span> <span class="subkeyword">each</span> <span class="subkeyword">object</span> <span class="subkeyword">with</span> <span class="subkeyword">label</span> all_jetpacks <span class="keyword">do</span>
<span class="comment">-- ...</span>
<span class="keyword">end</span></pre>
<p>
Most programming languages let you create as many variables as you need. Megalo doesn't; you have a limited pool of variables to use, and ReachVariantTool doesn't automatically manage them for you. You have the maximum level of control over them, but
also the maximum amount of responsibility. Aliases are a powerful tool for keeping things manageable.
</p>
<h2>Use object-scoped variables sparingly!</h2>
<p>
Megalo allows us to store information on objects in the game world, using variables that belong to those objects. However, only 512 objects at a time are allowed to have variables. If you try to assign variables to more objects than that, then you simply
won't be able to.
</p>
<h2>Comment your code!</h2>
<p>
Code comments are a great way to make sure that other people can easily understand your code. They're also very helpful for you, because you're gonna be "other people" in six months. It's always helpful to write informative comments which explain what
you're doing.
</p>
<pre>
<span class="keyword">if</span> opt_draw_rule > 0 <span class="keyword">and</span> draw_turn_count >= opt_draw_rule <span class="keyword">then</span>
<span class="comment">--</span>
<span class="comment">-- If 75 moves (by default) pass without there being pawns on the board, and </span>
<span class="comment">-- without either player capturing an enemy piece, then the game will end in </span>
<span class="comment">-- a draw automatically.</span>
<span class="comment">--</span>
ui_endgame.set_text(<span class="string">"Draw! (%n turns passed with no pawns and no captures.)</span>", draw_turn_count)
do_endgame_ui_visibility()
game.end_round()
<span class="keyword">end</span></pre>
<p>
It's somewhat common for novice programmers to write code comments that... aren't strictly helpful, like in this deliberately exaggerated example here:
</p>
<pre>
<span class="comment">-- Increase the number by five</span>
global.number[0] += 5</pre>
<p>
But... how does one write a good code comment? Well, a good way to view programming is as its own form of communication, in a setting where precision is required and enforced, and we don't call these things "programming <em>languages</em>"
for nothing. When you write code, you're communicating with the machine, but you're also communicating with whoever else reads your code. Some ideas are easier to express in plain English, however — particularly high-level goals and abstractions
— and those are precisely the ideas you should aim to convey in a code comment.
</p>
<p>
The code that you write consists of low-level, step-by-step instructions — lots of "little picture" stuff. Let your comments convey the big picture... and the medium picture, I suppose.
</p>
</main>
<script src="resources/sidebar.js"></script>
<script src="resources/header-links.js"></script>
</body>
</html>