-
Notifications
You must be signed in to change notification settings - Fork 928
Add a new map object movement behavior
This tutorial is for how to add a new map object movement behavior.
Map objects are defined by object_events in map event scripts, and their assigned SPRITEMOVEDATA_* constants define their movement behavior. This controls how the objects' sprite appears, how it moves, and how it interacts with the player. For example, objects with SPRITEMOVEDATA_WALK_UP_DOWN appear as a 16x16 pixel sprite that walks up and down within a certain radius; while objects with SPRITEMOVEDATA_BIGDOLL appear as a 32x32 pixel sprite that does not move.
(Map objects are not the same as sprites. A sprite is an 8x8 pixel entity, of which you can have 40 on-screen at a time. Map objects are composed of sprites—a 16x16 pixel object consists of four sprites, for instance—but sprites are used throughout the game, not just in the overworld map engine.)
At a minimum, you need to define a new SPRITEMOVEDATA_* constant and its corresponding data. As an example, we'll define SPRITEMOVEDATA_SWIM_UP_DOWN.
Edit constants/map_object_constants.asm:
; SpriteMovementData indexes (see data/sprites/map_objects.asm)
const_def
const SPRITEMOVEDATA_00 ; 00
...
const SPRITEMOVEDATA_SWIM_WANDER ; 24
+ const SPRITEMOVEDATA_SWIM_UP_DOWN
NUM_SPRITEMOVEDATA EQU const_valueAnd edit data/sprites/map_objects.asm:
SpriteMovementData::
; entries correspond to SPRITEMOVEDATA_* constants
; SPRITEMOVEDATA_00
db SPRITEMOVEFN_00 ; movement function
db DOWN ; facing
db OBJECT_ACTION_STAND ; action
db WONT_DELETE ; flags1
db 0 ; flags2
db 0 ; palette flags
...
; SPRITEMOVEDATA_SWIM_WANDER
db SPRITEMOVEFN_RANDOM_WALK_XY ; movement function
db DOWN ; facing
db OBJECT_ACTION_STAND ; action
db 0 ; flags1
db 0 ; flags2
db SWIMMING ; palette flags
-; 25
- db SPRITEMOVEFN_00 ; movement function
- db DOWN ; facing
- db OBJECT_ACTION_STAND ; action
- db 0 ; flags1
- db 0 ; flags2
- db 0 ; palette flags
+; SPRITEMOVEDATA_SWIM_UP_DOWN
+ db SPRITEMOVEFN_RANDOM_WALK_Y ; movement function
+ db DOWN ; facing
+ db OBJECT_ACTION_STAND ; action
+ db 0 ; flags1
+ db 0 ; flags2
+ db SWIMMING ; palette flagsNote that we had to delete some unused data at the bottom which didn't correspond to any SPRITEMOVEDATA_* constant.
Here's what the individual db values mean:
-
movement function: A
SPRITEMOVEFN_*constant, as defined in constants/map_object_constants.asm. -
facing:
UP,DOWN,LEFT, orRIGHT. -
action: An
OBJECT_ACTION_*constant, as defined in constants/map_object_constants.asm. -
flags1: A combination of any of these values, or 0 for none of them:
-
WONT_DELETE: The object won't be deleted if it moves off-screen. Example:SPRITEMOVEDATA_STRENGTH_BOULDER, which needs to stay where it's been pushed. -
FIXED_FACING: The object doesn't change its facing direction if it moves. Example:SPRITEMOVEDATA_SHADOW, which moves along with the player over a ledge but always looks the same. -
SLIDING: The object doesn't animate its steps if it moves. Example:SPRITEMOVEDATA_GRASS, which moves along with the player through tall grass but doesn't have a "stepping" animation. -
MOVE_ANYWHERE: The object isn't limited to moving within a particular radius. Example:SPRITEMOVEDATA_STRENGTH_BOULDER, which can be pushed anywhere. -
EMOTE_OBJECT: The object is meant to be transient and gets deleted differently. Example:SPRITEMOVEDATA_EMOTE, which pops up briefly above an NPC.
-
-
flags2: A combination of any of these values, or 0 for none of them:
-
LOW_PRIORITY: The object will appear below other objects, which have normal priority by default. Example:SPRITEMOVEDATA_BOULDERDUST, which appears below Strength boulders when they're pushed. -
HIGH_PRIORITY: The object will appear above other objects. Do not combine withLOW_PRIORITY. Example:SPRITEMOVEDATA_GRASS, which appears above the player when walking through tall grass. -
USE_OBP1: The object will use SGB palette #1 instead of #0. This was relevant for Gold and Silver since they could be played on the Super Game Boy, but not Crystal.
-
-
palette flags: A combination of any of these values, or 0 for none of them:
-
SWIMMING: The object can move over water but is blocked by land, instead of vice-versa. Example:SPRITEMOVEDATA_SWIM_WANDER, which is used for the Lapras in Union Cave. -
STRENGTH_BOULDER: The object blocks the player if they haven't used Strength. Example:SPRITEMOVEDATA_STRENGTH_BOULDERof course, but also theSPRITEMOVEDATA_BIGDOLL*data for some reason. -
BIG_OBJECT: The object blocks the spaces below it, to its right, and to its bottom-right, not just the space its coordinates are at. Example:SPRITEMOVEDATA_BIGDOLLSYM, which is used for the Snorlax in Vermilion City.
-
In the example, we based SPRITEMOVEDATA_SWIM_UP_DOWN off of SPRITEMOVEDATA_SWIM_WANDER but gave it the same movement function as SPRITEMOVEDATA_WALK_UP_DOWN. In particular, it needed the SWIMMING palette flag.
One more thing: there happens to be a bug that affects objects which swim and move randomly; they're not actually limited by their movement radius. So be sure to fix that.
Anyway, that's all! Now you can use SPRITEMOVEDATA_SWIM_UP_DOWN for object_events just like the rest.

TODO: define new SPRITEMOVEFN_*, OBJECT_ACTION_*, and FACING_* data.
TODO: define new STEP_TYPE_* and STEP_* data.