Skip to content

Utilities and Debugging

vitellaryjr edited this page Nov 20, 2021 · 39 revisions

Utilities

Kristal contains a Utils library with many functions that can be used to assist coding. Additionally, it implements the Timer, Class, and Vector-light libraries from hump libraries. Timer is implemented as an Object; this means that you create new instances of timers through Timer() instead of Timer.new(), and you don't need to manually call update on new timers (since parents automatically update their children). This also means you can't use the global Timer variable as a timer instance itself, like the hump documentation says; instead, you'll likely want to use existing timers already parented to objects. Game.battle.timer and Game.world.timer are examples of easily accessible Timer objects.

The rest of this page details functions defined by Kristal. All of the following functions in this section are contained within the global Utils table, and can be called universally.

copy(table, deep): Returns a copy of a table. If deep is true, all tables within the table will be copies of themselves as well.
dump(table): Returns a string detailing the contents of a table. Useful for debugging.
split(string, sep, remove_empty): Splits string with sep as a separator, and returns a table of the new strings. If remove_empty is true, empty strings ("") won't be added to the table.
hook(target, name, func): Allows you to hook a function. target is the table that holds the function, name is the name of the function you're hooking, and func is the new function that you're replacing the old with, passing in the original function as the first argument. For example, if you want to hook Utils.hook (please don't), you would do something like:

Utils.hook(Utils, "hook", function(orig, target, name, hook)
  -- code here gets executed before the original

  -- since Utils.hook usually returns something, your code should also return something
  -- usually you'd want to return the results that the original function returns
  -- so you can keep the values the original returns as variables, then return them later
  -- Utils.hook only returns 1 value, so we only need to keep 1 variable
  local result = orig(target, name, hook)

  -- code here gets executed after the original

  -- return the result gotten earlier
  return result
end)

equal(a, b, deep): If a and b are tables, the function returns whether their contents are the same (and if deep is true, it checks this for all tables within the table as well). Otherwise, it simply returns whether a and b are equal.
hslToRgb(h, s, l): Returns 3 values between 0 and 1, converting HSL values between 0 and 1 to RGB.
rgbToHsl(r, g, b): Returns 3 values between 0 and 1, converting RGB values between 0 and 1 to HSL.
hexToRgb(hex, value): Returns a table of values between 0 and 1, converting a hex code ("#" required) to RGB. If value is provided, that will be passed in as the 4th value in the table; otherwise, the 4th value of the table will be 1.
rgbToHex(rgb): Returns a hex value string ("#" included), converting a table of RGB values to a hex code.
merge(tbl, other, deep): Merges 2 tables, returning a new one containing the values from both. If deep is true and it finds that both tables have a table value at the same index, it will merge those tables as well.
removeFromTable(tbl, value): Removes val from a numerically indexed table.
containsValue(tbl, value): Returns whether a numerically indexed table contains val.
round(value, to): Returns the value rounded to the nearest integer, or, if to is provided, to the nearest multiple of to.
clamp(value, min, max): Returns value if it is between min and max; otherwise, returns min if value is less than it, or max if value is greater than it.
sign(value): Returns -1, 0, or 1, based on the polarity of the value.
approach(value, target, amount): If value is less than target, returns value + amount, otherwise it returns value - amount. amount should always be a positive number. If value ± amount goes past target, it returns target instead. In simple terms, it moves value towards target by amount, not allowing it to exceed it.
lerp(a, b, t, oob): Returns a value between a and b, by 100*t%. For example, if t is 0.5, the function will return the value halfway between a and b. If a and b are both tables with the same number of values, return a new table with each value being lerped between a and b. If oob is not true, then t will be clamped between 0 and 1.
ease(a, b, t, mode): Returns a value between a and b, eased by 100*t%. The easing methods available are the same as are available for the Timer's tweening methods.
clampMap(value, min_a, max_a, min_b, max_b, mode): Gets the ratio value is at between min_a and max_a, and returns a new value with the same ratio between min_b and max_b. For example, Utils.clampMap(5, 0,10, 20,40) would give 30, since 5 is 50% between 0 and 10, so it returns the value 50% between 20 and 40. mode is an optional argument referring to an easing method; if not specified, the function assumes linear.
random(a, b, round): This function returns different values depending on the amount of arguments passed in:

  • If no arguments are provided, it returns a random decimal between 0 and 1.
  • If a is specified, it returns a random decimal between 0 and a.
  • If a and b are specified, it returns a random decimal between a and b.
  • If a, b, and round are specified, it returns a random decimal between a and b, rounded to the nearest multiple of round.

randomSign(): Returns either -1 or 1 randomly.
randomAxis(): Returns a table of 2 values, representing a random polarity. The table can be either {1,0}, {0,1}, {-1,0}, or {0,-1}.
filter(tbl, filter): Takes a table and a function(value) that should return a bool. Returns a new table, containing the values from tbl that filter(value) returns true for.
pick(tbl, filter): Returns a random value from tbl. If filter is provided, returns a random value from tbl filtered through filter.
pickMultiple(tbl, amount, filter): Returns multiple random values from tbl, not returning the same value more than once. If filter is provided, it filters the table before choosing.
angle(x1, y1, x2, y2): Return the angle, in radians, between the points specified.
angleDiff(a, b): Returns the difference between 2 angles, accounting for wrap-around. Will be a value between -pi and pi.
dist(x1, y1, x2, y2): Returns the distance between 2 points.
startsWith(value, prefix): If value and prefix are strings, it returns whether value starts with the string prefix, followed by the substring of value with that prefix removed. If value and prefix are numerically indexed tables, it returns whether the first values of value are equal to the values in prefix, followed by a copy of value with the values in prefix removed.

Global Variables

Outside of the Utils library, Kristal also has several global variables that can be used to help with code. These variables always exist, and can be read from anywhere. These variables are:

SCREEN_WIDTH, SCREEN_HEIGHT: Refers to the current window size.
DT: The time that has elapsed since the last game update. Usually approximately equal to the framerate.
DTMULT: DT multiplied by 30 (the default FPS of Deltarune). At 30fps, this value will be approximately equal to 1. When changing values over the course of time, the change should be multiplied by DTMULT so that it's consistent across different framerates.
COLORS: A table of default colors available. Each index contains a table of 4 values, referring to R, G, B, and alpha of a color. The available colors are aqua, black, blue, dkgray, fuchsia, gray, green, lime, ltgray, maroon, navy, olive, orange, purple, red, silver, teal, white, and yellow.
LAYERS: A table of constants that refer to the layer values of objects. The indexes relevant to battles, from bottom to top, are:

  • bottom: -1000
  • below_battlers: -200
  • battlers: -100
  • above_battlers, below_ui: 0
  • ui: 100
  • above_ui, below_arena: 200
  • arena: 300
  • above_arena, below_soul: 400
  • soul: 500
  • above_soul, below_bullets: 600
  • bullets: 700
  • above_bullets: 800
  • top: 1000

DEBUG_RENDER: A boolean toggled by a debug keybind that enables showing hitboxes of bullets, the player, and the arena. Can be used in code to render things for debug purposes.

Debugging

Kristal also has keybinds available to use for debugging and coding purposes. These include:
F6: Toggles DEBUG_RENDER.

Clone this wiki locally