Skip to content
tolmar edited this page Aug 11, 2024 · 9 revisions

Control Code Script, or CCScript, is an amazing programming language made specifically for EarthBound hacking. You can use any text editor you prefer, but many people in the scene have been known to recommend Notepad++. Notepad++ also comes with the handy benefit of user-defined syntax highlighting, of which a CCS syntax highlights file has been made and is available on the CCScript Library page.

You can find a list of all of its commands here: CCScript Command Reference, and documentation on the language itself (and some additional handy tidbits) here: CCscript Language Reference.

Various helpful .ccs files have been curated on this wiki via Gist - the CCScript Library! To add these to your project, simply navigate to the ccscript folder, create a blank text file, and rename it to <name>.ccs and paste the stuff right in. (You may need to enable file extensions first. On Windows, it's under the View tab of File Explorer.)

Adding new text to the game

CCScript files must all be placed in the ccscript directory of your CoilSnake project. You can create a .ccs file and then edit it with your favorite text editor. Add labels (so you can point NPCs and etc. to the text), and add text. Here is an example of what your text may look like:

BrandNewNPC:
    "@Hello " name(1) "!" next
    "@It's good to see you." end

Let's break down what's going on here.

  • BrandNewNPC: This is a label. Labels let you point to parts of your code, you'll need them whenever one part of the game needs to know how to find another. A label is text followed by a colon. Labels are used by some commands, and also in some yml files (you can set an NPC's text pointer to this_files_name.BrandNewNpc in npc_configuration_table.yml to make them say this, because BrandNewNpc is a label).
  • "@Hello " Letters inside of quotes are printed as text instead of interpreted as commands. The @ character prints the bullet point (•) which EarthBound uses at the start of sentences.
  • name(1) prints the first character's name (that's Ness!), as defined by the player on the naming screen. name() is a command and can only be used outside of quotation marks (otherwise the game would literally print "name()") See the CCScript reference linked above for more commands.
  • "!" Letters inside of quotes are printed, so this just prints !
  • next displays the blinking triangle in the bottom right, and waits for a player input. When it receives one, it will begin printing the following text on a new line.
  • "@It's good to see you." This is more text printing.
  • end Does two things - it waits for the player to press a button (just like next), and then it ends the current script. A similar command, eob, just ends the current script without waiting for a button press. It is very important to end your scripts in either end or eob! The game does not know to stop looking for text without these, and forgetting will make it continue on into other scripts, or even garbage data, which can cause confusing and cursed behavior.

You'll notice that the above example has a space inside the quotes for "@Hello ". This is because there should be a space between "Hello" and Ness's name. It can be awkward to write things this way though, so ccscript offers an alternative:

BrandNewNPC:
    "@Hello {name(1)}!" next
    "@It's good to see you." end

This does exactly the same thing as the above example. Things inside {}s inside quotes behave as if they're not in quotes. Many people find the code easier to read this way.

Labels, calls, and gotos

Let's look at another example

SomeNpcProbably:
  "@Hi!" next
  goto(Label2)

Label1:
  "@Isn't that pointless?" end

Label2:
  "@Everything I say is out of order!" next
  goto(Label1)

Recall that words ending in a colon are a label.

The goto(label) command makes the text continue at that label. This is important when you want to write text out of order. This is completely useless on its own (the above example really is pointless) but will come in handy with other commands.

Let's look at another example

WhoIsThisPerson:
  "@Hi!" next
  "@I really like the word " call(FavoriteWord) "!" next
  "@" call(FavoriteWord) ", " call(FavoriteWord) ", " call(FavoriteWord) "!" end

FavoriteWord:
  "Banana"
  eob

The call(label) command is like goto, but once the text finishes (from an end or an eob) it will come back to where the call started.

Menus

Selection menus can be managed with CCScript as well. There are control codes for them, but this method is much easier. Here is an example:

"@Do you like EarthBound?" next
menu{

    "Yes": {goto(sayYes)}
    default "No": {goto(sayNo)}
}
sayYes:
  "@Neat me too." end

sayNo:
  "@I will fight you." end

Start a menu with menu{. You can then add options to this menu with "Option text": { } (Replace Option text with what you want the options to say.) Inside the curly braces of your options, you can write CCScript as normal, but it's much neater to use goto()s. You can write multiple lines of text, just don't forget the end curly brace. Lastly, close off the entire menu function with another }.

Additionally, default can be used to specify what text should be printed if the player presses B. If no default option is specified, the game will continue printing whatever text comes after the menu option.

Control codes

Control codes are how the game does all sorts of things. In fact, CCScript commands are actually control codes with a fancy coat of paint. Unfortunately, however, the current version of CCScript does not have aliases for every control code, and there are some handy functions that you may like to use. There is a list of control codes and their uses available on DataCrystal here.

Control codes are slightly odd compared to commands as they must be within quotation marks to function. For instance, "@Hello[13]" and "@Hello" wait. These are functionally identical, as wait is an alias for "[13]", but the difference is that the control code is within quotation marks.

byte, short, and long

In the Data Crystal documentation of control codes, you'll notice that arguments are presented as "XX XX" or "YY" or even "XX XX XX XX". These are in hexadecimal, so to handle conversion and endianness and data length, there are a few functions you can use.

  • "XX" - {byte num}
  • "XX XX" - {short num}
  • "XX XX XX XX" - {long label} used for labels, so put the label here

For some more advanced stuff, you may find that you'll need to use a 24-bit (3 byte) label.
For that, you can use command adr24(a) "[{byte[0] a} {byte[1] a} {byte[2] a}]", which is also defined in asm65816.ccs.


Modifying existing text

If you want to modify the game's original script, you will need to do this:

  1. Backup the project you just made somewhere - This helps if something goes wrong or you want to look at original files at some point
  2. Click on the Decompile Script tab in CoilSnake
  3. Click on the "Browse..." button next to the ROM: field
  4. Select your EarthBound ROM
  5. Now click on the "Browse..." button next to the Project: field and go to the directory of the CoilSnake project we created above
  6. Make sure that the path in the Project: field is to the actual folder where all your project files are stored
  7. Now click on the big "Decompile Script" button

Watch a video of these steps: https://youtu.be/C6bkgrGB-n8

Modifying the Main Text

All of the main game text is now located in the ccscript folder in your project files. If you haven't backed up a copy of this folder I would recommend doing that before you edit it. Having the original somewhere for reference is a good idea. Just put a copy of it somewhere outside of your project folder.

The ccscript folder now contains .ccs files, most of which are data_xx.ccs. Please don't worry about main.ccs, this is a file that helps everything be repointed, which means you don't have to worry about ROM space, or how long or short your project's text is compared to the original script data. This may sound unremarkable, but it makes editing text a lot less frustrating compared to older tools!

Finding a specific line of dialogue can be tricky, but AstroGrep or a similar file-search utility can be used to great effect. Notepad++ also has a "Find in all opened files" function.


Parts of the CCScript language

  • Normal Text: You can tell if something is normal text if it is surrounded by quotation marks AND doesn't appear between square [ ] or curly { } braces.
  • Labels: labels are what CCScript uses to organize blocks of text. They are a name, followed by a colon.
  • Control codes: These are hexadecimal values surrounded by square brackets within the text, such as [1C 02 00]. They tell the game all kinds of vital instructions.
  • CCScript Commands: These are normal commands that ccscript uses to tell the game what to do. They are usually outside of quotation marks or between curly braces. The most common are linebreak, which tells the game to jump to the next line when printing out text, next, which waits for the player to press a button before going to the next line while printing out text (this shows the little downward arrow prompt), eob, which means the end of a text block, etc. I would recommend reading about the basic commands here.
  • Comments: These occur after two forward slashes // or between a /* and a */. Comments are not parsed as text at all, they are only meant for organization and notes.
  • @: The @ character simply represents the little circle dot that starts at the beginning of most sentences in EarthBound.
  • | and /: | and / are shortcuts of the pause() command. A slash pauses for five frames (pause(5)) and a pipe pauses for fifteen.
  • < and >: Since double-quotation marks (") are used in the syntax of CCScript, these act as aliases to print them in-game. For instance, <Cracked Bat> will print "Cracked Bat"
Clone this wiki locally