Quality Conditionals
Thought we'd change it up! And actually talk some ACTUAL gamedev.
WTF IS GOING ON!? WHAT SORT OF TWILIGHT ZONE NIGHTMARE IS THIS WHERE ILLTEMPEREDTUNA IS ACTUALLY TALKING GAMEDEV AND NOT CRYING INTO A PILLOW!?
So this is kinda common knowledge, but one thing I've been meaning to clean up for a while is conditionals and they are SO DAMNED IMPORTANT to get right. They actually make up more of the sanity of your project than most people realize. You want conditionals like the ones below so you can check that things happen or shouldn’t happen, like walljumps, or triggering dialogue, or… LITERALLY ANYTHING IN A DAMN VIDEO GAME HOLY SHIT THIS IS FUCKIGN IMPORTANT.
Naming conventions (USE LONG NAMES WHERE NEEDED), where you put them in your code, tidying them up with regions #region Conditionals, exposing them in the inspector when debugging.
Here are some Examples:
isTouchingGround
isTouchingWall
HasMenuOpenButHasntTeleportedRecentlyAndAvoidsThatWeirdFadeBug //you won’t have to comment this everywhere you put it, it will just be inherent to the name
isHoldingStill
You get the idea…
So let's say you want your player to be able to charge up a certain attack, but only when they're still, so you create this logic:
if(isHoldingStill) CheckForButtonHeldForCharge();
It works! But days later, OH NO!..
You just accidently found out that when engaging with NPC's you can accidentally trigger the charge and it puts the player in a broken charge state as they release the button and your combat logic isn't set up to handle dialogue states.
Well let's look over our conditionals...
public bool isTalking => dialogueOpen == true;
public bool notTalking => !isTalking; //Sometimes it helps to have simple and straightforward logic for the reverse case!
There we go, we can use the notTalking conditional!
But then you remember you created another thing that catches even more edge cases...
public bool isBusy => isTalking || isPaused || isLoading; //there oculd be all sorts of conditionals you could consider for this
Bool notBusy => !isBusy;
So rather than having all these mad and bizarre lines of logics like
if(moveSpeed< .1f && !paused && !isTalking && combatReady) CheckForButtonHeldForCharge();
we can have much cleaner conditionals like this:
if(notBusy and isHoldingStill) CheckForButtonHeldForCharge();
And here's the best part! If you ever encounter a weird bug regarding these systems, it becomes VERY easy to check which one of these conditionals is the problem. Simply remove them one by one in the problem if check, then you can deep dive the logic in each isolated conditional till you find the culprit.
If at any point you think you have a better logical solution, you can update the logic, and it will propagate throughout your project rather than having some unique cancerous mass of error prone logic for each and every check you perform in your project.
For example:
bool isStill => xAxisInput == 0f && yAxisInput == 0f;
You might find that even when the player releases input buttons, they STILL can be moving at times because they're sliding down a hill or due to inertia so you get false positives. So if we change the logic to be
bool isStill => rigidBody.velocityMagnitude < .1f; //leaving a touch of wiggle room
Now the logic where we check stillness will be updated and working across the entire project. If we have edge cases in the future, we can rest assured the fixes will propagate to other problem areas.
I like to keep most my conditionals grouped together so it's easy to tuck them away and keep the project tidy, and oftentimes when I'm looking to make a new conditional, it's good to see what already exists to see if there's any smarter ways of consolidating them, or if there are redundancies. Ideally, they are set up so that they can easily be mixed and matched to make even more powerful and handy global conditionals we can use in many logic situations, for example:
bool resting => outOfCombat && isStill;
Just to give you some ideas for more of these!
So many of the things we do in gamedev spin out of trying to understand all the discreet math (I JUST LEARNED THIS TERM LAST WEEK ON THE SHITHOLE OF TWITTER), and too often we force ourselves to look at these horribly confusing mish mash of sybols, and quantities, and checks, when at the end of the day we just want to scream.
"DAMN IT WHY WON'T THIS THING ONLY HAPPEN WHEN THE PLAYER IS OUT OF COMBAT AND NOT MOVING AROUND!
Well now it's easy!
bool outOfCombat => timeSinceBeingHit > 2 && timeSinceAttacking < 1;
if(outOfCombat && isStill) DoThing():
Here’s a random bit of conditionals code from my project for the heck of it, there are times you want to use getters and setters or whatever they’re called, you can even run function calls when you run the conditionals at these times
I could blather for days about this crap and best practices, but at some point I would like to get a little work done today. Not feeling great but good enough to get a little done today.
Get SeaCrit
SeaCrit
Deceptively Deep!
Status | In development |
Author | illtemperedtuna |
Genre | Action, Role Playing, Shooter |
Tags | Beat 'em up, Casual, Indie, Roguelike, Roguelite, Side Scroller, Singleplayer |
More posts
- About Time We Lay Low and Let the Heat Die Down8 days ago
- Take a Breather9 days ago
- It's Over... It's Over.10 days ago
- POTATO11 days ago
- Writer's Block13 days ago
- SOON13 days ago
Leave a comment
Log in with itch.io to leave a comment.