Best practices

When writing scripts, there are a number of things you can do to make things easier for yourself and others.

Back up your original source code

Megalo is a compiled 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 Halo: Reach can quickly read and execute. Aliases, code comments, and similar are not saved, and if you lose them, they cannot be recovered by decompiling.

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.

Use aliases everywhere

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.

--
-- Variables that need to remain "pristine" throughout a single game tick, or across
-- multiple game ticks, get meaningful names:
--
alias sudden_death_enabled   = allocate global.number -- set this to 1 when you want Sudden Death to be active, or 0 otherwise
alias announced_sudden_death = allocate global.number -- 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 = allocate temporary object
   alias distance      = allocate temporary number
   --
   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

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:

alias opt_leader_points = script_option[0]
alias opt_kill_points   = script_option[1]

And of course, it's also useful to do that for script traits, script widgets, and the indices of unnamed Forge labels:

alias leader_traits = script_traits[0]

alias ui_turn_clock = script_widget[0]

alias all_jetpacks = 1
for each object with label all_jetpacks do
   -- ...
end

Most programming languages let you create as many variables as you need. ReachVariantTool's dialect of Megalo is lower-level; you have a limited pool of variables to use, and the compiler 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.

Use object-scoped variables sparingly!

Megalo allows us to store information on objects in the game world, using variables that belong to those objects. However, only a limited number of 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.

Comment your code!

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.

if opt_draw_rule > 0 and draw_turn_count >= opt_draw_rule then
   --
   -- If 75 moves (by default) pass without there being pawns on the board, and 
   -- without either player capturing an enemy piece, then the game will end in 
   -- a draw automatically.
   --
   ui_endgame.set_text("Draw! (%n turns passed with no pawns and no captures.)", draw_turn_count)
   do_endgame_ui_visibility()
   game.end_round()
end

It's somewhat common for novice programmers to write code comments that... aren't super helpful, like in this deliberately exaggerated example here:

-- Increase the number by five
global.number[0] += 5

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; we don't call these things "programming languages" 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.

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.