diff --git a/game/03-JavaScript/npcCompressor.js b/game/03-JavaScript/npcCompressor.js
index ecc76fd950c75c12f31b4bca9055bfafdddeb02f..ba6be9959e3f7df0302d1c77dc3e5da254cd2618 100644
--- a/game/03-JavaScript/npcCompressor.js
+++ b/game/03-JavaScript/npcCompressor.js
@@ -127,12 +127,12 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
 	const genproList = ["mm", "fm", "hm", "mf", "ff", "hf"]; /* stores gender first, pronoun second. */
 	const breastdescList = ["nipple","budding","tiny","small","pert","modest","full","large","ample","massive","huge","gigantic","enormous"];
 	const sizeList = ["tiny", "small", "normal", "large"];
-    const skinColourList = ["white","black","light", "medium", "dark", "ylight", "ymedium", "ydark"];
+    const skinColourList = ["white","black","light", "medium", "dark", "ylight", "ymedium", "ydark", "ghostlyPale"];
 	const noClawList = ["dog","pig","wolf","dolphin","boar","fox","hawk","cow","bull"];
-	const teenFDescList = ["slight","lithe","lean","thin","slender","lissome","slim","taut","graceful","trim","mousy","cute","fit","petite","toned","shapely","robust","plump","wide-eyed","vulgar","minor demon"];
-	const teenMDescList = ["slight","lithe","lean","thin","slender","lissome","slim","taut","graceful","trim","mousy","cute","fit","petite","toned","shapely","robust","plump","wide-eyed","brutish","minor demon"];
-	const adultFDescList = ["slight","lithe","lean","thin","slender","lissome","slim","taut","petite","trim","muscular","curvy","toned","plump","plush","shapely","robust","voluptuous","lush","vulgar","demon"];
-	const adultMDescList = ["petite","slight","slim","thin","slender","lanky","lissome","lithe","trim","lean","taut","plump","toned","bulky","broad","robust","rugged","muscular","burly","brutish","demon"];
+	const teenFDescList = ["slight","lithe","lean","thin","slender","lissome","slim","taut","graceful","trim","mousy","cute","fit","petite","toned","shapely","robust","plump","wide-eyed","vulgar","minor demon", "tutorial", "debug"];
+	const teenMDescList = ["slight","lithe","lean","thin","slender","lissome","slim","taut","graceful","trim","mousy","cute","fit","petite","toned","shapely","robust","plump","wide-eyed","brutish","minor demon", "tutorial", "debug"];
+	const adultFDescList = ["slight","lithe","lean","thin","slender","lissome","slim","taut","petite","trim","muscular","curvy","toned","plump","plush","shapely","robust","voluptuous","lush","vulgar","demon", "tutorial", "debug"];
+	const adultMDescList = ["petite","slight","slim","thin","slender","lanky","lissome","lithe","trim","lean","taut","plump","toned","bulky","broad","robust","rugged","muscular","burly","brutish","demon", "tutorial", "debug"];
     const beastDescList = ["large","large","fat","enormous","bottlenose","scaly","brown","hairy","strange","huge","large","fierce","huge","slimy"];
     const penisDescList = {
         human: ["none","tiny penis", "penis", "thick cock","hefty cock","big cock","large cock","veiny cock","meaty cock", "massive cock","huge cock","humongous cock","immense cock","gigantic cock","enormous cock"],
@@ -143,7 +143,7 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
 	const adultMHealthList = [125,125,150,150,150,150,175,175,200,200,200,200,250,250,250,250,275,275,275,400,600];
     const beastHealthList = [200,150,200,300,200,250,500,300,200,500,200,150,400];
 
-    const motherFatherList = ["Unknown","pc","Avery","Bailey","Briar","Charlie","Darryl","Doren","Eden","Gwylan","Harper","Jordan","Kylar","Landry","Leighton","Mason","Morgan","River","Robin","Sam","Sirris","Whitney","Winter","Black Wolf","Niki","Quinn","Remy","Alex","Great Hawk","Wren","Sydney","Ivory Wraith"];
+    const motherFatherList = [undefined, "Unknown","pc","Avery","Bailey","Briar","Charlie","Darryl","Doren","Eden","Gwylan","Harper","Jordan","Kylar","Landry","Leighton","Mason","Morgan","River","Robin","Sam","Sirris","Whitney","Winter","Black Wolf","Niki","Quinn","Remy","Alex","Great Hawk","Wren","Sydney","Ivory Wraith", "cum bucket", "Harper's Serum"];
 
     //child items
     const hairColourList =  {
@@ -165,7 +165,7 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
 	'changingroom', 'starfish', 'promenade', 'backyard', 'garden', 'seabeach', 'searocks', 'seadocks', 'seacliffs', 'coastpath', 'seapirates',
 	'residential', 'domus', 'barb', 'danube', 'commercial', 'connudatus', 'high', 'nightingale', 'oxford', 'industrial', 'mer', 'elk', 'harvest'];
 
-    const childClothingList = ["naked", "clothed"]
+    const childClothingList = [undefined,"naked", "clothed"]
 
     //base 64 conversion string.
     const table = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_+";
@@ -231,16 +231,16 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         }
 
         //assigns all the values to their correct order. The number of items for beast and human type NPCs should be kept equal.
-        npc_data[0] = npcTypeIndex < 10 ? "0" + npcTypeIndex : npcTypeIndex; //can be above 10
+        npc_data[0] = npcTypeIndex.toString().padStart(2,"0"); //can be above 10
         npc_data[1] = genderPronoun;
         npc_data[2] = penisSize;
-        npc_data[3] = penisDesc < 10 ? "0" + penisDesc : penisDesc; //can be above 10
-        npc_data[4] = breastSize < 10 ? "0" + breastSize : breastSize; //can be above 10
-        npc_data[5] = insecurityIndex < 10 ? "0" + insecurityIndex : insecurityIndex; //can be above 10
+        npc_data[3] = penisDesc.toString().padStart(2,"0"); //can be above 10
+        npc_data[4] = breastSize.toString().padStart(2,"0"); //can be above 10
+        npc_data[5] = insecurityIndex.toString().padStart(2,"0"); //can be above 10
         npc_data[6] = sizeIndex;
         npc_data[7] = adult;
         npc_data[8] = monster ? monster : skin;
-        npc_data[9] = descriptionIndex < 10 ? "0" + descriptionIndex : descriptionIndex; //can be above 10
+        npc_data[9] = descriptionIndex.toString().padStart(2,"0"); //can be above 10
 
         npc_code =  (compressorVersion < 10 ? '~' : '') +  reduceZeros( compressorVersion.toString() + npc_data.join("") );
 
@@ -472,7 +472,7 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         }
         
         let childTypeIndex = typeList.indexOf(childType);
-		if (childTypeIndex === -1) throw new Error("An invalid child type: " + childType + ", was passed!");
+		if (childTypeIndex === -1) throw new Error(`An invalid child type: ${childType}, was passed.`);
 
         let gender = ["m", "f", "h"].indexOf(passedChild.gender);
         if (gender < 0) gender = 1;  
@@ -495,10 +495,16 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         let clothes = passedChild.features.clothes ? childClothingList.indexOf(passedChild.features.clothes) : 0; //make sure this can take in other types once clothing is more developed.
         if (clothes === -1) clothes = 0;
 
-        let twinplets = passedChild.features.identical ? 1 : 0;
+        // this needs to be expanded upon. talk about it later
+        let twinplets;
+        switch (passedChild.features.identical) {
+            case undefined: twinplets = 0; break;
+            case true: twinplets = 1; break;
+            case false: twinplets = 2; break;
+        }
 
         let birthID = passedChild.birthId;
-        if(!birthID || birthID < 0) throw new Error("The child compressor was passed a child with an invalid birth ID of: " + birthID);
+        if(!birthID || birthID < 0 || isNaN(birthID)) throw new Error(`The child compressor was passed a child with an invalid birth ID of: ${birthID}. birth ID values should be integers above 0.`);
         birthID = "" + birthID.toString().length + birthID;
 
         let birthLocation = locationList.indexOf(passedChild.birthLocation);
@@ -510,54 +516,57 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
 		let conceivedLocation = locationList.indexOf(passedChild.conceivedLocation);
         if (conceivedLocation < 0) conceivedLocation = 0;
 
+		//Determines the needed information about the passed parents. There are three different groups: 0 for named NPCs =>  1 for human NPCs => 2 for beast NPCs
+		//Named NPCs looks through the list of named NPCs and determines if that is a valid choice. If it is not, then it checks if the npc is a beast by looking for the words male and female.
+		//If the npc is not a beast, then the age of the npc is determined and the index of the descriptors is added after it.
         let mother, father, parentTemp, parentTempList;
 
         //mothers
         if(!!passedChild.mother) {
-            //Order for checks goes: named => human npc => beast npc
 
             if(motherFatherList.includes(passedChild.mother)) {
                 mother = motherFatherList.indexOf(passedChild.mother);
-                mother = mother.toString().padStart(3, "0");
+                mother = mother.toString().padStart(4, "0");
             }
-            else if(!beast) {
-
+            else if(!passedChild.mother.includes("female")) {
+				
                 if (passedChild.mother.includes("girl")) {mother = 0; parentTempList = teenFDescList;}
-                else {mother = 40; parentTempList = adultFDescList;}
+                else {mother = 1; parentTempList = adultFDescList;}
 
                 parentTemp = passedChild.mother.replace(/ .*/,'');
                 parentTempList = parentTempList.indexOf(parentTemp);
-                parentTempList = parentTempList;
+                parentTempList = parentTempList < 0 ? 10 : parentTempList;
                 
-                mother = "1" + (parentTempList + mother);
+                mother = "1" + mother + parentTempList.toString().padStart(2,"0");
             }
             else {
                 parentTemp =  passedChild.mother.match(/\w+$/)[0];
                 parentTempList = typeList.indexOf(parentTemp);
-                mother = "2" + parentTempList.toString().padStart(2,"0");
+                mother = "2" + parentTempList.toString().padStart(3,"0");
             }
 
         }
-        else {mother = "000"}
+        else {mother = "0000"}
+
+        //console.log(`Input mother: ${passedChild.mother}; Index output: ${mother}`);
 
        //fathers
        if(!!passedChild.father) {
-            //Order for checks goes: named => human npc => beast npc
 
             if(motherFatherList.includes(passedChild.father)) {
                 father = motherFatherList.indexOf(passedChild.father);
-                father = father.toString().padStart(3, "0");
+                father = father.toString().padStart(4, "0");
             }
-            else if(!beast) {
+            else if(!passedChild.father.includes("male")) {
 
                 if (passedChild.father.includes("boy")) {father = 0; parentTempList = teenMDescList;}
-                else {father = 40; parentTempList = adultMDescList;}
+                else {father = 1; parentTempList = adultMDescList;}
 
                 parentTemp = passedChild.father.replace(/ .*/,'');
-                parentTempList = passedChild.father.indexOf(parentTemp);
-                parentTempList = parentTempList;
+                parentTempList = parentTempList.indexOf(parentTemp);
+                parentTempList = parentTempList < 0 ? 10 : parentTempList;
                 
-                father = "1" + (parentTempList + father);
+                father = "1" + father + parentTempList.toString().padStart(2,"0");
             }
             else {
                 parentTemp =  passedChild.mother.match(/\w+$/)[0];
@@ -566,65 +575,57 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
             }
 
         }
-        else {father = "000"}
+        else {father = "0000"}
+		
+        //console.log(`Input father: ${passedChild.father}; Index output: ${father}`);
 
+		//Used to determine whether or not the child's parents are known. The final value is a combination of the mother's and father's known states.
+		//mother: Unknown = 0 | known = 2; father: Unknown = 0 | known = 1;
+		let parentsKnown = 0;
+
+		if (passedChild.motherKnown) parentsKnown = 2;
+		else parentsKnown = 0;
+
+		if (passedChild.motherKnown) parentsKnown += 1;
+		else parentsKnown += 0;
 
         //assigns all the values to their correct order.
-        child_data[0] = childTypeIndex  < 10 ? "0" + childTypeIndex : childTypeIndex; //preplan this having 2 palces.
+        child_data[0] = childTypeIndex.toString().padStart(2,"0"); //preplan this having 2 places.
         child_data[1] = gender;
-        child_data[2] = tformBeast < 10 ? "0" + tformBeast : tformBeast;
-        child_data[3] = tformDivine < 10 ? "0" + tformDivine : tformDivine;
+        child_data[2] = tformBeast.toString().padStart(2,"0");
+        child_data[3] = tformDivine.toString().padStart(2,"0");
         child_data[4] = monster;
         child_data[5] = size;
-        child_data[6] = hair < 10 ? "0" + hair : hair; //needs 2 places
-        child_data[7] = eyes < 10 ? "0" + eyes : eyes; //needs 2 places
-        child_data[8] = skin; //shouldn't need another digit but double check
-        child_data[9] = clothes < 10 ? "0" + clothes : clothes; //preplan this having 2 palces.
+        child_data[6] = hair.toString().padStart(2,"0"); //needs 2 places
+        child_data[7] = eyes.toString().padStart(2,"0"); //needs 2 places
+        child_data[8] = skin.toString().padStart(2,"0"); //preplan this having 2 places.
+        child_data[9] = clothes.toString().padStart(2,"0"); //preplan this having 2 places.
         child_data[10] = twinplets;
         child_data[11] = birthID; // this can have up to 10 places. 9 for the id and 1 for the id length.
-        child_data[12] = birthLocation < 10 ? "0" + birthLocation : birthLocation; //preplan this having 2 palces.
-        child_data[13] = childLocation < 10 ? "0" + childLocation : childLocation; //preplan this having 2 palces.
-		child_data[13] = conceivedLocation < 10 ? "0" + conceivedLocation : conceivedLocation; //preplan this having 2 palces.
-        child_data[14] = mother;
-        child_data[15] = father;
+        child_data[12] = birthLocation.toString().padStart(3,"0"); //preplan this having 2 places.
+        child_data[13] = childLocation.toString().padStart(3,"0"); //preplan this having 2 places.
+		child_data[14] = conceivedLocation.toString().padStart(3,"0"); //preplan this having 2 places.
+        child_data[15] = mother;
+        child_data[16] = father;
+		child_data[17] = parentsKnown;
 
         child_code =  (compressorVersion < 10 ? '~' : '') +  reduceZeros( compressorVersion.toString() + child_data.join("") );
 
         //Currently we have both dates added if they are there.
-        let day, month, year, conceivedDate, birthDate;
+        let conceivedDate, birthDate;
 
         if (!!passedChild.conceived) {
-            conceivedDate = "";
-            day = passedChild.conceived.day;
-            if (day < 10) day = "0" + day;
-
-            month = monthNameList.indexOf(passedChild.conceived.month);
-            if (month < 10) month = "0" + month;
-
-            year = passedChild.conceived.year;
-            year = year.toString().padStart(4,"0");
-
-            conceivedDate +=".c" + day + month + year;
+            conceivedDate = ".c" + verifyPassedDate(passedChild.conceived);
         }
         else {
-            conceivedDate +=".c" + "00000000";
+            conceivedDate =".c" + "0".repeat(8);
         }
 
         if (!!passedChild.born) {
-            birthDate = "";
-            day = passedChild.born.day;
-            if (day < 10) day = "0" + day;
-
-            month = monthNameList.indexOf(passedChild.born.month);
-            if (month < 10) month = "0" + month;
-
-            year = passedChild.born.year;
-            year = year.toString().padStart(4,"0");
-
-            birthDate +=".b" + day + month + year;
+            birthDate = ".b" + verifyPassedDate(passedChild.born);
         }
         else {
-            //birthDate +=".b" + "00000000";
+            //birthDate +=".b" + "0".repeat(8);
         }
 
         if (bothDates) {
@@ -636,10 +637,16 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
             else child_code += conceivedDate;
         }
 
-        //this should be in the format motherID + "." + birth number for this child  + "|" + fatherID + "." + birth number for this child
+        //this should be in the format m#b#d#f#
         let childId = passedChild.childId;
 
-        child_code +=".i" + childId;
+        if (childId.match(/m(\d?[m,b,d,f]?[m,b,d,f]?\d+?)+/)) child_code +="." + childId;
+        else {
+            childId = `A child with either no childId or an invalid Id was passed to the compressor. Passed value: ${passedChild.childId}. Format should be m#b#d#f# with an unknown value being no number.
+        m# should be the mother's Id, b# should be the birth number of this child for the mother, d# should be the father's Id, f# should be the birth number of this child for the father.
+        In cases where a parent's information is not known, then no number should replace the # values. A known mother with an unknown father would be: m#b#df \n`;
+            throw new Error(childId); 
+        }
 
         return child_code;
     }
@@ -690,8 +697,8 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         let eyeColour = eyeColourList[Number(expandedChild.slice(position, position + 2))];
         position +=2;
 
-        let skinColour = skinColourList[Number(expandedChild[position])];
-        position ++;
+        let skinColour = skinColourList[Number(expandedChild.slice(position, position + 2))];
+        position +=2;
 
         let clothes = childClothingList[Number(expandedChild.slice(position, position + 2))];
         position +=2;
@@ -705,14 +712,14 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         let birthId = Number(expandedChild.slice(position, position + birthTemp));
         position+=birthTemp;
 
-        let birthLocation = locationList[Number(expandedChild.slice(position, position + 2))];
-        position +=2;
+        let birthLocation = locationList[Number(expandedChild.slice(position, position + 3))];
+        position +=3;
 
-        let location = locationList[Number(expandedChild.slice(position, position + 2))];
-        position +=2;
+        let location = locationList[Number(expandedChild.slice(position, position + 3))];
+        position +=3;
 
-		let conceivedLocation = locationList[Number(expandedChild.slice(position, position + 2))];
-        position +=2;
+		let conceivedLocation = locationList[Number(expandedChild.slice(position, position + 3))];
+        position +=3;
 
         let parentTemp, parentTempList;
 
@@ -721,17 +728,22 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         position ++;
 
         if (mother === 0) {
+			position ++;
             mother = motherFatherList[Number(expandedChild.slice(position, position + 2))];
         }
         else if (mother === 1) {
-            parentTemp = Number(expandedChild.slice(position, position + 2));
+            parentTemp = Number(expandedChild.slice(position, position + 1));
+
+			if (parentTemp === 1) {mother = " woman"; parentTempList = adultFDescList;}
+			else {mother = " girl"; parentTempList = teenFDescList;}
 
-            if (parentTemp >= 40) {mother = " woman"; parentTemp -=40; parentTempList = adultFDescList;}
-            else {mother = " girl"; parentTempList = teenFDescList;}
+			position ++;
+			parentTemp = Number(expandedChild.slice(position, position + 2));
 
             mother = parentTempList[parentTemp] + mother;
         }
         else if (mother === 2) {
+			position ++;
             parentTemp = Number(expandedChild.slice(position, position + 2));
             mother = " female " + typeList[parentTemp];
             parentTempList = beastDescList[parentTemp - 1];
@@ -739,23 +751,29 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         }
         position +=2;
 
-        motherKnown = !mother.includes("Unknown");
+        //console.log(`Output mother: ${mother}; Index input: ${expandedChild.slice(position-4, position)}`);        
 
         //father
         let father = Number(expandedChild[position]);
         position ++;
 
         if (father === 0) {
+			position ++;
             father = motherFatherList[Number(expandedChild.slice(position, position + 2))];
         }
         else if (father === 1) {
-            parentTemp = Number(expandedChild.slice(position, position + 2));
-            if (parentTemp >= 40) {father = " man"; parentTemp -=40; parentTempList = adultMDescList;}
+            parentTemp = Number(expandedChild.slice(position, position + 1));
+
+            if (parentTemp === 1) {father = " man"; parentTempList = adultMDescList;}
             else {father = " boy"; parentTempList = teenMDescList;}
 
+			position ++;
+			parentTemp = Number(expandedChild.slice(position, position + 2));
+
             father = parentTempList[parentTemp] + father;
         }
         else if (father === 2) {
+			position ++;
             parentTemp = Number(expandedChild.slice(position, position + 2));
             father = " male " + typeList[parentTemp];
             parentTempList = beastDescList[parentTemp - 1];
@@ -763,7 +781,18 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         }
         position +=2;
 
-        fatherKnown = !father.includes("Unknown");
+        //console.log(`Output father: ${father}; Index input: ${expandedChild.slice(position-4, position)}`);
+
+        let fatherKnown, motherKnown;
+
+		let parentsKnown = Number(expandedChild.slice(position, position + 1));
+
+        switch (parentsKnown) {
+            case 0: fatherKnown = false; motherKnown = false; break;
+            case 1: fatherKnown = true; motherKnown = false; break;
+            case 2: fatherKnown = false; motherKnown = true; break;
+            case 3: fatherKnown = true; motherKnown = true; break;
+        }
 
         if (beast) {
             if (childType === "cow" && gender === "m") type = "bull";
@@ -790,25 +819,27 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         let check;
 
         check = expandedChild.match(/\.c\d+/);
-        check = check ? check[0].slice(2) : "00000000";
+        check = check ? check[0].slice(2) : "01010000";
         let conceived = convertToDMYFormat(check);
         conceived.month = monthNameList[conceived.month];
 
         check = expandedChild.match(/\.b\d+/);
-        check = check ? check[0].slice(2) : "00000000";
+        check = check ? check[0].slice(2) : "01010000";
         let born = convertToDMYFormat(check);
         born.month = monthNameList[born.month];
 
-        check = expandedChild.match(/\.i-?\d+\.-?\d+\|-?\d+\.-?\d+/);
-        if (check) check = check[0].slice(2);
+        check = expandedChild.match(/\.m(\d?[m,b,d,f]?[m,b,d,f]?\d+?)+/);
+        if (check) check = check[0].slice(1);
         else {
-            check = `A child with either no childId or an invalid Id was passed to the decompressor. Passed value: ${expandedChild.match(/\.i.*/)}`;
+            check = `A child with either no childId or an invalid Id was passed to the decompressor. Passed value: ${expandedChild.match(/\.m.*/)}. Format should be .m#b#d#f# with an unknown being no number.
+        m# should be the mother's Id, b# should be the birth number of this child for the mother, d# should be the father's Id, f# should be the birth number of this child for the father.
+        In cases where a parent's information is not known, then no number should replace the # values. A known mother with an unknown father would be: m#b#df \n`;
             throw new Error(check); 
-        } 
+        }
         let childId = check;
 
 
-        //assignemnt of values
+        //assignment of values
         childItems = {
             "type": childType, gender, birthId, conceivedLocation, birthLocation, location, mother, motherKnown, father, fatherKnown, conceived, born, childId,
             features: {beastTransform, divineTransform, monster, size, hairColour, eyeColour, skinColour, clothes, identical}
@@ -821,13 +852,36 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
     }
 
 
-    //converts the passed number from base 10 to base 64. If the number you need converted is bigger than the allowable max integer number, store than number as a string and pass it the same way you would a number.
-    function toBase64(passedNum) {
+    /**
+     * @desc converts the passed number from base 10 to base 64. If the number you need converted is bigger than the allowable max integer number, store than number as a string and pass it the same way you would a number.
+     * @param {Number} passedNum The number you want to convert to base 64.
+     * @param {Boolean} safe If the number is smaller than the max safe integer then this can be set to true.
+     * @returns 
+     */
+    function toBase64(passedNum, safe = false) {
         if (!isFinite(passedNum)) return String(passedNum);
         if (passedNum === 0) return "0";
         if (passedNum < 0) return "-"+toBase64(-passedNum);
-        
-        if (passedNum.toString().length > 15) return toBase64(passedNum.toString().slice(0,15)) + "!" + toBase64(passedNum.toString().slice(15));
+
+        if (passedNum.toString().length > 15 && !safe) {
+            let zeroCheck = 0;
+            
+            while (passedNum.toString()[15 + zeroCheck] == 0) {
+                zeroCheck++;  
+            }
+
+            if (Number(passedNum.toString().slice(0,15 + zeroCheck)) > Number.MAX_SAFE_INTEGER) {
+                zeroCheck = 0;
+                while (passedNum.toString()[15 + zeroCheck] == 0) {
+                    zeroCheck--;  
+                }
+            }
+            
+            let frontSplit = passedNum.toString().slice(0,15 + zeroCheck);
+            let backSplit = passedNum.toString().slice(15 + zeroCheck);
+
+            return toBase64(frontSplit, true) + "!" + toBase64(backSplit);
+        }
 
         var str = "", r;
 
@@ -869,7 +923,7 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         if (isNaN(passedNumber)) return passedNumber;
         if (passedNumber === 0) return "0";
         let result = String(passedNumber);
-        
+
         result = result.replace(/0{3,}/g, (zeros) =>  '' + zeros.length % 9 + '|' + (zeros.length > 9 ? (zeros.length > 17 ? Math.floor(zeros.length / 9 ) + '>' : '>') : '') );
         result = result.replace(/[0-9]{2,}/g, (number) => toBase64(number) );
 
@@ -882,16 +936,40 @@ const {npcCompressor, npcDecompressor, childCompressor, childDecompressor } = (f
         if (passedString.length === 0 || passedString === "0") return 0;
         if (passedString === "NaN" || passedString === "Infinity") return Number(passedStr);
         let result = passedString;
-    
+        
         result = result.replace(/[a-zA-Z0-9_+]+/g, (group) => fromBase64(group));
         result = result.replace(/([0-9]+)>/g,(_str, p1) => "0".repeat( Number(p1) * 9 ));
         result = result.replace(/>/g,"9|");
         result = result.replace(/!/g,"");
         result = result.replace(/([0-9])\|/g, (_str, p1) => p1 > 0 ? "0".repeat( Number(p1)) : "0".repeat(9) ) ;
-    
+        
         return result;
     }
 
+
+	//Makes sure that the passed dates are valid. If they are not, then it assigns default values.
+    function verifyPassedDate(date = {day, month, year}) {
+        let returnDate, day, month, year;
+
+        if (!isNaN(date.day) && (date.day > 0 && date.day < 32) ) day = date.day.toString().padStart(2,"0");
+        else day = "01";
+
+        if (isNaN(date.month)) {
+            month = monthNameList.indexOf(date.month);
+            month = month > 0 ? month.toString().padStart(2,"0") : "01";
+        }
+        else if (!isNaN(date.month) && (date.day >= 0 && date.day < 12) ) month = date.month.toString().padStart(2,"0");
+        else month = "01";
+
+        if (!isNaN(date.year)) year = date.year.toString().padStart(4,"0");
+        else year = "0000";
+
+        returnDate = day + month + year;
+
+        return returnDate;
+    }
+
+
     return { npcCompressor, npcDecompressor, childCompressor, childDecompressor };
 })();
 window.npcCompressor = npcCompressor;
@@ -1223,46 +1301,60 @@ function compressionVerifier(npcList, result = true, detail = false, verboseDeta
 
     const {compareKeys, findDiffKeys, compareValues, findDiffValue, findByteSize, trun} = (function() {
 
-        //compares the keys of two objects to see if they are the same.
-        function compareKeys(a, b) {
-            var aKeys = Object.keys(a);
-            var bKeys = Object.keys(b);
-        
-            aKeys.forEach(key => {
-                if (typeof a[key] == "object") aKeys = aKeys.concat(Object.keys(a[key]));
-            })
-        
-            bKeys.forEach(key => {
-                if (typeof b[key] == "object") bKeys = bKeys.concat(Object.keys(b[key]));
+        //Gets all keys in an object, including those in a nested object
+        function getAllKeys(passedObject) {
+            let list = Object.keys(passedObject);
+            list.forEach(key => {
+                //console.log(`key: ${key}; type: ${typeof passedObject[key]}`);
+                if (typeof passedObject[key] == "object") list = list.concat(Object.keys(passedObject[key]));
             })
 
-			aKeys = aKeys.sort();
-			bKeys = bKeys.sort();
+            return list;
+        }
 
+        //compares the keys of two objects to see if they are the same.
+        function compareKeys(a, b) {
+            var aKeys = getAllKeys(a).sort();
+            var bKeys = getAllKeys(b).sort();
             return JSON.stringify(aKeys) === JSON.stringify(bKeys);
         }
-        
+
         //finds the different keys between two objects
-        function findDiffKeys(a, b) {
-            let list = []
+        function findDiffKeys(a, b, inObj = null, caught = []) {
             var aKeys = Object.keys(a).sort();
             var bKeys = Object.keys(b).sort();
-        
+            let str;
+
             aKeys.forEach(key => {
-                if (!bKeys.includes(key)) list.push( ("second list missing key: " + key).padEnd(38) + "\n");
+                str = `Second list missing key: ${key}`
+                if (typeof a[key] == "object") caught = caught.concat(findDiffKeys(a[key], b[key], key, caught)); 
+                if (inObj) str += ` in object ${inObj}`;
+
+                if (!bKeys.includes(key) && !caught.includes(key)) {
+                    caught.push(key);
+                    console.log( str.padEnd(38) + "\n");
+                }
             });
-        
+
             bKeys.forEach(key => {
-                if (!aKeys.includes(key) && !list.includes(key)) list.push(("first list missing key: " + key).padEnd(38) + "\n");
+                str = `First  list missing key: ${key}`
+                if (typeof b[key] == "object") caught = caught.concat(findDiffKeys(a[key], b[key], key, caught));
+
+                if (inObj) {str += ` in object ${inObj}`;}
+
+                if (!aKeys.includes(key) && !caught.includes(key)) {
+                    caught.push(key);
+                    console.log( str.padEnd(38) + "\n");
+                }
             });
-        
-            return list;
+
+            return caught
         }
         
-        //compares the values of two objects to see if they are the same.
+       //compares the values of two objects to see if they are the same.
         function compareValues(a, b) {
             let equal = true;
-        
+
             if (compareKeys(a,b)) { 
                 Object.keys(a).forEach(key => {
                     if (typeof a[key] == "object") equal = compareValues(a[key], b[key]);
@@ -1272,23 +1364,21 @@ function compressionVerifier(npcList, result = true, detail = false, verboseDeta
             else {
                 equal = false;
             }
-        
+
             return equal
         }
-        
+
         //finds the values that are different between two objects with the same keys
-        function findDiffValue(a, b) {
-            let list = []
-        
+        function findDiffValue(a, b, inObj = null) {
+            let temp = "";
+
             Object.keys(a).forEach(key => {
-                if (typeof a[key] == "object") findDiffValue(a[key], b[key]);
+                if (typeof a[key] == "object") findDiffValue(a[key], b[key], key);
                 else if (a[key] != b[key] ) {
-                    console.log(("missing key / key value: " + key).padEnd(38))
-                    list.push((key + ": a: " + a[key] +" b: " + b[key]).padEnd(38) + "\n");
+                    if (inObj) temp = ` in object ${inObj}`
+                    console.log(`Key ${key}${temp} has mismatched values. First list = ${a[key]} and second list = ${b[key]}`)
                 }
             });
-        
-            return list;
         }
 
         //finds the size of a passed string or object.
@@ -1353,18 +1443,25 @@ function compressionVerifier(npcList, result = true, detail = false, verboseDeta
             // console.log("decompression time:  " + trun(decopmressTime, 3).toString().padEnd(5, " ") + " miliseconds")
         }
 
-        if (!compareKeys(currentNPC,decompressedNPCString)) {
-            if (detail) console.log("keys");
-            textOutput = "" + findDiffKeys(currentNPC,decompressedNPCString);
-            returnOutput.push(false);
-        }
-        else if (!compareValues(currentNPC,decompressedNPCString)) {
-            if (detail) console.log("values");
-            textOutput = "" + findDiffValue(currentNPC,decompressedNPCString);
-            returnOutput.push(false);
+        let keyStatus = compareKeys(currentNPC,decompressedNPCString);
+        let valueStatus = compareValues(currentNPC,decompressedNPCString);
+
+        //console.log(`keyStatus: ${keyStatus}, valueStatus ${valueStatus}`);
+
+        if (!keyStatus || !valueStatus) {
+            if (!keyStatus) {
+                if (detail) console.log("\nKeys");
+                findDiffKeys(currentNPC,decompressedNPCString);
+                returnOutput.push(false);
+            }
+            if (!valueStatus) {
+                if (detail) console.log("\nValues");
+                findDiffValue(currentNPC,decompressedNPCString);
+                returnOutput.push(false);
+            }
         }
         else {
-            textOutput = "All keys and their values match for " + type + " " + key;
+            textOutput = "\nAll keys and their values match for " + type + " " + key;
             returnOutput.push(true);
         }