TRI NGUYEN GAME DESIGNER
  • Professional
  • Personal
  • About Me

Loot Table Spreadsheets


Loot Table Data Structure

​LINK TO SPREADSHEET: 

LOOT TABLES
The loot tables that I decided to use are a general lootTable that would be attached to an NPC, and other loot tables that would be linked to it named: lootTableRarity, lootTableGuaranteed, lootTableGearType, lootTableWeaponType, and currencyTable.

lootTable: This is the general loot table, choosing between 4 items, all with specific weights. It was designed this way so that the player has a chance to get something cool with each NPC encounter, like armor or weapons. There is a slightly higher chance for the player to get currency, because it is a bit less valuable than gear. Finally, there is a very large chance that the player will get junk (which is either null or something that is a bit useless to the player). This encourages them to grind more to try and get what they really want.
​
​lootTableRarity: ​This loot table is used to figure out what kind of rarity that the loot will be when it is dropped for the player. It uses Poor, Common, Uncommon, Rare, and Epic. It does not use Legendary because that is for very specific situations like raids and events. This table also has an additional variable with the nonRareOrEpicCounter, which increments by 1 every time the player does not get a rare or epic drop. This value would be checked, and if it hits a certain value (in this case, I have set it to 40), it will then pass through to the lootTableGuaranteed.

lootTableGuaranteed: When the nonRareOrEpicCounter hits a specific number, instead of using lootTableRarity, it will pass through this table to ensure that the player gets a high level drop. It still encourages the player to play the game and grind, but if their luck is really bad, then we can guarantee at least some satisfaction every 40 or so calculations. This number can be tweaked to fit the feel and style of the particular MMO.

​lootTableGearType: This loot table is to calculate what kind of gear / armor is going to drop, divided into all of the types of armor / gear that the player can equip. This loot table uses a non-replacement system, which means that the weight of each item will decrease by 1 every time that the piece is chosen. When it hits 0, it will reset the weight so that the player can get it again. This is so that the player doesn't happen to constantly get helmets every time gear drops. It will make gear drops be more varied.

lootTableWeaponType: This loot table is to calculate what kind of weapon will drop for the player. This will check a condition when setting the weights of each weapon. If the player prefers a specific type of weapon, the weight of that particular weapon will be increased slightly so the player will have a better chance of getting that. However, the player will still be able to get other weapons, which encourages to continue playing and grinding to get what they want and to give them the opportunity to experiment with different weapon types.

currencyTable: This loot table is to calculate approximately how much cash will drop for the player. It is based on the tier of NPC that is killed. The higher the tiers get, the higher amount of cash the player will receive. (Tier 0 is Level 1 to 30). This encourages the player to get a subscription, because eventually in the later tiers, the player will get so much cash and not be able to use it because of the restriction.

There were a couple of loot tables that I did not implement. One was a loot table for specific events like raids. The other was not accounting for items that are account bond. I included the loot tables that I did because I felt like they were the most necessary to have a fun experience, and any other loot tables will be adding onto this base.
IMPLEMENTING THE LOOT TABLES WITH JAVASCRIPT

Just as a proof of concept, I implemented some of the loot tables using Javascript and having it directly interact with the google sheet. I implemented the lootTable and currencyAmount loot tables, so that the player could know what kind of loot they got, and if they got cash, how much they got. This was to showcase that the loot tables were working on a practical level.

I have included the javascript code below for you to look through and a couple of screenshots showing the outputs of when I would run the scripts.

TECH DOC:
If you want to look at how the javascript interacts with the spreadsheet:
1.) open spreadsheet
2.) open tools->script editor
3.) at the top, change the function to "lootTable"
4.) to run, press the play "run" button.
​5.) It may take some time to run.
Picture
Picture
jQuery UI Accordion - Collapse content

LootTable.js

function lootTable() {
  var typeList = new Array();
  var chosenType;
    
  //get spreadsheet
  var app = SpreadsheetApp;
  var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
  var output = activeSheet.getRange("A25").getValue();
  
  //get type names
  var type1 = activeSheet.getRange("C5").getValue();
  var type2 = activeSheet.getRange("C9").getValue();
  var type3 = activeSheet.getRange("C13").getValue();
  var type4 = activeSheet.getRange("C17").getValue();
  
  //get type weights
  var typeWeight1 = activeSheet.getRange("C6").getValue();
  var typeWeight2 = activeSheet.getRange("C10").getValue();
  var typeWeight3 = activeSheet.getRange("C14").getValue();
  var typeWeight4 = activeSheet.getRange("C18").getValue();
      
  //get total weight of types
  var totalTypeWeight = typeWeight1 + typeWeight2 + typeWeight3 + typeWeight4;
  
  //put type data into an array
  typeList[0] = {
    'name':type1,
    'weight':typeWeight1
  }
  typeList[1] = {
    'name':type2,
    'weight':typeWeight2
  }
  typeList[2] = {
    'name':type3,
    'weight':typeWeight3
  }
  typeList[3] = {
    'name':type4,
    'weight':typeWeight4
  }
  
  //initialize random value, and typeLeft and typeRight values for checking random value against array
  var randomValue = Math.floor(Math.random() * (totalTypeWeight));
  var typeLeft = 0;
  var typeRight = typeList[0].weight;
  
  
  for(var i=0; i < typeList.length; i++){
    
    if (randomValue > typeLeft && randomValue <= typeRight){
      chosenType = typeList[i].name;
      break;    
    }
    else{
      typeLeft = typeRight;
      typeRight = typeRight + typeList[i+1].weight;
    }
  }
  
  if (chosenType == "gear"){
    return "You got some dope ass " + chosenType;
  }
  else if (chosenType =="currency"){
    return "You got " + currencyAmount() + " cash!";
  }
  else if (chosenType =="weapon"){
    return "You got a dope ass " + chosenType + "!";
  }
  else if (chosenType == "junk"){
    return "You got some lame ass " + chosenType + "!";
  }
}

function currencyAmount(){
  var currencyList = new Array();
  
  //get spreadsheet
  var app = SpreadsheetApp;
  var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
  
  //get tier levels
  var playerTier = activeSheet.getRange("A22").getValue(); 
  
  //get currency tier, min, and max
  var currencyTier0 = activeSheet.getRange("W5").getValue();
  var currencyMin0 = activeSheet.getRange("W6").getValue();
  var currencyMax0 = activeSheet.getRange("W7").getValue();
  
  var currencyTier1 = activeSheet.getRange("W10").getValue();
  var currencyMin1 = activeSheet.getRange("W11").getValue();
  var currencyMax1 = activeSheet.getRange("W12").getValue();
  
  var currencyTier2 = activeSheet.getRange("W15").getValue();
  var currencyMin2 = activeSheet.getRange("W16").getValue();
  var currencyMax2 = activeSheet.getRange("W17").getValue();
  
  var currencyTier3 = activeSheet.getRange("W20").getValue();
  var currencyMin3 = activeSheet.getRange("W21").getValue();
  var currencyMax3 = activeSheet.getRange("W22").getValue();
  
  var currencyTier4 = activeSheet.getRange("W25").getValue();
  var currencyMin4 = activeSheet.getRange("W26").getValue();
  var currencyMax4 = activeSheet.getRange("W27").getValue();
  
  var currencyTier5 = activeSheet.getRange("W30").getValue();
  var currencyMin5 = activeSheet.getRange("W31").getValue();
  var currencyMax5 = activeSheet.getRange("W32").getValue();
  
  var currencyTier6 = activeSheet.getRange("W35").getValue();
  var currencyMin6 = activeSheet.getRange("W36").getValue();
  var currencyMax6 = activeSheet.getRange("W37").getValue();
  
  var currencyTier7 = activeSheet.getRange("W40").getValue();
  var currencyMin7 = activeSheet.getRange("W41").getValue();
  var currencyMax7 = activeSheet.getRange("W42").getValue();
  
  var currencyTier8 = activeSheet.getRange("W45").getValue();
  var currencyMin8 = activeSheet.getRange("W46").getValue();
  var currencyMax8 = activeSheet.getRange("W47").getValue();
  
  //put type data into an array
  currencyList[0] = {
    'tier':currencyTier0,
    'min':currencyMin0,
    'max':currencyMax0
  }
  currencyList[0] = {
    'tier':currencyTier0,
    'min':currencyMin0,
    'max':currencyMax0
  }
  currencyList[1] = {
    'tier':currencyTier1,
    'min':currencyMin1,
    'max':currencyMax1
  }
  currencyList[2] = {
    'tier':currencyTier2,
    'min':currencyMin2,
    'max':currencyMax2
  }
  currencyList[3] = {
    'tier':currencyTier3,
    'min':currencyMin3,
    'max':currencyMax3
  }
  currencyList[4] = {
    'tier':currencyTier4,
    'min':currencyMin4,
    'max':currencyMax4
  }
  currencyList[5] = {
    'tier':currencyTier5,
    'min':currencyMin5,
    'max':currencyMax5
  }
  currencyList[6] = {
    'tier':currencyTier6,
    'min':currencyMin6,
    'max':currencyMax6
  }
  currencyList[7] = {
    'tier':currencyTier7,
    'min':currencyMin7,
    'max':currencyMax7
  }
  currencyList[8] = {
    'tier':currencyTier8,
    'min':currencyMin8,
    'max':currencyMax8
  }
    
  for(var i=0; i < currencyList.length; i++){
    if (playerTier == currencyList[i].tier){
      var outputCurrencyAmount = Math.floor(Math.random() * (currencyList[i].max - currencyList[i].min + 1) + currencyList[i].min); 
      return outputCurrencyAmount;   
    }
  }  
}


Powered by Create your own unique website with customizable templates.
  • Professional
  • Personal
  • About Me