ID:151879
 
So im remaking my quest system and decided that before I spend a lot of time on something I want to get some opinion on what would be the best method to use. I have several different ideas each with pros and cons:

1.Have Quest objects and add to players personal quest when they get a quest. Use procs for the object to manage the task and outputs.
Pros:Can be specialized per player and easy to modify when the quest is done. Keeping track of quest status is easy and neat. Easy to cycle through and display quest in log.
Cons:Using Lummox DMIFonts to display messages so have to create the icons to display message on new; causes some lag for mulitple messages. Creating an object for each player using for the same quest could get costly with lots of quest and lots of players could be lots of objects


2. Have a single global list with ALL quest added to it and display only the ones players have when looking at quest log.
Pros:Can create the quest(and Icons for messages) at world start to allow more efficient display of images. Not using lots of objects limit the objects to one per quest.
Cons:Have to manage players progress with other method (currently using associate list for quest to both show if they have it and what the status of the quest is). Have to cycle through long list of quest to find the one they are on and to call actions.


3. Change to a single quest at a time system to only need to worry about one at a time.
Pros:Dont need list to keep track and can assign one variable to the quest obj. Decreases to one quest obj per player. Could use datum instead of object cause wouldnt need click proc with only one.
Cons:Cant do more than one quest at a time



Those are the 3 systems that Im thinking of and are debating on. If you have any suggestions for other systems or ways around the cons I would like to here those as well. And for the con of using lots of objects I considered using datums for this, but you cant use Click() (as far as I have been told) with datums and I would like that to display the quest details when players want to see about a quest
So any thoughts
NightJumper88 wrote:
So im remaking my quest system and decided that before I spend a lot of time on something I want to get some opinion on what would be the best method to use. I have several different ideas each with pros and cons:

Using my XML method is a good idea </plug> Nah I kid... kind of...

1.Have Quest objects and add to players personal quest when they get a quest. Use procs for the object to manage the task and outputs.
Pros:Can be specialized per player and easy to modify when the quest is done. Keeping track of quest status is easy and neat. Easy to cycle through and display quest in log.
Cons:Using Lummox DMIFonts to display messages so have to create the icons to display message on new; causes some lag for mulitple messages. Creating an object for each player using for the same quest could get costly with lots of quest and lots of players could be lots of objects

What message are you displaying? New Quest Available? Something static like that? In that case, you can create it at start up and essentially keep it out of the way:
var/image/NewQuest = image(DMI Font Message)

New_Quest
NewQuest.loc = mob
mob << NewQuest
spawn(50)
if(mob&&mob.client)
mob.client.images -= NewQuest
Or something like that.


2. Have a single global list with ALL quest added to it and display only the ones players have when looking at quest log.
Pros:Can create the quest(and Icons for messages) at world start to allow more efficient display of images. Not using lots of objects limit the objects to one per quest.
Cons:Have to manage players progress with other method (currently using associate list for quest to both show if they have it and what the status of the quest is). Have to cycle through long list of quest to find the one they are on and to call actions.

Not much I can comment here.

3. Change to a single quest at a time system to only need to worry about one at a time.
Pros:Dont need list to keep track and can assign one variable to the quest obj. Decreases to one quest obj per player. Could use datum instead of object cause wouldnt need click proc with only one.
Cons:Cant do more than one quest at a time

I really do not like to be stuck with one quest at a time, especially if the quest requires me to kill some uber boss that needs me to level up a lot before I can face it.


Those are the 3 systems that Im thinking of and are debating on. If you have any suggestions for other systems or ways around the cons I would like to here those as well.

My XML quest system :P Though it is just a demo...

And for the con of using lots of objects I considered using datums for this, but you cant use Click() (as far as I have been told) with datums and I would like that to display the quest details when players want to see about a quest

You can always set a specific datum as parent_type=/obj if you want, so it has the properties of /obj. You can even have something like obj/HUD/See_Quest() and make it list quests available and such when Click()ed.
In response to GhostAnime
For messages it messages concerning the quest so like the quest data, what you need to do, next step for multi step quest, stuff for that. Its different for every quest.

As for setting a datum with a parent of obj, it makes it an object so it still counts towards your object count so the only benefit is that its easier to call in your code by only needing to type /Quest instead of /obj/Quest.

Ill have to take a look at your XML demo but im not familiar with it and i dont like using html in my code i think it kinda doesnt blend with the rest of byond (my personal opinion though)
NightJumper88 wrote:
So im remaking my quest system and decided that before I spend a lot of time on something I want to get some opinion on what would be the best method to use. I have several different ideas each with pros and cons:

1.Have Quest objects and add to players personal quest when they get a quest. Use procs for the object to manage the task and outputs.
Pros:Can be specialized per player and easy to modify when the quest is done. Keeping track of quest status is easy and neat. Easy to cycle through and display quest in log.
Cons:Using Lummox DMIFonts to display messages so have to create the icons to display message on new; causes some lag for mulitple messages. Creating an object for each player using for the same quest could get costly with lots of quest and lots of players could be lots of objects

Right now I'm currently working with this idea. The concept behind the objects was to make enough variables where the quests could be created at runtime, randomised, and given to players, as well has static quests as part of a "storyline." You don't have to do the messages on screen, either. I would personally use a browser to display all that text, as well as any other additional info on the related quest. Things such as items needed, how many left, rewards, etc etc. Also, if you just use a /quest, and you have no itention to show them to the player, just keep them in a log, you COULD use an entirely different datum.

This was what I did in my first attempt (though I butchered it entirely, and broke it a few days ago). It works quite well, because you can just make it with a browser interface, and it looks rather nice. I think my windows look something like:

<table><tr><td>
<link>accept</link></td>
<td>name (with tooltip containing the description; hover over it and get the description. it takes a lot less room!)</td>
<td>condition or item required (amount if applicable)</td>
<td>reward(s)</td></tr>
<tr>
next quest, blah blah..

please excuse the crappy html, and whatnot, I just wrote it in the browser now, as well as my babbling, I don't believe it made perfect sense :P
In response to NightJumper88
XML is not HTML, even if they do have similiar mark-up. Also, you would preferably store the XML in external files.
NightJumper88 wrote:
So im remaking my quest system and decided that before I spend a lot of time on something I want to get some opinion on what would be the best method to use. I have several different ideas each with pros and cons:

1.Have Quest objects and add to players personal quest when they get a quest. Use procs for the object to manage the task and outputs.
Pros:Can be specialized per player and easy to modify when the quest is done. Keeping track of quest status is easy and neat. Easy to cycle through and display quest in log.
Cons:Using Lummox DMIFonts to display messages so have to create the icons to display message on new; causes some lag for mulitple messages. Creating an object for each player using for the same quest could get costly with lots of quest and lots of players could be lots of objects


2. Have a single global list with ALL quest added to it and display only the ones players have when looking at quest log.
Pros:Can create the quest(and Icons for messages) at world start to allow more efficient display of images. Not using lots of objects limit the objects to one per quest.
Cons:Have to manage players progress with other method (currently using associate list for quest to both show if they have it and what the status of the quest is). Have to cycle through long list of quest to find the one they are on and to call actions.

Personally, I think you could combine the first two. You can have a global list of all the quest objects which contain all of the information about the quest that is the same from person to person. (e.g. what the task is, what the reward is, etc.) Give each quest an ID number.
Then give every player a list of a second type of object that corresponds with whatever quests they are currently working on, associated with the ID of that quest. The second type of object would contain all of the information that is specific to the quest.
Yes, you create two objects instead of one, but you don't have to deal with the Department of Redundancy Department for each quest.

I'm trying a similar system with NPCs.

Edit: (Since I generally fail at explanations)
Quest
var/ID
var/logPath = /QuestLog
//Define anything universal for quests here, such as who issues the quest or perhaps rewards
proc/meetsRequirements(Player/P) //can the player take the quest?
if(ID in P.completedQuests) return 0
return 1
proc/takeQuest(Player/P)
new logPath(P,ID)
proc/completeQuest(Player/P)
var/QuestLog/L = P.activeQuests(ID)
P.completedQuests += ID
P.activeQuests -= ID
Destroy_The_Death_Star
ID = "George Lucas"
logPath = /QuestLog/StarWars
meetsRequirements(Player/P)
if(!P.isJedi) return 0
return ..()
takeQuest(Player/P)
..()
P << "May the force be with you" //This is where you could do your text thing.
Destroy_The_One_Ring
ID = "J.R.R. Tolkein"
logPath = /QuestLog/LOTR
QuestLog
var/ID
//Define anything universal for quest logs here.
New(Player/P,_ID)
ID = _ID
P.activeQuests[ID] = src
LOTR
var/hasOneRing

Star_Wars
var/usingTheForce


Player //Or mob, but...
var/list/activeQuests = list()
var/list/completedQuests = list() //Put the IDs of completed quests in here.
In response to Chessmaster_19
That doesnt make much since it kinda takes the negatives of the first two and makes them worse. One your creating more objects than needed so instead of creating just one object or one per person your creating one for the world and one per person, waste of objects. Second if your gonna create one per person you can keep all the same info hard coded in like you would for the global one having a couple variables like text and numbers isnt gonna cause any problems, all thats doing is creating unnecessary calls to other objects when you could do it all in itself. Also your creating extra list which arent needed.
Greetings NightJumper88.

I also am working on a quest system, though I have already chosen the path, but before I get into working on it I will somehow link my NPC system with the Quest system itself for ease of use and implementation. I need them to link well and not cause abuse to my computer (Heh, I MADE JOKE!).

My path is simple, it is to create my own datums, it's as simple as that. I can add variables as I go along, I can create special procedures which return the users quests, the users quest stats e.g.

"Have 5/10 tomatoes"

and I can also make a variable which links to the NPC who has given the quest, easy? Sure is...

Thanks Much.
Haywire
In response to Haywire
actually I had a system that uses datums and if i didnt need to be able to click on them I would use them, if i am able to find a way to work around not being able to click a datum then i will end up using that but as of now i need to be able to click on it for my interface and display system.

But on a non negative note that is the preferred way because the datum limit is a lot higher and yeah dont have all the useless procs that you dont need. but you can do all the same customization and procs and everything with objects as well.

In response to NightJumper88
I disagree. Yes, it's two objects, but collectively they are smaller than simply having one quest object per person. If you simply had one quest object per person, you would need to have ALL the data for the quest within that object, and every person would have a copy of that data. By "factoring out" the stuff that is constant for a quest, you're saving space. Yes, it's one for the world and one per person, but the one per person is much smaller than it would be.

It's really not a question of two objects or one object. It's one global quest object, and many small player objects, instead of having many big player objects (as in option 1) or one hard to deal with global object (in option 2)

Anyways, it's just my opinion. I like the system, but if it's not for you, that's up to you.
In response to Chessmaster_19
I think your missing the point of the problem with having two objects, its not the size of the data its the amount of objects, byond is currently limited to 64K objects in the entire game (i think its that right now it might still be 32K).

So what im actually worried about here is having too many objects floating around, say you have 20 quest per person and 100 people on. thats 2000 objects and each person has say 20 things in there inventory thats another 2000, plus items NPCs have, projectiles and attacks, objects on the map,screen objects, etc with a bigger game you could easily reach the 64K without even noticing. Now my game is no where near reaching that and most shouldnt be (especially if they are programmed right). But its things like that that make it possible to reach the limit.

As for the data size of the objects (i could be wrong on the next part but I believe this is how it works). When an object is created in game its a reference to a base type of object that you coded, now it has its own data like variables and what not, but if things arent different it just calls the reference data in the code. So all the procs and verbs associated with that object is just called throught the code and is not made with each object. So all the quest data wouldnt be much data at all. Especially cause most of it would be text strings which are real small in data.

I really think using two objects to represent one quest is a bad idea its useless overhead of talking between the two and calling eachother through references, youre gonna lose more in efficiency because you have to call things through references back and forth than you would with the little bit of extra data you would get with having more objects (which i think would be very very very little like a few bytes at most).
In response to NightJumper88
He's actually using /datums, which has a limit that far exceeds things deprived from /atoms.
In response to Mega fart cannon
Then I refer to my post to responding to Haywire, I know datums would be a prefered method here because the limit is much higher and they have less overhead do to not having useless included procs (useless for that case not completely useless dont understand that).

However I still think even using datums(notice im using the word datum when refering to a datum easier to understand) that it creates a useless datum cause all that info could easily and more efficiently be stored in a single datum. Theres no benefit to having the it seperated in two like that. Any size you might save (and I seriously think it would be minor if any) would be negated for the extra commands you would have to call and calling back and forth between the two.
In response to NightJumper88
(I'll try to refer to datums as datums not objects, I've been coding in Java in school, so I've been getting my terminology switched around...)
It's really not even that many items more compared to your first option. Lets say you've got... 100 players on and 20 quests in your game. (I believe those are the numbers you gave) Well, we've got the 20 global quest datums plus one quest datum for every ACTIVE* quest that the player has. Now, granted, some players might try to take on all the quests at once, but that's probably far from the norm, and if that's really a problem, you could put in a limit (like 5 quests at a time). So, I'll average it at 5 quests per person * 100 people = 500 quests + the 20 global quests = 520 datums. Really, 520 is not that bad, especially with the same numbers, your option A would amount to 500 larger quest objects. So, comparing the two options, I would say I would gladly sacrifice 20 out of 64k+ datums for the sake of cutting down savefiles and object sizes.

I'm not sure what all those commands for calling back and forth are that you're worried about. You can access one from the other with one line of code, (Either globalQuestList[ID] or Player.activeQuests[ID]) and even if you spend several lines or a method being careful about it (verifying whether or not the quest is the right type, or it exists, etc.), a few lines of code like that are fairly insignificant in the long run. We're talking nanoseconds, and it's not even a commonly called function. (Not compared to something like Stat(), where you really need to conserve code)

Anyways, I'm not trying to be pushy about this, simply defending my idea. (And I enjoy a good debate)

*Only active quests really need datums, I simply recorded the ID of completed quests so that you can't retake the same quest again. (Unless of course you want to allow them to)
In response to Chessmaster_19
Generally a nice comparison. Just to tack something on, the datum limit is 2^31, unlike other DM elements. You get an upper limit of 2,147,483,648 datums.
In response to Stephen001
And I doubt anyone will make over two billion datums (it would be pretty funny if someone left their computer running long enough to do this, though!).
In response to Chessmaster_19
Also im not trying to be pushy and i too like a good debate it allows for the best idea to come through.

Im not worried about hitting the limit for datums they are way high like the guy below your post said like 2 million or something like that. So its really not a problem. I think datums would be the preferred method, but like I said I needed them to be objects so I can click them for viewing purposes.

As for my example i was talking of each player having 20 active quest, my game already has around 50 quest in it and its getting bigger as i code in more and more. The game revolves around quest, I do see how doing two quest could be useful but for the amount of data thats needed its just more work than its worth.

Lets take a look at the average quest and what data is needed. so a quest to say kill 5 guys easy enough:
1.text string describing quest
2.variable to keep track of kills
3.variable to say howmany kills needed(or could be hard coded but if your doing it with system usually youll have this)
3.proc to update when mob is killed
4. proc to complete quest
5. another text string or two for in progress text and finish text

thats it. For size that is very small and not worth splitting up for the 3 text strings cause the rest are gonna be different.

But really this is a matter of opinion and getting away from my original question. But i do enjoy the discussion
In response to Stephen001
Stephen001 wrote:
Generally a nice comparison. Just to tack something on, the datum limit is 2^31, unlike other DM elements. You get an upper limit of 2,147,483,648 datums.

Small question on this: can you only make 2 billion datums? Or do they all have to be present in the world to reach the limit?
In response to Stephen001
Stephen001 wrote:
Generally a nice comparison. Just to tack something on, the datum limit is 2^31, unlike other DM elements. You get an upper limit of 2,147,483,648 datums.

Actually to clarify, the limit is currently 2^24, for about 16.7 million datums. While the ID portion of the reference is indeed four bytes, the \ref macro always creates a 4-byte value with the MSB reserved for the datatype, so to allow for that I kept the limit at 24 bits instead of 32. Turfs also have a 24-bit limit.

Lummox JR
Page: 1 2