Compare commits
4
Commits
master
..
ce3b6e9298
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce3b6e9298 | ||
|
|
4c3c8a0348 | ||
|
|
6ce991f44b | ||
|
|
7f0024a212 |
@@ -13,6 +13,11 @@ dotnet_sort_system_directives_first = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_prefer_braces = true:suggestion
|
||||
|
||||
# Naming and language conventions here reflect this project's own style; they
|
||||
# do not by themselves enforce the "no unsolicited comments" / "English by
|
||||
# default" rules in CLAUDE.md, which apply to any human or AI contributor
|
||||
# regardless of what an analyzer can mechanically check.
|
||||
|
||||
[*.{csproj,json,yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
+2
-427
@@ -1,429 +1,4 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
bin/
|
||||
obj/
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.env
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
|
||||
[Dd]ebug/x64/
|
||||
[Dd]ebugPublic/x64/
|
||||
[Rr]elease/x64/
|
||||
[Rr]eleases/x64/
|
||||
bin/x64/
|
||||
obj/x64/
|
||||
|
||||
[Dd]ebug/x86/
|
||||
[Dd]ebugPublic/x86/
|
||||
[Rr]elease/x86/
|
||||
[Rr]eleases/x86/
|
||||
bin/x86/
|
||||
obj/x86/
|
||||
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
[Aa][Rr][Mm]64[Ee][Cc]/
|
||||
bld/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Build results on 'Bin' directories
|
||||
**/[Bb]in/*
|
||||
# Uncomment if you have tasks that rely on *.refresh files to move binaries
|
||||
# (https://github.com/github/gitignore/pull/3736)
|
||||
#!**/[Bb]in/*.refresh
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
*.trx
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Approval Tests result files
|
||||
*.received.*
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
.artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.idb
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
# but not Directory.Build.rsp, as it configures directory-level build defaults
|
||||
!Directory.Build.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
**/.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
**/.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
**/.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
**/__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
#tools/**
|
||||
#!tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
MSBuild_Logs/
|
||||
|
||||
# AWS SAM Build and Temporary Artifacts folder
|
||||
.aws-sam
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
**/.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
**/.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
**/.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
@@ -7,8 +7,13 @@
|
||||
"isVisible": "true"
|
||||
},
|
||||
{
|
||||
"id": "PluginDescription",
|
||||
"name": { "text": "Plugin Description" },
|
||||
"id": "skipRestore",
|
||||
"name": { "text": "Skip Restore" },
|
||||
"isVisible": "true"
|
||||
},
|
||||
{
|
||||
"id": "SkipGit",
|
||||
"name": { "text": "Skip Git" },
|
||||
"isVisible": "true"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/template",
|
||||
"classifications": [ "Common", "Library", "SCP:SL", "LabAPI", "Game Plugin" ],
|
||||
"identity": "SCP.PluginTemplate",
|
||||
"identity": "SCPSL.LabApi.PluginTemplate",
|
||||
"name": "SCP: Secret Laboratory LabAPI Plugin",
|
||||
"shortName": "labapi-plugin",
|
||||
"tags": {
|
||||
@@ -10,47 +10,48 @@
|
||||
},
|
||||
"sourceName": "LabApiPluginTemplate",
|
||||
"preferNameDirectory": true,
|
||||
"sources": [
|
||||
{
|
||||
"source": "./content",
|
||||
"target": "./"
|
||||
}
|
||||
],
|
||||
"symbols": {
|
||||
"PluginAuthor": {
|
||||
"type": "parameter",
|
||||
"datatype": "string",
|
||||
"defaultValue": "Your Name",
|
||||
"defaultValue": "YourName",
|
||||
"replaces": "YourName",
|
||||
"description": "Name used as the plugin's author."
|
||||
"description": "Name used as the plugin's author (EntryPoint's Author property)."
|
||||
},
|
||||
"PluginDescription": {
|
||||
"skipRestore": {
|
||||
"type": "parameter",
|
||||
"datatype": "string",
|
||||
"defaultValue": "Your Description",
|
||||
"replaces": "TODO: describe what this plugin does.",
|
||||
"description": "Short description of what the plugin does."
|
||||
"datatype": "bool",
|
||||
"description": "If set, skips running 'dotnet restore' automatically after creating the project.",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
"SkipGit": {
|
||||
"type": "parameter",
|
||||
"datatype": "bool",
|
||||
"description": "If set, skips printing the reminder to initialize a git repository.",
|
||||
"defaultValue": "false"
|
||||
}
|
||||
},
|
||||
"primaryOutputs": [
|
||||
{ "path": "LabApiPluginTemplate/LabApiPluginTemplate.csproj" }
|
||||
{ "path": "LabApiPluginTemplate.csproj" }
|
||||
],
|
||||
"postActions": [
|
||||
{
|
||||
"description": "Adds the generated project to the nearest solution file, if one exists.",
|
||||
"manualInstructions": [
|
||||
{ "text": "Run 'dotnet sln add' manually to add the project to your solution." }
|
||||
],
|
||||
"actionId": "D396686C-DE0E-4DE6-906D-291CD29FC5DE",
|
||||
"continueOnError": true
|
||||
},
|
||||
{
|
||||
"description": "Restores the NuGet packages required by this project.",
|
||||
"condition": "(!skipRestore)",
|
||||
"description": "Restores the NuGet packages required by this project (including LabAPI).",
|
||||
"manualInstructions": [
|
||||
{ "text": "Run 'dotnet restore'" }
|
||||
],
|
||||
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
|
||||
"continueOnError": true
|
||||
},
|
||||
{
|
||||
"condition": "(!SkipGit)",
|
||||
"description": "This project is not a git repository yet.",
|
||||
"manualInstructions": [
|
||||
{ "text": "Run 'git init && git add -A && git commit -m \"Initial commit\"'" }
|
||||
],
|
||||
"actionId": "AC1156F7-BB77-4DB8-B28F-24EEBCCA1E5C",
|
||||
"continueOnError": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This repo **is** a `dotnet new` project template (identity `SCPSL.LabApi.PluginTemplate`,
|
||||
shortName `labapi-plugin`), not a runnable plugin. It scaffolds SCP: Secret Laboratory
|
||||
LabAPI plugins.
|
||||
|
||||
The next section only applies while you're editing **this template repository**
|
||||
(i.e. a `.template.config/` folder is present next to this file). It does not apply
|
||||
if you're instead looking at a plugin someone already generated from this template —
|
||||
that folder never contains `.template.config/`, and its `EntryPoint.cs`/`Config.cs`
|
||||
are ordinary project files at that point, not template scaffolding.
|
||||
|
||||
## Repo is template *source* — read before touching any file
|
||||
|
||||
`.template.config/template.json` sets this folder's name as the template's
|
||||
`sourceName` and defines one text-replacement `symbol`, `PluginAuthor` (plus
|
||||
`skipRestore` and `SkipGit`, which only toggle post-generation actions and replace no
|
||||
text). The dotnet templating engine does a literal, repo-wide **string replacement**
|
||||
at generation time — not semantic renaming — driven by that config:
|
||||
|
||||
- The folder/project name (`sourceName` in `template.json`, currently this repo's own
|
||||
folder name) → whatever `-n`/`--name` the consumer passes to `dotnet new`.
|
||||
- The placeholder value of the `PluginAuthor` symbol (the string currently sitting in
|
||||
`EntryPoint.cs`'s `Author` property) → the consumer's `--PluginAuthor`.
|
||||
|
||||
Open `template.json` to see the exact current literal for each — don't hardcode them
|
||||
again here or anywhere else in prose, because this file itself ships inside every
|
||||
generated project and any exact match gets rewritten too (self-referential text like
|
||||
"the project is called X" would silently turn into nonsense after generation).
|
||||
|
||||
Consequences:
|
||||
- Never introduce an exact match of one of those two literals elsewhere in the repo
|
||||
unless you intend it to be substituted too.
|
||||
- If you add a new thing that should be configurable at generation time, add a symbol
|
||||
to `template.json` (`type: parameter`, `replaces: "<literal>"`) instead of
|
||||
hardcoding a magic string.
|
||||
- `EntryPoint` and `Config` (the class names) are **not** substituted and must stay
|
||||
literally named that — LabAPI's `PluginLoader` discovers plugins by type
|
||||
inheritance, not by name, and the file names `EntryPoint.cs`/`Config.cs` are a fixed
|
||||
part of this template's contract. Only the *namespace* tracks the project name.
|
||||
|
||||
## Repo layout (only what affects decisions)
|
||||
|
||||
- `.template.config/template.json` — template identity, the symbols above plus
|
||||
`SkipGit` (a display-only toggle, see below), `primaryOutputs` (points at the
|
||||
project file using its pre-substitution literal name — that's correct and expected,
|
||||
not a bug), and two `postActions`: the standard dotnet-templating "restore NuGet
|
||||
packages" action (id `210D431B-...`; skipped in Visual Studio, which restores on
|
||||
its own) and a "display manual instructions" action (id `AC1156F7-...`) that prints
|
||||
a reminder to run `git init` — see "Git on generation" below for why it's just a
|
||||
printed reminder and not an executed command.
|
||||
- `.template.config/ide.host.json` — Visual Studio-only UI hints for the New Project
|
||||
wizard. It does **not** rename any symbol (the CLI flags stay `PluginAuthor`/
|
||||
`skipRestore`/`SkipGit` — a flag can't contain a space); it only maps each symbol's
|
||||
`id` to a human-readable `name.text` label (e.g. `SkipGit` → "Skip Git") shown in
|
||||
VS's UI, via `isVisible: "true"` per entry (VS hides a symbol from that UI unless
|
||||
explicitly marked visible here). Ignored entirely by `dotnet new` on the CLI.
|
||||
- The `.csproj` at the repo root — the project file every generated plugin ships with.
|
||||
- `EntryPoint.cs` / `Config.cs` — the scaffolded plugin (`Plugin<Config>`) and its
|
||||
YAML-backed settings class.
|
||||
- `.editorconfig` — formatting/naming only (indentation, brace style). It does **not**
|
||||
enforce the comment/language rules below — those aren't analyzer-checkable.
|
||||
- No `.sln`, no test project, no CI, no packaging (`.nupkg`) project, no GitHub
|
||||
Copilot instructions file currently exist in this folder. Don't assume any of them.
|
||||
This repo itself does have its own git history (see `git log`) — that's unrelated
|
||||
to whether a *generated* project gets one, which is what "Git on generation" below
|
||||
covers.
|
||||
|
||||
## Git on generation — why there's no automated `git init`
|
||||
|
||||
A generated project is **not** a git repository by default; a `postAction` only
|
||||
prints a reminder to run `git init && git add -A && git commit -m "Initial commit"`.
|
||||
This was a deliberate choice after testing the alternative:
|
||||
|
||||
- `dotnet new`'s only postAction capable of running an arbitrary process is the
|
||||
"Run script" action (id `3A7C4B45-...`). Actually wiring it to run `git init`/
|
||||
`git add`/`git commit` was tested and it **hangs forever** in any non-interactive
|
||||
shell: the CLI's script-execution security gate demands an explicit `Y` typed at a
|
||||
`Do you want to run this action [Y(yes)|N(no)]?` prompt, once per script action,
|
||||
with no flag on this SDK to pre-approve it — unlike the NuGet-restore postAction,
|
||||
which the CLI treats as trusted and never gates. Do not reintroduce "Run script"
|
||||
postActions for this without re-verifying that gate no longer applies.
|
||||
- Visual Studio's own "New Project" dialog already has a built-in "Create new Git
|
||||
repository" checkbox that works for any template, including this one, with zero
|
||||
template-side configuration — so VS users get this for free regardless.
|
||||
- CLI users see the printed reminder above (governed by the `SkipGit` symbol) and run
|
||||
the one-liner themselves.
|
||||
|
||||
## LabAPI contract (verified against northwood-studios/LabAPI source, not guessed)
|
||||
|
||||
`Plugin<TConfig>` (`LabApi.Loader.Features.Plugins`) requires implementing:
|
||||
`Name`, `Description`, `Author`, `RequiredApiVersion` (all abstract get-only) plus
|
||||
`Enable()`/`Disable()`. Overridable but optional: `Version` (defaults to the
|
||||
assembly's version), `Priority` (`LoadPriority`, defaults to `Medium`),
|
||||
`ConfigFileName` (defaults to `"config.yml"`). `Config` is a plain `class` with a
|
||||
public parameterless constructor and public get/set properties — the base class
|
||||
(de)serializes it via YamlDotNet automatically; don't hand-roll config I/O.
|
||||
|
||||
**Never invent a LabAPI class/namespace/method/property/attribute.** Before using one
|
||||
you haven't already seen in this repo, check the restored package (`LabApi.dll` +
|
||||
`LabApi.xml` under `%userprofile%\.nuget\packages\northwood.labapi\<version>\lib\net48\`)
|
||||
or https://github.com/northwood-studios/LabAPI. If you can't verify a member exists,
|
||||
say so instead of guessing. No Skill/plugin specific to C#, .NET, MSBuild, NuGet, or
|
||||
LabAPI exists in the Claude Code skill catalog as of this writing — check
|
||||
`ToolSearch`/`SearchSkills` for one before editing in case that has changed, but don't
|
||||
assume one exists.
|
||||
|
||||
## Toolchain choices — don't "fix" these without being asked
|
||||
|
||||
- The project's `TargetFramework` is `netstandard2.1` on purpose, even though
|
||||
LabAPI's own docs and the `Northwood.LabAPI` NuGet package only target
|
||||
`net48`/`net481`. This is a deliberate compatibility choice (compiled output still
|
||||
loads under the game's Mono/.NET Framework 4.8 host) that trades away some
|
||||
netstandard2.1 BCL/language surface .NET Framework can't actually run (e.g. default
|
||||
interface members). Don't switch it to `net48`, don't add multi-targeting, unless
|
||||
the user asks.
|
||||
- `LangVersion` is pinned explicitly (currently `14.0`) — don't let it drift to
|
||||
`latest`.
|
||||
- The `.csproj` suppresses exactly two warnings, both scoped as narrowly as MSBuild
|
||||
allows, because of the netstandard2.1/net48-only-package combination above:
|
||||
`NU1701` (via a per-`PackageReference` `<NoWarn>`, not a project-wide one) and
|
||||
`MSB3270` (via `ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch=None`). Don't
|
||||
broaden either into a blanket suppression and don't remove them without
|
||||
understanding why (comments sit next to both in the `.csproj`).
|
||||
- The `Northwood.LabAPI` `PackageReference` uses a floating `Version="*"` on purpose,
|
||||
so every `dotnet restore` always pulls whatever is the latest stable release on
|
||||
NuGet at that moment — there's no version to bump here. This is intentionally
|
||||
**not** wired to `EntryPoint.cs`'s `RequiredApiVersion`, which can't be a floating
|
||||
value (`System.Version` has no such concept and would throw at runtime if it tried).
|
||||
`RequiredApiVersion` is a separate, manually-maintained literal representing the
|
||||
minimum LabAPI version the scaffolded code is known to work with — bump it by hand
|
||||
if you verify compatibility with a newer release, don't try to auto-sync it with the
|
||||
floating restore. Also be aware a floating version means a plugin generated today can
|
||||
restore a different (newer) LabAPI release than one generated last week, with no
|
||||
pinning — that's the deliberate trade-off of "always latest" over reproducibility.
|
||||
|
||||
## Code style for anything you write here
|
||||
|
||||
- No `//`, `/* */`, or `///` comments unless the user explicitly asks for
|
||||
comments/documentation in that request. No comments restating self-explanatory code.
|
||||
`EntryPoint.cs`/`Config.cs` are already comment-free — keep them that way and follow
|
||||
the same standard for any new file.
|
||||
- All text embedded in code defaults to **English**: string/log/console messages,
|
||||
exception messages, `[Description]`/config text, any user-facing string. Example:
|
||||
`Logger.Info("Plugin initialized successfully")`, not a Spanish equivalent.
|
||||
- This never applies to identifiers the user picked — project name, namespace,
|
||||
class/method/property/variable names stay exactly as requested (standard C# casing
|
||||
rules aside). Honor an explicit request for a specific piece of text in another
|
||||
language.
|
||||
|
||||
## How to verify a change (no test suite exists — this is the actual check)
|
||||
|
||||
There is no automated test project. Verify any template change by actually
|
||||
generating a project from it and building that output. Replace `<repo-name>` below
|
||||
with this repo's actual folder name (the value you'd see in `sourceName`):
|
||||
|
||||
```bash
|
||||
dotnet new uninstall .
|
||||
dotnet new install .
|
||||
dotnet new labapi-plugin -n VerifyPlugin -o ../_verify/VerifyPlugin
|
||||
cd ../_verify/VerifyPlugin
|
||||
dotnet build
|
||||
```
|
||||
|
||||
Expect `Build succeeded. 0 Warning(s) 0 Error(s)`. If it isn't 0/0, the change broke
|
||||
either the template's own warning suppressions or something in `EntryPoint.cs`/
|
||||
`Config.cs`/the `.csproj`.
|
||||
|
||||
Notes:
|
||||
- Re-run `dotnet new uninstall .` + `dotnet new install .` after **any** edit to
|
||||
`.template.config/template.json` or the scaffolded files — the template cache
|
||||
keys off the installed path and stale content otherwise gets regenerated.
|
||||
- `dotnet build` also works directly inside `<repo-name>` (the placeholder project
|
||||
is itself valid and compilable), but that only proves the *unsubstituted*
|
||||
placeholder compiles — it does not exercise symbol substitution. Always additionally
|
||||
verify through an actual `dotnet new` generation before calling a change done.
|
||||
- On Windows, if cleaning up `../_verify` fails with "resource busy", run
|
||||
`dotnet build-server shutdown` first, then retry.
|
||||
- Delete the `../_verify` scratch output when done; it isn't part of the template.
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using LabApi.Features.Console;
|
||||
using LabApi.Loader.Features.Plugins;
|
||||
using LabApi.Loader.Features.Plugins.Enums;
|
||||
|
||||
namespace LabApiPluginTemplate
|
||||
{
|
||||
@@ -8,20 +9,22 @@ namespace LabApiPluginTemplate
|
||||
{
|
||||
public override string Name => "LabApiPluginTemplate";
|
||||
|
||||
public override string Description => "YourDescription";
|
||||
public override string Description => "TODO: describe what this plugin does.";
|
||||
|
||||
public override string Author => "YourName";
|
||||
|
||||
public override Version Version => new Version(1, 0, 0);
|
||||
public override Version RequiredApiVersion { get; } = new Version("1.1.7");
|
||||
|
||||
public override Version RequiredApiVersion { get; } = new Version(LabApiProperties.CompiledVersion);
|
||||
public override LoadPriority Priority => LoadPriority.Medium;
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
Logger.Info($"{Name} has been enabled.");
|
||||
}
|
||||
|
||||
public override void Disable()
|
||||
{
|
||||
Logger.Info($"{Name} has been disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- .NET Standard 2.1: the most modern ABI that can still be loaded inside the
|
||||
.NET Framework 4.8 / Mono process the SCP:SL dedicated server uses, letting the
|
||||
project use recent C# syntax (see LangVersion) while still producing an
|
||||
assembly compatible with the game's host runtime. -->
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
|
||||
<!-- C# language version explicitly requested by the project. -->
|
||||
<LangVersion>14.0</LangVersion>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<RootNamespace>LabApiPluginTemplate</RootNamespace>
|
||||
<AssemblyName>LabApiPluginTemplate</AssemblyName>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
<!-- Northwood.LabAPI only ships net48/net481 binaries. Restoring it into a
|
||||
netstandard2.1 project makes NuGet fall back to that asset group and raise
|
||||
NU1701 to flag it. That's expected and safe here (the resulting assembly is
|
||||
still loaded by the server's .NET Framework/Mono runtime either way), so this
|
||||
suppresses just that one warning and only for this package. -->
|
||||
<NoWarn>$(NoWarn);NU1701</NoWarn>
|
||||
|
||||
<!-- LabAPI's prebuilt assembly (and the game's own managed assemblies it depends
|
||||
on) are built for .NET Framework, which on some SDK/platform combinations
|
||||
triggers a processor-architecture mismatch warning (MSB3270) when resolving
|
||||
references. It isn't an actual runtime problem, so this turns off just that
|
||||
specific check instead of every MSBuild warning. -->
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Floating version: restore always resolves to the latest stable Northwood.LabAPI
|
||||
release published on NuGet at the time, instead of a version pinned here. -->
|
||||
<PackageReference Include="Northwood.LabAPI" Version="*">
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,25 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageType>Template</PackageType>
|
||||
<PackageId>SCP.PluginTemplate</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<Title>SCP: Secret Laboratory LabAPI Plugin Template</Title>
|
||||
<Description>Provides a fast way to create a LabApi plugin.</Description>
|
||||
<PackageTags>dotnet-new;templates;scpsl;labapi</PackageTags>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<IncludeContentInPack>true</IncludeContentInPack>
|
||||
<ContentTargetFolders>content</ContentTargetFolders>
|
||||
<NoDefaultExcludes>true</NoDefaultExcludes>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
<NoWarn>$(NoWarn);NU5128</NoWarn>
|
||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include=".template.config/**/*" Exclude=".template.config/**/bin/**;.template.config/**/obj/**" />
|
||||
<Content Include="content/**/*" Exclude="content/**/bin/**;content/**/obj/**" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,93 +0,0 @@
|
||||
SCP: Secret Laboratory LabAPI plugin generated from the `labapi-plugin` template.
|
||||
|
||||
## Project Overview
|
||||
|
||||
* The plugin targets `netstandard2.1` intentionally.
|
||||
* LabAPI runs on the game's .NET Framework 4.8 environment, but the Unity version used by SCP: Secret Laboratory supports loading plugins targeting `netstandard2.1`.
|
||||
* The official LabAPI repository is [LabApi GitHub](https://github.com/northwood-studios/LabAPI). Use it to verify LabAPI APIs, behavior, and implementation details instead of guessing.
|
||||
|
||||
## Rules
|
||||
|
||||
* Do not change `TargetFramework`.
|
||||
* Do not add multi-targeting.
|
||||
* Do not change `LangVersion`.
|
||||
* Do not remove or broaden the existing warning handling.
|
||||
* Do not replace the floating `Northwood.LabAPI` version with a pinned version unless explicitly requested.
|
||||
* Do not automatically synchronize `RequiredApiVersion` with the NuGet package version.
|
||||
* Do not add comments unless explicitly requested.
|
||||
* Do not invent LabAPI APIs, namespaces, classes, methods, properties, events, or attributes.
|
||||
* Do not hand-roll configuration serialization or file I/O.
|
||||
* Do not make unrelated changes to project configuration.
|
||||
* Do not scan or read the repository broadly at the start of a task.
|
||||
* Only inspect files relevant to the current request.
|
||||
* Prefer targeted searches over broad repository exploration.
|
||||
|
||||
## Documentation
|
||||
|
||||
* The `docs` directory contains project documentation and must be consulted before starting any task.
|
||||
* Use the relevant documentation in `docs` to understand the project's architecture, conventions, design decisions, and non-obvious behavior before making changes.
|
||||
* Do not create documentation that merely restates what the code already makes obvious.
|
||||
* Document architecture, non-obvious behavior, important design decisions, and conventions that cannot be understood easily from the code alone.
|
||||
* Keep documentation concise and focused on useful context.
|
||||
* Update the relevant documentation when a change affects documented behavior, architecture, conventions, or design decisions.
|
||||
* Keep documentation consistent with the current state of the code.
|
||||
* Do not create unnecessary documentation files.
|
||||
|
||||
## LabAPI API Guidelines
|
||||
|
||||
`Plugin<TConfig>` requires the following members:
|
||||
|
||||
* `Name`
|
||||
* `Description`
|
||||
* `Author`
|
||||
* `RequiredApiVersion`
|
||||
* `Enable()`
|
||||
* `Disable()`
|
||||
|
||||
Optional overridable members include:
|
||||
|
||||
* `Version`
|
||||
* `Priority`
|
||||
* `ConfigFileName`
|
||||
|
||||
`Config` is automatically serialized and deserialized by LabAPI using YamlDotNet.
|
||||
|
||||
Before using a LabAPI API that is not already present in the project, verify that it exists and confirm its signature using one of these sources:
|
||||
|
||||
1. The restored `LabApi.dll` and `LabApi.xml` from the NuGet package.
|
||||
2. The official LabAPI source: https://github.com/northwood-studios/LabAPI.
|
||||
|
||||
Never guess an API. If an API or member cannot be verified, say so.
|
||||
|
||||
## Code Style
|
||||
|
||||
* Keep code simple and direct.
|
||||
* Prefer existing project patterns over introducing new abstractions.
|
||||
* Do not add unnecessary wrappers, helpers, interfaces, or dependencies.
|
||||
* All text embedded in code must be in English.
|
||||
* Identifiers do not need to be in English when a specific name has been requested.
|
||||
* Avoid comments unless explicitly requested.
|
||||
|
||||
## Project Configuration
|
||||
|
||||
The following settings are intentional and must not be changed unless explicitly requested:
|
||||
|
||||
* `TargetFramework`
|
||||
* `LangVersion`
|
||||
* `Northwood.LabAPI` version
|
||||
* `NU1701` warning handling
|
||||
* `MSB3270` warning handling
|
||||
|
||||
`RequiredApiVersion` is a manually maintained minimum compatible LabAPI version. Update it only after compatibility with a newer LabAPI version has been verified.
|
||||
|
||||
## Verification
|
||||
|
||||
After making changes, run:
|
||||
|
||||
```bash
|
||||
dotnet build
|
||||
```
|
||||
|
||||
The expected result is:
|
||||
|
||||
`Build succeeded. 0 Warning(s) 0 Error(s).`
|
||||
@@ -1 +0,0 @@
|
||||
@AGENTS.md
|
||||
@@ -1,2 +0,0 @@
|
||||
<Solution>
|
||||
</Solution>
|
||||
@@ -1,25 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>14.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NoWarn>$(NoWarn);NU1701;MSB3277</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Northwood.LabAPI" Version="1.1.7" Private="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp-publicized" HintPath="$(ScpDeps)\Assembly-CSharp-Publicized.dll" Private="false" />
|
||||
<Reference Include="CommandSystem.Core" HintPath="$(ScpDeps)\CommandSystem.Core.dll" Private="false" />
|
||||
<Reference Include="Mirror" HintPath="$(ScpDeps)\Mirror.dll" Private="false" />
|
||||
<Reference Include="Pooling" HintPath="$(ScpDeps)\Pooling.dll" Private="false" />
|
||||
<Reference Include="UnityEngine.CoreModule" HintPath="$(ScpDeps)\UnityEngine.CoreModule.dll" Private="false" />
|
||||
<Reference Include="UnityEngine.PhysicsModule" HintPath="$(ScpDeps)\UnityEngine.PhysicsModule.dll" Private="false" />
|
||||
<Reference Include="ThaumielMapEditor" HintPath="$(ScpDeps)\ThaumielMapEditor.dll" Private="false" />
|
||||
<Reference Include="SecretLabNAudio.Core" HintPath="$(ScpDeps)\SecretLabNAudio.Core.dll" Private="false" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user