DynRPG  v0.14a
RM2k3 Plugin SDK
Rules and guidelines for plugin developers

Rules

The RPG Maker is written in Delphi (and I didn't have access to the source code of its classes, etc.), while my SDK uses C++. Thus, many things are not working the way you might expect.

There is a set of rules which you must follow under all circumstances when you are developing a DynRPG Plugin:

Guidelines

There is also a set of guidelines which you are strongly advised to follow, but there might be cases in which there is a better solution.

Event comments

Comments in event scripts are a great way to let events scripts invoke functions of your plugin. Please follow the following guidelines:

Use the parsedData parameter of your onComment handler to get the comment data in an already nicely parsed form!

Note:
The maximum number of parameters is 100. The maximum number of characters per parameter (or command name) is 200. You have to parse the comment yourself if you need more.

Example for a "special" comment:

@FooBar 123, "abc", V55, VV66, N7, NV8, Nothing

The command name is foobar.
The first parameter is numerical.
The second parameter is a string.
The third parameter is a numerical value read from variable #55.
The fourth parameter is a numerical value read from the variable whose ID is stored in variable #66.
The fifth parameter is a string, read from the name of actor #7.
The sixth parameter is a string, read from the name of the actor whose ID is stored in variable #8.
The seventh parameter is a token named nothing.

You might advise users to download RPG Maker 2009 Ultimate if they need to enter comments longer than 4 lines.

Configuration

Many plugins need some kind of configuration. An important rule is: Make as many things configurable as possible.

If possible, store configuration in a DynRPG.ini file. Also, you should use your plugin's name which you get as parameter to the onStartup function as section name. If you need several sections, you can append an underscore and an additional identifier to the name and use it as section name. This will prevent conflicts with other plugins while still combining all relevant configuration of a game in one file.

You may use the RPG::loadConfiguration function as a convenient way to load configuration data to a std::map<std::string, std::string> in the onStartup function.

If you need more or more complex configuration, like XML data, use a filename containing your plugin's name.

In-game data

Your plugin may also use data which is changed in-game and needs to be preserved. Savestate-independent data (like a highscore) should be stored in the DynRPG.ini file together with configuration (use the WinAPI function WritePrivateProfileString).

Savestate-related data (data which should be saved when the user saves the game and loaded when the use loads a saved game) should be saved using the function passed as savePluginData parameter to the onSaveGame function. When the user loads the savestate again, you will get the same data back, in the parameters to the onLoadGame function. Internally, this data is saved in a file called SaveXX.dyn where XX is the savestate ID.

An example usage of savestate-related plugin data is shown here:

// Plugin-related data
int score;
int level;

// ...

void onLoadGame(int id, char *data, int length) {
               if(length == sizeof(int) * 2) { // make sure it is valid data
                              int *dataArray = (int *)data;
                              score = dataArray[0];
                              level = dataArray[1];
               }
}

void onSaveGame(int id, void __cdecl (*savePluginData)(char *data, int length)) {
               int[2] dataArray;
               dataArray[0] = score;
               dataArray[1] = level;
               savePluginData((char *)dataArray, sizeof(dataArray));
}

(Of course, the same result could have been achieved by saving score and level in in-game variables which are automatically saved.)

Optimization

Time is a very important factor. Especially with many plugins, it is important to use as little time as possible in your callback handlers, otherwise the game will eventually start lagging. Thus, try to optimize your code where you can. If possible, always test your plugin with several other plugins in a "real-life situation" to see whether your plugin slows the game down too much. Remember that most of your code will be executed a minimum of 60 times per second (many parts more often than that, for example onCheckEventVisibility will be called 900 times per second if there are 150 events on the map).

Here is a bit of advice how to optimize your plugin code:

 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator