NESMaker Plugins Part 2

Hello and welcome to Part 2 of the NESMaker plugin guide! By now you have probably started your first plugin to give a better user experience than telling them to go in and edit your asm files by hand. You also might have run into a problem getting info from the base NESMaker model. Fear not! As of version 4.1.1, you will have access to almost everything available from the Project Settings dialog. Let’s talk about how to get there.

When your plugin starts up, you will be passed in an INesMaker interface. If you would like to access the project settings part of the model, it is all done through the ProcessCommand() method. The first thing you should do is check the version of NESMaker that your user is running. To do this, create a class that implements the INESCommand interface, and set the Action property to “GET VERSION”. Version 4.1 will return a blank string and will not support any other calls. Version 4.1.1 and above WILL support additional calls. You should see “4.1.1” (or a higher version) returned in the Result property.

Next, you should call ProcessCommand() with the Action property set to “GET COMMAND_LIST”. This will let you know if the commands that your plugin needs are available and if any newer commands have been added.

Here is a list of all the “GET” commands that you can call as of version 4.1.1. They all return a JSON object in the Result property.

* "GET PROJECT_LABELS"
* "GET PROJECT_TILESETS"
"GET PROJECT_SCRIPTS"
"GET PROJECT_USER_DEFINED_VARS"
"GET PROJECT_USER_CONSTANTS"
"GET PROJECT_ZERO_RAM"
"GET PROJECT_OVERFLOW_RAM"
"GET PROJECT_OBJECT_VARS"

Most of these commands do not require any additional information. There are 2 exceptions however! “GET PROJECT_LABELS” and “GET PROJECT_TILESETS” both require a JSON string to be set in the Target property of your request. To simplify a LOT of the JSON syntax stuff, I prefer to use the Newtonsoft.Json  dll. You can install it from the visual studio Nuget reference manager.

Let’s discuss “GET PROJECT_TILESETS” first. NESMaker has 7 types of tilesets. They are Main, Screen, Path, Monster, specialTiles, objectTiles, and HudTiles. These are located in different graphic banks. To specify the tilesets that I want information on, I need to pass in the graphic bank and the type. An example is shown below:

The key takeaway here is that you specify the extra info that the call needs in the JSON object, then convert it to a string and set the Target property. It might sound confusing, but once you use it a couple times, it will be second nature to you. Your response will be in the Result property. It will be in the form of a JSON object as well, so the easiest way to read it is with a call like this:

JObject jsonTilesets = JObject.Parse(response.Result);

Getting project labels is very similar. It however requires a field named “LabelOffset” as an int in the JSON object. That offset specifies what type of label you are interested in. 0=Tile Types, 1=Change Tile Types, etc…

Besides getting information from the NESMaker model, you can also SET. The table below gives a list of all the SET commands and the JSON parameters that they expect.

CommandParam NameParam Type

 SET PROJECT_LABEL  LabelOffset
ValueOffset
Label
int
int
int
 SET PROJECT_TILESET GraphicBank
TilesetID
TilesetType
DisplayName
BMPFile
int
int
string
string
string
 SET PROJECT_SCRIPT Name
Define
Script
string
string
string
 SET PROJECT_USER_DEFINED_VAR Name
Enabled
InitialValue
Notes
string
bool
int
string
 SET PROJECT_USER_CONSTANT Name
Enabled
InitialValue
Notes
string
bool
int
string
 SET PROJECT_ZERO_RAM Name
Enabled
Bytes
Notes
string
bool
int
string
 SET PROJECT_OVERFLOW_RAM Name
Enabled
Bytes
Notes
string
bool
int
string
 SET PROJECT_OBJECT_VARS Name
Enabled
TotalObjectCount
Notes
string
bool
int
string

I hope that this gives you a good start in working with the INesMaker.ProcessCommand() method. I plan on adding more functionality so that plugin writers will be able to add even greater functionality! Good luck making your games!

–Josh

 

 

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!

 

 

NESMaker Code management

Hey NESMakers!

First off, I want to thank everyone that has supported NESMaker. You guys are the best. I know everyone is excited about using the latest version. At the time that I am writing this 4.1 is about to be released! I thought this would be a great time to talk a little about code management. I know it’s not the sexiest thing to discuss, but I think that it will make your lives much easier as you become more familiar with NESMaker, and want to dig into the asm a little.

In previous versions of NESMaker, editing the asm could be stressful because if you make a change that breaks everything, you might be worried about getting back to a known good working point. I am writing this article to show you how easy it is to play around with different versions of the asm and see how it affects your game. I’ll show you how to flip back and forth between multiple versions, and how easy it is to back everything up in case you want to share it with other developers. This tutorial is written for 4.1, but most of it is still applicable to previous versions too! Let’s get started!

First off all, let’s start with  a brand new project.

Creating a new project

  1. Click on “File-New” from the menu.
  2. This will give you the dialog shown below. I like to start with Blank tiles, but you can choose whatever you like. Type in a folder name for your tilesets, and choose whatever starting module you like. I chose a module that I made. (I’ll show you how to do that in a future article!) But, you can select whatever you like.
  3. Next, lets save your project. Click File-Save, verify that you are in your “Projects” folder and give it a good name. I like to have my project name match, or be similar to the folder name that my tiles are in. You don’t have to though. It’s your game, so do what you like! The reason why I like to save right away is because it’s easy to forget what folder all of your tilesets are in so this keeps everything fresh in your mind.

At this point, you can start making your game! You can edit your tiles. You can start creating heroes, monsters, assets, whatever you like! Now lets say that you reach a point in your development where you want to play with changing the .asm files.  Great! Let’s stay safe though. The first thing we are going to do is make a copy of all the files that we might want to tweak. Then, when we work with them, if we ever want to go back to the original scripts, it’s very easy! This is how we do it.

Creating a backup of the script folder

  1. Click “File-Backup Script Folder” from the menu. This will show a dialog for creating a “ZipScript” file. It might look odd, but it will make a lot of sense. 
  2. Next, click on the ellipse for “Folder to Backup” and navigate to the “GameEngineData\Routines” folder. From there, navigate into the folder of the module you are working with. If you are making an adventure game, it might be the “adventure” folder. If it’s a platform game, it might be “platform”. If you are not sure, you can click on the “Project-Project Settings” menu option then go to the “Script Settings” tab. In the example below, you can see that all the scripts are in the “Basic” folder, so that is where I navigate to. Once there, don’t worry about clicking on a file; you are good.
  3. Now, you should verify two things. first, that you have selected the correct module folder. It’s always good to double check! Second, you’ll notice that the “Restore Root Location” has changed! This should reflect the folder that you picked. In my case, it says “Basic”.
  4. Next, Specify the location that you want to save the zip file. You can save this anywhere you like, but you might want to create a folder called “Backup” and save it there. That’s what I did. Just pick a good name for it that you’ll remember.
  5. Finally, because we want to keep our original scripts safe, we are going to change the name of the Restore Location Root. In this example, I want to remember that it is the first change from the original “Basic” set of scripts, so I named it “Basic.01”. Make sure you check the “Include Root Define” checkbox!
  6. Now, when you click “OK” it will create a normal zip file with All of your asm scripts in the correct place! You can use this like any other zip file. There is a special difference though! Inside this zip you will find an XML file. This xml contains instructions to NESMaker on how to link all those zip files to the defined scripts. That is where the magic happens. I’ll post another article in the future that gives more information on what each line does.

Restoring the backup

We are now reaching the fun part! Lets restore this backup so we can change the scripts without worrying about breaking everything.

  1. Click the “Project-Run Project Script” menu option.
  2. Select the zip file that you just created, and click OK.
  3. You should see a success dialog!
  4. The final step is to go to the “Project-Project Settings” menu option, and select the “Script Settings” tab. Verify that the “ROOT” is set to the location that you specified before when you created the zip file, and then click the “Update Root” button. This will update the location of all of your scripts to now point to the new folder specified in Root!
  5. Now try building and testing your application. It should run exactly like before. The only difference is that NESMaker is now using all the scripts in the new folder. You can now make any changes you like to the asm files and see how the changes are reflected in your game! If you want to go back to the way things were BEFORE you make any changes to your asm files, just select the “ROOT” entry in Project Settings, change it back to the previous value (In my case, it would say “Routines\Basic”) and then click The “Update Root” button again. It will all be back to normal!

Thanks for reading this guys! I hope that the level of detail was about right. If you think that it was too little, or too much, please let me know. If you would like a little more info on what is happening in that xml file, read on, and I’ll give some of the gory details! If you just want to backup up your files though, and keep them safe, you are good to go.

 

OK, I am assuming that if you are still reading, you are comfortable extracting the xml file from that zip file that you created, and have it opened in Notepad. In that zip file, there are two types of lines: The “AddAction / AddScript” line, and the “LinkAction/LinkScript” line. The AddAction line just tells NESMaker to extract the file specified in the “source” parameter from the zip file, and place it where “target” says. Simple! The LinkAction line just tells NESMaker to set an entry in Script settings that is specified in the display/label/param parameters. It is that easy! In fact, if you wanted to create a zip file by hand that only had that single zml file in it, and all that xml file had was LinkAction lines, you could very easily set all of your links with just a click. I’ll leave that for you to try out.

Thanks again guys! As always we appreciate your support, and I hope that this was helpful.