diff --git a/docs/.markdownlint.json b/docs/.markdownlint.json
index b23c1528..50b77304 100644
--- a/docs/.markdownlint.json
+++ b/docs/.markdownlint.json
@@ -6,5 +6,8 @@
},
"single-h1": {
"front_matter_title": ""
+ },
+ "no-trailing-punctuation": {
+ "punctuation": ",;:!?。,;:!?"
}
}
\ No newline at end of file
diff --git a/docs/articles/dev-resources/Demo.csproj b/docs/articles/dev-resources/Demo.csproj
new file mode 100644
index 00000000..c79dd5d1
--- /dev/null
+++ b/docs/articles/dev-resources/Demo.csproj
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+ net472
+ Demo
+
+
+
+
+
+
+
diff --git a/docs/articles/dev-resources/Plugin.cs b/docs/articles/dev-resources/Plugin.cs
new file mode 100644
index 00000000..1022758b
--- /dev/null
+++ b/docs/articles/dev-resources/Plugin.cs
@@ -0,0 +1,61 @@
+using System;
+using IPA;
+using IPA.Logging;
+using IPA.Config;
+using IPA.Config.Stores;
+
+namespace Demo
+{
+ /*
+ [Plugin(RuntimeOptions.DynamicInit)]
+ */
+ [Plugin(RuntimeOptions.SingleStartInit)]
+ internal class Plugin
+ {
+ public static Logger log { get; private set; }
+
+ [Init]
+ public Plugin(Logger logger, Config conf)
+ {
+ log = logger;
+ PluginConfig.Instance = conf.Generated();
+ log.Debug("Config loaded");
+
+ // setup that does not require game code
+ // this is only called once ever, so do once-ever initialization
+ }
+
+ /*
+ [Init]
+ public Plugin(Logger logger)
+ {
+ log = logger;
+ log.Debug("Basic plugin running!");
+
+ // setup that does not require game code
+ // this is only called once ever, so do once-ever initialization
+ }
+ */
+
+ /*
+ [OnEnable]
+ public void OnEnable()
+ */
+ [OnStart]
+ public void OnStart()
+ {
+ // setup that requires game code
+ }
+
+ /*
+ [OnDisable]
+ public void OnDisable()
+ */
+ [OnExit]
+ public void OnExit()
+ {
+ // teardown
+ // this may be called mid-game if you are using RuntimeOptions.DynamicInit
+ }
+ }
+}
\ No newline at end of file
diff --git a/docs/articles/dev-resources/PluginConfig.cs b/docs/articles/dev-resources/PluginConfig.cs
new file mode 100644
index 00000000..e2821257
--- /dev/null
+++ b/docs/articles/dev-resources/PluginConfig.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using IPA.Config.Stores;
+using IPA.Config.Stores.Attributes;
+using IPA.Config.Stores.Converters;
+
+[assembly: InternalsVisibleTo(GeneratedExtension.AssemblyVisibilityTarget)]
+
+namespace Demo
+{
+ /*
+ public class PluginConfig
+ */
+ internal class PluginConfig
+ {
+ public static PluginConfig Instance { get; set; }
+
+ /*
+ public int IntValue { get; set; } = 42;
+
+ public float FloatValue { get; set; } = 3.14159f;
+
+ [UseConverter(typeof(ListConverter))]
+ public List ListValue { get; set; } = new List();
+
+ [UseConverter(typeof(CollectionConverter>))]
+ public HashSet SetValue { get; set; } = new HashSet();
+ */
+
+ public virtual int IntValue { get; set; } = 42;
+
+ public virtual float FloatValue { get; set; } = 3.14159f;
+
+ [UseConverter(typeof(ListConverter))]
+ public virtual List ListValue { get; set; } = new List();
+
+ [UseConverter(typeof(CollectionConverter>))]
+ public virtual HashSet SetValue { get; set; } = new HashSet();
+
+ public virtual void Changed()
+ {
+ // this is called whenever one of the virtual properties is changed
+ // can be called to signal that the content has been changed
+ }
+
+ public virtual void OnReload()
+ {
+ // this is called whenever the config file is reloaded from disk
+ // use it to tell all of your systems that something has changed
+
+ // this is called off of the main thread, and is not safe to interact
+ // with Unity in
+ }
+ }
+}
\ No newline at end of file
diff --git a/docs/articles/dev-resources/description.md b/docs/articles/dev-resources/description.md
new file mode 100644
index 00000000..f6af112d
--- /dev/null
+++ b/docs/articles/dev-resources/description.md
@@ -0,0 +1,7 @@
+# Demo Plugin
+
+A little demo for the BSIPA modding introduction.
+
+---
+
+WE CAN USE MARKDOWN!!!
diff --git a/docs/articles/dev-resources/manifest.json b/docs/articles/dev-resources/manifest.json
new file mode 100644
index 00000000..9237d0b6
--- /dev/null
+++ b/docs/articles/dev-resources/manifest.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://raw.githubusercontent.com/beat-saber-modding-group/BSIPA-MetadataFileSchema/master/Schema.json",
+ "author": "ExampleMan",
+ "description": [
+ "#![Demo.description.md]",
+ "A demo plugin written for the BSIPA basic tutorial."
+ ],
+ "gameVersion": "1.6.0",
+ "id": null,
+ "name": "Demo Plugin",
+ "version": "0.0.1",
+ "features": [
+
+ ],
+ "links": {
+ "project-home": "https://example.com/demo-plugin",
+ "project-source": "https://github.com/exampleman/demo-plugin/",
+ "donate": "https://ko-fi.com/exampleman"
+ },
+ "misc": {
+ "plugin-hint": "Demo.Plugin"
+ }
+}
\ No newline at end of file
diff --git a/docs/articles/start-dev.md b/docs/articles/start-dev.md
index 735274b5..d615da9b 100644
--- a/docs/articles/start-dev.md
+++ b/docs/articles/start-dev.md
@@ -3,5 +3,23 @@ uid: articles.start.dev
title: Making your own mod
---
-# Overview
+# Making a mod
+## Overview
+
+What follows is a *very* barebones, and frankly not very useful plugin class, even as a starting point,
+but it should be enough to give a decent idea of how to do quick upgrades of existing mods for those who want to.
+
+[!code-cs[Plugin.cs](./dev-resources/Plugin.cs?range=1-3,6-8,12-16,29-37,39,44-45,46-49,54-57,59-)]
+
+There are basically 4 major concepts here:
+
+1. , the logging system.
+2. , which declares that this class is a plugin and how it should behave.
+3. , which declares the constructor (and optionally other methods) as being
+ used for initialization.
+4. The lifecycle event attributes and .
+
+Read the docs at those links for a better idea of what they do.
+
+TODO: expand this to explain more, and expand on the base example
diff --git a/docs/docfx.json b/docs/docfx.json
index 3eba9733..30623cd4 100644
--- a/docs/docfx.json
+++ b/docs/docfx.json
@@ -12,7 +12,8 @@
"TMP Exporter/**.csproj",
"BuildTools/**.csproj",
"Doorstop/**.csproj",
- "Net3-Proxy/**.csproj"
+ "Net3-Proxy/**.csproj",
+ "docs/**.csproj"
]
}],
"dest": "api",