#(0TickPingo) questing system

122 messages · Page 1 of 1 (latest)

ashen forge
#

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?

timid spireBOT
#

(0TickPingo) questing system

timid spireBOT
#

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.

bleak ravineBOT
#
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.

quick carbon
#

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.

ashen forge
#

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

ashen forge
#

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

pseudo smelt
#

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

ashen forge
#

smart

ashen forge
#

the other types are simply "presets" like fetching, talking to NPC, etc because those are very common

pseudo smelt
#

Yeah the script I have is a little old, it still uses yaml for quest data

#

would go for a data script

ashen forge
#

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

ashen forge
#

now how would i determine the location of the interaction entity? the text display pivots

ashen forge
#

alright i think i need to somehow get the line height of a text display

spring flare
#

@warm jacinth 😒

ashen forge
#

did it

#

now how detect hover

warm jacinth
ashen forge
#

now properly accounts for multiline options

ashen forge
#

Why ping lol 😆

warm jacinth
ashen forge
#

oh

ashen forge
warm jacinth
ashen forge
#

oh, do you use some sort of backend infrastructure

warm jacinth
ashen forge
#

you said its not denizen only

#

or am i misunderstanding

warm jacinth
ashen forge
#

Ok

untold iron
#

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)

ashen forge
#

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

median mist
#

I didn't even think about text display for narration, that's smart.

ashen forge
#

@marsh dune everyone's liking your idea for dialogue

marsh dune
#

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.

ashen forge
marsh dune
#

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

ashen forge
#
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

velvet sky
#

I think I added more to it later, I'll try to find a newer version of it

velvet sky
ashen forge
#

looks like your script does things quite manually

#

i wonder how that will scale

velvet sky
#

i was fairly new to denizen when i made this

#

but it works so i just let it be for now

ashen forge
#

its still a nice reference :)

velvet sky
#

yeah, I hope it helps out a bit

ashen forge
#

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

ashen forge
#

so i need to think of smth else

ashen forge
#
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]>
ashen forge
#

quest gui

ashen forge
spring flare
#

@ashen forge any update

bleak ravineBOT
#
Thread Reopened

Thread was manually reopened by @spring flare.

ashen forge
#

school work :(

spring flare
#

i appreiciate u

ashen forge
spring flare
#

approx how long will you be home?

ashen forge
spring flare
#

alrr

ashen forge
ashen forge
#

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

warm jacinth
#

@spring flare

ashen forge
#

lol

spring flare
#

thank you bb

spring flare
ashen forge
#

could you elaborate

warm jacinth
# ashen forge 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

ashen forge
#

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?

warm jacinth
#

yeah but with the dialogue also in the definemap

ashen forge
#

wouldnt that be more verbose as in you have to make a definemap with every dialogue

warm jacinth
#

I mean I’d say it would be a tad neater but not sure about verbosity tbh

ashen forge
#

keep in mind that an average single dialogue could have like 20 dialogue lines

spring flare
ashen forge
#

sounds sus

spring flare