Visual Studio Tips - PULSAR-Modders/pulsar-mod-loader GitHub Wiki

Auto-Copy to Mods Dir on Build

Instead of manually copying DLLs to the Mods directory, MSBuild Targets can do it automatically after each successful build. This saves a lot of copy/paste effort during rapid development. There are two ways to handle this, best used by single developers and multiple developers of the same project respectively.

For solo developers

Enter project > Properties > Build Events. Copy paste the following batch code into the text field for Post-Build events. Next, edit the MOD_DIR variable to target your mods folder.

If the game is running and this code tries copying over an existing mod, there will likely be an exception preventing the code from executing properly. Sequential builds which do not rebuild the output files will not execute the code, so you will need to hit the rebuild button or set the build event to always run.

SET MOD_DIR="C:\Program Files (x86)\Steam\steamapps\common\PULSARLostColony\Mods\"

IF EXIST %MOD_DIR% (
    ECHO Copying DLLs to Mods directory...
    XCOPY /Y /F "$(TargetPath)" %MOD_DIR%
)

For multiple developers

First, use Command Prompt to set the PULSAR_PATH environment variable to the directory containing PULSAR_LostColony.exe, and then restart Visual Studio. This helps keep things flexible when working with other developers who might use a different install path.

setx PULSAR_PATH "C:\Program Files (x86)\Steam\steamapps\common\PULSARLostColony"

Next, edit the .csproj as an XML/text file, scroll to the bottom, then paste the following before the </project> end tag:

<!-- Copy extra files from solution dir to output dir (e.g., README.md) -->
<Target Name="CopyMarkdownFiles" AfterTargets="AfterBuild">
  <CreateItem Include="$(SolutionDir)\*.md">
    <Output TaskParameter="Include" ItemName="MarkdownFiles" />
  </CreateItem>
  <Copy SourceFiles="@(MarkdownFiles)" DestinationFiles="@(MarkdownFiles->'$(OutDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<!-- Copy select files from output dir to Mods dir -->
<Target Name="DeployMod" AfterTargets="CopyMarkdownFiles" Condition="'$(PULSAR_PATH)' != ''">
  <Error Condition="!Exists('$(PULSAR_PATH)')" Text="PULSAR_PATH set but directory doesn't exist!  Ensure the path is right: PULSAR_PATH='$(PULSAR_PATH)'" />
  <CombinePath BasePath="$(PULSAR_PATH)" Paths="PULSAR_LostColony_Data\Managed" >
    <Output TaskParameter="CombinedPaths" PropertyName="ManagedDir"/>
  </CombinePath>
  <CombinePath BasePath="$(PULSAR_PATH)" Paths="Mods" >
    <Output TaskParameter="CombinedPaths" PropertyName="ModsDir"/>
  </CombinePath>
  <CreateItem Include="$(TargetDir)\*.md">
    <Output TaskParameter="Include" ItemName="MarkdownFiles" />
  </CreateItem>
  <CreateItem Include="$(TargetDir)\*.dll*">
    <Output TaskParameter="Include" ItemName="Assemblies" />
  </CreateItem>
  <Message Importance="High" Text="Copying build output to Mods directory: $(ModsDir)" />
  <Copy SourceFiles="@(MarkdownFiles)" DestinationFiles="@(MarkdownFiles->'$(ModsDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
  <Copy SourceFiles="@(Assemblies)" DestinationFiles="@(Assemblies->'$(ModsDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>

To create new variables, extend the <PropertyGroup> section and refer to it as $(ElementName) (e.g., <ManagedDir> -> $(ManagedDir)). This is useful to keep things readable and easy to update, especially when reusing the same values in multiple locations.

For variables that combine file paths, use <CombinePath> instead. This saves headaches over slash types, trailing slashes, etc.

To change what gets included or excluded, add/update <CreateItem> sections and <Copy ...> elements. Wildcards are allowed. $(TargetDir) refers to the original build output directory, so <CreateItem> will almost certainly use it for Include and Exclude.

See also

Troubleshooting

  • Was the path surrounded with double quotes (") when running setx?
  • PULSAR_PATH is definitely right, but Visual Studio doesn't pick up on it.
    • Restart Visual Studio. Like Command Prompt, VS doesn't noticed changes to environment variables while it's running.

Reducing Number of DLLs in Project Output Directory

Most assemblies referenced by PULSAR mods are already part of the game or .NET in general, so only the mod and "non-standard" assemblies need to be distributed. However, Visual Studio's default behavior is to copy all relevant assemblies to the output folder, so it may be too cluttered and confusing to decide what to distribute. This can be changed so only important assemblies are copied, making distribution more straight forward.

In the Solution Explorer, expand the mod project > References. Highlight undesired references > right click > Properties, then set Copy Local: False. Subsequent builds will not copy those assemblies, making it easier to pick files for distribution.

Copy Local: False

In general, only assemblies specially added to your project need to be distributed (e.g., custom libraries or added via NuGet). Some common assemblies that don't need to be copied:

  • 0Harmony.dll
  • Assembly-*.dll
  • Pulsar.Assemblies.dll
  • PulsarModLoader.dll
  • System*.dll
  • Unity*.dll
⚠️ **GitHub.com Fallback** ⚠️