This framework is designed to make it as easy as possible for your to distribute mods and have them work with other mods. As this framework is developed, we will attempt to identify potential conflicts in mods.

The framework is attribute based, you'll be adding one of several custom attributes to your classes.

First steps for a mod

Load up Visual Studio and create a new Class Library (.NET Framework) DLL project targeting .NET Framework 2.0. This ensures Unity compatibility. I recommend Visual Studio Express 2017.

Download the patcher from above and install. Then add a reference to PWGR Framework.dll from your DLL project. This framework contains the attributes you need as well as provides a logging service and will be the basis for future helps classes.

If you need to access Unity classes, add a reference to the UnityEngine.dll in your FPW managed directory. If you need to access FPW classes, add a reference to the Assembly-CSharp.dll in your FPW managed directory.

It's helpful to change the build location to output to the FPW managed directory, so you don't have to move files around while testing.

Want to provide great descriptions in the patcher?

A key to making your mods easy to apply is making sure you use groups appropriately. Groups allow a user to combine a set of changes at once. They also give a simple name and description to help the user identify the feature.
Any attribute that you use can have a group parameter applied to it. The group parameter is a string and all changes that have a matching group will be turned on/off together in the patcher. This applies to ALL attributes. I recommend using a constant.

[FieldAccess(Class = "Cos_CmnConst", Field = "TeScaleMax", Group = GROUP_UNLOCK_SCALING)]

Additionally, you can provide a group description to give a nicer name and description. This is a class level attribute, although it does not need to be in any specific class.

[GroupDescription(Group = GROUP_SKIP_TO_MENU, Name = "Skip straight to game menu", Description = "This starts the game up at the game menu, it will skip all steam workshop updates and downloads. If 'Disable initial edit download' and 'Skip straight to game menu' are both selected, only 'Disable initial edit download' will be active.")]

Want to replace a method?

72ec8e5a-ddfa-4703-8fa3-27e8c19bb65a.png?asset_id=f95fa475-901e-497c-bca2-4a261dc305bb&img_etag=160ec35ee0750559879d73bd21694b37&size=1024
Method Replace Example
[Hook(TargetClass = "Menu_Title", TargetMethod = "Check_Demo", InjectFlags = (int) HookInjectFlags.ModifyReturn)]

This is a method attribute that should be applied to any static method in your mod. We say we want to modify the return value of a method and insert our new method at the very beginning. This example demonstrates us effectively removing a method by doing nothing, and as demonstrated works for void methods. The boolean return value of this method indicates if the we should return out of the calling method once we exit here. In this case we always return. In a case where you want to use the remaining behavior from the original method, you can return false.

This feature also supports InjectLocation and InjectDirectionFlags for indicating exactly where in the IL you would like to insert this call.

This feature also provides a way to pass the invoking instance, pass parameters, and pass local variables. Explanations

Want to change the access level of a variable or method?

Access Level Change Example
[FieldAccess(Class = "Cos_CmnConst", Field = "TeScaleMax", Group = GROUP_UNLOCK_SCALING)]

This is a class attribute that should be applied to any class in your mod. This turns the specific Field in the specified Class into a public variable.

Want to change the default value of a field?

6194aa67-e8f4-4ed1-bb5f-84b293df6bea.png?asset_id=f8ff3705-9d22-41d6-8b0f-3de07d20a09d&img_etag=897df802ffd77f71a1cebf927a2c752d&size=1024
Value Rewrite Example
This is a class attribute that should be applied to any class in your mod. This attribute modifies the constructor of that class so that it is initialized with a new default value. This is a little hokey and prone to breaking between versions of FPW. The location is the IL line in the constructor that sets the default value. I have only tested it with ints.

Want to add a GUI to your mod?

b0e5c075-4856-4c3f-ba1d-950523d37f37.png?asset_id=546b5fae-76bd-4c03-b286-c45f198c3544&img_etag=5b41e1e0ed9efd43f9a4d692a953ae63&size=1024
Control Panel Example
This is a method attribute that should be applied to a static method that returns a Form. This Form will be turned into an MDI child. Location and sizing will be saved/loaded by the framework.

Want to do stuff on the UI thread?

TBD. For now. There's some complications with the normal Windows UI thread. The PWGR Framework API will provide a mechanism to execute tasks through the Unity framework.

Hooking a method twice?

As of now, the methods will inject in the same order as they are in your code. Use this to figure out the correct location if hooking the same method multiple times. Future releases may make this more predictable. You can use max int for the location to go at the end of the method.

I want to log things.

DG.L.D(string message, params object formatObjects)

Want to allow PWGR Patcher to update your mods?

Version 1.0.79.0 and above, of the patcher, provide a mechanism to download and install mod updates. Future versions will contain a full mod repo so that user's can discover your mods through the patcher.

Contact moc.gdekim|rgwpekim#moc.gdekim|rgwpekim to get your mod repo added.

You will need to host a repo json file on a server somewhere. This repo will contain metadata for your mods. As of 8/10/2017, the only currently used fields are the DownloadUrl, Version, DllName, and ModName.

  • DownloadUrl is the url that the latest version will be downloaded from.
    • Download url should point to a zip file that has the full directory structure so it can be unzipped into the root Fire Pro directory. The example below includes a dll in the FireProWrestlingW_Data\Managed directory, where all mod dlls should wind up. It also packages an asset bundle in the FireProWrestlingW_Data\StreamingAssets directory.
image.png
  • Version is the version number of the latest version. This must correspond to the assembly file version number of your mod DLL or behavior will be unreliable.
  • ModName is the display name of your mod. This will be displayed in the patcher.
  • DllName is the file name of your dll. This will be used to check the version on the local machine.

The example below is a sample of a valid repo file.

[
  { "DownloadUrl" : "http://www.pwgrevenge.com/pwgr framework.zip",
    "Version": "10.0.0.0",
    "News": "Nothing new here",
    "DllName": "PWGR Framework.dll",
    "ModName": "PWGR Framework",
    "ModUrl": "http://www.pwgrevenge.com"
  },
  { "DownloadUrl" : "http://www.pwgrevenge.com/pwgr hook.zip",
    "Version": "10.0.0.0",
    "News": "Nothing new here",
    "DllName": "PWGR Public Hook.dll",
    "ModName": "PWGR Quality of Life Mods",
    "ModUrl": "http://www.pwgrevenge.com"
  },
  { "DownloadUrl" : "http://www.pwgrevenge.com/balloon.zip",
    "Version": "1.0.0.0",
    "News": "Nothing new here",
    "DllName": "DG Balloon Explosion Deathmatch Hook.dll",
    "ModName": "Balloon Explosion Deathmatch",
    "ModUrl": "http://www.pwgrevenge.com"
  }
]
  • ModUrl will be used in the future to provide a link to a web page for your mod.
  • News will be used in the future to surface news about your latest update.

If you have an idea for a new field, let me know.

The aseembly file version can be changed from your project properties as shown below.

image.png

When an update is available, the user will be notified by the (Update Available) text in the patcher. They will then be able to click the update button. Your latest update will be downloaded and unzipped.

image.png