Preface
Today we're going to build a CSV based stats editor for Feed and Grow Fish. This editor will allow you to trivially edit the stats using an external CSV file.
Can I see it in action?
Here's s companion video that shows off all of this in action:
Let's build a mod
Let's load Feed and Grow Fish into dnSpy so that we can begin to add the CSV editor into the game.
We need to get our code inserted into the right place.
Jump into your Assembly-CSharp.dll and click on the "FishSelectFilterButton" class which is within Assets.Code.UI.Extensions:
Within the FishSelectFitlerButton class you need to use the search functionality (control + f) to search for "NPCS". You are looking for the "LoadAll" function as seen below:
You need to click on the "LoadAll" orange text which will jump you over to that function. Upon clicking on it you should see something like this:
We need to edit this code. Right click anywhere in the page and select "Edit Class (C#)" as seen below:
Remove everything from within the "LoadAll" function (in other words, just the line that starts with return Resources.ConvertObjects), and replace it with the following block of code:
It should look something like this:
Let's scroll to the very top of the code, and replace the entire section that has "using xxx" with the following:
This will end up looking something like this:
The final thing we need to do as add some assembly references. Click the add assembly reference in the bottom left hand corner of the editor:
This will open a browse to window. You need to add the "Assembly-CSharp.dll" and "UnityEngine.Networking.dll", this can be done using the button twice:
Finally press the compile button in the lower right hand corner of the code editor.
We can now save our changes. Select "File" and then "Save All...", and then press "OK" to override the DLL and save our changes.
You can now close the game and there will be a stats.csv file in the root directory of your Feed and Grow Fish game.
Edit the stats.csv file using Microsoft Excel or any other text editor, save it, and make sure to close the editor. If you don't close the editor then Feed and Grow Fish may error out and not let you select any fish.
All of the stat changed you made will be applied to the fish.
Once again, if you have any questions, let us know below, or on the video.
We need to get our code inserted into the right place.
Jump into your Assembly-CSharp.dll and click on the "FishSelectFilterButton" class which is within Assets.Code.UI.Extensions:
Within the FishSelectFitlerButton class you need to use the search functionality (control + f) to search for "NPCS". You are looking for the "LoadAll" function as seen below:
You need to click on the "LoadAll" orange text which will jump you over to that function. Upon clicking on it you should see something like this:
We need to edit this code. Right click anywhere in the page and select "Edit Class (C#)" as seen below:
Remove everything from within the "LoadAll" function (in other words, just the line that starts with return Resources.ConvertObjects), and replace it with the following block of code:
// Load in the resources that were requested T[] array = Resources.ConvertObjects<T>(Resources.LoadAll(path, typeof(T))); // Did we request the NPCS?
if (path == "NPCS") {
// Does a stats file already exist? if (File.Exists("stats.csv")) {
// Yes a stats file exists
// Read in the stats CSV file and split it up into an array with one line as each entry string[] array2 = File.ReadAllText("stats.csv").Replace("\"", "").Split(new char[] { '\n' });
// Loop over each NPC foreach (LivingEntity livingEntity in array as LivingEntity[]) {
// Search the CSV for the NPC we are currently dealing with string[] array3 = null; string[] array4 = array2;
// Loop over each line in the CSV for (int i = 0; i < array4.Length; i++) {
// Split the line based on a comma string[] array5 = array4[i].Split(new char[] { ',' });
// Was this the fish we are currently dealing with? if (array5[0] == livingEntity.name) {
// Yep, grab it, and stop looping array3 = array5; break; } }
// Did we find the fish in our CSV? if (array3 != null) {
// Yes we found the fish
// Apply all of the properties from the CSV
// Some are floats, some are ints, we are just parsing the CSV livingEntity.AttackSpeed = float.Parse(array3[1]); livingEntity.AdditiveMaxEggs = int.Parse(array3[2]); livingEntity.Anger = float.Parse(array3[3]); livingEntity.CurrentSpeed = float.Parse(array3[4]); livingEntity.DamageStat = float.Parse(array3[5]); livingEntity.DefaultFocus = float.Parse(array3[6]); livingEntity.EggsInside = int.Parse(array3[7]); livingEntity.Health = float.Parse(array3[8]); livingEntity.HealthStat = float.Parse(array3[9]); livingEntity.MaxTemp = float.Parse(array3[10]); livingEntity.MinTemp = float.Parse(array3[11]); livingEntity.MinSize = float.Parse(array3[12]);
// Handle the mouth, just need to apply it correctly string a = array3[13]; if (!(a == "Beak")) { if (!(a == "Teeth")) { if (a == "Empty") { livingEntity.Mouth = ActiveThing.MouthType.Empty; } } else { livingEntity.Mouth = ActiveThing.MouthType.Teeth; } } else { livingEntity.Mouth = ActiveThing.MouthType.Beak; }
// Handle some more attributes: livingEntity.MovemSpeed = float.Parse(array3[14]); livingEntity.RoamStrenght = float.Parse(array3[15]); if (livingEntity is Fish) { (livingEntity as Fish).RotationSpeed = float.Parse(array3[16]); }
// Handle the skin type a = array3[17];
if (!(a == "Leather"))
{
if (!(a == "Plate"))
{
if (a == "Scale")
{
livingEntity.Skin = ActiveThing.SkinType.Scale;
}
}
else
{
livingEntity.Skin = ActiveThing.SkinType.Plate;
}
}
else
{
livingEntity.Skin = ActiveThing.SkinType.Leather;
}
}
}
}
else
{
// No, a stats file doesn't exist
// Create the header for the CSV file string text = "Name,"; text += "AttackSpeed,"; text += "AdditiveMaxEggs,"; text += "Anger,"; text += "CurrentSpeed,"; text += "DamageStat,"; text += "DefaultFocus,"; text += "EggsInside,"; text += "Health,"; text += "HealthStat,"; text += "MaxTemp,"; text += "MinTemp,"; text += "MinSize,"; text += "Mouth,"; text += "MovemSpeed,"; text += "RoamStrenght,"; text += "RotationSpeed,"; text += "Skin"; text += Environment.NewLine;
// Loop over every entity that we loaded from above foreach (LivingEntity livingEntity2 in array as LivingEntity[]) {
// Add the fields into the CSV text = text + livingEntity2.name + ","; text = text + livingEntity2.AttackSpeed + ","; text = text + livingEntity2.AdditiveMaxEggs + ","; text = text + livingEntity2.Anger + ","; text = text + livingEntity2.CurrentSpeed + ","; text = text + livingEntity2.DamageStat + ","; text = text + livingEntity2.DefaultFocus + ","; text = text + livingEntity2.EggsInside + ","; text = text + livingEntity2.Health + ","; text = text + livingEntity2.HealthStat + ","; text = text + livingEntity2.MaxTemp + ","; text = text + livingEntity2.MinTemp + ","; text = text + livingEntity2.MinSize + ","; text = text + livingEntity2.Mouth + ","; text = text + livingEntity2.MovemSpeed + ","; text = text + livingEntity2.RoamStrenght + ",";
// Are we dealing with a fish? if (livingEntity2 is Fish) {
// Yep, we are dealing with a fish, allow rotation speed to be edited text = text + (livingEntity2 as Fish).RotationSpeed + ","; } else {
// Nope, we are not dealing with a fish, this isnt applicable text += "N/A,"; }
// Add the remaining fields and a new line text += livingEntity2.Skin; text += Environment.NewLine; }
// Save the CSV File.WriteAllText("stats.csv", text); } } return array;
It should look something like this:
Let's scroll to the very top of the code, and replace the entire section that has "using xxx" with the following:
using System; using System.IO; using System.Runtime.CompilerServices; using Assets.Code; using Assets.Code.Things; using UnityEngineInternal;
This will end up looking something like this:
The final thing we need to do as add some assembly references. Click the add assembly reference in the bottom left hand corner of the editor:
This will open a browse to window. You need to add the "Assembly-CSharp.dll" and "UnityEngine.Networking.dll", this can be done using the button twice:
Finally press the compile button in the lower right hand corner of the code editor.
We can now save our changes. Select "File" and then "Save All...", and then press "OK" to override the DLL and save our changes.
How do I use the mod?
With the mod installed, you need to launch the game, load a map, and access the menu where you select a fish.You can now close the game and there will be a stats.csv file in the root directory of your Feed and Grow Fish game.
Edit the stats.csv file using Microsoft Excel or any other text editor, save it, and make sure to close the editor. If you don't close the editor then Feed and Grow Fish may error out and not let you select any fish.
All of the stat changed you made will be applied to the fish.
Once again, if you have any questions, let us know below, or on the video.