ive decided on another long term goal which is to implement a full questing system in my server. i think my first step is to find inspiration/references. on the plugin side, i like the amount of control that betonquests gives you, but i also think the configuration system is a bit unintuitive and leads to a lot of code (config) repetition. on the script side, i havent really seen large-scale quest systems in denizen before, so does anyone have/know of existing questing systems implemented with denizen?
#(0TickPingo) questing system
122 messages · Page 1 of 1 (latest)
(0TickPingo) questing system
Hi I'm AutoThreadBot! Don't mind me, I'll just be adding the helper team to this thread so they can see it. A human will get to you soon.
Changed to Discussion
Thread is now a Discussion thread. This indicates that the thread is not requesting help in any way, and is just discussing a broad topic openly. If you need help with something, use </helpthread:1028674284870180883> to switch the thread back to a normal help thread.
I wrote a questing system a while back (which could be a lot more optimized now that i backread the code lol), it really depends on how you want it to work.
I made a config data script with entities and blocks as key names, and the rewards for each level as the values, then when the player breaks a block or kills an entity, I just checked if the block/entity is in the data script as well as the players quest progress and reward them.
interesting
im thinking of an objective system like Quests
objectives:
Talk to NPC A:
type: interact
npc: X
...
Some complex thing:
type: custom
# use world and task scripts like update_objective or complete_objective or smth
i think the first thing i need to figure out is how data is stored and what format it is stored in
maybe like a player flag with
tickquests.quests:
questA:
currentObjective:
name: Talk to NPC A
progress: 3
and then for more complex stuff i could do something like a "compound objective"
objectives:
Talk to any NPC:
type: compound
objectives:
Talk to NPC A: ...
Talk to NPC B: ...
succeed: Talk to NPC A || Talk to NPC B
i think your system is more of a bestiary system or smth
regarding where these quest configs will be actually stored
perhaps data scripts with a tag on them
my_quest:
type: data
tickquest: true # <-- the tag
conditions:
- <player.is_flying>
objectives:
...
on_start: ...
on_finish: ...
i'll probably make some procs for convenience as well, like get_progress has_completed_(quest|objective) has_started_(quest|objective)
this also means i'll have to implement a dialogue system
which i'll also need help with because ive never done that before, so i'll need to look for existing dialogue scripts
regarding dialogue though, i think something like betonquest's is good, but it floods the chat too much, perhaps have some integration with clientizen
another issue with BQ is a lot of code repetition as mentioned in the first message, so i think i'll need to add some inheritance
for example,
objectives:
kill something:
inherit: <script[some_other_script].data_key[objectives.kill mobs]>
# other stuff here
and it could probably be implemented with just maptag.include
since quest conditons are so common, i should implement a syntax for that
quest:
quest_conditons:
- my_quest.a
- "!my_quest.b"
- my_quest.c || my_quest.d
maybe something like this? but this gets complicated quick as i'll have to build a performant parser and everything
I use a subflag and the relevant event for tasks
like kill 10 zombies
and check the flag path in the event header
flagged:quests.task.kill
and the value is a list of maps
which hold the relevant quest info from all quests the player currently has
smart
so this is kinda like the custom type i showed above
the other types are simply "presets" like fetching, talking to NPC, etc because those are very common
Yeah the script I have is a little old, it still uses yaml for quest data
would go for a data script
dialogue thingy
# speaker:
# title (string)
# text (string)
# options:
# - text (string)
# click (task)
tickquests_create_dialogue_task:
type: task
definitions: d|loc
script:
- define title <[d.speaker.title]>
- define text <[d.speaker.text]>
- define lines <list>
# TITLE
- define lines:->:<[title]>
- define lines:->:<empty>
# TEXT
- define lines:->:<&[base]><[text]>
- define lines:->:<empty>
# OPTIONS
- foreach <[d.options]> as:opt:
- define lines:->:<&[base]><[opt.text]>
- define text <[lines].separated_by[<n>]>
- spawn text_display[text=<[text]>;background_color=black;pivot=center;display=left] <[loc]> save:text
- define text_entity <entry[text].spawned_entity>
tickquests_sample_dialogue:
type: data
d:
speaker:
title: James
text: Hello, I'm <element[James].custom_color[emphasis]>. This is a sample dialogue.
options: <list[<map[text=Opt 1]>].include_single[<map[text=Opt 2]>]>
thoughts
https://paste.denizenscript.com/View/115038 ok i made some changes, im really not sure how to find the locations of the options to place interaction entities
Content of Denizen Script Paste #115038: Unnamed Denizen Script Paste... pasted 2023/09/10 03:28:51 UTC-07:00, Paste length: 1342 characters across 47 lines, Content: # speaker:# title (string)
https://paste.denizenscript.com/View/115042 found a way to get all the option lines now
Content of Denizen Script Paste #115042: Unnamed Denizen Script Paste... pasted 2023/09/10 05:19:42 UTC-07:00, Paste length: 1830 characters across 58 lines, Content: # speaker:# title (string)
now how would i determine the location of the interaction entity? the text display pivots
alright i think i need to somehow get the line height of a text display
@warm jacinth 😒
did it
now how detect hover
https://paste.denizenscript.com/View/115054 this is what i have so far
Content of Denizen Script Paste #115054: Unnamed Denizen Script Paste... pasted 2023/09/10 07:14:19 UTC-07:00, Paste length: 3629 characters across 91 lines, Content: # speaker:# title (string)
lol
now properly accounts for multiline options
we were planning on making a full quest system too lol
oh
wait what do you mean "were"
or well, we still are going to be making one, but I meant as in you beat us to a fully fledged denizen-only one
oh, do you use some sort of backend infrastructure
elaborate, wdym o.o
yeah no I meant you beat us to making a fully fledged denizen-only quest system
Ok
oh, neat idea to use text displays instead of spamming the chat when talking to NPCs! I plan on making a questing system for my server too (after I finsihed some other stuff)
nice
i think this is also a good time for me to learn about interact and assignment scripts?
im not sure if i should use them here/they are the right solution because i dont know much about them
I didn't even think about text display for narration, that's smart.
@marsh dune everyone's liking your idea for dialogue
Because it’s a good idea. If you can accurately get the user options UI side to work and make sure it’s instanced per player, that’s even better.
yeah it is already instanced per player
how's the dialogue options going then? I presume that's still a bit hectic
I'd imagine rxing the player>option entity hitbox would tell the menu which index it's on, then it just listens for interact
objectives:
First Objective:
type: dialogue
dialogue:
- ~run quest_dialogue def.queue:<queue> "def.dialogue:What is your name?" def.responses:<player.name>|James def.return:name
- narrate "Hello <[name]>!"
- if <[name]> == James:
- ~run quest_dialogue def.queue:<queue> "def.dialogue:Oi stop lying!" def.responses:Okay...
- ~run quest_objective_set def.quest:Quest1 "def.objective:Second Objective"
# automatically ends the dialogue
dialogue format maybe
the only problem is that its slightly verbose
hmm looks like i cant do the def.return thing because theres no mechanism to adjust the definition map
so ill have to use save:x and <entry[x].determinations.first> or something?
so i also have no idea if assignment or interact scripts will help here
(continuing from #chatter message)
Discord
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
(continuing from here #chatter message )
i was fairly new to denizen when i made this
but it works so i just let it be for now
its still a nice reference :)
yeah, I hope it helps out a bit
ok so i think i have a way of detecting hover?
something like <player.eye_location.ray_trace_target[ignore=<player>].if_null[null]>
and check that every once in a while
how laggy would that be though
assume it ownt be that laggy because i can apply filters to if the player is in a dialogue and stuff
also, you can't run a data script right
so i need to think of smth else
progress
quest_dialogue_example:
type: task
script:
- ~run quest_dialogue def.id:test def.queue:<queue> "def.dialogue:What is your name?" def.responses:<player.name>|James save:name def.source:<npc[2]>
- define name <entry[name].created_queue.determination.first>
- narrate "Hello <[name]>!"
- if <[name]> == James:
- ~run quest_dialogue def.id:test def.queue:<queue> "def.dialogue:Oi stop lying!" def.responses:Okay... def.source:<npc[2]>
quest gui
ok i wonder how i can make this less verbose
@ashen forge any update
Thread Reopened
Thread was manually reopened by @spring flare.
school work :(
sure, if you want to work on it or something, i'll send when im home
thank youuu
approx how long will you be home?
4h
alrr
so the current way you make a dialogue is something like this:
quest_dialogue_example:
type: task
debug: false
script:
- ~run quest_dialogue def.id:test def.queue:<queue> "def.dialogue:What is your name?<n><n><&7>(Right click)|<player.name>|James" save:name def.source:<npc[2]>
- define name <entry[name].created_queue.determination.first.strip_color>
- if <[name]> == James:
- ~run quest_dialogue def.id:test def.queue:<queue> def.stop:false "def.dialogue:Hey, stop lying!|Okay..." def.source:<npc[2]>
- kill <player>
- else:
- ~run quest_dialogue def.id:test def.queue:<queue> "def.dialogue:Hello, <[name]>!|Hello!" def.source:<npc[2]>
- ~run quest_dialogue_remove def.id:test
# - ~run quest_objective_set def.quest:Quest1 "def.objective:Second Objective"
i wonder if theres a way to make this less verbose
@spring flare
lol
thank you bb
paas ot through a definemap?
could you elaborate
assuming he’s saying that in the run command, have a single definition take in a map tag, and define map a map of different things required for, say, the dialogue
im not sure i understand.
- definemap args:
id: test
queue: <queue>
source: <npc[2]>
- ~run quest_dialogue defmap:<[args].with[dialogue].as[...]>
do you mean this?
yeah but with the dialogue also in the definemap
wouldnt that be more verbose as in you have to make a definemap with every dialogue
I mean I’d say it would be a tad neater but not sure about verbosity tbh
keep in mind that an average single dialogue could have like 20 dialogue lines
maybe an inject defining the things?
sounds sus
how do u run it
Spawn an npc and run that task