Skip to content
PhoenixBound edited this page Mar 2, 2024 · 9 revisions

Flags are a collection of on-off switches the game stores to your save file to mark plot progress, presents opened, and things of that nature. You can set or unset them, and the game will remember the last of these you did. They all start out unset.

Most flags don't have any inherent meaning in the game's engine (see below for exceptions), they just mean however the script uses them. A collection of how the original game uses flags is listed on Data Crystal.

Several of the yml files that CoilSnake produces use flag controls:

  • enemy_groups.yml has "Fear Event Flag" which controls when enemies run away from you
  • map_changes.yml has an Event Flag that controls when the map change happens. You can add 0x8000 to instead have the change apply when the flag is unset.
  • map_doors.yml has an Event Flag that controls when the door is impassible. If the specified flag is set, you can't use the door. You can add 0x8000 to instead make the door impassible when unset. Unfortunately, Coil Snake dumps these flags in decimal, so they instead have added 32768, which is a lot harder to read.
  • map_enemy_groups.yml uses an Event Flag to control which sub-group is used
  • map_music.yml uses Event Flags to determine which music is played. The music associated with the first flag that's unset is used. You can add 0x8000 to make it whether the music is set, instead.
  • map_palette_settings.yml uses Event Flags to determine which palette a map has. If an event flag is unset, it'll instead use the Event Palette (an entire extra palette entry). You can add 0x8000 to make it when the event flag is set, instead.
  • npc_config_table.yml has an Event Flag for when the NPC is visible. The "Show Sprite" setting determines how this flag is read.
  • photographer_cfg_table.yml has an Event Flag that is set by the photographer once the photo is taken. This makes the photo visible in the final slideshow, but does not control when the photographer itself appears
  • psi_teleport_dest_table.yml has an Event Flag that controls whether that teleport destination is available
  • telephone_contacts_table.yml has an Event Flag that controls whether that contact appears when you use a phone. (Ness's phone unsets some of these flags, and his door sets them back.)

Organizing your flags

If you're making a hack, you'll definitely need to use event flags to keep track of what happens in your story. As Plok will tell you, it's always good to keep track of your flags! It can be tough to use them solely as hex numbers, but thankfully, there's a way to define helpful, descriptive names for each and every one you need!

In any ccscript file, you can do the following: define saturnIsInYourParty = flag 0x1D

This means that in that ccscript file, you can say set(saturnIsInYourParty) instead of set(0x1D)! This is extremely helpful...but what if I told you we can do even better?

Create a file in your ccscript folder called flags.ccs. In this file, define a bunch of flags like this:

define disable_enemies =        flag 11 //This is from the vanilla game, use it to turn encounters on and off
define normal_winters_music =   flag 544 //this is also from the vanilla game
define jeff_visible =           flag 0x15d //turn on and off the new NPC in Snow Wood
define maxwellConvo_1 =         flag 0x1F //set after you've heard his first message
define maxwellConvo_2 =         flag 0x20 //set after you've heard his second message
define jeff_in_party =          flag 0x1D //Use this for dialogue differences depending on if you decide to rescue him later in the story or not
define photo1_viewed =          flag 0x19
define photo2_viewed =          flag 0x1A
define photo3_viewed =          flag 0x1B
define darkroom =               flag 0x1C //TODO: use this to determine if you can leave the chem lab while you're developing film
define saturnIsInYourParty =    flag 0x1D
define bossFight1Finished =     flag 0x1E //Use this to prevent the player from beating the first boss, walk away, walk back, and trigger the fight again
//Put more flags here as needed!

initialize: //run this when the game initializes!
  set(flags.jeff_visible)
  unset(flags.jeff_in_party)
  unset(flags.maxwellConvo_1)
  unset(flags.maxwellConvo_2)
  unset(flags.photo1_viewed)
  unset(flags.photo2_viewed)
  unset(flags.photo3_viewed)
  unset(flags.bossFight1Finished)
  unset(flags.saturnIsInYourParty)
  set(flags.normal_winters_music)
  //Put more flags here as needed!
  eob

Notice how I include helpful comments to remind myself what each of these are for. The initialize script sets each flag to what it's supposed to be set to at the start of the game, and is meant to be called during my new newgame_startup() block! (TODO: Link to a part of this tutorial that covers what these commands do)

When you define a flag, it only works within the context of the ccscript file it's in. But if you do it like this, you can use all of your flags in every ccscript file! All you have to do is refer to it as flags.[insert what you named the flag here].

Here's an example from a single dialogue tree:

Maxwell:
  //TODO: organize this better?? I'd prefer if these if statements could be checked in order
  if flags.maxwellConvo_2 goto(Maxwell_ConfusedChara) //have him say the third message if you've seen the first two
  
  if not flags.maxwellConvo_1 //display the first line of dialogue
  {
    set(flags.maxwellConvo_1)
    "@Oh, {name(1)} and {name(3)}. You startled me!" next
    "@Are you here to work on chemistry homework?" next
    "@Oh, just film. That's cool." end
  }
  else
  {
    //display the second line of dialogue
    set(flags.maxwellConvo_2)
    "@It's for the school paper, right?" end
  }

Maxwell_ConfusedChara:
  //This is the third line of dialogue. It's a hint on what the player's supposed to Check in this room
  "@Uh, what's with that look on your face?" next
  "@It's like you've never developed film before." next
  "@...Maybe you're just tired from staying up last night." next
  "@Well, I'm no expert..." next
  "  ...but it probably has to do with those chemicals on the table there." next
  "@I'm sure you'll feel better after you get warmed up." end

And here's an example of an npc_config_table entry!

1279:
  Direction: down
  Event Flag: 0x15d
  Movement: 8
  Show Sprite: when event flag set
  Sprite: 3
  Text Pointer 1: oldtext.JeffJoinText
  Text Pointer 2: $0
  Type: person

As you can see, the Event Flag field here can only accept numbers, at least in the current version... But elsewhere, notice how I'm referring to flags using their descriptive names from flags.ccs! This technique can be a real game-changer.

Noteworthy flags from the vanilla game

Flags with hard-coded engine-level effects

  • flag 1 (0x1) through flag 10 (0xA) are temp flags, which are reset whenever you enter a door.
  • flag 11 (0xB) is "peaceful mode" and prevents enemies from appearing
  • flag 73 (0x49) is "beat Giygas" and changes what regions you're allowed to use the bike in. (It's also referenced just about everywhere, and changes music and lots of NPC scripts.)
  • flag 74 (0x4A) is set when you beat Ness's Nightmare, and in addition to its plot affects, also doubles Ness's PP
  • flag 475 (0x1DB) sends you to the title screen after death, when you don't want to continue the game
  • flag 749 (0x2ED) puts Ness in his pajamas (except in Magicant and the past)
  • flag 754 (0x2F2) prevents you from teleporting
  • flag 775 (0x307) prevents Dad from calling you

Flags that are referenced in unusual places

  • flag 18 (0x12) is "Buzz Buzz in party" is referenced in the global "door refresh" script. (You can change this with the on_refresh command in ccscript.)
  • Many movement scripts check and set flags, which can be surprising since movement scripts are rather opaque. For example, Lier X. Aggerate in his basement has a bunch of movement scripts that set flags 0x20, 0x21, 0x132, and 0x133 as he runs around.
  • flag 146, "Runaway Five free from Topolla" is also referenced in the Clumsy Robot's death action

Flags needed to get out of the game's intro

If you're not doing a total conversion, trying to get Onett working without the meteor sequence can be a big headache. These are the flags that you need:

set (flag 0x68) // Pokey/Picky punished, first day events cleaned up
set (flag 0x1A6) // Onett daytime palette
set (flag 0x205) // Ness's house's lights are on
unset (flag 0x6B ) // When on, primes sunrise transition exiting Pokey's house
unset(flag 749) // No pajamas?
set (flag 0x1D5) // Suppresses the day 1 townsfolk
set (flag 0x14) // Picky joined your party. Never unset
set (flag 0x22) // Post Starman Jr / Picky left party. Never unset
set (flag 0x64) // King doesn't want to go outside
set (flag 0x177) // Most Onett townsfolk
set (flag 0x5E) // Seems to fix your mom
unset (flag 0x5F ) // Makes phones work (might already be unset)
set (flag 0x62) // Makes Ness's phone specifically work
set (flag 0xC7) // Know how to call Ness's dad
set (flag 0xC8) // Know how to call Ness's mom
unset (flag 0xB) // Turns on random enemy spawns
Clone this wiki locally