Advanced Modding Guide/Reflection

Reflection is part of the .NET Framework, and can be used to access private/protected class members from another class (ie. your mod).

This article will walk you through the basics of Reflection (for the common things you'll need it for in Outward). If you want to skip to finding some helper methods, see the Reflection Helpers section below.

Publicized Assemblies
Instead of using Reflection, you can instead publicize the entire game assembly so that everything is public.

You can either use the standalone tool, or the BepInEx plugin to achieve this.

Importantly, you must allow Unsafe code in your CS project which you can do by simply opening the Properties for your project and ticking the box for it.

Reflection Helpers
It is common with Reflection to use a helper class, especially in projects which make heavy use of it.

For Outward, there are two common options used by the community:
 * Harmony's . Documentation can be seen here. Namespace is.
 * SideLoader's class. Documentation can be seen when using these methods in your IDE as Summaries. Namespace is.
 * See here for the source code.

When using these libraries, it will be different to the examples shown below. These libraries simplify the process or reflection for you.

If you need to use reflection directly yourself for whatever reason, continue reading.

Private Fields
Firstly, let's look at getting and setting a private Field on a class. In this case, we'll use the class.

Private Properties
For properties, you will very rarely find one without a public accessor, however it is not uncommon to find one with a private set method.


 * You should use dnSpy or similar tools to look at the property and see what is really going on, there may be a Field you can use instead.
 * To get a PropertyInfo, simply use . You do not need binding flags to get a PropertyInfo.

Private Methods
Using Reflection on Methods is also possible. For the most part, it's fairly straightforward, but there are two important things to keep in mind related to the arguments (also known as parameters) of the method.

Let's take a look at how to call a method. This is a simple method with no arguments.

Like FieldInfo and PropertyInfo, if the member is static then the target object should be null. In that case, it would look like.

With, it is possible that you can encounter an  in the case that there are multiple methods on the class with the same name. To avoid this exception, you can pass the of each argument in an object array, as shown in this next example.

Let's look at the method .. There are actually two methods with this name: one which expects a string _eventUID, int _stackAmount and a bool _sendEvent, and another method which expects a _event and an int _stackAmount. So what would the argument type array look like for these?

In the case that the method you want has no arguments, then use.