-
Notifications
You must be signed in to change notification settings - Fork 37
NPCs
Non-Playable Characters are a staple of the RPG genre, and EarthBound is obviously no exception. Whether they are as simple as a present box or as complex as Pokey Minch, almost all NPCs are handled in the same fashion by CoilSnake. You got a brief glimpse at how they work in the previous chapter, so let's go into more detail in here.
Before we begin, you have to remember (and this applies in almost every case) that there is no way to add new objects directly. In the case of NPCs, each time you want to add a new one, be it a phone, a character, or anything else, you have to edit an existing entry and overwrite it with your new data. So before you start creating new things, make sure your hack can do away with at least one object which the player won't need to enjoy your hack.
List of files used:
SpriteGroups/
npc_config_table.yml
sprite_groups.yml
All the NPC sprites CoilSnake can extract from EarthBound are located within the SpriteGroups
directory. Each sprite group is composed of 16 "slots" for sprites, some of them being unused (since not all NPCs use all of their possible animations). Each individual sprite represents a possible position for the NPC, such as sideways, forward-facing, and so on. Sprite groups are identified by their filename, when they are used in other files produced by CoilSnake; for example, 079.png
would be identified by 79
.
The sprite groups images can be modified using one of the programs suggested in the introduction of this manual.
While enemy sprites can be any combination of 15 colors + one color for transparency, overworld sprites are more complicated to work with palette-wise. If you change one of the sprites to use a combination of colors that aren't in sprite_group_palettes.yml, that sprite won't compile properly. However, if you change that YML file, it'll break any other sprites that use the palette you edited. Normally, people either don't mess with the palette information, or use a tool like JHack to change a vanilla ROM's palettes, then decompile that to get the right values in the YML file.
Sprite groups also need to be configured so that the game engine knows how to animate characters correctly. Their properties are all defined in sprite_groups.yml
, using a rather self-explanatory format (as you will soon find out, a lot of CoilSnake's project files are easy to understand):
1:
East/West Collision Height: 8
East/West Collision Width: 8
Length: 16
North/South Collision Height: 8
North/South Collision Width: 8
Size: 16x24
Swim Flags: [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
This is the definition for the group sprite 1 (Ness), as is indicated by the 1:
at the top. Let's take a
look at each individual property.
-
East/West Collision Height
- The collision height of the sprite when it is facing east or west. Collision heights and widths are all specified in pixels, and are counted starting from the bottom center of the sprite. -
East/West Collision Width
- The collision width of the sprite when it is facing east or west. -
Length
- The number of available sprites within that sprite group. The minimum number here is1
and the maximum is16
. -
North/South Collision Height
- The collision height of the sprite when it is facing north or south. -
North/South Collision Width
- The collision width of the sprite when it is facing north or south. -
Size
- The dimensions in pixels of each individual sprite in the sprite group. -
Swim Flags
- Determines whether or not a sprite should be affected when entering a swim region (by partially submerging the sprite) by specifying a boolean (true
/false
) for each sprite, in left-to-right order.
However, configuration of sprite groups is obviously insufficient to place new NPCs, so additional steps are required.
The configuration associated with NPCs can be found in the npc_config_table.yml
file. Each entry defines a specific NPC (such as a Tenda bystander or an aggressive Shark), with appropriate behavior. Let's take a look at a definition for one of the non-aggressive bag-wielding ladies, of ID 82
:
82:
Direction: right
Event Flag: 0x0
Movement: 12
Show Sprite: always
Sprite: 57
Text Pointer 1: $c72822
Text Pointer 2: $0
Type: person
Let's once more look at these properties one by one.
-
Direction
- Indicates the initial direction the NPC should be facing (and thus which sprite to use initially). This can beright
,left
,down
, orup
. This is mostly useful if your NPC will be standing still, as other types of movements (see below) will make it change its direction as time goes. Item boxes should always start with thedown
direction, to indicate their closed status. -
Event Flag
- Identifies the event to be used to trigger the appearance of this NPC, if necessary (example:0x1a6
). If an event flag is not needed (for example, if the sprite must always be displayed), this should be the null flag:0x0
. If the NPC is an item type, this flag will be used by the game to determine whether or not the item has been taken from the NPC. -
Movement
- Identifies the type of movement to be applied to the NPC; there are hundreds of options to choose from. In this case,57
makes the lady walk very quickly to the bottom left, passing through anything in her way, once the player gets close enough. -
Show Sprite
- Sets the condition for the NPC's visibility. In this case, since there is noEvent Flag
, the sprite shouldalways
be shown. Other options, to be used when an event flag is specified, arewhen event flag set
andwhen event flag unset
. For item NPCs, this should always be set toalways
. -
Sprite
- Specifies the sprite group to be used (as explained in the previous section). -
Text Pointer 1
- A pointer to some dialogue to be displayed when the user interacts (by examining it or talking) with the NPC. This can either be hex code, or it could be a CCScript label. -
Text Pointer 2
- A pointer to some dialogue to be displayed when an item is used on the NPC. It if is an item, this should point to the item to be obtained.$100
will make it an empty box. Any setting higher than that provides money to the player (for example,$10A
adds $10 to the player's wallet). -
Type
- Specifies whether the NPC is aperson
, anobject
(such as an ATM machine) oritem
(such as a present box).
Note: While it may seem like a NPC definition lends itself to re-usability, you should never have several instances of a NPC on your map, as this might cause instability.
Once your NPCs have been set and configured, you can use them from the EB Project Editor to place them in the appropriate location. You can also assign them some dialogue using CCScript (see the CCScript tutorial).
Note however that NPCs do not include enemy characters (these are handled differently, as we will see in the following chapters), so make sure you don't assign them movements which will provoke an attack, as a general rule (there might be exceptions, of course, depending on your hack).
- Overworld Sprites
- Battle Backgrounds
- Battle Sprites
- Title Screen
- Window Graphics
- Logos
- Fonts
- Animations
- Swirls
- EB Project Editor
- Tile Data
- Tile Editor
- Collision Data
- Adding Map Palettes
- Map Editor
- Doors
- Warp Styles
- Enemy Placement
- Hotspots