Item & Monster Specs
ZeroZero, I'm looking at how the character creation does attributes, and it doesn't look like a simple random function. Did you have a disassembled event for character creation?
Did you find a new place to host the disassemblies? I noticed Desmet Irkm had one that I couldn't find here. It has been decades since I've done much 6502 assembly code, but it should be easier than trying to guess a function to fit the results I'm seeing.
Did you find a new place to host the disassemblies? I noticed Desmet Irkm had one that I couldn't find here. It has been decades since I've done much 6502 assembly code, but it should be easier than trying to guess a function to fit the results I'm seeing.
So here's what I got from the nm1b.asm:
What is this $a253 table? I'm guessing the lower limits on attributes for each race. Where can I find the actual numbers?
This would seem to give a pretty even distribution on attributes with a hugely lopsided tendency to give 18's. That's not what I'm seeing. Hmmm. Maybe I'll have to download a C64 Emulator and see what actual attributes it tends to give on character create.
Code: Select all
b6fb:00fd:1 20 2a 08 mk_attr jsr $082a ; create RND
b6fe:0100:1 a6 71 ldx $71 ; get back offset
b700:0102:1 a5 5a lda $5a ; get RND lo byte
b702:0104:1 29 07 and #$07 ; only bits 0, 1, 2
b704:0106:1 18 clc
b705:0107:1 7d 53 a2 adc $a253,x ; add the base value to RND
b708:010a:1 c9 13 cmp #$13 ; is 19?
b70a:010c:1 90 02 bcc val_ok ; if smaller, ok
b70c:010e:1 a9 12 lda #$12 ; else set maximum of 18
b70e:0110:1 99 49 a2 val_ok sta $a249,y ; store into attrib packing buffer
b71
This would seem to give a pretty even distribution on attributes with a hugely lopsided tendency to give 18's. That's not what I'm seeing. Hmmm. Maybe I'll have to download a C64 Emulator and see what actual attributes it tends to give on character create.
I updated the roster file format in the sticky:
As you can see, for a HUMAN e.g. the minimum attrib values are:
ST 10, IQ 6, DX 8, CN 8, LK 5
and maximums (bits 0-2 of RND)
ST 17, IQ 13, DX 15, CN 15, LK 12
These can be increased in review board.
Code: Select all
--------------------------------------------------------------
3) in guild event used table for attrib creation
--------------------------------------------------------------
Basic values per RACE for attributes
Five values per race, indexed by race value
a253 0A 06 08 08 05 08 09 09
a25b 06 06 0C 06 07 0A 03 04
a263 06 0C 05 0A 09 08 09 07
a26b 06 0B 03 08 0B 04 09 0A
a273 07 03 04
ST 10, IQ 6, DX 8, CN 8, LK 5
and maximums (bits 0-2 of RND)
ST 17, IQ 13, DX 15, CN 15, LK 12
These can be increased in review board.
Thanks, ZeroZero. That's exactly what I was looking for.
But that would give us a pretty even distribution across the ranges, with double the possibility of 18 for Dwarf Strength and Hobbit Dex.
That's not what I'm seeing on my MSDOS game. I'm getting a lot more numbers toward the top of the range, and very few on the bottom of the range.
Hmmmm. More testing needed...
But that would give us a pretty even distribution across the ranges, with double the possibility of 18 for Dwarf Strength and Hobbit Dex.
That's not what I'm seeing on my MSDOS game. I'm getting a lot more numbers toward the top of the range, and very few on the bottom of the range.
Hmmmm. More testing needed...
Well you have the full disasembled source code.
But I have a hint for you, why the distribution is not like you expect :
The random number generator does NOT work using whole integers,
but the lower 3 bits of any number rolled....
Does a bell ring?
(And again: I ONLY had a look into the C64 version, there are dramatic
differences in every single aspect of the game in other versions, even in
character value creation, e.g. in initial HP and SP. I could also imagine,
that on the DOS version a different base value table is used or the
RND uses the whole integer value.)
But I have a hint for you, why the distribution is not like you expect :
The random number generator does NOT work using whole integers,
but the lower 3 bits of any number rolled....
Does a bell ring?
(And again: I ONLY had a look into the C64 version, there are dramatic
differences in every single aspect of the game in other versions, even in
character value creation, e.g. in initial HP and SP. I could also imagine,
that on the DOS version a different base value table is used or the
RND uses the whole integer value.)
Trying to guess more information about item effects, I made a list of all the items with effects, sorted by the byte in the item table. I can't figure out what the high order bit might mean.
Looks like the Thor Fgn is an anomaly. Which might be a good thing. He isn't in the monster table. I summoned a Thor, and I was glad he was on my side! He has LO armor class and lots of hit points, and does lots of damage. Which is sorta irrelevant because he critical hits very round.
Code: Select all
01 Troll Ring HP Regen
01 Troll Staff HP Regen
02 Mage Staff Regen Magic
04 Conjurstaff Spells use half magic
05 Bardsword Unlimited Songs
05 Lak's Lyre Unlimited Songs
06 Luckshield
07 Speedboots
08 Theif Dagger
09 Crystal Sword Needed for the fight with the Crystal Golem
0a Eye Brings the Mad God to life
0b Silvr Square Needed on Mangar's Level
0c Silvr Circle Needed on Mangar's Level
0d Silvr Triang Needed on Mangar's Level
0e Onyx Key Needed to enter Mangar's Domain
0f Master Key Used to get past gates in town
90 Lightwand Light - Range 2 - Does not detect secret doors
90 Dayblade Light - Range 2 - Does not detect secret doors
91 Heal Harp Heal 2-8 damage
12 Powerstaff Burns one group for 4-16 Damage
93 Galt's Flute Summons Wolf
94 Pipes of Pan Casts Light of some type
95 Ogrewand Summons Ogre
96 Broom Levitation
96 Ali's Carpet Levitation
97 Pureblade Flesh Anew
98 Travelhelm Teleport
19 Dag Stone Light - Range 3 - Does not detect secret doors
1a Sorcerstaff Disrupt Illusion
1a Truthdrum Disrupt Illusion
1b Ring of Power Burns one group for 10-40 Damage
9c Lorehelm Casts Sorceror Sight
9c Arc's Eye Sorceror Sight
9d Kiels Compass Casts Scry Site
9e Magic Mouth Area Enchant spell (Detects stairs)
9f Arcshield Fries one group for 6-24 Damage
a0 Arc's Hammer Casts light of some type
a2 Ybarrashield Ybarra's Mystical Coat of Armor
a3 Staff of Lor Restoration
a4 Exorwand Disposess
a5 Sword of Pak Summons Lesser Demon
a5 Spiritdrum Summons Lesser Demon
a5 Spirithelm Summons Lessor Demon
a6 WizWand Summons Demon
a7 Deathring Animate Dead
28 Spectre Snare Spell Bind
2b Fire Horn Burns one group for 16-64 Damage
2c Dragonwand Steams one group for 20-80 Damage
2d Frost Horn Freezes one group for 24-96 Damage
2d Dragonshield Freezes one group for 24-96 Damage
2f Flame Horn Fries one group for 40-160 Damage
b0 Torch
b1 Lamp
b2 Dragon Fgn
b3 Giant Fgn
b4 Ogre Fgn
b5 Mongo Fgn
b7 Old Man Fgn
39 Thor Fgn
ba Mage Fgn
bb Lich Fgn
bc Samurai Fgn
bd Titan Fgn
be Golem Fgn
The check for single use items is:I believe B0 and above is single-use item.
Code: Select all
if ((effect & 0x7f) >= 0x30)
single_use = true;
The high bit is not used in the DOS version. The effect is AND'd with 0x7f immediately after access which strips the high bit.I can't figure out what the high order bit might mean.
Item values
Code: Select all
seg019:41A8 itemPriceList db 0, 28h, 78h, 41h, 19h, 11h, 39h, 12h; 0
seg019:41A8 ; DATA XREF: garth_getItemValue
seg019:41A8 db 31h, 11h, 21h, 0Ah, 39h, 79h, 1Ah, 3Ah; 8
seg019:41A8 db 21h, 29h, 41h, 21h, 69h, 69h, 69h, 1Ah; 16
seg019:41A8 db 22h, 2Ah, 4Ah, 2Ah, 32h, 3Ah, 62h, 0Bh; 24
seg019:41A8 db 12h, 1Ah, 22h, 1Ah, 1Ah, 13h, 1Ah, 0Bh; 32
seg019:41A8 db 3Ah, 0Ah, 6Ah, 32h, 3Ah, 22h, 0Bh, 2Ah; 40
seg019:41A8 db 32h, 2Ah, 2Ah, 1Ah, 22h, 2Ah, 22h, 32h; 48
seg019:41A8 db 32h, 0Bh, 42h, 62h, 42h, 22h, 42h, 62h; 56
seg019:41A8 db 82h, 0Bh, 13h, 13h, 2Bh, 33h, 5Ah, 7Ah; 64
seg019:41A8 db 23h, 43h, 1Bh, 3Bh, 0Ch, 63h, 62h, 0Bh; 72
seg019:41A8 db 42h, 5Ah, 1Ah, 32h, 43h, 23h, 4Bh, 63h; 80
seg019:41A8 db 23h, 7Bh, 23h, 1Bh, 43h, 73h, 33h, 13h; 88
seg019:41A8 db 14h, 14h, 1Ch, 1Ch, 24h, 34h, 0Ch, 14h; 96
seg019:41A8 db 0Ch, 0Ch, 1Ch, 2Ch, 42h, 0Bh, 44h, 0Dh; 104
seg019:41A8 db 0Dh, 2Ah, 3Ch, 0Ch, 34h, 0Bh, 62h, 2Ch; 112
seg019:41A8 db 62h, 64h, 0Bh, 0Bh, 0Bh, 13h, 7Ah, 15h; 120
To convert to a real value:
Code: Select all
static uint32_t getValue(uint8_t v)
{
uint8_t i;
uint32_t rval = 1;
i = v & 7;
while (i--) rval *= 10;
return (rval * (v >> 3));
}
This is based entirely on where you are. The "monster level for random encounters" for the current level you are on is used to determine what can drop. There are two arrays that are use to determine which item to drop (and also what type of monster to fight. The algorithm is the same.)
Code: Select all
seg019:1F8E monsterRandomMask db 15,15,31,31,31,31,31,31; 0
seg019:1F9E monsterLevelOffset db 0,8,8,16,32,48,64,81 ; 0
The code to get the random item is like this:
newItemNumber = (random() & monsterRandomMask[monsterLevel]) + monsterLevelOffset[monsterLevel]
if (newItemNumber == 0)
newItemNumber = 1
Determining Character Attack Priority
The monPriorityList is also used for:
Code: Select all
charPriority = char.battlesWon >> 9;
if (char.dexterity > 14)
charPriority += (char.dexterity - 14) << 3;
charPriority += random() & 0x1f;
switch (char.class) {
case magician:
case conjurer:
case sorcerer:
case wizard:
charPriority += (char.level >> 3);
break;
case bard:
case rogue:
charPriority += (char.level >> 2);
break;
case monk:
charPriority += char.level;
break;
default:
charPriority += (char.level >> 1);
break;
}
if (charPriority == 0)
charPriority = 1;
if (charPriority > 0xff)
charPriority = 0xff;
- char.battlesWon is at 0x58 of the character file. It is incremented every time a battle is won.
Code: Select all
This is the table used to determine monster priority
seg019:1B42 monPriorityList db 0,0,0,1,1,1,1,0,0,2,2,2,2,1,3,2,3,4,3,3,4,2,2,2,2,4; 0
seg019:1B42 ; DATA XREF: bat_getMonMeleeSuccess+54r
seg019:1B42 ; bat_getMonMeleeSuccess+A9r ...
seg019:1B42 db 24h,3,4,5,84h,4,5,5,4,4,4,4,4,6,26h,7,6,8,7,7,7,8,7; 26
seg019:1B42 db 7,8,88h,6,6,6,6,0Ah,9,9,0Ah,6Ah,0Ah,0Bh,0Bh,0Dh,6Bh; 49
seg019:1B42 db 0Bh,8,8,8,8,0Bh,0Ch,2Bh,0Ch,0ABh,0Ch,4Dh,8Eh,0Ch,0Ah; 66
seg019:1B42 db 0Ah,0Ah,0Ah,0EEh,0Fh,0Fh,0Eh,90h,11h,0D0h,30h,10h,12h; 81
seg019:1B42 db 53h,74h,13h,13h,14h,14h,10h,17h,16h,10h,10h,10h,13h; 94
seg019:1B42 db 56h,18h,36h,59h,0BBh,12h,15h,15h,15h,18h,1Ah,0F8h,1Ch; 107
seg019:1B42 db 1Ch,1Eh,9Dh,75h,0B7h,15h,0DFh,0FFh; 120
It is used to determine individual monster priority like this:
monPriorityBase = (monPriorityList[monType] & 0x1f) << 2;
individualPriority = monPriorityBase + (random() & 0x1f);
if (individualPriority > 0xff)
individualPriority = 0xff;
- Determining the monster's to-hit range.
- Determining the monster's damage dice and special attack
- Determining whether the monster group will advance.
Last edited by drifting on Wed Jan 04, 2012 10:25 pm, edited 1 time in total.
Well, look at that! I have been wondering about those things since... forever. Thank you for posting these things and clearing up these mysteries.
So now I can go check and make sure I got the item costs correct. And I can build a better (more accurate) table of what drops where. I'm assuming the town has a monster level of 0, and at night it gets bumped up to 1? Yes, I see that matches what I have experienced.
That bit about monster attack priority is most interesting. So no wonder my Monk always seems to hit first. But the Dex has a HUGE impact, and the number of battles won is also a factor, but only after 512 battles. Wow. That has implications.
This is great stuff!
So now I can go check and make sure I got the item costs correct. And I can build a better (more accurate) table of what drops where. I'm assuming the town has a monster level of 0, and at night it gets bumped up to 1? Yes, I see that matches what I have experienced.
That bit about monster attack priority is most interesting. So no wonder my Monk always seems to hit first. But the Dex has a HUGE impact, and the number of battles won is also a factor, but only after 512 battles. Wow. That has implications.
This is great stuff!
That is awesome stuff! where did you get that?
So for calculating the prices, I assume you have to do the following:
Interesting to know that the maximum price of an item can be 310 million gold
So for calculating the prices, I assume you have to do the following:
Code: Select all
28h 00101000 5*10^0=5
78h 01111000 15*10^0=15
41h 01000001 8*10^1=80
19h 00011001 3*10^1=30
11h 00010001 2*10^1=20
39h 00111001 7*10^1=70
12h 00010010 2*10^2=200
...
A question about monks:
on the first page of this thread, Maven gave an overview of the items and the damage that weapons do. Is there any data on the damage that monks do with no weapons equiped (i.e. dice rols) and how this increases when they level up?
I understand how their DEX increases their chance to hit, but I would like to know what damage levels they do.
on the first page of this thread, Maven gave an overview of the items and the damage that weapons do. Is there any data on the damage that monks do with no weapons equiped (i.e. dice rols) and how this increases when they level up?
I understand how their DEX increases their chance to hit, but I would like to know what damage levels they do.
Caracas wrote:A question about monks:
on the first page of this thread, Maven gave an overview of the items and the damage that weapons do. Is there any data on the damage that monks do with no weapons equiped (i.e. dice rols) and how this increases when they level up?
I understand how their DEX increases their chance to hit, but I would like to know what damage levels they do.
Code: Select all
seg019:2512 monkDamageList db 0,1,2,3,4,23h,23h,24h,24h,25h,25h,25h,25h,26h,26h,26h; 0
seg019:2512 ; DATA XREF: bat_getCharMeleeSuccess+165r
seg019:2512 db 44h,44h,44h,44h,45h,45h,45h,45h,63h,63h,63h,64h,64h; 16
seg019:2512 db 64h,65h,66h,0,0 ; 29
damageDice = monkDamageList[char.level >> 1];
Code: Select all
seg019:250A meleeDiceMask db 3,7,15,31,63,127,255,1; 0
So to translate into XdY, you do:
X = (damageDice & 0x1f) + 1;
Y = meleeDiceMask[damageDice >> 5] + 1;
damageDice = 0x26;
X = 7
Y = 8
So the damage would be 7d8 per attack
Found something interesting while looking in to the monster to-hit code. The Word of Fear and Curse spells actually increase the monster's ability to hit. It's easy to verify.
Take a wizard into the city alone and enter a battle. Cast MIMI until the AC is L0. All of the monsters in the city should miss every time with an AC of L0. Now start casting CURS each round. After a few rounds the monsters will start hitting you.
This is on the DOS version. Does this happen on any of the other versions?
Take a wizard into the city alone and enter a battle. Cast MIMI until the AC is L0. All of the monsters in the city should miss every time with an AC of L0. Now start casting CURS each round. After a few rounds the monsters will start hitting you.
This is on the DOS version. Does this happen on any of the other versions?
More interesting stuff...
I did the test on the FEAR spell. I ran around until I found 8 Kobolds, and made sure my AC was LO. Then I started casting FEAR spells and watching how much I got hit. I needed 4 FEAR spells before they started hitting sometimes, and 18 FEAR spells before they were hitting every time. Maybe I'm off one or two, though, because that doesn't seem right.
You're right. It definitely HELPS the enemy to cast FEAR.
The information about attack priority was fascinating to me. I had noticed that my Monk was always the first one in my party to attack, and even faster than some of the high level monsters, as he got up there in levels. I wondered if it was because he was a Monk or a Hobbit, or both. Now I know! It also means there's an upper cap to the attack priority on enemies, and even Mangar and Demon Lords and Old Men can be beaten. The upper cap is 155. So all I have to do is get my attack priority up to 156, and I'll beat them every time. The formula shows that the way to do that is to win more than 63488 battles, and even a level 1 Wizard will beat them every time.
So I created a new party and fired up my keystroke recorder program. Since I want to win lots of battles, it seemed optimal to fight small groups at a time. I started on the Samurai Statue, and as soon as I got the Wind Giant spell, I moved up to Stone Giants and Golems. It was fascinating to watch as my Monk slowly started to attacker faster than my Storm Giant. Eventually, I upgraded to a Demon Lord to watch as my Monk started even beating him. I'm at the point now where even my Bard beats the Storm Giant sometimes, but my magic users are still way behind.
One thing I noticed doing this test is the drops. There seem to be a couple of screwy things with the drops when only fighting one monster at a time. When fighting statues, the game seems to pick two items and drop them over and over. Halbards and Plate Armor, for example. If I restart the game, it picks two other items and drops them over and over. Scale Armor and War Axes, or Torches and Maces. Even stranger--at night, when I don't usually get drops of items whose Index is less than 8, I can get Torches, Halbards, and War Axes.
When I started fighting the Stone Golems in the first level of the Castle, it would pick 4 items. Leather Glvs, Mthr Scale, Mthr Gloves, Fin's Flute, for example. The item indices were always 8 apart. If I wanted another item to drop, I could leave the game and restart, and it would pick 4 other items.
Oh, and it seems the same party member always gets the drops. Until his inventory is full.
I did the test on the FEAR spell. I ran around until I found 8 Kobolds, and made sure my AC was LO. Then I started casting FEAR spells and watching how much I got hit. I needed 4 FEAR spells before they started hitting sometimes, and 18 FEAR spells before they were hitting every time. Maybe I'm off one or two, though, because that doesn't seem right.
You're right. It definitely HELPS the enemy to cast FEAR.
The information about attack priority was fascinating to me. I had noticed that my Monk was always the first one in my party to attack, and even faster than some of the high level monsters, as he got up there in levels. I wondered if it was because he was a Monk or a Hobbit, or both. Now I know! It also means there's an upper cap to the attack priority on enemies, and even Mangar and Demon Lords and Old Men can be beaten. The upper cap is 155. So all I have to do is get my attack priority up to 156, and I'll beat them every time. The formula shows that the way to do that is to win more than 63488 battles, and even a level 1 Wizard will beat them every time.
So I created a new party and fired up my keystroke recorder program. Since I want to win lots of battles, it seemed optimal to fight small groups at a time. I started on the Samurai Statue, and as soon as I got the Wind Giant spell, I moved up to Stone Giants and Golems. It was fascinating to watch as my Monk slowly started to attacker faster than my Storm Giant. Eventually, I upgraded to a Demon Lord to watch as my Monk started even beating him. I'm at the point now where even my Bard beats the Storm Giant sometimes, but my magic users are still way behind.
One thing I noticed doing this test is the drops. There seem to be a couple of screwy things with the drops when only fighting one monster at a time. When fighting statues, the game seems to pick two items and drop them over and over. Halbards and Plate Armor, for example. If I restart the game, it picks two other items and drops them over and over. Scale Armor and War Axes, or Torches and Maces. Even stranger--at night, when I don't usually get drops of items whose Index is less than 8, I can get Torches, Halbards, and War Axes.
When I started fighting the Stone Golems in the first level of the Castle, it would pick 4 items. Leather Glvs, Mthr Scale, Mthr Gloves, Fin's Flute, for example. The item indices were always 8 apart. If I wanted another item to drop, I could leave the game and restart, and it would pick 4 other items.
Oh, and it seems the same party member always gets the drops. Until his inventory is full.