Previously On IT Ninja . . .
Last time I got to work implementing an in-game timekeeping system. This will allow me to hook events, quests, and other things on that system. This has got me back to thinking about the way quests work in the world. So now it’s time to go back and improve the questing system and add functionality that I had planned from the beginning.
And Now On IT Ninja . . .
How Questing Works
Let’s take a look at the current logic behind questing. We have an object that is a “Quest Giver” with the appropriate script attached. The object has a collider and a text indicator. If the player doesn’t have the quest, the collider will activate the text indicator when the player enters and then hide it when they leave. If they’re in the collider and press the use key it opens the quest dialog.
How Questing Should Work
A few things need to change. First, I have to get the quest prerequisite function added and working. I also want to add a visual indicator that a quest is available. And finally, I need to change the text indicator to a button to allow clicking with the mouse. Oh, and the definition of a quest needs to change. Right now, the “type” of quest is a string, but I want to allow only certain things, so I need to change that to an enumeration.
Digging in to Enumerations
And, of course, I start with the new concept I am unfamiliar with. It seemed easy, at first. But now that I’m actually working on implementing it I’m having trouble. Pretty simple fix in the end, but I just didn’t understand how enumerations work. I actually had to add a new variable to hold an instance of the enumeration and use that for comparison. Whatever, it seems to work, I hope.
Next step is to add a visual indicator to the world so the player knows there is a quest available to them. Currently, the script checks the player to see if the quest is assigned to the player already. That’s not good enough, I need to have a few different things I can see. Is the quest assigned, is the quest complete, and is the quest available? I’ll add those to the quest tracker script for ease of use.
I took my existing quest check script and moved it. Took a bit of modification to get it working right that way. But now I have a simple function I can call from anywhere to see if my player has the specific quest assigned. I then took that and copied it three more times. Changed up those functions, one to see if the quest’s prerequisites are met, one to see if the quest is complete, and the third to check if the quest is even assignable. I feel like I need to go into a bit of detail about these checks, so here we go. . .
QuestAssigned returns a boolean value when fed a quest object. It goes through all the quests assigned to the player and matches up the quest ID. If the player’s list of assigned quests contains one with a matching ID it will return true, else it returns false.
QuestComplete is nearly identical to the QuestAssigned function. The main difference is the value it returns is based on the value of the QuestComplete on the quest in the player’s log. I’m not explaining it very well, let me try again. If the player doesn’t have the quest, it returns false, otherwise it returns the value of the QuestComplete variable on the quest in the player’s log.
QuestPreReqsMet is somewhat complicated. It starts off the same as the others, iterating through the list of quests in the player’s log until it finds the quest. Wait, shit, it’s all wrong! I originally had it based off the other two, but that made no sense. So now it returns true if there are no prerequisites. Otherwise it checks each of the prereqs to see if they’re complete. If any of them aren’t complete it stops checking and returns false, otherwise it returns true.
QuestAvailable relies on QuestAssigned and QuestPreReqsMet. It’s a pretty simple function. . . If the quest isn’t assigned and the quests prerequisites are met it will return true, otherwise it returns false.
So now I have these checks I can use to improve my quest givers. First I need to create a new variable to hold a sprite we’ll use to indicate if a quest is available. I think I actually need to create a whole new prefab for quests. The main problem is I’m using all kinds of canvases and stuff and those mess with me. Once I get a good one made as a prefab it should be okay though.
So, the prefab, I need a GameObject with a collider, and two children, one a sprite (quest indicator) and one a button. Should be easy enough, right? BAH! Actually it wasn’t too bad. I took the settings from the original quest giver and just copied them to a new object. Did some modifications and a lot of little tweaks until I had what I liked.
Now I have an object I can drag into the world and it has quests to give! If there’s a quest available you see a little icon. When you get close, you can interact with it to get a quest. If the quest is a “Go to” variety you can complete it. This is what I needed to go further into my game design. I’ve got checks in place to prevent issues with duplicate quests or being able to get a quest you shouldn’t.
Next Time On IT Ninja . . .
There we go, improved quest experience! See, I told you, start simple, make something that works. Then later come back and improve it. That’s what I did, I created a barely functional quest system then later came back and added functionality and improved it greatly! So now that we have better quests we should really start filling out the game world a bit.