Daggerfall Mechanics thread: Volunteers welcome

Discuss Daggerfall Unity and Daggerfall Tools for Unity.
Post Reply
Narf the Mouse
Posts: 833
Joined: Mon Nov 30, 2015 6:32 pm

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Narf the Mouse »

At a guess, heavy weapons rely more on strength; light weapons rely more on agility; with the difference being a flat [-5, +5]?
Previous experience tells me it's very easy to misunderstand the tone, intent, or meaning of what I've posted. If you have questions, ask.

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

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Jay_H »

I've uploaded the spreadsheet since I'm done for now. I'll probably get back to it in a few hours after a nice break. In this image you can see what we have so far:
Image
The trends are fairly surprising. I had written off Agility entirely, but now I'm not sure what to make of it. Weapon skill is always the most important factor. I'd try to put it into words but my brain's a little fried now, so I'll let the image speak for itself right now and come back again when my mind's fresher.

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

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Jay_H »

Back to testing.

100 Agility, 100 Blunt Weapon:

17/19
15/16
15/15
16/17

94.03%

100 Agility, 100 Long Blade, Daedric Saber:

13/14
16/17
13/13
14/14

96.55%. I'm sticking to my theory that Agility has no beneficial impact on To-Hit.

Adrenaline Rush:

14/17
16/22
14/19
17/26

72.62%. Equivalent to baseline. My previous testing with Adrenaline Rush gave higher results.

Bonus to Hit Human:

14/18
16/20
16/24
14/18

75.00%. Equivalent to baseline. Bonus to Hit continues without results.

Phobia of Human:

15/19
14/19
16/21
16/19

78.21%. Equivalent to baseline. Phobia and Bonus to Hit have no effect.

Expertise in Weapon:

15/18
14/22
15/19
15/18

76.62%. Equivalent to baseline. This differs from my previous results.

Athleticism:

18/22
15/25
15/21
14/22

68.89%. A little far from baseline, but I count it as an anomaly.

That's all from me for today. A lot of the work I intend to do from here regarding combat will be repeating the stat+weapon type tests on the left side of the spreadsheet until we see something resembling stability. I've highlighted in yellow the fields that I believe to be anomalous.

Now then, taking a step back. Narf, I don't yet have a clear understanding of the difference between calling from memory and caching, and the meaning of the word "struct." I'm halfway through and I feel like I'm missing some vital points because of it. Would you be able to explain them further?
Attachments
To-Hit.xlsx.zip
(4.55 KiB) Downloaded 154 times

Narf the Mouse
Posts: 833
Joined: Mon Nov 30, 2015 6:32 pm

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Narf the Mouse »

Jay_H wrote:Now then, taking a step back. Narf, I don't yet have a clear understanding of the difference between calling from memory and caching, and the meaning of the word "struct." I'm halfway through and I feel like I'm missing some vital points because of it. Would you be able to explain them further?
Sure.

Ok, so the different storage mediums in your computer can return data at different speeds. SSDs (solid-state drives) are faster than HDDs (hard disk drives). RAM is faster than SSDs. Your CPU has its own, on-chip RAM that's even faster, since it's in the same chip. Modern CPUs will try to figure out what data they need, and fetch it to their on-chip cache. If the data isn't in the CPU's cache, you have a cache miss, and from there, it can take thousands to hundreds of thousands of CPU cycles before the data arrives. Lastly, and most immediate, CPUs have registers, which contain small amounts of data that the CPU can operate on without delay.
But I should probably explain what a CPU cycle is, before I go further. Ok, so you know how your computer has some speed rating in "GHz", or "Gigahertz"? That's the number of times your CPU can cycle per second. "Hertz" is a quick way of saying "per second"; if you type at 3 keyboard presses per second, you type at 3 keyboard press hertz. "Giga" is a metric prefix meaning "billion".

Yes, your computer is running up to 4.x billion cycles per second.

Ok, so what do cycles mean? Everything your computer does takes a certain number of cycles. For example, Intel's Skylake CPUs take 4 cycles to do one floating-point operation. So if you want to add, multiply, divide (modulo and power functions are derived from the other three) floats, and you have a 4 GHz CPU, you can do 1 billion of those per second...Under optimal conditions.
However, there's some reasons why you probably won't be able to. First, there's the overhead of whatever loop you're running. Second, there's whatever else is running on your OS. Third, if the data is not in the registers, it has to be fetched from the cache. If it's not in the cache...Well, the CPU might have to call all the way out to that spinning magnetic platter of a HDD. This is called a cache miss, BTW.

Ok, so if you want some data, you could do one of these:

Code: Select all

Data CalculateData(//... Inputs)
{
	/// Calculate.
}

Code: Select all

private Data cachedData;
private bool cachedDataChanged;
Data CalculateData(//... Inputs)
{
	// Why (cachedDataChanged == false) and not (!cachedDataChanged)?
	// The former makes it clear what you want, and is less likely to get missed
	// or accidentally deleted.
	if (cachedDataChanged == false)
		return cachedData;
	else
	{
		// Calculate.
		cachedData = calculatedData;
		return cachedData;
	}
}
Now, which is faster? ...It depends. Calculating the data might be faster, because the inputs are close to the CPU, and the calculation is fast. OTOH, returning the cached data might be faster, because the CPU's already preloaded it, and it was close enough to the CPU. And maybe the calculation is slow. Either one can take more CPU cycles; as always, test. :)

Ok, so that's caching, and calculating data. What's a method call?

First, how are methods stored? Methods are stored in memory, and when you call a method, you literally copy that data to the CPU. While your computer receives it in the context of instructions, and not data, the exact same notes about CPU cycles applies.
But it's more than that, too.
Programs store data in one of two ways: On the stack, and on the heap. The stack is just that, a stack; add things to the top, take things off the top...Works pretty much the same (in the general sense) as C#'s Stack class.
The heap is a heap. You can put things anywhere, and you can retrieve them without worrying about the order of things...As long as you know where stuff is, you can get it out.
You may have heard about pointers. Pointers point into the heap, allowing something to be retrieved.

Methods are called using pointers. So, when you call a method, you pop a pointer from the stack, push a marker noting where the method should return to, to the stack, push all the parameters of the method onto the stack, jump to that pointer (so the CPU continues execution at that pointer) which pulls the method's instructions to the CPU... So yeah, calling into a method is slow. You might think you should make one larger method to reduce method calls, but the larger it is, the longer it takes to load the instructions to the CPU (and if it's big enough, the CPU might have to fetch instructions more than once). It's a trade-off.

So, that's a method call, and why it's slow.

Now, to explain structs. Don't worry, it won't take long. Structs are data that is stored on the stack. As a corollary, classes are stored on the heap. So, structs can be faster, because the data is right there on the stack. Conversely, classes can be faster, because you only have to pass a pointer...And a pointer is an Int32 or Int64 in fancy dress. Int32 on a 32-bit platform; Int64 on a 64-bit platform.
A reference (C# uses references) is a pointer in fancy dress.

I've left out some abstractions, and how C# defines structs and classes is specific to C#.

Oh, and I should note that both the stack and the heap are stored in RAM.

Hopefully that makes things at least a little less muddy. :)
Previous experience tells me it's very easy to misunderstand the tone, intent, or meaning of what I've posted. If you have questions, ask.

Al-Khwarizmi
Posts: 177
Joined: Sun Mar 22, 2015 9:52 am

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Al-Khwarizmi »

ifkopifko wrote: So the work on spells seems to be comple now... a big thanks to Al-Khwarizmi for the starting impulse. :)
And thanks a lot to you for completing the reverse-engineering job and to Jay for carefully providing all the data!

I would have liked to do more apart from that starting impulse, but had some travel and then busy weeks at work... but anyway, with such a great community, between all of us it all got done :) Spell costs are known now. Amazing.

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

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Interkarma »

What a great thread this has become, for so many reasons. :)

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

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Jay_H »

Well, Interkarma, you weren't really thinking of doing all this work by yourself, were you? ;)

I've done a little more combat testing, but it's getting really repetitive, so I'm trying some other things in the meantime. Right now I did some testing with sales prices. We have before us a mystery that I simply can't explain. I've attached the spreadsheet to this post.

The relevant parts are all the Ripmarket sections. I tested in the same store, all on the same day (with one exception). The variances in personality, mercantile, and shop prices were not surprising; to summarize:

1 Personality, 1 Mercantile: Sell for 35.50%.
50 Personality, 1 Mercantile: Sell for 39.45%.
100 Personality, 1 Mercantile: Sell for 43.35%.
1 Personality, 50 Mercantile: Sell for 49.20%.
1 Personality, 100 Mercantile: Sell for 63.28%.
100 Personality, 100 Mercantile: Sell for 71.09%.

Going from 1 to 100 Personality gives an improvement of 7.85%, and from 1 to 100 Mercantile is 27.78%. That's fairly reasonable, albeit less than I expected. The mystery isn't there, though.

Something alters the base offers the shop gives. It's a modifier applied to all goods at a time in the store, which varies by something I don't have enough data to predict yet. My previous work shows that two Cobbled stores or two Straightforward stores in the same city do not offer the same prices, as seen in the Ripmarket 1P 100M sheet. Now I've seen, from that time to today, that even the same store doesn't offer the same prices each time; from my previous testing to now, there was an 18.95% shift in the prices with no variable altered. That's an enormous difference. My current theory, bizarre as it is, is that some variable is chosen each time you enter a city that gets assigned to the shopkeeper, altering to some degree the prices offered to you.

This sort of throws out the window what we've always presumed about store prices; if the exact same store can change its sale price by nearly 19%, I don't know if even going to an Incense or Rusty store is always enough to counteract that. If the numbers are in flux with each visit, that makes the testing process extremely convoluted, though I believe it will still be possible to a large degree. It'll just require an overwhelming amount of data to understand. If the shop variable theory is true, we'll have to find out whether the same variable applies to all shops in the same day, or if they vary independently; if the latter, finding the exact range that an Incense store varies from a Not Fit store will be a lot of guesswork and darkness.

Checklist:
  • Do stores vary their prices over time?
  • Do all stores within a city shift uniformly?
  • What price differences are there between the five qualities of store?
  • Do different stores buy and sell certain goods for different prices? Do general stores buy weapons for less than weaponsmiths?
  • How often do stores vary their prices? Is it each day, upon leaving the city, etc?
As excellent as our work on spells was, it may have been an easy part. If variables are involved with shop prices, I'm supposing that would be something visible in memory -- at least that's my hope. This is all I'm doing for now but I'll see when I can get back to this.
Attachments
DF Shops.xls.zip
(5.81 KiB) Downloaded 157 times

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

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Interkarma »

Jay_H wrote:Well, Interkarma, you weren't really thinking of doing all this work by yourself, were you? ;)
Haha, it's true. You guys are doing an amazing job. :)

Narf the Mouse
Posts: 833
Joined: Mon Nov 30, 2015 6:32 pm

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Narf the Mouse »

Having fought skeletal warriors with long blades, and lately, with blunt weapons, I'm fairly sure that the damage range specified by the weapon isn't all there is to it; skelys seem to die quite a bit faster to blunt weapons, while rats and bats seem to live longer.

Things you don't see in most fantasy novels: "Cure back pain"...
Previous experience tells me it's very easy to misunderstand the tone, intent, or meaning of what I've posted. If you have questions, ask.

Al-Khwarizmi
Posts: 177
Joined: Sun Mar 22, 2015 9:52 am

Re: Daggerfall Mechanics thread: Volunteers welcome

Post by Al-Khwarizmi »

Narf the Mouse wrote:Having fought skeletal warriors with long blades, and lately, with blunt weapons, I'm fairly sure that the damage range specified by the weapon isn't all there is to it; skelys seem to die quite a bit faster to blunt weapons, while rats and bats seem to live longer.
It's been long since I actually played Daggerfall seriously, but I remember that my impression was the same: blunt better for skeletons, blades better for bats and rats.

Post Reply