-
Notifications
You must be signed in to change notification settings - Fork 55
Objects
Objects are the basic form of entity in Kristal. Everything in Kristal is an object: UI elements, characters, the overworld, bullets, everything. As such, understanding the basics of how they work is important to being able to use Kristal.
The essential properties of an object are its position, width and height, and parent. When an object is parented to another object, its position becomes relative to that object. All objects must be parented to something, otherwise the game will not recognize them (see Creating New Objects below for more details). The highest object is called the stage, and it is what most essential objects are parented to.
x
, y
: Position of the object, relative to its parent.
width
, height
: Size of the object.
color
: Table of 3 numbers between 0 and 1, representing the RGB of the object's color (by default, it's {1, 1, 1}, which is white).
alpha
: Number between 0 and 1, representing the transparency of the object.
scale_x
, scale_y
: Visual scale of the object. Does not affect width or height.
rotation
: Visual rotation of the object, in radians.
flip_x
, flip_y
: Boolean variables that flip the visuals of the object horizontally and vertically. Always flips it around its center.
inherit_color
: Whether the object multiplies its own color by that of its parent.
origin_x
, origin_y
: Numbers between 0 and 1 usually, representing where the origin of the object is relative to its width and height. 0, 0
means its origin is the topleft of the object, 1, 1
means it's at the bottomright, and 0.5, 0.5
means the origin is centered. By default, all origin values are 0. Origin values can be less than 0 or greater than 1, which puts the origin outside of the object's size.
scale_origin_x
, scale_origin_y
, rotation_origin_x
, rotation_origin_y
: Same rules as origin_x
and origin_y
, affecting where scaling and rotation originates from.
parallax_x
, parallax_y
: Numbers between 0 and 1 usually, representing how much the object will be moved when the camera moves. 0 means the object is unaffected by camera movement, and will stay in the same position on-screen regardless of it, and 1 means it will move along with the camera. By default, it is 1.
cutout_left
, cutout_top
, cutout_right
, cutout_bottom
: Determines a visual cut from the object if specified, in number of pixels. For example, if cutout_top
is 5, then the object will have the top 5px of its sprite cut off.
physics
: A table of values that will be automatically used to move the object when it updates. All values are 0 by default. The values that can be defined in it are:
-
speed_x
,speed_y
: How many pixels the object will move horizontally and vertically per frame at 30fps. -
speed
: How many pixels the object will move indirection
per frame at 30fps. -
direction
: The direction the object will move in ifspeed
is defined, in radians. -
spin
: How muchdirection
will change per frame at 30fps. -
match_rotation
: If set to true, thendirection
will be updated to match the object'srotation
. -
friction
: The amount the object'sspeed_x
,speed_y
, andspeed
will be reduced by per frame at 30fps. -
gravity
: The amount the object's will accelerate towardsgravity_direction
per frame at 30fps. Ifspeed
is defined, thengravity
will affect it; otherwise,gravity
affectsspeed_x
andspeed_y
. -
gravity_direction
: The direction the object will accelerate towards, in radians. Ifspeed
is defined, thendirection
will approachgravity_direction
(or be set directly if it isn't yet defined); otherwise,speed_x
andspeed_y
will accelerate towards the angle defined.
graphics
: A table of values that will be automatically used to alter the object's visual properties when it updates. The values that can be defined in it are:
-
fade
: How much the object's alpha will approachfade_to
per frame at 30fps. By default, it is 0, and thusfade_to
will not be approached. -
fade_to
: The alpha that the object's alpha will approach. -
fade_callback
: A function, taking inself
as an argument, that will be called when the object's alpha reaches itsfade_to
value. -
grow_x
,grow_y
: How much the object'sscale_x
andscale_y
will change per frame at 30fps. -
grow
: How much the object's scale will change per frame at 30fps (affecting bothscale_x
andscale_y
simultaneously). -
remove_shrunk
: If set to true, the object will be removed if its scale becomes 0 or negative. -
spin
: How much the object'srotation
will change per frame at 30fps.
layer
: Number representing the order the object will be rendered and updated in. The higher this number is, the later it will render and update (appearing in front of and updating after objects with lower layer values). Should only be changed directly before it's added to a parent; for changing layer after being added to a parent, see setLayer()
below in Functions. A list of common layer values for objects can be found in the global variables list.
collider
: Specifies how other objects collide with this object. See Collision for more detail.
collidable
: Determines whether other objects can collide with this object. See Collision for more detail.
active
: Whether the object updates.
visible
: Whether the object renders.
parent
: The parent of the object. Should not be changed directly, see addChild()
and removeChild()
below in Functions.
children
: A table of objects, if the object itself is a parent. Should not be changed directly, see addChild()
and removeChild()
below in Functions.
All functions for objects require that you pass the object into them. While this could be done by doing Object.move(self, x, y, speed)
, Lua has simpler syntax for this, in the form of Object:move(x, y, speed)
. Unless specified otherwise, all functions for any objects on this wiki should be called in this way.
move(x, y, speed)
: Moves the object x pixels horizontally and y pixels vertically, multiplied by speed
if speed is provided.
collidesWith(other)
: Whether the object collides with the other object specified.
setPosition(x, y)
, setSize(width, height)
, setScale(x, y)
, setColor(r, g, b, a)
, setOrigin(x, y)
, setScaleOrigin(x, y)
, setRotationOrigin(x, y)
, setParallax(x, y)
, setCutout(left, top, right, bottom)
, setSpeed(x, y)
: Functions used to set multiple values at once.
getPosition()
, getSize()
, getScale()
, getColor()
, getOrigin()
, getScaleOrigin()
, getRotationOrigin()
, getParallax()
, getCutout()
, getSpeed()
: Functions used to get multiple values at once. Always returns each value individually, as opposed to a table of values (eg getColor() returns r, g, b, a
as opposed to {r,g,b}, a
).
shiftOrigin(x, y)
: Moves the origin of the object while not moving the object itself.
setLayer(layer)
: Sets the layer of the object. Must be used instead of changing layer
directly.
getLayer()
: Gets the layer of the object.
fadeTo(target, speed, callback)
: Sets fade_to
, fade
, and fade_callback
respectively for the object's graphics
table.
fadeOutAndRemove(speed)
: Sets fade_to
to 0 and fade
to the specified speed for the object's graphics
table. When the object's alpha reaches 0, the object is removed.
setHitbox(x, y, width, height)
: Sets the object's collider
to a new Hitbox with the provided values. See Collision for more detail.
getHitbox()
: Returns the coordinates and dimensions of the object's Hitbox if it exists.
setScreenPos(x, y)
: Sets the object's position relative to the topleft of the screen.
getScreenPos()
: Gets the object's position relative to the topleft of the screen.
localToScreenPos(x, y)
: Gets the screen position of a point specified, relative to the object.
screenToLocalPos(x, y)
: Gets the position relative to the object of a point on the screen.
A note for screen position functions: the screen position accounts for the window scale, such that any coordinates will be the same in-game position regardless of window size.
setRelativePos(other, x, y)
: Sets the position of the object x units horizontally and y units vertically from another object.
getRelativePos(other, x, y)
: Gets the position of the object x units horizontally and y units vertically from another object.
getStage()
: Gets the highest parent of the object. In other words, if the object's parent has its own parent, return parent:getStage()
instead.
getDrawColor()
: Gets the color of the object, multiplied by its parent's color if inherit_color
is true.
collidesWith(other)
: Returns whether the object is colliding with other
. other
can be either a Collider or an Object with collider
defined. See Collision for more detail.
remove()
: Removes the object.
explode()
addChild(child)
: Makes the object the parent of the specified child.
removeChild(child)
: Removes a child from an object.
setParent(parent)
: Makes the object the child of the specified parent, and, if it had a parent previously, removes itself from that parent.
Kristal uses a class-based coding structure implementation in Lua, similar to languages like C#. To create a new instance of an existing class, you call that class's name like a function, passing in values matching what that class's Init function requires. For example, creating a new instance of an Object would be done with Object(x, y, width, height)
. However, creating instances of just an Object is generally not helpful; instead, you'll generally want to make classes that extend Object.
To extend a class, you'll want to make a new .lua file in scripts/objects
. Object files in this folder get loaded automatically; you can place object files in other folders, but you'll have to require
them yourself. An example of a new class that extends Object:
-- Create a new class which extends Object
local MyObject, super = Class(Object)
-- A class that extends a different class contains all of the functions of the class it extends.
-- Class(classname) returns two values: the new class you'll be changing,
-- and a copy of the class you're extending.
-- By setting MyObject:init, we replace the function Object:init for this class.
-- This is called overriding a function, and it's important to understand for extending classes.
function MyObject:init(x, y, width, height)
-- This is what 'super' is used for: we need to still call the original function,
-- so we call super:init(self, ...) to call the original Object:init(...).
-- As mentioned earlier, majority of functions for Objects require self to be passed in.
-- Because of this, we always need to pass in the new object's self
-- into any super functions as the first argument, followed by the rest of the arguments.
super:init(self, x, y, width, height)
end
-- Called every frame by this object's parent
function MyObject:update(dt)
-- Update code goes here, like moving the object
-- We're overriding Object:update, so again, we can call the original using 'super'
-- This calls update on all this object's children, so place it where you want!
super:update(self, dt)
-- By default, update() also handles moving the object by its speed_x and speed_y,
-- and making its alpha approach its target_fade (calling fade_callback when reached)
end
-- Called every frame too, during rendering
function MyObject:draw()
-- Draw code goes here, you can draw textures and rectangles and whatever you want basically
-- Once more, we're overriding Object:draw, so we can call the original using 'super'
-- This calls draw on all this object's children, so placement is important!
-- Code before this line will be drawn below children, code after this line will be drawn above children
super:draw(self)
end
-- Returns the class, to be used later
return MyObject
Other overridable functions are:
onAdd(parent)
: Called when the object is added as a child to a parent.
onRemove(parent)
: Called when the object is no longer a child of a parent (either as a result of the object being removed via remove()
, or as a result of its parent being changed via a new addChild(object)
or removeChild(object)
).
Sometimes, extending classes will not work with the normal method of passing in the class itself. Circumstances like global variables not being created for a class, or indeterminate loading order of class files, can cause this. To extend a class from these circumstances, you'll want to pass the file path, relative to the current base folder for the class file, of the class you want to extend. For example, if you want an Object file to extend an object located at scripts/objects/ZObject.lua
, you would call Class("ZObject")
, since you can't guarantee that ZObject would load first.
When a class is made in scripts/objects
, a global variable named after the file name is created. This global variable is used to create instances of this new class. For example, with the above code at scripts/objects/MyObject.lua
, you can create new instances of MyObject by calling MyObject(x, y, width, height)
.
As mentioned earlier, in order for new instances of objects to be recognized by the game, they must be parented to another object. This parent will be responsible for updating and rendering its children. When creating a new object, your code will generally look something like this:
local object = MyObject(...)
-- someParent is an already existing object that's been added to something else
someParent:addChild(object)
-- OR
object:setParent(someParent)
When an object is parented to another object, its position and layer become relative to its parent's position. Thus, when describing objects that are commonly used as parents, the wiki will often state what its position is relative to, so that children positions can be adjusted accordingly. For example, Game.battle.arena
's layer is 300, and its position is relative to its center; therefore, a child of the arena at 40, 40
with a layer of 1 will be positioned 40 pixels to the right of and 40 pixels below the arena's center, and it will render above the arena, since its layer is effectively 301.
However, it is worth noting that children of an object cannot render above objects that render above its parent, since the parent renders its children directly, and so they inherit its render order overall. This means that an object with a layer of 200 parented to the arena will not render above an object parented to Game.battle
with a layer of 400; while the object's layer is effectively 500, the arena's layer is 300, and thus it will render before the object at 400. This all applies to updating too; children of an object will update before any objects with a higher layer than its parent.
Common objects to be parents are:
-
Game.world
for objects in the overworld. Its position will be relative to the topleft of the room the player is in. -
Game.battle
for objects in battle. Its position will be relative to the topleft of the screen. -
Game.stage
for miscellaneous objects outside of either battles or overworld. It is always present, and it's whatGame.world
andGame.battle
are parented to. Its position will be relative to the topleft of the screen.
Downloading Kristal
Installing and playing mods
Game options
File structure
mod.json and mod.lua
Libraries
Save data
Game and Kristal variables and functions
Important tips
Using objects
Creating new objects
Extra notes
Collision
DrawFX
Sprites and the Sprite object
Custom fonts
Sounds and music
External libraries
Utility functions
Global variables
Debug shortcuts
Debug menus
Making an actor
ActorSprite
Default animations
Creating a party member
Using and overriding functions
Types of Items
Default items
Inventory
Defining a spell
Making rooms
Using rooms in your mod
The Map class
Game.world functions
Events and Controllers
Existing events
Characters
Types of Characters
Battle areas and World bullets
Making a cutscene
Starting cutscenes
The Text object
In-text modifiers
Creating a shop
Overridable functions
Shop states
Shopkeepers
Making an encounter
Game.battle functions
Battle and PartyBattler states
PartyBattlers and EnemyBattlers
Creating an enemy
Overridable functions
Misc. functions and variables