Important
Most of the time, you'll want to follow this page:
https://kristal.cc/wiki/downloading
It has instructions to download and set up the source code, rather than using the builds here.
An even bigger update to Kristal, which took even longer than the last one, somehow. Either way, it's packed with some pretty good things!
Thanks to all our contributors for continuing to maintain the project.
Changelog
Climbing
- Climbing has been implemented
- Relevant objects are
ClimbArea,ClimbEntry,ClimbExit,ClimbLanding,ClimbUnsafe, andFallingClimbArea ClimbMoverhas been added as well, which moves the player to a location when overlapped- The system uses markers in many places, which can now be Tiled object references
- World bullets now hurt the player if they're in the climbing state
ClimbEnemyhas been added, which areWorldBullets which can be killed when jumped into
Reduced Tension
- In your encounter, set
reduced_tensiontotruein init (or overrideEncounter:hasReducedTension()) - For enemies, override
EnemyBattler:getGrazeTension()and always return0(since reduced tension fights do not give TP from grazing) - For any custom bullets with custom TP set, either remove it or set it to
0(same reason as above) - When you spawn bullets (from a wave, or in a bullet's
init), setgrazedtotrue(because reduced tension fights do not give the "graze tick") - The TensionBar can now flash with
TensionBar:flash()(thanks, @yeetussnoopy!)
Swooning
- You can now disable auto healing through
Encounter:isAutoHealingEnabled() Encounter:canSwoon(target)now exists (so you can filter out Kris, or have other conditions)Bullet:shouldSwoon(damage, target, soul)now exists (should just returntrue)- Party members now have
battler/swoonedanimations, set it tobattler/defeatif you dont have a unique sprite EnemyBattler:getHealthDisplay()now exists, feel free to return "???" if you're imitating the Knight- Party health in the battle UI now has a lower limit
Chapters 3 and 4
- Items have been implemented (@SylviBlossom, #376, @NellMonell, #443, #495, @FireRainV, #572, #588, @Agent517, #623)
- Rude Buster has been updated (@HmmNoPls, #416)
- TIRED/Pacify changes, Tired and Awake messages (@MrOinky, #367, #377, #457, @FireRainV, #413, @AcousticJamm-dev, #434)
- Health conversion between the light world and the dark world now works properly in chapters 3 and 4
- Light world save point + menu behavior (@Agent517, #363)
- Light world save points no longer heal by default
- Chapter 3's invulnerability frames have been dropped from 40 to 30
- New projects default to chapter 4
- New portraits have been added (@NellMonell, #589)
- Additive mercy (Organikk, Shadowguy) has been added (@HmmNoPls, #387, #389)
- Action buttons in battles can now be disabled
- Attack effect overrides for weapons (@Agent517, #365)
- A "thin" option for the Dark Fountain has been added (@Agent517, #404)
- Customizing the mercy display has been added (@FireRainV, #426)
- Attack and magic level up caps have been added (@FireRainV, #569)
- FiberScarf was updated for chapter 3 (@NellMonell, #485)
- Default equipment is now based off of Chapter (@NellMonell, #473)
- The amount of storage slots is no longer hardcoded (@FireRainV, #469)
- Kris's menu dog is now in the second slot in chapter 4 (@FireRainV, #631)
- Check description (@NellMonell, #482)
- Shops can now decide whether they hide the world or not (@DIAMONDDELTAHEDRON, #491)
- Power Act accuracy has been improved (@NellMonell, #530)
- The shop UI was updated (@DIAMONDDELTAHEDRON, #550)
- DarkEquipMenu and DarkPowerMenu have both been updated to be accurate once again after DELTARUNE's full release changed them (including a special-case in Chapter 1, still)
- Config files and basic changes (@MrOinky, #366)
Battle background changes
BattleBackgroundhas been added, which is an object which draws the battle's backgroundBattleDarkenerhas been added, which is an object which darkens the battle's background, and also is responsible for darkening party battlers- To spawn a custom background, override
Encounter:createBackground()and return an instance ofBattleBackground. You must add it to the battle yourself, so the code would look something likereturn Game.battle:addChild(MyCustomBattleBackground()) - The same exists for
Encounter:createBattleDarkener(), but it is unlikely this needs to be overridden Encounter:drawBackground(fade)has been removed
Tiled changes
- Any "list properties" (ex.
text1,text2) in Tiled now support actual Tiled lists (@Hyperboid, #513) - The "class" field in Tiled layers now work properly
- Transitions can now take Tiled object references if the marker is in the same room
- Markers can now have a
player_stateproperty. When the player spawns at one, their state will be set to the value of that property. This can be used to have rooms which you enter while climbing or sliding. - A new "event registry" has been added, allowing developers to easily register events
-
- Rather than being automatically registered from the
eventsfolder (which is no longer preferred), events and objects should be registered throughGame:registerEvent(id, constructor).
- Rather than being automatically registered from the
-
Game:registerEvent("tensionbar", function(data) return TensionBar(data.x, data.y) end)is an example registering a Tiled event. Placing thetensionbarevent in Tiled will spawn theTensionBarobject when the map is loaded.
-
- This gives developers finer control over how their objects are instantiated by the event system, allowing any object to be created and not just those in the
eventsfolder, and allows better organization.
- This gives developers finer control over how their objects are instantiated by the event system, allowing any object to be created and not just those in the
-
- With this system, events should be put in the
objectsfolder like any other object. Events which remain in theeventsfolder will continue to be automatically registered (to not break older projects), but this is not preferred.
- With this system, events should be put in the
- The "Events" table in projects, if that was ever used, has now been removed. It was undocumented, and a very poor way to interact with the event system.
- Group layers now have a "thin" property which sticks them together for depth purposes (@Hyperboid, #359)
- The silhouette event now has a custom color property (@HUECYCLES, #583)
- Layer parallax now affects objects (@HmmNoPls, #483, #488, #489)
- Tiled polygon shapes can now be used as Event collision (@MrOinky, #343, @Hyperboid, #353)
- Flipped + rotated tiles now appear correctly (@Hyperboid, #620)
- Some errors for Tiled path resolution have been improved
Utils split
- The Utils module has been split into smaller modules, and Utils has been mostly transformed into deprecated functions, to be removed in the future. For things which still exist in Utils without being moved, you can expect them to be moved eventually. (@NyakoFox, #403)
Utils.numberFromKey(t, name)has been removed.Utils.keyFromNumber(t, number)has been removedUtils.hexToRgb(hex, value)now supports hex codes which aren't just #RRGGBB, so value can now be a multiplier if you enter hex with alpha, for example #00FF00AAUtils.lerp's table support (now handled by TableUtils.lerp) is more strict and will error if table sizes are mismatched
Dev mode
mod.jsonnow contains adevkey, controlling "Dev mode". If not present, it's assumed to betrue- In "dev mode", you have full access to the Kristal debug system
- When disabled, you can no longer use the debug system in Kristal
- WHen disabled, the hotkey
CTRL+ALT+SHIFT+Mcan forcibly enable it for the session, to help with debugging issues in released projects - Kristal itself now has a
RELEASE_MODEoption invendcust, which controls whether these options are allowed in the engine itself, intended for standalone project releases, and "stable releases" of Kristal
Debug changes
- Battles now show debug hotkeys in the top-left if debug rendering is enabled
CTRL+Know gives max tension instead of twice that, as that was only intended for testing SnowGrave early on- Hotkey for gaining tension in the overworld (@FireRainV, #310, #505)
CTRL+Ris now disabled under certain conditions (to prevent some crashes)- Text input has been improved slightly as well
- The debug system had a ton of improvements and should work smoother
- A debug option for "give spell" has been added (@NyakoFox, @MrOinky, #487)
- The wave selector can now select multiple waves at once (@MrOinky, #486)
- A debug option for "give money" has been added (@HUECYCLES, #481)
Accuracy changes
- Text shake is finally framerate-independent
- Text shake offset no longer persists after a shake is reset
- Fixed downing a defending party member taking away TP
- Sprite animation speeds have been fixed
- Walking animations have been made more accurate
battle/transition_outhas been added for actors- The "plain" font's accuracy has been improved
- Menu boxes are no longer "broken" like earlier releases of DELTARUNE and now look like their modern fixed versions
- The "name" font has had some color consistency corrected
- Text is now disconnected from BattleUI itself, so it does not move when BattleUI does
- The UIBox animation is now accurate to DELTARUNE
- Shaking logic has been fixed at higher framerates
- Mercy messages are now more consistent with DELTARUNE. By default, mercy messages will always appear, and the previous behavior can be attained through manual checks (@NellMonell, #555)
- The cell phone is now accurate for chapter 1 (@SweetSylveon, #625)
Miscellaneous changes
-
Sounds now have
jsonmetadata files, which allows developers to control the default volume of sounds -
- Default volumes for a bunch of built-in sounds have been added, matching the volumes of the sounds in DELTARUNE
-
Playing sounds at a volume greater than
1will no longer play multiple instances of the sound at once, but instead the sample data gets amplified through code -
Window scale is now automatically calculated by default, like DELTARUNE. It can be disabled, and you can still choose your own window scale
-
"Forced fullscreen" mode has been added, forcibly enabling borders, forcing fullscreen, and changing the in-game DarkConfigMenu to be accurate to DELTARUNE's console releases
-
getEncounterTextcan now return a portrait and an actor, allowing characters to talk in the battle UI -
DarkMenu:addButtonnow returns the button index for the newly added button -
TileLayers are now drawn through SpriteBatches rather than onto a canvas, improving performance (@Hyperboid, #612, #619)
-
dark/lightTextboxStyleconfigs have been added, andgetUISkinnow takes proper priority -
World:hurtPartynow checks follower alpha to know whether or not they're visible before spawning a damage number -
TARGET_MODcan now show the file select menu even if no saves are present (@mario64thane, #385) -
Shaders are always now validated as GLES, which is supported on all platforms (@Hyperboid, #543)
-
Character:jumpTo'sjump_spritenow works even if theland_spriteis not defined -
Sprite:setFramenow allows float values, which get floored -
Loading into a light world map now properly sets the border to the light border.
-
Many internal refactors to split up large functions, making it easier to hook them
-
Most user-facing instances of "mod" have been replaced. The term "project" is now preferred
-
Battle:endWaves()andWave:setFinished()have both been added for easier wave control -
OverworldSoulno longer has its own reference toworld -
Character/Actorsprite:getFacing()has been added, andfacinghas been made private -
The metatable tweaks from the previous release have been reverted
-
LegendCutscene now has functions for controlling the "cover" sprite
-
The TensionBar can now be rotated properly (no longer uses scissoring)
-
Player movement speed has been reworked internally
-
The fader color no longer resets to black once the fader is idle
-
"Bare-bones" encounters, generated by a ChaserEnemy without a defined encounter, have been removed, and replaced with an error. These "generated" encounters haven't worked for a while, and you should really be making encounters by yourself.
-
In the main menu error screen (when projects fail to load), you can now continue (as the code for that was missing completely)
-
love.graphics.resetnow works properly. This might reveal some bugs in your own draw code, so make sure to fix those by properly setting fonts, colors and other draw settings, before using them -
- The "rough" line style is used by default
-
Not being in a map, shop or encounter no longer kicks you back to the menu
-
StringUtils.containsnow takes a plaintext filter rather than a pattern -
The DarkTransition now has a
sparkles_characteroption (@HUECYCLES, #324) -
HookSystem.hookScript()is a new, now-preferred way to hook classes (@Hyperboid, #352, #370, #371, #375, #382) -
super:syntax has been removed. Please replace all instances ofsuper:withsuper.in your codebase. (@Hyperboid, #338) -
Input.vibrate()(@Hyperboid, #288) -
AUTO_MOD_STARTinvendcust(@Hyperboid, #295) -
CTRL+ALT+SHIFT+Remergency restart bind in the error handler (@MrOinky, #344) -
Configurable spell cast and select animations (@CosmicPikachu001, #378)
-
Bullet:onGraze(first)callback (@AcousticJamm-dev, #386) -
Kris now has their unused light world slide sprite (@TFLTV, #322)
-
Anywhere which takes text input can now be set to overtype instead of insert mode (@Dobby233Liu, #196)
-
XACTENEMYSELECT has been removed, merged with ENEMYSELECT (@FireRainV, #234, #428)
-
Shops can define their background speed (@FireRainV, #306)
-
Party members can now attack without a weapon (@FireRainV, #417)
-
Shift+F9will now open the screenshots folder (@FireRainV, #300) -
DamageNumber and RecruitMessage now persist into the overworld (@Hyperboid, #494, #496)
-
Bullets now have a
Bullet:getInvulnTime()getter (@Hyperboid, #518) -
Spells and items now have a
:getTarget()getter (@NellMonell, #519) -
onTextColoris now an engine event which gets called when thecolormodifier is used. This allows custom registration of colors -
The
cleanupengine event has been added (@FireRainV, #547) -
The
onGameOverengine event has been added (@FireRainV, #561) -
Item:onWorldDamageandItem:onBattleDamagenow exist (@Simbel0, #605) -
World:checkCollisions()now exists, returning a list of collisions (@FireRainV, #606) -
Sprite:crossFadeTonow has an options table, and the"blocky"fade mode was added (@HUECYCLES, #582) -
Character:alert()now has an optional custom sound (@HUECYCLES, #628) -
Filenamer name conditions are now case insensitive by default, and can be toggled to be case sensitive (@MrOinky, #520)
-
The documentation and website system was heavily improved by @skarph (#393), and further improved by @NyakoFox
-
A bunch of miscellaneous additions, fixes and changes from PRs:
-
- @FireRainV: #104, #301, #311, #314, #329, #331, #337, #414, #418, #447, #445, #452, #453, #459, #465, #468, #470, #502, #508, #534, #536, #537, #538, #539, #542, #544, #545, #548, #546, #549, #552, #557, #563, #565, #566, #567, #578, #579, #593, #594, #596, #601, #607, #608, #613, #617, #618, #621, #629, #632, #635
-
- @minwacali: #551, #570, #581, #590
-
- @SweetSylveon: #584, #585, #586, #633
Full Commit History: v0.9.0...v0.10.0
Instructions
Important
Most of the time, you'll want to follow this page:
https://kristal.cc/wiki/downloading
It has instructions to download and set up the source code, rather than using the builds here.
Windows: Download and extract kristal-x.x.x-win.zip, and run kristal.exe to play
Others: Download and extract kristal-x.x.x-love.zip, and run kristal.love with LÖVE to play
Check out the documentation for how to use this engine, and download example-project.zip for project structure, as well as overworld and battle examples.