Skip to content

World Objects

Nyako edited this page May 31, 2022 · 21 revisions

Relevant files: event.lua, events folder, character.lua, player.lua, follower.lua, chaserenemy.lua, worldbullet.lua

Events and Controllers

Objects on the overworld are usually created as an extension of Event. They're created by the objects layer in maps: when a room loads, it will go through each shape on the object layer and attempt to load it. There are 4 different ways events can be loaded, and it attempts them in order (moving to the next method if one fails):
1: If the map has overridden loadObject() and returns an object for the shape's name (see the Map class for more detail)
2: If the mod has a loadObject() function that returns an object for the shape's name (see mod.lua for more detail)
3: If the mod has a .lua file with the same name as the shape in scripts/world/events
4: If Kristal has a default object with the shape's name (eg. "savepoint" or "transition")

The main method to create new events is to make a file for it in scripts/world/events. This file should extend Event (or one of its extensions, discussed below), taking in data as an argument. data is a table defining the fields name, x, y, center_x, center_y, width, height, and properties, based on shapes in the map file for a room. name is the name of the shape, x and y refer to its topleft, center_x and center_y refer to its center if it has a width and height, width and height refer to its width and height if it exists, and properties is a table containing all custom properties defined by the shape.

Event objects have the following variables and functions available to be used and overridden:

solid: If true, the event will be a solid to characters.
world: A reference to the current World instance. Defined after initiation.
data: The data table used to create the event. Defined after initiation.
postLoad(): Called after all events have been loaded.
onInteract(chara, dir): Called when the player interacts with the event. chara is the Character instance interacting with the event, and dir is a string referring to the direction the player is facing. If this function returns true, it will prevent the interaction input from interacting with any other events. onCollide(chara): Called every frame a character is overlapping the event. chara is the Character instance colliding with the event.
onEnter(chara): Called once when a character first enters the event. chara is the Character instance colliding with the event.
onExit(chara): Called once when the character leaves the event's hitbox. chara is the Character instance exiting the event.
getUniqueID(): Returns a string unique to the event instance. This string will be consistent every time the room is loaded.
setFlag(flag, value): Sets a save data flag for the object instance to the specified value.
getFlag(flag, default): Gets a save data flag for the object instance, returning default if the flag doesn't exist.

Additionally, all events can define the following custom properties to define conditions for loading the event:

flagcheck: A string defining a flag name that must be true for the event to be loaded. If the string is prefixed with an ! (eg. !condition), then the flag must instead be false to load the event.
cond: A string defining Lua code that will be checked; if the code results in a boolean whose value is true (eg. Game.world.player.x < 100), the object will be loaded.

Controllers are similar to events, but they have a few key differences; the primary distinction is that controllers are not visible objects in the overworld, and are simply responsible for "controlling" specific behavior in a room. They are also added to the generic Game.world.controller object, instead of Game.world directly.

The process for making controllers is very similar to making a custom event. They still extend Event, but the functions to override and locations to place files are different:

1: If the map has overridden loadController() and returns an object for the shape's name (see the Map class for more detail)
2: If the mod has a loadController() function that returns an object for the shape's name (see mod.lua for more detail)
3: If the mod has a .lua file with the same name as the shape in scripts/world/controllers
4: If Kristal has a default object with the shape's name (eg. "toggle")

Existing Events

There are several extensions to Event that exist for conveniently making several common object types from Deltarune. The following is a list of these classes, along with what name to give the shape in the objects layer of the map to automatically load one of these events, and a list of custom properties that can be defined in the map. Some events take a properties argument in their constructor; this refers to a table containing fields correlating to custom properties that can be defined for shapes in the map.

Transition(x, y, w, h, properties) (transition): Creates a transition to another room. The shape needs to be a rectangle, and can define the following custom properties:

  • x, y OR marker: The position the player should spawn at in the new room. If x and y are defined as numbers, it refers to the coordinates in pixels from the topleft of the room; if marker is defined as a string, it refers to the position defined by a marker with that name.
  • map: The ID of the map to load.
  • shop: The ID of the shop to load. If this is defined, then the position defined by x and y or marker will refer to the position the player will be put when they exit the shop.
  • facing: An optional property specifying the direction the party should face upon spawning in the new room. If undefined, the party will automatically face the direction they were looking when they entered the transition.

Script(x, y, w, h, properties) (script): Creates a region that executes code upon being entered by the Player character. The shape needs to be a rectangle, and can define the following custom properties:

  • cutscene: The file path to the cutscene, relative to scripts/world/cutscenes. The cutscene function will receive the Script instance and the Character instance that activated it as arguments. See Starting Cutscenes for more detail.
  • script: The file path to a script, relative to scripts/world/scripts. These files work similarly to cutscene files, but they do not take a Cutscene instance when called, instead only receiving the Script instance and the Character that activated it; they are intended for simpler code to be run. An example script file would be:
return function(script, chara)
  chara:setFlag("booped_thing", true)
end
  • setflag: An optional string referring to the name of the flag to set when the script is activated.
  • setvalue: An optional property defining what to set the flag determined by setflag to when the script is activated; if undefined, the flag will just be set to true.
  • once: If true, the script will only be able to be activated once in a save file. This is optional, and defaults to true.

Interactable(x, y, w, h, properties) (interactable): Creates a region that can be interacted with to start cutscenes or text. The shape needs to be a rectangle, and can define the following custom properties:

  • cutscene: The file path to the cutscene, relative to scripts/world/cutscenes. The cutscene function will receive the Interactable instance, the Character instance that activated it, and the direction the character is facing as arguments. See Starting Cutscenes for more detail.
  • script: The file path to a script, relative to scripts/world/scripts. The script will receive the Interactable instance, the Character instance that activated it, and the direction the character is facing as arguments.
  • text OR text1, text2, ...: A string or series of strings defining text that will appear upon interacting with the event.
  • solid: Whether the event has a solid hitbox or not.
  • setflag: An optional string referring to the name of the flag to set when the script is activated.
  • setvalue: An optional property defining what to set the flag determined by setflag to when the script is activated; if undefined, the flag will just be set to true.
  • once: If true, the script will only be able to be activated once in a save file.

NPC(actor, x, y, properties) (npc): Creates an NPC. When created through code, actor should refer to the ID of the actor to use. The shape should be either a point or a rectangle, and can define the following custom properties:

  • actor: The ID of the actor to use.
  • sprite OR animation: If sprite is defined, the NPC's sprite will be set to path specified. Otherwise, if animation is defined, the NPC's sprite will be set to the animation with the ID specified, if the actor has it defined.
  • facing: An optional property, defining the initial facing direction of the NPC.
  • cutscene: The file path to the cutscene, relative to scripts/world/cutscenes. The cutscene function will receive the Interactable instance, the Character instance that activated it, and the direction the character is facing as arguments. See Starting Cutscenes for more detail.
  • script: The file path to a script, relative to scripts/world/scripts. The script will receive the Interactable instance, the Character instance that activated it, and the direction the character is facing as arguments.
  • text OR text1, text2, ...: A string or series of strings defining text that will appear upon interacting with the event.
  • solid: An optional property, defining whether the NPC is solid.
  • setflag: An optional string referring to the name of the flag to set when the script is activated.
  • setvalue: An optional property defining what to set the flag determined by setflag to when the script is activated; if undefined, the flag will just be set to true.

ChaserEnemy(actor, x, y, properties) (enemy): Creates an enemy that can be used to start an encounter. When created through code, actor should refer to the ID of the actor to use. The shape should be either a point or a rectangle, and can define the following custom properties:

  • actor: The ID of the actor to use.
  • encounter: The ID of the encounter that this enemy will start upon collision.
  • group: A string defining an arbitrary ID that multiple enemies in a room can have to define a group of enemies. If one enemy in a group is defeated, all of them will disappear from the room.
  • path: An optional property, referring to the name of the path shape the enemy will follow.
  • speed: If path is defined, this is a number referring to the speed that the enemy will move along the path.
  • progress: If path is defined, this is a number between 0 and 1 referring to the distance along the path the enemy is.
  • chase: An optional property, defining whether the enemy will chase the player when they see them.
  • chasedist: If chase is true, this is a number defining the distance (in pixels) that the enemy can see the player from (defaulting to 200).
  • chasespeed: If chase is true, this is a number defining the speed (in pixels per frame at 30fps) that the enemy will chase the player (defaulting to 9)
  • aura: If defined as false, the enemy will not have a glowing red aura around it.

TreasureChest(x, y, properties) (chest): Creates a chest that can contain either money or an item. The shape should be either a point or a rectangle, and can define the following custom properties:

  • item OR money: If item is defined, then interacting with the chest will give an item with the matching ID to the party. Otherwise, if money is defined, then interacting with the chest will give that amount of gold to the party.

CyberTrashCan(x, y, properties) (cybertrash): Creates a trash can that can contain either money or an item. The shape should be either a point or a rectangle, and can define the following custom properties:

  • item OR money: If item is defined, then interacting with the trash can will give an item with the matching ID to the party. Otherwise, if money is defined, then interacting with the trash can will give that amount of gold to the party.

Savepoint(x, y, properties) (savepoint): Creates a savepoint. Extends Interactable, and has all properties that can be defined for it. The shape must be a rectangle, and can additionally define the following custom properties:

  • marker: If defined, the player will spawn at the specified marker when loading the game from this savepoint; otherwise, the player will spawn at the room's spawn marker.

Outline(x, y, w, h) (outline): Creates a region that will cause characters inside it to display an outline that displays over other objects. The shape must be a rectangle, and does not need any custom properties defined.
Silhouette(x, y, w, h) (silhouette): Creates a region that will cause characters inside it to display a transparent silhouette that displays over other objects. The shape must be a rectangle, and does not need any custom properties defined.
HideParty(x, y, w, h, alpha) (hideparty): Creates a region that will fade the party's followers' alphas while the player is inside it. When created via code, alpha is a number between 0 and 1 defining the alpha the followers should be set to. The shape must be a rectangle, and can define the following custom properties:

  • alpha: An optional number defining the alpha the followers should be set to. Defaults to 0.

SlideArea(x, y, w, h) (slidearea): Creates a region that the party will slide down. The shape must be a rectangle, and does not need any custom properties defined.
CameraTarget(x, y, w, h, properties) (cameratarget): Creates a region that will pan the camera to a specific x and/or y while the player is inside it. The shape must be a rectangle, and can define the following custom properties:

  • x, y OR marker: The room position to pan the camera to.
  • lockx, locky: Booleans determining whether the region should affect x and y, respectively. Defaults to true for both.
  • time: The time the camera will take to pan to the specified position.
  • returntime: The time the camera will take to return to the player after the player exits the region.

SetFlagEvent(x, y, w, h, properties) (setflag): Creates a region that will set a flag to a specified value. The shape must be a rectangle, and can define the following custom properties:

  • flag: The name of the flag to set.
  • value: The value to set the flag to. Defaults to true if undefined.
  • once: If true, the region will only be able to be activated once in a save file.

Forcefield(x, y, w, h, properties): (forcefield): Creates an electric forcefield that can stop the player. The shape must be a rectangle, and can define the following custom properties:

  • solid: Whether the forcefield is solid or not. Defaults to true.
  • visible: Whether the forcefield will always be visible, or only be visible when the player is close to it. Defaults to false, meaning it will be invisible from afar.
  • flag: A string defining the flag to check the value of to determine whether the forcefield is active; when the condition is met, the forcefield will be active. If the string starts with !, the condition will be inverted.
  • inverted: If true, the condition specified by flag must not be true for the forcefield to be active.
  • value: If specified, the value retrieved by flag must be equal to whatever this value is.

PushBlock(x, y, w, h, properties, sprite, solved_sprite) (pushblock): A block that can be pushed on a grid by the player. When created via code, sprite and solved_sprite are strings correlating to their respective properties. The shape must be a rectangle, and can define the following custom properties:

  • sprite: A string defining the file path for the sprite that the block will use. Defaults to world/events/push_block.
  • solvedsprite: A string defining the file path for the sprite that the block can use when it is in a solved state (eg. on a TileButton). Defaults to sprite if defined, and world/events/push_block_solved otherwise.
  • pushdist: How many pixels the block will move when pushed. Defaults to 40, which is equivalent to 1 tile.
  • pushtime: How long it takes for the block to be pushed. Defaults to 0.2 seconds.
  • pushsound: A string defining the file path to the sound that will be used when the block is pushed. Defaults to noise.
  • lock: Whether the block can no longer be pushed once it's in a solved state. Defaults to false.

TileButton(x, y, w, h, properties, idle_sprite, pressed_sprite) (tilebutton): A button that can be pressed by characters or blocks. When created via code, idle_sprite and pressed_sprite are strings correlating to the properties sprite and pressedsprite, respectively. The shape must be a rectangle, and can define the following custom properties:

  • sprite: A string defining the file path for the sprite that the tile will use. Defaults to world/events/glowtile/idle.
  • pressedsprite: A string defining the file path for the sprite that the tile can use when it is in a pressed state. Defaults to sprite if defined, and world/events/glowtile/pressed otherwise.
  • onsound: An optional string defining the file path to the sound that will be played when something presses the button.
  • offsound: An optional string defining the file path to the sound that will be played when the button stops being pressed.
  • blocks: If true, the button will only be able to be activated by PushBlocks; otherwise, the button will be able to be activated by NPCs, Followers and the Player. Defaults to false.
  • group: A string defining the group the tile is part of. The group is activated when all buttons with the same group property are pressed.
  • flag: If defined, this flag will be set to true when the tile's group is activated.
  • cutscene: If defined, this custscene will play when the tile's group is activated.
  • script: If defined, this script will run when the tile's group is activated.
  • once: If true, the flag / cutscene / script will only activate once in a save file.
  • keepdown: If true, the button will remain pressed even when the object that pressed the button leaves it.

Controllers

Since controllers' positions and size do not typically matter, this section will not specify what type of shape the controller should be, as it can usually be any shape, with any position. The following is a list of default controllers in Kristal:

ToggleController(properties) (toggle): Toggles the existence of any event in the map. It can define the following custom properties:

  • flag: A string defining the flag to check the value of to determine whether the selected event is active; when the condition is met, the event will exist. If the string starts with !, the condition will be inverted.
  • inverted: If true, the condition specified by flag must not be true for the event to be active.
  • value: If specified, the value retrieved by flag must be equal to whatever this value is.
  • target OR target1, target2, ...: An Object property that defines the event that the controller refers to. If multiple targets are specified, all of them will be toggled by the same condition.

Characters

Characters are Objects that have actors as sprites, with several functions to make moving them around an overworld simple. In the overworld, every NPC and party member is an instance of a Character. (In battles, those become Battlers; Characters and Battlers are exclusive to their respective game states, and will not function in the other.)

It is usually not necessary to directly instantiate a character within code; party members are automatically created by World, and NPCs can be created through the NPC class, which extends Character. However, understanding their variables and functions is helpful, as it allows you to manipulate characters in many different ways, which can be applied within cutscenes or any other code.

The variables and functions used by characters are:

actor: The Actor instance the character uses.
sprite: The ActorSprite instance for the character.
facing: A string, being right, down, left, or up, referring to the facing direction of the character. Defaults to down.
noclip: Whether the character ignores collision.
is_player: A boolean stating whether the character is the party leader.
setFlag(flag, value): Sets a save data flag for the character to the specified value.
getFlag(flag, default): Gets a save data flag for the character, returning default if the flag doesn't exist.
getPartyMember(): If the character is part of the party, return the PartyMember instance associated with it.
setActor(actor): Sets the character's actor. actor can be either a string referring to the ID of an actor, or a table of data to create an actor.
setFacing(dir): Sets the character's facing direction to the string specified.
moveTo(x, y, keep_facing), moveTo(marker, keep_facing): Moves the character to the specified position, relative to the topleft of the current room, in pixels. keep_facing is an optional boolean determining whether the character should maintain their current facing direction.
move(x, y, speed, keep_facing): Moves the character x pixels horizontally and y pixels vertically, multiplied by speed if provided. keep_facing is an optional boolean determining whether the character should maintain their current facing direction.
shake(x, y): Shakes the character's sprite.
setSprite(sprite), setCustomSprite(sprite, ox, oy), resetSprite(), setAnimation(anim), play(speed, loop, reset, on_finished): Shorthand for calling ActorSprite functions.
walkTo(x, y, time, facing, keep_facing), walkTo(marker, time, facing, keep_facing): Makes the character walk to the specified position over a period of time. time is the amount of seconds it should take for the character to reach the specified position, facing is an optional string defining the direction they should face when they reach the destination, and keep_facing is an optional boolean determining whether the character should maintain their current facing direction while walking.
walkToSpeed(x, y, speed, facing, keep_facing), walkToSpeed(marker, speed, facing, keep_facing): Makes the character walk to the specified position at a specific speed. speed is the speed in pixels per frame at 30fps the character should walk, facing is an optional string defining the direction they should face when they reach the destination, and keep_facing is an optional boolean determining whether the character should maintain their current facing direction while walking.
walkPath(path, options): Makes the character walk along a specified path. Arguments are the same as Object:slidePath(), with a few extra fields that can be defined for options:

  • facing: Defines the direction the character should face when reaching the end of the path.
  • keep_facing: If true, the character will not change their facing direction while walking along the path.

jumpTo(x, y, speed, time, jump_sprite, land_sprite): Makes the character jump to the specified position, relative to the topleft of the room. speed is how high the character jumps, time is how long the jump takes in seconds, jump_sprite is an animation ID or sprite path to use for the jump animation, and land_sprite is an animation ID or sprite path to play when the character lands at the intended position.
statusMessage(type, arg, color, kill): Spawns a DamageNumber at the character's position. type is the type of message, arg is an argument referring to data the type of message needs, color an optional field referring to the color of the message, and kill is an optional boolean defining whether other status messages should disappear when this one does. Returns the DamageNumber instance. See Battlers for more detail.
convertToFollower(index): Converts the character to a follower (see below), inserting it at index if defined, and at the end otherwise. Returns the new Follower instance.
convertToPlayer(): Converts the character to the new party leader. Returns the new Player instance.
convertToNPC(properties): Converts the character to an NPC. properties is a table of data correlating to properties that can be defined by a map NPC (see above). Returns the new NPC instance.
spin(speed): Causes the character to start spinning. speed is a number referring to how fast the character spins, where positive numbers spin clockwise.

Types of Characters

Alongside the Character class exists multiple extensions of it. Each extension is responsible for handling specific functionality for different kinds of characters. The game handles the assignment of types automatically, and the Character:convertTo... functions can be used to change what type a Character is. Each of the following sections will describe an extension of Character, what it's responsible for, and the variables and functions that can be used for it.

Player

The Player character is the party leader. This character is what the human player controls during overworld gameplay. It is also responsible for interacting with events, colliding with overworld bullets, and other important overworld activities. Players can be created through Game.world:spawnPlayer(x, y, actor). By default, there only ever exists one Player instance at a time; spawning a new Player through the World:spawnPlayer() function gets rid of the old one.

The following variables and functions exist for Player:

force_run: Whether the player is forced to run or not.
alignFollowers(facing, x, y, dist): Sets the player's followers' intended positions be behind the player, in a line. facing is what direction the line should consider the player to be facing (eg. right will make the followers line up to the left of the player), x and y are optional numbers defining where the function should align the followers (defaulting to the player's position), and dist is how far behind the line should be behind the player.

Follower

Followers are characters that follow a Charaacter; by default, this refers to any party members that aren't the first one. They don't strictly need to have PartyMember data defined for them; any character can be a follower if converted to one. They also don't necessarily need to follow a Player. Followers can be created through Follower(actor, x, y, target), where target is a Character instance.

index: The placement of the follower in the list. The follower directly behind the target character has an index of 1, and it increases for each follower.
target: The Player instance that the follower follows. returnToFollowing(speed): If the follower was detached from the character, make the follower return to its intended position in the line. speed is how fast the follower should approach its intended position.
getTarget(): Returns the Character instance the follower is following, defaulting to Game.world.player if target is undefined.

ChaserEnemy

ChaserEnemies refer to any enemies on the overworld. As mentioned earlier in Events, they're responsible for starting encounters, and can be created through the class mentioned. They don't have any variables or functions useful to change.

Battle Areas and World Bullets

Battle areas refer to regions where bullets will start spawning. When the player is colliding with one, the overworld will darken, the battleareas tile layer will become visible (if one is made for the room), all followers will turn invisible, and the player's soul will appear and they'll darken and get a colored outline. During this, Game.world.in_battle will be set to true; you can check this bool to see when to spawn bullets.

WorldBullet is an Object that will damage the party when it collides with the player. They can be spawned through Game.world:spawnBullet(bullet, ...). There are 2 different ways bullets can be loaded, and it attempts them in order (moving to the next method if one fails):
1: If a file that returns a WorldBullet extension exists at scripts/world/bullets/[bullet].lua, where [bullet] is the string passed into the first argument of World:spawnBullet(). When using this method, ... will be passed into the WorldBullet's constructor as arguments.
2: If a sprite exists at the path defined by the first argument passed into World:spawnBullet(). When using this method, ... refers to the x, y, and sprite of the bullet. x and y are relative to the topleft of the current room in pixels, and sprite will automatically be passed into setSprite() for the bullet (see below).

By default, all bullets have a scale of 2, and an origin of 0.5, 0.5. This means its collider, sprite, and any other children will be relative to the topleft of the bullet's width and height, which are automatically set to the dimensions of its sprite if the bullet is initiated with a path specified (in other words, making all children relative to the topleft of the bullet's sprite). When making any bullet's collider, remember that it will be scaled 2x because of this.

WorldBullets have many variables and functions that should be used to define information about them. Since they are Objects, the physics table can be used to move them automatically. The available variables and functions are:

damage: How much damage the bullet will deal to each party member (defaults to 10).
inv_timer: How long the party will be invincible after being hit by the bullet (defaults to 1.33).
destroy_on_hit: Whether the bullet will remove itself upon colliding with the player (defaults to false).
remove_offscreen: Whether the bullet will remove itself when it goes offscreen (defaults to true).
battle_fade: Whether the bullet's opacity fades out when the battle area is exited (defaults to true).
world: Refers to the current World instance. Is defined when it's added to a parent, if the parent is a World instance.
setSprite(texture, speed, loop, on_finished): Sets the sprite of the bullet, and sets the bullet's width and height to the image's dimensions. speed, loop, and on_finished will be passed into the sprite's play() function.
isBullet(id): Returns whether the bullet either is the bullet with the specified ID, or extends it.

Additionally, if you make an extension of WorldBullet in scripts/world/bullets, there exists a few functions that can be overridden to define extra functionality if desired:

getDamage(): How much damage the bullet will deal to each party member. Returns damage by default.
onCollide(soul): Called when the player collides with the bullet. Responsible for calling onDamage() and removing the bullet if destroy_on_hit is true.
onDamage(soul): Called by onCollide() if the soul's invincibility timer is 0. Responsible for damaging the player by the amount returned by getDamage().

Clone this wiki locally