Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bug Reports

Development::Bug Reports Post detailed bug reports and what you would like to see next in the emu here.

Reply
 
Thread Tools Display Modes
  #16  
Old 10-05-2008, 11:15 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

r = 10 (the total count of items in the table for this example)
totalchance = 100 (the total of the percentages in the table for this example 10 items each with 10% chance to drop)
thischance = 10 (the chance this particular item has to drop in this example. They are all set to 10 so it is the same for all)
found = true/false (this is set to true once an item is "found" to be the drop when running the while loop)

The While Loop:
k = random integer between 0 and 9 (10 - 1) in this example. This is randomed for the total number of items in the table

thischance = the drop chance % of the randomly selected item from the table
drop_chance = random percentage from the totalchance (100 in this case)

If drop_chance < thischance, it will drop this item

So, it should be randomly selecting an item from the list. Then it should be picking a random number from 1 to 100 in this case. And if the random number is less than the percentage drop rate on the particular item, it should be dropping that item.

That is, if I am understanding this correctly. That does sound about right, but judging by what other players and myself have seen, it seems like the system still isn't exacly as random as it should be. I am still checking into it to see if I can figure out if there is a reason for it, or if I have just had some really insane odds in some cases. I apologise if I am making an ordeal out of something that isn't an issue. But, if there was an issue, it would definitely be worth correcting considering that a large portion of the game is based on loot
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #17  
Old 10-06-2008, 01:35 AM
ChaosSlayer
Demi-God
 
Join Date: May 2007
Posts: 1,032
Default

Quote:
Originally Posted by trevius View Post
That is, if I am understanding this correctly. That does sound about right, but judging by what other players and myself have seen, it seems like the system still isn't exacly as random as it should be. I am still checking into it to see if I can figure out if there is a reason for it, or if I have just had some really insane odds in some cases. I apologise if I am making an ordeal out of something that isn't an issue. But, if there was an issue, it would definitely be worth correcting considering that a large portion of the game is based on loot

well Trev you need to take few things into account when you say that "people are noticing". On LIVE when you would try to evaluate chance of mob droping something if you go to Allakhazam and pull up say mob which during course of EQ has been killed over and over for YEARS then yeah you could make a conclusions, but just a dozen kills you don't get much of statistic. Another important thing is the size of the loot table. If raid boss can drop as many as 20 items say all with equal chance, after 100 kills you not even scrathing a surface to reliable statistics. (btw you can give said boss a x20 loot multyplier and see how many times any given item gets picked)

For example on LIVE Aten Ha Ra has a loot table of 15+ items long and can drop up to 6 items at once (x6 multyplier essentialy). One guild has reported that out of 26 AHR kills (that over course of 2 years, and basicly 26*6=156 Random rolls) they got Leggins of Judgement total of ONCE. On my own first AHR kill I got lucky - she actualy droped them for me =)

There was another instance with one of PoP gods (can't recall which) and specific weapon that guy could drop. One guild reported that in 2 dozens raids they NEVER got it, yeat another guild reported that 3 of them droped on a single kill once.

essentialy if 2 items have equal chance of been droped, thats only a CHACE not a garantee. You can flip a coin all day long and get all "tails" =)
While statisticly you should get a 50/50 split, there is ZERO garantee that it will happen for sure =) But speaking pure math, as ammount of atempts approaches infinity, the probability slowly starts falling in line with predictions
Reply With Quote
  #18  
Old 11-09-2009, 12:53 PM
ChaosSlayer
Demi-God
 
Join Date: May 2007
Posts: 1,032
Default

I decided to bump this to see if there have been any progress on improving the RND code since?
thanks =)
Reply With Quote
  #19  
Old 11-09-2009, 11:38 PM
GeorgeS
Forum Guide
 
Join Date: Sep 2003
Location: California
Posts: 1,475
Default

In .net and other programing languages you require to create a randomnumber seed, and most use a timer/current time to randomize to it, that way you don't get the same numbers each loop.

Then you would get a better gaussian looking distribution. It still requires quite a bit of sampling to get this however, as mentioned before.

In my D2 loot editor, (random loot) - quite a few people have asked me why specific items drop too often, and others hardly at all. I could not blame it on the loot order or the %drop either. Trev's argument seems likely, and may be an idiosyncrasy of this C++ compiler...

GeorgeS
__________________
Your source for EQ database tools
Toolshop is open for business


http://www.georgestools.chrsschb.com//
Reply With Quote
  #20  
Old 11-22-2009, 08:06 PM
iggi
Sarnak
 
Join Date: Feb 2006
Posts: 62
Default

Couldn't you do it like this:


while(number of drops > 0){
randnum % loottablesize = item picked
randnum % 10 = (actual)randnumber
if ((actual)randnumber <= (probability*10) ){ \\assuming probability is in decimal
drop(item picked);
}
number of drops--;
}

This would allow a weighted random drop with number of drops scaling with the number of items in the loot table (which generally correlates w/raid bosses) However you want to determine the number of drops though is up to you and can be removed. Also, the number of drops can be scaled by adding a multiplier to adjust as needed.

p.s.- Don't trust me, just ponder on it, I have little experience in programming, that's just how I was taught, poorly adapted that is.
Reply With Quote
  #21  
Old 11-23-2009, 07:08 AM
iggi
Sarnak
 
Join Date: Feb 2006
Posts: 62
Default

EDIT- This got deleted in my previous post when editing:

randnum % loottablesize = number of drops
(optional)number of drops = number of drops * frequency modifier
while(number of drops > 0){
randnum % loottablesize = item picked
randnum % 10 = (actual)randnumber
if ((actual)randnumber <= (probability*10) ){ \\assuming probability is in decimal
drop(item picked);
}
number of drops--;
}

If you wanted to add a weight to number of drops, you can always use this pseudo code again accounting for the weighted drops instead of probability of drops.
Reply With Quote
  #22  
Old 01-15-2010, 08:31 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

After looking at this again, maybe trying a slight modification like this would work.

Change the part in Red here from zone/loottables.cpp:

Code:
void ZoneDatabase::AddLootDropToNPC(NPC* npc,int32 lootdrop_id, ItemList* itemlist) {
	const LootDrop_Struct* lds = GetLootDrop(lootdrop_id);
	if (!lds) {
	 //   LogFile->write(EQEMuLog::Error, "Database Or Memory error GetLootDrop(%i) == 0, npc:%s", lootdrop_id, npc->GetName());
		return;
	}
	if(lds->NumEntries == 0)	//nothing possible to add
		return;

//Removed code for pool looting which isn't applicable to this example

#else
	//non-pool based looting

	int32 r;
	int32 totalchance = 0;
	for (r = 0; r < lds->NumEntries; r++) {
		totalchance += lds->Entries[r].chance;
	}
	uint32 thischance = 0;
	unsigned short k;
	bool found = false;
	
	while(!found) {
		k = MakeRandomInt(0, lds->NumEntries-1);
		
		thischance = lds->Entries[k].chance;
		unsigned int drop_chance = rand() % totalchance;
#if EQDEBUG>=11
			LogFile->write(EQEMuLog::Debug, "Drop chance for npc: %s, total chance:%i this chance:%i, drop roll:%i", npc->GetName(), totalchance, thischance, drop_chance);
#endif
		if (   totalchance == 0 
			|| thischance == 100
			|| thischance == totalchance // only droppable item in loot table
			|| drop_chance < thischance	//can never be true if thischance is 0
			) {
			found = true;
			int32 itemid = lds->Entries[k].item_id;
			
			const Item_Struct* dbitem = GetItem(itemid);
			npc->AddLootDrop(dbitem, itemlist, lds->Entries[k].item_charges, lds->Entries[k].equip_item, false);
			
			break;
			//continue;
		}	//end if it will drop
	}	//end loop
#endif
Into the part in blue here:

Code:
void ZoneDatabase::AddLootDropToNPC(NPC* npc,int32 lootdrop_id, ItemList* itemlist) {
	const LootDrop_Struct* lds = GetLootDrop(lootdrop_id);
	if (!lds) {
	 //   LogFile->write(EQEMuLog::Error, "Database Or Memory error GetLootDrop(%i) == 0, npc:%s", lootdrop_id, npc->GetName());
		return;
	}
	if(lds->NumEntries == 0)	//nothing possible to add
		return;

//Removed code for pool looting which isn't applicable to this example

#else
	//non-pool based looting

	int32 r;
	int32 totalchance = 0;
	for (r = 0; r < lds->NumEntries; r++) {
		totalchance += lds->Entries[r].chance;
	}
	uint32 thischance = 0;
	unsigned short k;
	bool found = false;
	
	k = MakeRandomInt(0, lds->NumEntries-1);

	while(!found) {
		if (k > (lds->NumEntries - 1)) {
			k = 0;
		}

		thischance = lds->Entries[k].chance;
		unsigned int drop_chance = rand() % totalchance;
#if EQDEBUG>=11
			LogFile->write(EQEMuLog::Debug, "Drop chance for npc: %s, total chance:%i this chance:%i, drop roll:%i", npc->GetName(), totalchance, thischance, drop_chance);
#endif
		if (   totalchance == 0 
			|| thischance == 100
			|| thischance == totalchance // only droppable item in loot table
			|| drop_chance < thischance	//can never be true if thischance is 0
			) {
			found = true;
			int32 itemid = lds->Entries[k].item_id;
			
			const Item_Struct* dbitem = GetItem(itemid);
			npc->AddLootDrop(dbitem, itemlist, lds->Entries[k].item_charges, lds->Entries[k].equip_item, false);
			
			break;
			//continue;
		}	//end if it will drop
		k++;
	}	//end loop
#endif
Basically, what that will do is to make it so it only runs the RNG 1 time to decide the starting point to loop through the table entries. That is apposed to using the RNG every time it loops to chose a random entry to check if it will drop or not.

If there is an issue with the loot drop system, as far as I can tell, it would have to be due to the RNG itself. I think it is pretty well-known that the RNG is never as random as it really should be. This will at least prevent the RNG from repeatedly hitting the same drop over and over as it decides loot. There will still be RNG involved, but this should at least force it to continue down the list after it selects the random starting entry to check first.

I have personally seen some drop issues that point to there being a definite problem with drop rates. I think that it may work fine when repopping the same NPC over and over as in the example Cavedude gave. But, my theory is that the problem is something to do with server or zone restarts that cause it to give preference to certain drops for the first time a NPC spawns after a zone/server restart. I don't know why that would be the case, but that is just my best guess.

Either way, it might be worth giving this a long test to see if there is any improvement through feedback of players and testing and such.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 01-20-2010 at 10:23 PM..
Reply With Quote
  #23  
Old 01-17-2010, 11:32 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Well, I got this change added to run on Storm Haven currently for the past week and it seems to be working at least as well as the original way. I won't put this change on the SVN without approval from KLS or Derision or someone like that, though. I want them to see what they think first before changing something this essential that has the potential to cause issues with players.

I think that this might be a better way to handle doing loot tables. Instead of the previous way, where it used the RNG every time to select which item to check if it will drop, it would now only RNG to pick the item in the list to start checking at and then continue down the list and cycle through it until one of them is successfully picked. This just takes 1 step of the RNG out of the picture and since the RNG is known to not truely be as random as it should be, I think that would be a good thing to help make drop rates closer to being exactly what they should be.

While discussing this on my own forums, I came up with an idea that might be useful. The idea would be to write a new quest command that will let you get a list of all of the items currently on an NPC at any particular time. So, you could use it to get a list of items on an NPC at the time it is killed and then use quest::write() to write the list to a file. By doing this, you could log certain NPCs that are killed regularly and then over time you could get enough data to have a pretty clear picture on if drop rates are actually what they should be. Another use of being able to get the list of loot on an NPC would be to keep track of what drops were on an NPC when it was killed, for certain high end bosses. I know I have had cases where zone crashes were occurring due to certain issues and people wouldn't get to loot items. At least with this, I would have been able to confirm which items actually dropped or should have dropped before the crash occurred.

Now, I just gotta think of a way to get that list and make it into something that can be used in perl. Maybe exporting them to an array would work, or even just set them all into string or something.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #24  
Old 01-19-2010, 02:12 AM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Quote:
Originally Posted by trevius View Post
Now, I just gotta think of a way to get that list and make it into something that can be used in perl. Maybe exporting them to an array would work, or even just set them all into string or something.
Array + 1.
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
  #25  
Old 07-28-2010, 02:31 PM
Jim95841
Fire Beetle
 
Join Date: Dec 2009
Location: Sacramento
Posts: 1
Default Loot Table Info

Has this issue been addressed (items that are alphabetically first in the loot table having a higher chance of selection than they 'should' have)? Are the loot tables for EQEMU the same as in Live (except for customer servers)?

Are the loot table percentages public domain, or are we not supposed to know them (I usually rely on Allakhazam for help, but it's hit-and-miss).

Thanks!
Reply With Quote
  #26  
Old 07-28-2010, 03:52 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Loot drop rates should be fine now. I haven't heard of any complaints with them for quite a while now. Things should be dropping at the rates they are set to drop at.

If you are playing on a server that uses the PEQ DB or other servers that try to mimic EQ Live, then yes, ideally they should drop at the same rate as on Live. If they do not, it is most likely a database issue, which is only relevant to the server you play on, not to these forums as we only deal with how to Source Code works here, not how the DB is set.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #27  
Old 07-28-2010, 04:16 PM
Irreverent
The Solo Server
 
Join Date: May 2007
Posts: 416
Default

only thing I could think of is if the same index size error exists for loot/fishing/etc as forage had until recently. (where it would roll over if the sum % was > 254)
__________________
OP of Irreverent Server (The Solo Server)
Our Forums
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 11:23 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3