Asset Management - KristalTeam/Kristal GitHub Wiki
Relevant files: sprite.lua, assets.lua, music.lua
Before reading this page, it is recommended to read Objects first.
Sprites, and the Sprite Object
Sprites are a necessary concept to understand for Kristal mod development; nearly every single object involves a sprite, or multiple, in some way. Usage of sprites is aided by the Sprite object, a generic Object that can be added to other objects, responsible for rendering images, with tons of configuration available.
A Sprite is instantiated by calling Sprite(texture, x, y, width, height, path). texture represents the path to the image, and x and y represent the coordinates of where the sprite spawns. width and height define how large the game considers the sprite; if not defined, the game will default to the image's dimensions. path, if provided, refers to the path to get to texture, and is used by other functions such as getPath(). For example, to make a sprite with an image located at assets/sprites/subfolder/sub2/idle.png, you could call either Sprite("subfolder/sub2/idle", ...) or Sprite("idle", ..., "subfolder/sub2").
Sprites will automatically gather a set of images under the correct conditions. If a series of images has a number at the end of each image, then Kristal will consider these all to be an animation of one texture. For example, with the images idle_1.png, idle_2.png, and idle_3.png, calling Sprite("idle", ...) will create an animation that's ready to play those 3 images. Note that because Lua is 1-indexed, an image with the name idle_0.png will not be detected for animations.
Sprites have many variables and functions available to use, making them very powerful objects. These are:
wrap_texture_x, wrap_texture_y: Whether the image repeats horizontally and vertically, respectively. Defaults to false.
frame: If the sprite is an animation, refers to the current frame number of the animation.
getTexture(): Returns the current texture of the sprite.
getPath(name): Returns the path up to the current texture, or up to name if specified, relative to the sprite's path (or simply assets/sprite if path was not defined).
setSprite(texture, keep_anim): If texture is a string referring to a single image, set the sprite's texture to the specified path. If texture is either a string referring to a series of images, or a table of strings referring to images, set the sprites animation to the specified value. Additionally, if path was defined for the sprite, it will prefix texture with that. From previous example, if path is set to "subfolder/sub2", then setSprite("idle") will work. If keep_anim is set to true, the sprite will continue animating if it already is; otherwise, the animation will stop.
setAnimation(anim): Sets the sprite's animation using information provided by anim, which is a table of values. The first value of the table represents the path to the images for the animation. The second value is the delay between frames, in seconds. Deltarune renders at 30fps by default, so a value of 1/15 for this is what's often used. The third value represents whether the animation loops or not. If not, it will remain on the final frame. You can also define extra information in the table with other indexes. It accepts the following definitions:
duration: Number of seconds that the animation will last if it loops.frames: A table of numbers or strings that allows you to override the automatic process of selecting frames in order. If a value is a string, it will attempt to parse special syntax for it. Two forms of syntax are available:"1-5"and"1*5". The format1-5will add each frame between 1 and 5 (including each) to the table (eg.frames={"1-5"}gives the table{1,2,3,4,5}). The format1*5will add the frame specified repeatedly, for the number of frames specified (eg.frames={"1*5"}gives the table{1,1,1,1,1}).callback: A function that will be called when the animation ends, passing in the Sprite instance as an argument.
Alternatively, anim can be a function instead, with the format function(sprite, wait). This function will become a coroutine when the animation is called, passing in the Sprite class the animation is using, and a function called wait(num) that waits for the specified amount of seconds before continuing in the code. However, this is very complicated, and unnecessary for most practical use cases, so making animations with tables is the recommended approach.
play(speed, loop, on_finished): If an animation is ready (via being set by setFrames() or setSprite()) and has not been started, calling this function will play the sprite's animation. speed is the delay between frames, loop is whether the animation loops (true if undefined), and on_finished is a function that will be called when the animation ends.
stop(keep_frame): Stops the sprite's animation if it's playing. If keep_frame is true, then the animation will pause on the current frame; otherwise, the animation gets reset to its first frame.
pause(): If an animation is playing, pause it.
resume(): If the animation was previously paused, resume it.
setFrame(frame): If the sprite has multiple frames, set the frame to this number.
setProgress(progress): If the sprite has multiple frames, set the frame to this fraction of the animation. For example, for an animation with 10 frames, setProgress(0.3) would set the animation to the 3rd frame.
Custom Fonts
Kristal's fonts are made using LÖVE2D's ImageFont system. All font files should go in assets/fonts. Each font should have two files for it: a .png for the image the font should use, and a .json with the same name defining data for the font. The .json should define the following fields:
glyphs: A string containing a list of the characters in the image, in order.
lineSpacing: A number defining the number of pixels between each newline in the font.
defaultSize: An optional number defining the default size used for the font.
Instead of using an image, Kristal also supports using .ttf files. When using a .ttf file, it should still have a .json file with the same name, but the glyphs field is unnecessary for .ttf files.
Sounds and Music
Sounds can be used via functions within the global Assets table. The Assets table is responsible for storing and using all assets loaded in Kristal mods. It is worth specifying that Assets is not a class, and thus, calling functions for it do not require passing in the table itself; in other words, you would call Assets.getSound() instead of Assets:getSound(). The functions relevant to using sounds are:
getSound(sound): Returns a static LÖVE Source instance for the sound located at the path specified by sound. Changing this Source will affect all future instances of the sound.
newSound(sound): Returns a new Source instance for the sound at the specified path.
playSound(sound, volume, pitch): Creates and returns a new Source instance, playing it once, setting its volume and pitch to the arguments if specified.
Music, on the other hand, is handled by the Music class. Common instances of the Music class are Game.world.music and Game.battle.music, and you'll likely want to use one of these two to play music. Variables and functions available for the music class are:
volume: The volume of the music.
pitch: The pitch of the music.
current: The file path of the current song playing, relative to assets/music.
source: The Source used to play the song.
fade(to, speed, callback): Fades the music's volume to a value between 0 and 1. speed is how fast the music's volume with approach the target speed (0.1 by default), and callback is a function that will be called once the music reaches the specified volume.
play(music, volume, pitch): Plays the song at the specified path, setting volume and pitch if defined.
stop(), pause(), resume(): Calls the respective Source functions on source.
isPlaying(): Returns whether source is currently playing.