Skip to content

Added F# Support to BepInEx.PluginInfoProps#18

Open
wwwDayDream wants to merge 2 commits intoBepInEx:masterfrom
wwwDayDream:added/plugin-info-props/fsharp-support
Open

Added F# Support to BepInEx.PluginInfoProps#18
wwwDayDream wants to merge 2 commits intoBepInEx:masterfrom
wwwDayDream:added/plugin-info-props/fsharp-support

Conversation

@wwwDayDream
Copy link
Copy Markdown
Contributor

Expands functionality of BepInEx.PluginInfoProps' auto-generation.

I won't get into the debate of using F# to mod, but adding support is somewhat trivial, with the exception of F#'s dependency-based compilation order throwing a wrench in the plans. Thankfully, or maybe regrettably, detecting the language via project file extension is easy enough to then determine file contents, extension, and how we handle compilation insertion.

Traditionally, the <Compile> is all that's necessary, but FSharp's compiler will take that as the final file and so it won't be visible by any <Compile> files declared before it (which is all the .fsproj files). In order to avoid this, we store the compile into an interim item and reinsert it after we add MyPluginInfo's compile tag. Woohoo, just like that we supprt MyPluginInfo goodness in a few more mods in all of the ecosystem; but hey! "Functionality" (ᵖˡᵘˢ ⁱ'ᵈ ˡᵒᵛᵉ ⁱᵗ ˡᵒˡ)

@alardev
Copy link
Copy Markdown

alardev commented Mar 19, 2026

@wwwDayDream Holy crap, this nerd-sniped me. Have you tested any plugins with il2cpp backend games? any caveats or issues you've encountered since?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds F# support to the BepInEx.PluginInfoProps MSBuild-based MyPluginInfo auto-generation, including updated documentation.

Changes:

  • Detect project language via $(MSBuildProjectExtension) and generate either MyPluginInfo.cs or MyPluginInfo.fs.
  • Adjust F# compilation item ordering so the generated file is compiled before existing Compile items.
  • Update BepInEx.PluginInfoProps README with F# usage/output examples.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
BepInEx.PluginInfoProps/README.md Documents new F# support and shows example generated output.
BepInEx.PluginInfoProps/BepInEx.PluginInfoProps.props Adds language detection, F# codegen output, and compile ordering adjustments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<FileExtension Condition="$(MSBuildProjectExtension) == '.fsproj'">fs</FileExtension>
<FileExtension Condition="$(MSBuildProjectExtension) == '.csproj'">cs</FileExtension>
</PropertyGroup>
<Target Name="AddGeneratedFile" BeforeTargets="BeforeCompile;CoreCompile" Inputs="$(MSBuildAllProjects)" Outputs="$(IntermediateOutputPath)GeneratedFile.$(FileExtension)">
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The target Outputs path ($(IntermediateOutputPath)GeneratedFile.$(FileExtension)) doesn’t match the file actually written/included ($(IntermediateOutputPath)MyPluginInfo.$(FileExtension)). This prevents incremental build from correctly skipping the target and can cause it to run every build. Align Outputs with the real generated file path (or update GeneratedFilePath to match).

Suggested change
<Target Name="AddGeneratedFile" BeforeTargets="BeforeCompile;CoreCompile" Inputs="$(MSBuildAllProjects)" Outputs="$(IntermediateOutputPath)GeneratedFile.$(FileExtension)">
<Target Name="AddGeneratedFile" BeforeTargets="BeforeCompile;CoreCompile" Inputs="$(MSBuildAllProjects)" Outputs="$(IntermediateOutputPath)MyPluginInfo.$(FileExtension)">

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +5
Generates a `MyPluginInfo.cs`, or `.fs`, based on project tags.

Supports C# & F# projects, and will read the `.csproj` or `.fsproj` to determine values.
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README says it generates MyPluginInfo.cs, or .fs, but the build writes MyPluginInfo.$(FileExtension) (i.e., MyPluginInfo.fs). Also, the generated file includes a namespace $(RootNamespace) wrapper (see props), which isn’t reflected in either the C# or F# examples. Update the wording and samples so they match the actual generated output.

Copilot uses AI. Check for mistakes.
@@ -14,13 +16,23 @@ Define the following properties in your `csproj`:

this will generate the following class:
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text "this will generate the following class:" is no longer accurate for F# output (it generates a module). Consider rephrasing to something language-neutral (e.g., "this will generate the following code") or splitting wording per language section.

Suggested change
this will generate the following class:
this will generate the following code:

Copilot uses AI. Check for mistakes.
<FileExtension Condition="$(MSBuildProjectExtension) == '.fsproj'">fs</FileExtension>
<FileExtension Condition="$(MSBuildProjectExtension) == '.csproj'">cs</FileExtension>
</PropertyGroup>
<Target Name="AddGeneratedFile" BeforeTargets="BeforeCompile;CoreCompile" Inputs="$(MSBuildAllProjects)" Outputs="$(IntermediateOutputPath)GeneratedFile.$(FileExtension)">
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FileExtension is only set for .csproj/.fsproj, but the target still runs and unconditionally adds $(GeneratedFilePath) to @(Compile). If this .props is imported by another project type (e.g., .vbproj), $(FileExtension) will be empty and this can generate/include MyPluginInfo. (no extension), breaking the build. Add a target-level Condition (e.g., only run when $(FileExtension) is cs or fs) and/or set a safe default / emit a clear error for unsupported project types.

Suggested change
<Target Name="AddGeneratedFile" BeforeTargets="BeforeCompile;CoreCompile" Inputs="$(MSBuildAllProjects)" Outputs="$(IntermediateOutputPath)GeneratedFile.$(FileExtension)">
<Target Name="AddGeneratedFile" BeforeTargets="BeforeCompile;CoreCompile" Condition=" '$(FileExtension)' == 'cs' Or '$(FileExtension)' == 'fs' " Inputs="$(MSBuildAllProjects)" Outputs="$(IntermediateOutputPath)GeneratedFile.$(FileExtension)">

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants