NESMaker Plugins Part 1

This post goes into detail on the NESMaker plugin system. It is assumed that you have a copy of NESMaker, you are familiar with all of it’s basic features, and you can write code in C#.

The first thing to do is grab this starter project: NESMakerPluginStarter. Load it into Visual Studio and look at the code. You will see what methods need to be implemented, and what methods should be modified.

At this point, Once you change a couple things that the comments in the code mention, you should be able to compile, copy your DLL into the NESMaker plugin folder, and test it out! Lets talk a little more about what each method does though. If you have the project open, you can follow along.

The first thing to examine isn’t even a method. It’s an attribute on your plugin class. It looks like this initially:

[ExportMetadata("ID", "YOURNAME/PLUGINNAME/PLUGIN_VERSION")]

This identifies your plugin to NESMaker and keeps it separate from all the other plugins out there. It is what allows NESMaker to locate your plugin and pass in all of the project information that you want to keep when the user loads and saves their project.

Next, comes the constructor and model.

 public PluginModel Model { get; set; }
 public NesMakerPlugin()
 {
 Model = new PluginModel();
 }

This is called when NESMaker initializes. Notice that we create an instance of your model class. This is where you should store any data that you want to save in the users project file.

The  NESMaker plumbing works by examining the node that the user clicks on, and then placing a UserControl in the work area. When the user clicks on a plugin node, NESMaker asks the plugin for something to display to the user. It does this via the GetControl(int offset) method. Just return an object derived from UserControl and you are good! The offset parameter lets your plugin know what node the user clicked on if you had more than one.

The whole point of NESMaker is to write asm for you, and the plugin will want to be able to write files as well. When the user decides to test her project, your plugin will want to generate all the needed .asm files. You can tell NESMaker all the files you want to write by returning a list of filenames from the GetExportFilenames() method. You will likely want your filenames to be named something that is specific to your plugin so that you do not accidentally get overwritten, or overwrite someone else’s file.

Once you have told NESMaker what filenames you want to export, it’s time to tell it the content of those files. NESMaker will call your Export(string filename) function once for every filename that you returned in GetExportFilenames(). I recommend writing header information at the top of the file so the user can verify when the file was last created.

The next couple functions are pretty self explanatory. Init(INesMaker app) gets called only once when NESMaker starts up. The key thing to notice is that it passes in an interface to itself. This is how you can communicate with NESMaker. I will give more information on this interface in the next post. Another thing to be aware of is that if you need to do something right before or right after you export your asm, you can hook into the Pre/PostBuild events.

The “int GetNodeCount()” method lets NESMaker know how many nodes you want. Most plugin writers will only want 1 node, but if your plugin is more complex, you might want multiple nodes. You have the power. Please don;t make this a huge number though as we wouldn’t want the plugin tree too cluttered.

The “string GetNodeName(int offset)” method should return the text that you want the user to see. It should be descriptive enough so the user will know that that node came from your plugin.

The “Image GetNodeIcon(int offset)” method does what it sounds like! It returns an image that will be used as the icon for your node. By default, I have included a file called PluginIcon.bmp, and placed it in your project as a resource. I recommend just painting over this with your icon art, and leaving the code alone. It’s easier that way. 🙂 Both GetNodeIcon, and GetNodeName are only ever called once, when NESMaker initializes.

The last 2 methods are Persist and Recall. This is how you save  your plugin information into the users Project file. Each method has either a BinaryWriter or a BinaryReader. The default implementation just calls your model’s persist and recall methods.  The important thing to consider here is that you must read the data back in the same order that it was written in.  For example, lets say that you had 3 pieces of data, X, Y, and NAME as properties in your model class.  To write those to the users project, you would say:

bw.Write(X);
bw.Write(Y);
bw.Write(NAME);

To read those values back in when the user loads their project, you would write:

X = br.ReadInt32();
Y = br.ReadInt32();
NAME = br.ReadString();

One last thing to consider is what you do when you upgrade your plugin… If you have a version 2 of your plugin, and it tries to load a version 1 of your user data, you do not want it to crash. To do this, put some if statements in your Recall() method so it only reads new properties if the save version is at a certain point.Something like this:

X = br.ReadInt32();
Y = br.ReadInt32();
NAME = br.ReadString();
if (fileVersion >= 2){
   MoreData = br.ReadInt32();
}

I hope this helps and motivates people to write plugins for NESMaker! If you have coded a cool technique, and want to support the community, put it in a plugin, and allow everyone to try it. Thanks to everyone for reading this, and good luck making your games!

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *