0.7.2: Quest timings

Discuss coding questions, pull requests, and implementation details.
User avatar
pango
Posts: 1649
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: 0.7.2: Tutorial quest timings

Post by pango » Sat Dec 29, 2018 12:49 pm

I started doing measurements by repeatedly not doing quests and checking how long before the quest disappears from my log. Of course we'd need more; specially, I didn't manage yet to get one of the "problematic" commoners quest you mentioned.
Few remarks, but feel free to double check and have a look directly at the measurements:
- Clock <name> <base duration> 0 flag 1 range 0 1 takes exactly <base duration> time to expire, not a minute more, not a minute less. For other cases I used 1 hour granularity, it was painful enough...
- When dialogue or log mentions some quest duration in days, it's actually rounding up the real quest expiration time; I've seen quest to do "in 13 days" expire in 12 days 2 hours, for example.
- I've seen some Clock <name> 00:00:00 0 flag 17 range X Y expire after a longer time than (<base duration> + <cautious travel time> * 2.5) + Y, I'm starting to suspect that Y is multiplicative instead of additive, maybe "range A B" <=> f(x) = (x + A) * B ? That would be consistent with "range 0 1" looking a lot like the identity function. That would require lot more measurements and knowing accurate travel times to confirm.
- I've seen some variability with Clock <name> <base duration> 0 flag 1 range 1 4, so range must have some randomness somewhere.
- I've had a run of quest A0C00Y12 and its unusual "flag 9", but it was rather buggy: self overwriting text, mention of what looks like an alchemist shop name that doesn't exist. They're also some hints that I should go to a library but the town I was doing the tests in doesn't have a library, that probably didn't help. So not much learned about that quest, except the quest expired as if that flag&8 bit wasn't there.
Nothing so far to explain how that "Clock _traveltime_ 00:00 0 flag 1 range 0 2" is supposed to work.
Given how some stuff above doesn't bother too much about being fair, and the presence of bugs, maybe it doesn't...
Attachments
Daggerfall clocks measurements.zip
(34.17 KiB) Downloaded 23 times
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
pango
Posts: 1649
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: 0.7.2: Tutorial quest timings

Post by pango » Sat Dec 29, 2018 5:07 pm

Updated, including some interesting ones like A0C00Y11. Some times are unusually high, even under multiplicative hypothesis, I'm not sure what to think
Attachments
Daggerfall clocks measurements.zip
(35.77 KiB) Downloaded 28 times
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
pango
Posts: 1649
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: 0.7.2: Quest timings

Post by pango » Mon Dec 31, 2018 8:47 pm

(renamed bug report from "Tutorial quest timings" to "Quest timings", that looks more appropriate now;
Also, another bug report involves timers, maybe those issues can be centralized).
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
pango
Posts: 1649
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: 0.7.2: Quest timings

Post by pango » Tue Jan 01, 2019 3:25 pm

Ok, after some discussion with Elenwel on Discord, it seems there's some bug in the way clocks were decompiled:
flags is a 16 bits value, so "range min" is really the upper byte of flags and "range max" is the clock type, exactly like what is written in the UESP. In other words "range" doesn't exist.
Some bits of flags may still be a bit mysterious, but other than that clocks don't look too complicated. He said he would publish his findings when ready.
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

Elenwel
Posts: 5
Joined: Tue Jan 01, 2019 5:14 pm

Re: 0.7.2: Quest timings

Post by Elenwel » Tue Jan 01, 2019 6:34 pm

Hi there,
Following to Pango questions, I looked to quest’s timers implementation in FALL.EXE, and even if I may need a couple more days to reach a better understanding, here are my first insight.
-As said by Pango, the textual representation of timers seems to be broken, for the moment I can confirm most of UESP QBN file format. For example clock A0C00Y11 :
  • textual

    Code: Select all

    Clock _questtime_ 00:00 0 flag 1 range 3 5 ) 
  • is stored as :
Image
So, range seems to be a miss interpretation of type and high(flags).

-As far as I understand timers, the meaningful fields are :
* type :
  • 0 : Random time from min to max
  • 1 : timer duration = min
  • 2 and 4 : one location duration will be travelTime( here(), link1) * 1,5
  • 3 : two locations (from=>To quest) duration will be travelTime(link1, link2)*1,5
  • 5 : two locations duration will be travelTime(here(), link1)*1,5 + travelTime(link1, link2)*1,5
Side note : depending on destination, duration may be increased by 1 week for 2, 3 and 4, and by 2 weeks for 5 (reasons unclear).
Side notes 2 : I did not look into travelTime calculation, however the internal travel time is always increased by 48 hours.
* flags :
  • for destination based timer, flags&0x100 : link1 is a NPC, if not link1 is a location
  • for destination based timer, flags&0x200 : link2 is a NPC, if not link1 is a location
  • flags&0x10 double timer’s duration (there and back)
  • flags&8 : timer can fire multiple time (unsure ? )
  • flags&4 : timer will set state to 0 upon expiration (unsure?)
  • flags&2 : timer will set state to 1 upon expiration + something (todo)
  • flags&1 : timer will set state to 1 upon expiration
  • other flags are reserved for internal uses (timer state)

User avatar
Interkarma
Posts: 4955
Joined: Sun Mar 22, 2015 1:51 am

Re: 0.7.2: Quest timings

Post by Interkarma » Tue Jan 01, 2019 9:36 pm

Welcome to the forums Elenwel. :) Thank you for the detailed information!

I think I'll move this one to dev discussion, as topic has grown a bit past a bug report at this stage.

User avatar
Interkarma
Posts: 4955
Joined: Sun Mar 22, 2015 1:51 am

Re: 0.7.2: Quest timings

Post by Interkarma » Thu Jan 03, 2019 12:01 am

I'm unpacking all of this now. Sadly all the quests have already been decompiled with this incorrect "range" textual representation and we don't have Tipton's source for TEMPLATE to generate corrected versions of the quests. It would be undesirable to generate all new quests in any case, as there's been too many other other localised compatibility and bug fixes specifically for DFU to the quest scripts.

But I don't think that will be necessary. If "range" is just a bad misrepresentation of flags high and type, no information has been lost. Just the quest text is somewhat incongruous from its intended meaning. And as Jay has demonstrated dozens of times over, custom quests can get by just fine without this extra complexity in the timers anyway. The way I was forced to build quest timings on limited information has generally resulted in a simplified timer setup for quest authors, and I'd like to maintain that.

The remaining challenge is really around classic quest emulation and ensuring timers are within sensible ranges. As with the tutorial quest, "guard the mages guild" also suffers from the timing problem I introduced with my "best effort" pass with incomplete information. I'm sure it's not the only other quest impacted by this.

I'll start looking for optimal solutions that involve minimal changes. In the short-term, the initial change suggested by Pango (remove the +1) is a good one. Thank you again Pango for your efforts, but especially your patience with me. :)

User avatar
Jay_H
Posts: 2912
Joined: Tue Aug 25, 2015 1:54 am

Re: 0.7.2: Quest timings

Post by Jay_H » Thu Jan 03, 2019 12:10 am

Thank you Elenwel for all the information :) With that said, yes, I completely agree we don't need all that in the quest system! The only things I could foresee needing are:

1. Urgent (calculated one-way from questgiver to final location in QBN)
2. Round-trip (calculated two-way between questgiver and final location in QBN)
3. Grouped (sum of travel to all quest locations in order in QBN)

While we could certainly get more creative than that, I feel as though the returns greatly diminish after that point.

That said, it's just my opinion and I'm aware of DFU's time and manpower restraints. I and others will work with whatever comes out.

User avatar
Interkarma
Posts: 4955
Joined: Sun Mar 22, 2015 1:51 am

Re: 0.7.2: Quest timings

Post by Interkarma » Thu Jan 03, 2019 1:06 am

Thanks for your input Jay. I'd definitely rather have clear keywords as you use above than obscure flag values (other than maintaining backwards compatibility of course). That's a privilege we have now with an entirely new open source quest platform at our disposal.

Also, something we all need to keep in mind is that you're one of the most experienced DFU quest authors in the world at this point. Your input carries a lot of weight, and I'll keep your needs in mind when I review this.

Elenwel
Posts: 5
Joined: Tue Jan 01, 2019 5:14 pm

Re: 0.7.2: Quest timings

Post by Elenwel » Thu Jan 03, 2019 9:28 pm

The main drawback of current timer format is that you have lost all information concerning timer targets (link 1 and 2) for types 2 and over.

I have the habit to wrote (quite dirty) python scripts to visualize binary structures as I work. I may hack it to produce a textual "clock format". For example for quest A0C00Y11.txt we currently have :

Code: Select all

 \A0C00Y11.txt (2 hits)
	Line 195: Clock _questtime_ 00:00 0 flag 1 range 3 5
	Line 196: Clock _delay_ 01:00 0 flag 1 range 0 1
A new representation can be :

Code: Select all

Clock2 questime TIMER_2REF_2DEST(5?) 0 0 flags 0301(769?) links 2 1 
Clock2 delay TIMER_SIMPLE(1?) 60 0 flags 0001(1?)
Using Clock2 namespace you can keep current codebase and compatibility with current usermade quests.

RFC for Clock2 : ( ;) )

Proposed format :

Clock2 NAME TYPE TIME_MIN TIME_MAX flags FLAGS [links LINK1 LINK2]

With :
  • NAME : resolved TVH as a cstring
  • TYPE : type, as enum (or as integer? it may be easier to parse)
    • 0 : 'TIMER_RANDOM'
    • 1 : 'TIMER_SIMPLE',
    • 2 and 4 : 'TIMER_1REF',
    • 3 : 'TIMER_2REF_FROMTO',
    • 5 : 'TIMER_2REF_2DEST'
  • TIME_MIN/TIME_MAX : integer, decimal value : time in minutes (as in QBN file)
  • FLAGS : flags as 4char hex strings (or decimal?)
  • for destination based timers LINK1 and LINK2 indexes of Location or NPC depending on flags value
This format is quite easy to produce actually, and is quite easy to insert instead of current 'Clock' representation in your Quest.txt files. And it can be modified as you wish :D

Post Reply