Skip to content

Commit

Permalink
Merge pull request #41 from Xilophor/touch-ups
Browse files Browse the repository at this point in the history
Touch-Ups and updated IDE instructions
  • Loading branch information
legoandmars authored Dec 18, 2023
2 parents c52864b + 78d5fc7 commit e57cdce
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 78 deletions.
3 changes: 2 additions & 1 deletion docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,6 @@ export default defineConfig({
editLink: {
pattern: 'https://github.com/LethalCompany/ModdingWiki/edit/main/docs/:path',
}
}
},
lastUpdated: true
})
119 changes: 62 additions & 57 deletions docs/advanced-modding/networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ Into something a bit less legible, but allows networking:
[ClientRpc]
public void EventClientRPC(string eventType)
{
NetworkManager networkManager = base.NetworkManager;
if (networkManager == null || !networkManager.IsListening)
{
return;
}
if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams clientRpcParams;
FastBufferWriter fastBufferWriter = base.__beginSendClientRpc(1302598205U, clientRpcParams, RpcDelivery.Reliable);
bool flag = eventType != null;
fastBufferWriter.WriteValueSafe<bool>(flag, default(FastBufferWriter.ForPrimitives));
if (flag)
{
fastBufferWriter.WriteValueSafe(eventType, false);
}
base.__endSendClientRpc(ref fastBufferWriter, 1302598205U, clientRpcParams, RpcDelivery.Reliable);
}
if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost))
{
return;
}
NetworkManager networkManager = base.NetworkManager; // [!code ++]
if (networkManager == null || !networkManager.IsListening) // [!code ++]
{ // [!code ++]
return; // [!code ++]
} // [!code ++]
if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost)) // [!code ++]
{ // [!code ++]
ClientRpcParams clientRpcParams; // [!code ++]
FastBufferWriter fastBufferWriter = base.__beginSendClientRpc(1302598205U, clientRpcParams, RpcDelivery.Reliable); // [!code ++]
bool flag = eventType != null; // [!code ++]
fastBufferWriter.WriteValueSafe<bool>(flag, default(FastBufferWriter.ForPrimitives)); // [!code ++]
if (flag) // [!code ++]
{ // [!code ++]
fastBufferWriter.WriteValueSafe(eventType, false); // [!code ++]
} // [!code ++]
base.__endSendClientRpc(ref fastBufferWriter, 1302598205U, clientRpcParams, RpcDelivery.Reliable); // [!code ++]
} // [!code ++]
if (this.__rpc_exec_stage != NetworkBehaviour.__RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost)) // [!code ++]
{ // [!code ++]
return; // [!code ++]
} // [!code ++]
// code here
}
```
Expand Down Expand Up @@ -88,23 +88,24 @@ The `NetworkHandler` houses the RPCs, Network Variables, and any other methods a

When creating the `NetworkHandler`, you must inherit the `NetworkBehaviour` class. This allows the script to utilize the networking methods.

```cs
```cs:line-numbers {11}
using System;
using Unity.Netcode;
using UnityEngine;
using Object = UnityEngine.Object;
namespace ExampleMod
namespace ExampleMod;
public class ExampleNetworkHandler : NetworkBehaviour // [!code focus:5]
{
public class ExampleNetworkHandler : NetworkBehaviour
{
public static ExampleNetworkHandler Instance { get; private set; }
}
public static ExampleNetworkHandler Instance { get; private set; }
}
```

We also add the one line of code to allow scripts to easily access any methods or variables, since in the case of our ExampleMod, there is only one version of this class. While you can just use:
We also add the one line of code to allow scripts to easily access any methods or variables, since in the case of our ExampleMod, there is only one version of this class.

While you can just use:

```cs
public static ExampleNetworkHandler Instance;
Expand Down Expand Up @@ -177,9 +178,9 @@ public override void OnNetworkSpawn()
{
LevelEvent = null;

if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
Instance?.gameObject.GetComponent<NetworkObject>().Despawn();
Instance = this;
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) // [!code ++]
Instance?.gameObject.GetComponent<NetworkObject>().Despawn(); // [!code ++]
Instance = this; // [!code ++]
base.OnNetworkSpawn();
}
Expand All @@ -189,37 +190,36 @@ public override void OnNetworkSpawn()

We finished! All that's left is to throw it all together into one script:

```cs
```cs:line-numbers
using System;
using Unity.Netcode;
using UnityEngine;
using Object = UnityEngine.Object;
namespace ExampleMod
namespace ExampleMod;
public class ExampleNetworkHandler : NetworkBehaviour // [!code focus:23]
{
public class ExampleNetworkHandler : NetworkBehaviour
public override void OnNetworkSpawn()
{
public override void OnNetworkSpawn()
{
LevelEvent = null;
LevelEvent = null;
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
Instance?.gameObject.GetComponent<NetworkObject>().Despawn();
Instance = this;
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
Instance?.gameObject.GetComponent<NetworkObject>().Despawn();
Instance = this;
base.OnNetworkSpawn();
}
base.OnNetworkSpawn();
}
[ClientRpc]
public void EventClientRpc(string eventName)
{
LevelEvent?.Invoke(eventName); // If the event has subscribers (does not equal null), invoke the event
}
[ClientRpc]
public void EventClientRpc(string eventName)
{
LevelEvent?.Invoke(eventName); // If the event has subscribers (does not equal null), invoke the event
}
public static event Action<String> LevelEvent;
public static event Action<String> LevelEvent;
public static ExampleNetworkHandler Instance { get; private set; }
}
public static ExampleNetworkHandler Instance { get; private set; }
}
```

Expand Down Expand Up @@ -283,7 +283,7 @@ public static void Init()
return;

networkPrefab = (GameObject)MainAssetBundle.LoadAsset("ExampleNetworkHandler");
networkPrefab.AddComponent<ExampleNetworkHandler>();
networkPrefab.AddComponent<ExampleNetworkHandler>(); // [!code ++]
}
```

Expand Down Expand Up @@ -311,7 +311,7 @@ public static void Init()
networkPrefab = (GameObject)MainAssetBundle.LoadAsset("ExampleNetworkHandler");
networkPrefab.AddComponent<ExampleNetworkHandler>();

NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
NetworkManager.Singleton.AddNetworkPrefab(networkPrefab); // [!code ++]
}
```

Expand All @@ -334,7 +334,7 @@ But wait, there's a catch: Only the host/server is allowed to spawn the network
[HarmonyPostfix, HarmonyPatch(typeof(StartOfRound), nameof(StartOfRound.Awake))]
static void SpawnNetworkHandler()
{
if(NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
if(NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) // [!code highlight]
{
var networkHandlerHost = Object.Instantiate(networkPrefab, Vector3.zero, Quaternion.identity)
networkHandlerHost.GetComponent<NetworkObject>().Spawn();
Expand All @@ -348,12 +348,17 @@ We want to attach this to `StartOfRound.Awake` as this method only runs when a n

Once we throw everything together, we get a class looking like this:

```cs
```cs:line-numbers
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
namespace ExampleMod;
[HarmonyPatch]
public class NetworkObjectManager
{

[HarmonyPostfix, HarmonyPatch(typeof(GameNetworkManager), nameof(GameNetworkManager.Start))]
[HarmonyPostfix, HarmonyPatch(typeof(GameNetworkManager), nameof(GameNetworkManager.Start))] // [!code focus:23]
public static void Init()
{
if (networkPrefab != null)
Expand Down Expand Up @@ -444,7 +449,7 @@ private static void NetcodeWeaver()

static void Awake()
{
NetcodeWeaver(); // ONLY RUN ONCE
NetcodeWeaver(); // ONLY RUN ONCE // [!code warning]
}
```

Expand Down
1 change: 1 addition & 0 deletions docs/extras/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This guide is mainly written by [Max](https://github.com/MaxWasUnavailable) & [B
### Developer / Tool Credits

- **BepInEx Contributors** for [BepInEx](https://github.com/BepInEx/BepInEx).
- **EvaisaDev** for [UnityNetcodeWeaver](https://github.com/EvaisaDev/UnityNetcodeWeaver).

Thank you to [everyone else](https://github.com/LethalCompany/ModdingWiki/graphs/contributors) that contributed to the guide on GitHub.

Expand Down
18 changes: 4 additions & 14 deletions docs/modding/initial-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,16 @@ To actually load mods into the game, we need a mod loader. This is where BepInEx

You'll first want to install BepInEx to your game. Follow their great [installation guide](https://docs.bepinex.dev/articles/user_guide/installation/index.html) to get this done. You'll want [this](https://github.com/BepInEx/BepInEx/releases/download/v5.4.22/BepInEx_x64_5.4.22.0.zip) version of BepInEx.

Once installation is complete, boot up the game once to have it generate some configuration files. Then, refresh the folder you just installed BepInEx into, and go into the `BepInEx/config` folder. Here, you'll find a file named `BepInEx.cfg`. Open it, and find and edit the following section:
Once installation is complete, boot up the game once to have it generate some configuration files. Then, refresh the folder you just installed BepInEx into, and go into the `BepInEx/config` folder. Here, you'll find a file named `BepInEx.cfg`. Open it, and find the `[Logging.Console]` section and make the following changes:

```ini
[Logging.Console]

## Enables showing a console for log output.
# Setting type: Boolean
# Default value: false
Enabled = false
```

to

```ini
[Logging.Console]

## Enables showing a console for log output.
# Setting type: Boolean
# Default value: false
Enabled = true
Enabled = false // [!code --]
Enabled = true // [!code ++]
```

### Decompiler (*highly recommended / near essential*)
Expand All @@ -89,7 +79,7 @@ There are a number of BepInEx plugins and tools that might be useful as you get

## Creating a GitHub account

We strongly recommend using git - a "version control system". The most popular website that offers this as a (free) service is GitHub; the website you're on right now.
We strongly recommend using git - a "version control system". The most popular website that offers this as a (free) service is [GitHub](https://github.com/).

The following video is a short primer on what git (and a version control systems in general) is: https://www.youtube.com/watch?v=2ReR1YJrNOM

Expand Down
62 changes: 56 additions & 6 deletions docs/modding/starting-a-mod.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Next, you'll want to create a new project (sometimes called "solution", in CShar

#### Using an IDE (more control)

Depending on your IDE, this process will look slightly different. You'll want to give the solution the name of your soon-to-be mod. If given the option to use a template (you may want to google for *"how to use template in `insert your IDE name here, for example "Rider" or "Visual Studio"`"*), use the `BepInEx 5 Plugin Template`.
Depending on your IDE, this process will look slightly different. You'll want to give the solution the name of your soon-to-be mod. If given the option to use a template (you may want to google for *"how to use template in Visual Studio"* or *"how to use template in Rider"*), use the `BepInEx 5 Plugin Template`.

#### Using the console (simpler)

Expand Down Expand Up @@ -60,13 +60,47 @@ name: BepInEx
url: https://nuget.bepinex.dev/v3/index.json
```

For Rider, you can do this by going to the NuGet window, going to its `Sources` tab, and then clicking on the green "+" icon in the `Feeds` sub-tab. There, add a new entry using the above configuration. See [Rider's docs](https://www.jetbrains.com/help/rider/Using_NuGet.html#sources) for more info.
::: details Visual Studio
For Visual Studio, you can do this by going to the NuGet Package Manager window and clicking on the settings/gear icon.

![Show Nuget Sources tab in Rider](/images/starting-a-mod/ridershownugetsources.png)
![View NuGet Packages in Visual Studio](/images/starting-a-mod/visualstudioviewnugetpackages.png)

![Rider Nuget Sources config with BepInEx added](/images/starting-a-mod/ridernugetfeeds.png)
![Show NuGet Project Settings in Visual Studio](/images/starting-a-mod/visualstudioshownugetsettings.png)

For Visual Studio, please follow [this documentation](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio#package-sources).
This will bring up an options modal; click on the `Package Sources` tab, and then click on the green "+" icon in the top right. From there, you can add a new entry using the above configuration.

![Visual Studio NuGet Sources config with BepInEx added](/images/starting-a-mod/visualstudionugetsources.png)

See [Visual Studios's docs](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio#package-sources) for more info.
:::
::: details Rider
For Rider, you can do this by going to the NuGet window, going to its `Sources` tab, and then clicking on the green "+" icon in the `Feeds` sub-tab. There, add a new entry using the above configuration.

![Show NuGet Sources tab in Rider](/images/starting-a-mod/ridershownugetsources.png)

![Rider NuGet Sources config with BepInEx added](/images/starting-a-mod/ridernugetfeeds.png)

See [Rider's docs](https://www.jetbrains.com/help/rider/Using_NuGet.html#sources) for more info.
:::
::: details VS Code
For VS Code, there is no built in method for NuGet Packages. The only way to add the BepInEx NuGet source is by modifying the `NuGet.Config` file in your project directory. Add the following code in the `<packageSources>` section:

```xml
<add key="BepInEx" value="https://nuget.bepinex.dev/v3/index.json" />
```

This should result in a complete file resembling the following:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="BepInEx" value="https://nuget.bepinex.dev/v3/index.json" /> // [!code ++]
</packageSources>
</configuration>
```

:::

### Making sure your mod is set up correctly

Expand All @@ -80,9 +114,25 @@ Our [template project](https://github.com/LethalCompany/LethalCompanyTemplate) h

Your IDE is capable of turning your code into a file that can be run (in this case by BepInEx as a mod). This process is called "building" or "compiling". In this case, it will turn your code into a `.dll` file. This file *is* your mod.

Depending on your IDE, the build button may be placed differently. For Rider, it is in the top right:
Depending on your IDE, the build button may be placed differently.

::: details Visual Studio
For Visual Studio, it is the green arrow button with your project name:

![Visual Studio's Build Project button](/images/starting-a-mod/visualstudiobuild.png)
:::
::: details Rider
For Rider, it is in the top right:

![Rider's Build Solution button](/images/starting-a-mod/riderbuild.png)
:::
::: details VS Code
VS Code has no built-in way of building a C# project, as VS Code is a lightweight code editor and not a IDE. In order to build a C# project, you instead have to download the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) extension.

After installing the extension, you can build by pressing `Ctrl+Shift+P`, typing in `Build` and selecting `.NET: Build`.

![VS Code's C# Dev Kit Build Solution command](https://code.visualstudio.com/assets/docs/csharp/build-tools/net-build-command.gif)
:::

Once built, you should be able to find the `.dll` file in your project's folder, in the following subfolder path (once again replacing `MyFirstPlugin` with the name you gave your mod/project): `MyFirstPlugin/bin/(Release or Debug)/netstandard2.1/MyFirstPlugin.dll`

Expand Down
Binary file modified docs/public/images/starting-a-mod/riderbuild.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/starting-a-mod/ridernugetfeeds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e57cdce

Please sign in to comment.