Mission Accomplished... and some tips on Godot Engine
Updated: Oct 27, 2021
Ladies and gentlemen, we did it. The last major update to TriHard is finally here. The game finally plays as designed/intended. But lets go through some details. If you use Godot Engine, this might be of particular interest.
Fixed issue of tricks occasionally becoming embedded in one another during rotation. This was achieved by changing the position and angular tween nodes 'process_mode' from 'idle' to 'physics'. Also solved other issues by utilizing "_physics_process" instead of "_process" on my kinematic2d nodes. I failed to even think about it throughout the entirety of development... I had copied and pasted a state machine from a node that doesn't incorporate physics instead of writing a new one from scratch. Since the kinematic node's state machine function calls influence node physics, as well as the tweens, this was causing issues as some movements were being performed during the idle frame. This resulted in physics engine to jitter the node and/or fail to detect collisions, allowing objects to become embedded in one another.
Fixed rainbow block breaking. This logic was/is fucked, honestly. It kind of worked as designed in previous versions, but not quite. Setting tricks adjacent to a rainbow trick isn't SUPPOSED to trigger a break check for the rainbow trick, unlike everything else. This is because a Rainbow block acts as a wild card while checking for breaks. Without proper logic, this can result in a single rainbow block taking out all blocks touching it. I had coded to ensure that doesn't happen, but to get the damned game to treat this thing right under all the conditions was ... fun.
Further improved performance. If you're a dev using Godot and are having performance issues, enabling 'Force Vertex Shading" in project settings -> rendering -> quality should help. Depending on your visuals and lighting effects you may or may not notice any visual differences (I didn't in TriHard) while reaping a solid performance boost. Other things to look for- ensure any node that your use to move a physics object (such as animation players and tweens) have their process_mode set to 'physics' instead of 'idle.' On a similar vein, if you have methods and functions being called that have nothing to do with physics in '_physics_process(delta)', see if you can't move them to another node under a '_process' call. Sounds like nuance, but misplacing physics and idle processes can have a huge impact on performance.
Gameplay adjustments. I adjusted the formula for hit point loss. In this game, you lose health whenever a trick breaks. It was way out of balance, causing a huge difficulty spike as early as levels 3-4. Not intentional. This has become more rounded to allow for mistakes early in play without such a huge and sudden spike in difficulty. The new hit point loss is calculated as followed:
var loss_amt = (1 + Global.ref.ctrl_reg.phase_breaks + vals.level + vals.bleed) * Global.ref.ctrl_reg.phase_breaks
hit point loss = (1 + number of break phases triggered during current turn + current level + bleed value) * number of break phases triggered during current turn
Bleed value is a hidden value that increases by 0.2 anytime a trick is broken. This value is persistent throughout the game, but can be reduced back down to 0 by 'sealing' tricks (When a trick has all three sides connected to other sides, it converts into a white 'sealed' trick that cant be broken). Anytime a trick is sealed this value is reduced by 1, to a minimum of 0.
Thats all I wanted to discuss. Thanks for coming to my Ted Talk.