diff --git a/home.md b/home.md new file mode 100644 index 0000000..6de0d91 --- /dev/null +++ b/home.md @@ -0,0 +1,11 @@ +--- +title: Home +description: +published: true +date: 2025-01-07T14:37:56.281Z +tags: +editor: markdown +dateCreated: 2025-01-07T14:37:53.512Z +--- + +# hahahahaha \ No newline at end of file diff --git a/se-launcher.md b/se-launcher.md new file mode 100644 index 0000000..50d658a --- /dev/null +++ b/se-launcher.md @@ -0,0 +1,14 @@ +--- +title: SE Launcher +description: Wiki for SE Launcher (CringeLauncher) docs +published: true +date: 2025-07-07T13:41:30.731Z +tags: +editor: markdown +dateCreated: 2025-07-07T12:13:43.540Z +--- + +# Welcome to Space Engineers Plugin Launcher/Loader (CringeLauncher) +This software allows you to run Space Engineers Game with latest runtime version and install custom plugins to enhance your gameplay. + +For information on developing your own plugin refer to [Plugin Development](./se-launcher/development) page. \ No newline at end of file diff --git a/se-launcher/development.md b/se-launcher/development.md new file mode 100644 index 0000000..48d3b06 --- /dev/null +++ b/se-launcher/development.md @@ -0,0 +1,89 @@ +--- +title: Plugin Development +description: Information about creating and maintaining plugin for SE Launcher (CringeLauncher) +published: true +date: 2025-07-07T13:40:59.987Z +tags: +editor: markdown +dateCreated: 2025-07-07T12:39:12.054Z +--- + +# Plugin Development + +Client plugins in **SE Launcher (CringeLauncher)** are designed to be significantly more powerful than regular Steam Workshop mods. They have the ability to **modify game behavior at runtime**, access **internal APIs**, and even **patch the game code**, including sensitive components like the **DirectX 11 renderer** of the game engine. This allows for extensive customization and feature development well beyond the capabilities of the vanilla modding system. + +> **Note**: Prior experience with **C# programming** is **required** to start developing plugins. + +You can start learning C# here: +- [Get started with C#](https://learn.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/) +- [Introduction to C# in .NET](https://learn.microsoft.com/en-us/dotnet/csharp/) + +--- + +## Getting Started + +To begin developing plugins for SE Launcher, follow the steps below: + +### 1. Choose and Install an IDE + +You will need a C#-capable integrated development environment. Below are some popular free options: + +- **Visual Studio 2022 Community Edition** + [https://visualstudio.microsoft.com/vs/community/](https://visualstudio.microsoft.com/vs/community/) + +- **JetBrains Rider (Free for Non-Commercial Use)** + [https://www.jetbrains.com/rider/](https://www.jetbrains.com/rider/) + +- **Visual Studio Code + C# Extension** + Download VS Code: [https://code.visualstudio.com/](https://code.visualstudio.com/) + Install the C# extension: [https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) + +### 2. Install Plugin Templates + +To create a plugin project, you need to install the official templates. Open a terminal or command prompt and execute: + +```bash +dotnet new install CringePlugins.Templates --nuget-source https://ng.zznty.ru/v3/index.json +``` + + +After installation, the **SpaceEngineers Plugin Template** will be available in your IDE’s "Create New Project" menu. + +### 3. Create and Launch the Plugin + +Create a new project using the installed template. Once the project is created, you can start debugging the game directly from your IDE. + +Here are typical hotkeys to start a debug session: + +- **Visual Studio**: `F5` to start debugging, `Shift + F5` to stop +- **Rider**: `Shift + F9` to debug, `Shift + F10` to run +- **VS Code**: `F5` to start debugging + +--- + +## What Next? + +Once you’ve created your initial plugin project, here are the next steps to explore and extend your plugin: + +1. **[Navigating Game Code](./development/decompiling-game)** + Learn how to decompile the game to understand its internal structure. + +2. **[How to Create Configs](./development/plugin-configs)** + Learn how to use the launcher's built-in config system to make your plugin configurable. + +3. **[Creating UIs](./development/plugin-ui)** + Explore different built-in UI frameworks supported by the launcher for developing user interfaces. + +4. **[Patching Game Code](./development/patching)** + Understand how to use the Harmony library to write runtime patches for the game. + +5. **[Publishing](./development/publishing)** + Instructions on preparing and publishing your plugin. + + 5.1 **[Publishing to Official PluginHub](./development/publishing/guidelines)** + Follow the guidelines to submit your plugin to the official PluginHub. + + 5.2 **[Distributing via Your Own Source](./development/publishing/custom-source)** + Learn how to host and distribute your plugin independently. + +--- diff --git a/se-launcher/development/decompiling-game.md b/se-launcher/development/decompiling-game.md new file mode 100644 index 0000000..148d90d --- /dev/null +++ b/se-launcher/development/decompiling-game.md @@ -0,0 +1,73 @@ +--- +title: Navigating Game Code +description: This page includes setup instructions for decompiling the game as well as basic description of game assemblies +published: true +date: 2025-07-07T13:40:23.556Z +tags: +editor: markdown +dateCreated: 2025-07-07T13:38:20.447Z +--- + +# Navigating Game Code + +Understanding and navigating the Space Engineers game code is essential for developing powerful plugins with SE Launcher. This page provides an overview of how to browse, analyze, and make sense of the game's internal structure. + +--- + +## Viewing Decompiled Code in IDEs + +Most modern C# IDEs provide built-in decompilation features that allow you to explore game code directly: + +- **Control + Click** on a type or method name in your code to navigate to its decompiled definition. + +> This is ideal for quickly checking method signatures, class hierarchies, and understanding usage patterns. + +--- + +## Using dnSpy for Deep Analysis + +For a more detailed and structured approach to exploring game internals, it is highly recommended to use **dnSpy**: + +- dnSpy is a powerful .NET assembly editor and decompiler that lets you browse the game's compiled assemblies with a complete tree view, IL inspection, and more. + +Download it here: +[https://github.com/dnSpyEx/dnSpy/releases](https://github.com/dnSpyEx/dnSpy/releases) + +--- + +## Game Code Structure Overview + +The game is split into several assemblies (DLLs), each with its own responsibility. Here’s a breakdown of the most important ones: + +### Core Engine Assemblies + +These contain low-level functionality shared across all parts of the game engine: + +- **`VRage`** – Base utility and system libraries +- **`VRage.Game`** – Core gameplay systems and logic definitions +- **`VRage.Input`** – Input management +- **`VRage.Math`** – Math utilities (vectors, matrices, geometry) +- **`VRage.Network`** – Networking layer + +### Game and Mod API Assemblies + +These contain actual gameplay logic and modding interfaces: + +- **`Sandbox.Common`** – Public interfaces and modding API; includes most definitions with `Ingame` suffix used in vanilla mods and scripts. +- **`Sandbox.Game`** – Core game logic, systems, components, blocks, and gameplay mechanics. This is the main body of the game logic. +- **`SpaceEngineers.Game`** – Game-specific logic for Space Engineers itself. + Originally, `Sandbox.Game` was shared between **Space Engineers** and **Medieval Engineers**, but the codebases were split long ago. + +--- + +## Accessing Game APIs from Plugins + +Plugins have full access to the same APIs and patterns used in vanilla modding, including: + +- **Session components** +- **Entity (GameLogic) components** +- **ObjectBuilders** (used to define and serialize game data) + +In addition, plugins are not restricted like workshop mods, and can also interact with internal or private APIs, patch methods, and hook into engine-level systems. + +This means you can both extend standard game logic and implement entirely new systems by leveraging both public and internal APIs. diff --git a/se-launcher/development/patching.md b/se-launcher/development/patching.md new file mode 100644 index 0000000..b5e577c --- /dev/null +++ b/se-launcher/development/patching.md @@ -0,0 +1,79 @@ +--- +title: Patching +description: This article explains how to use versatile Harmony library in launcher environment +published: true +date: 2025-07-07T15:32:19.754Z +tags: +editor: markdown +dateCreated: 2025-07-07T15:32:17.950Z +--- + +# Patching Game Code + +The SE Launcher uses the **[Harmony](https://harmony.pardeike.net)** library to patch and extend the behavior of the game at runtime. Plugins are also encouraged to use Harmony, as it allows for **safe and compatible method patching** even when multiple plugins modify the same methods. + +Harmony is widely used in the modding ecosystem and offers powerful features for injecting code before, after, or instead of existing method logic. + +> This article does not cover the full scope of Harmony’s capabilities. Developers should refer to the official documentation for detailed information: +> [https://harmony.pardeike.net/articles/intro.html](https://harmony.pardeike.net/articles/intro.html) + +--- + +## Simple Hello World Patch + +Below is an example plugin patch that adds a simple message to the game log each time the world is autosaved. + +### Patch Class + +```csharp +using HarmonyLib; +using NLog; +using Sandbox.Game.World; + +namespace TestPlugin; + +[HarmonyPatch(typeof(MySession), nameof(MySession.SaveEnded))] +public static class SavePatch +{ + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); + + public static void Prefix() + { + Log.Info("Hello world!"); + } +} +```` + +### What it does: + +* The patch targets `MySession.SaveEnded`, which is called by the game when an autosave completes. +* A `Prefix()` method is defined, which means it will run **before** the original method. +* `Log.Info("Hello world!")` will be printed to the log each time the game autosaves. + +--- + +## Applying the Patch in Your Plugin + +To apply the patch, you must initialize Harmony in your plugin’s `Init()` method: + +```csharp +using HarmonyLib; + +public void Init(object gameInstance) +{ + new Harmony("TestPlugin").PatchAll(typeof(Plugin).Assembly); +} +``` + +This line scans your plugin assembly for `[HarmonyPatch]` attributes and applies all defined patches. + +--- + +## Notes + +* The Harmony ID (`"TestPlugin"` in this case) should be unique per plugin to avoid conflicts. +* Harmony patches are designed to **coexist across multiple plugins**, so long as they do not directly conflict by trying to replace the same method behavior entirely. +* If needed, you can control patching more granularly with `Patch()` and `Unpatch()` methods instead of `PatchAll()`. + +For more complex patching scenarios, refer to the Harmony documentation: +[https://harmony.pardeike.net/articles/intro.html](https://harmony.pardeike.net/articles/intro.html) \ No newline at end of file diff --git a/se-launcher/development/plugin-configs.md b/se-launcher/development/plugin-configs.md new file mode 100644 index 0000000..13abe55 --- /dev/null +++ b/se-launcher/development/plugin-configs.md @@ -0,0 +1,135 @@ +--- +title: Plugin Configs +description: Documentation on how to use launcher-provided apis to make your plugin configurable +published: true +date: 2025-07-07T14:52:39.459Z +tags: +editor: markdown +dateCreated: 2025-07-07T14:52:37.701Z +--- + +# Plugin Configs + +While you can implement your own configuration system for your plugin, it is highly recommended to use the **built-in configuration system** provided by SE Launcher. This system offers **centralized storage**, a **unified format**, and seamless integration with the plugin lifecycle. + +--- + +## Using the Built-in Config System + +The launcher provides a utility class called `ConfigHandler`, which can be used to register and manage your plugin's configuration files. + +You can retrieve an instance of `ConfigHandler` via the game service provider: + +```csharp +var handler = MySandboxGame.Services.GetRequiredService(); +```` + +--- + +## Declaring a Config Class + +Here’s a simple example of a configuration class with one setting: + +```csharp +public class Config +{ + public string UserName { get; set; } = "John"; +} +``` + +The class must be **public**, have a **parameterless constructor**, and its properties must be **publicly gettable and settable** to be properly handled by the configuration system. + +--- + +## Plugin Example with Config Usage + +```csharp +using CringePlugins.Config; +using Microsoft.Extensions.DependencyInjection; +using NLog; +using Sandbox; +using VRage.Plugins; + +namespace TestPlugin; + +public class Plugin : IPlugin +{ + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); + + public void Dispose() + { + } + + public void Init(object gameInstance) + { + Log.Info("Test Plugin init"); + + var handler = MySandboxGame.Services.GetRequiredService(); + using var config = handler.RegisterConfig("test"); + + Log.Info("Hello, {UserName}", config.Value.UserName); + } + + public void Update() + { + } +} +``` + +### Explanation + +* `RegisterConfig(string id)` registers a config and returns a `ConfigReference`. +* The returned `.Value` contains the current config instance. +* This reference **automatically reflects changes** made to the config from other plugins or future disk reloads (disk reloading is **not yet implemented**, but planned). + +--- + +## Updating Config + +If your config class is **mutable** (as in the example), changing a property like this: + +```csharp +config.Value.UserName = "NewName"; +``` + +**will not automatically persist** the changes. + +To update and save the configuration, you need to **assign a new instance** to the `.Value` property: + +```csharp +config.Value = new Config +{ + UserName = "NewName" +}; +``` + +This ensures that the new value is **persisted to disk and broadcast to other consumers** of the same config. + +--- + +## Managing Config Lifetime + +The `ConfigReference` returned by `RegisterConfig` **must be disposed** when no longer needed. This releases associated resources and unhooks change tracking. + +In the example above, the config is used only during `Init()` and disposed immediately with a `using` block. + +If you need to access the config during the whole plugin lifetime, **store the reference in a field**, and dispose of it inside the `Dispose()` method: + +```csharp +private ConfigReference? _config; + +public void Init(object gameInstance) +{ + var handler = MySandboxGame.Services.GetRequiredService(); + _config = handler.RegisterConfig("test"); + + Log.Info("Welcome, {UserName}", _config.Value.UserName); +} + +public void Dispose() +{ + _config?.Dispose(); +} +``` + +This approach ensures that your plugin holds the configuration safely throughout its lifecycle and disposes of it properly when the game or plugin is closed. diff --git a/se-launcher/development/plugin-ui.md b/se-launcher/development/plugin-ui.md new file mode 100644 index 0000000..e16c904 --- /dev/null +++ b/se-launcher/development/plugin-ui.md @@ -0,0 +1,111 @@ +--- +title: Plugin UI +description: This article explains all available options to create user interfaces for your own plugins and how to use preffered Dear ImGui inside launcher environment +published: true +date: 2025-07-07T15:20:41.232Z +tags: +editor: markdown +dateCreated: 2025-07-07T15:20:39.406Z +--- + +# Creating UIs + +The SE Launcher supports multiple approaches to creating user interfaces. Depending on your needs and the context in which the UI is displayed, you may choose from a variety of supported frameworks: + +--- + +## Supported UI Frameworks + +- **VRage Sandbox GUI (`MyGuiScreenBase`)** + The native game GUI system used by the base game for menus and dialogs. + +- **EmptyKeys MVVM-XAML (`MyGuiScreenMvvmBase`)** + A more modern approach using MVVM and XAML, as used by some newer parts of the Space Engineers UI. + +- **Windows Forms / WPF** + Standard UI toolkits in the .NET ecosystem. These are generally used for **external or child windows**, since they cannot be rendered on the main game window. + +> These options are available and usable, but may require more complex setup and are outside the scope of this article. + +--- + +## Recommended: ImGui + +The **preferred UI system** in SE Launcher is **[Dear ImGui](https://github.com/ocornut/imgui)**, a powerful and immediate-mode GUI library. + +It is used for **all SE Launcher native UI** and is tightly integrated into the plugin system, making it the best choice for creating custom plugin UIs. + +This article focuses exclusively on using **ImGui**, as other frameworks are either documented elsewhere or can be studied via existing plugin implementations. + +--- + +## Getting Started with ImGui + +To create a UI with ImGui, define a class that implements the `IRenderComponent` interface. + +All ImGui rendering must be done **inside the `OnFrame()` method**, which is called every frame when the renderer is active. + +### Example: Simple UI Component + +```csharp +using CringePlugins.Abstractions; +using ImGuiNET; + +namespace TestPlugin; + +public class TestRenderComponent : IRenderComponent +{ + public void OnFrame() + { + if (ImGui.Begin("Test Window")) + { + ImGui.Button("Test"); + + ImGui.End(); + } + + ImGui.ShowDemoWindow(); + } +} +```` + +In this example: + +* A basic ImGui window titled **“Test Window”** is shown. +* A button labeled **“Test”** is rendered. +* `ImGui.ShowDemoWindow()` displays an interactive reference window with a showcase of all ImGui features and controls. + +This is an excellent way to explore the capabilities of ImGui while developing your UI. + +--- + +## Registering the Render Component + +To make your ImGui UI render in-game, you must **register the component** using the `RenderHandler` during plugin initialization: + +```csharp +public void Init(object gameInstance) +{ + RenderHandler.Current.RegisterComponent(new TestRenderComponent()); +} +``` + +Once registered, your `OnFrame()` method will be called every frame, and your ImGui-based UI will be drawn automatically. + +--- + +## Further Learning + +ImGui is a complex and versatile UI framework, and covering all of its features is beyond the scope of this article. + +To learn more, you can: + +* Explore the **ImGui Demo Window** via `ImGui.ShowDemoWindow()` +* Look at how the SE Launcher uses ImGui in its own UI components: + + * Plugin List: + [PluginListComponent.cs](https://git.zznty.ru/PvE/se-launcher/src/branch/master/CringePlugins/Ui/PluginListComponent.cs) + * Mod List from Client Mod Loader: + [ModListComponent.cs](https://git.zznty.ru/PvE/ClientModLoader/src/branch/master/Plugin.ClientModLoader/ModListComponent.cs) + +These examples demonstrate real-world usage patterns for building complex UI with ImGui in the launcher environment. diff --git a/se-launcher/development/publishing.md b/se-launcher/development/publishing.md new file mode 100644 index 0000000..0f508a7 --- /dev/null +++ b/se-launcher/development/publishing.md @@ -0,0 +1,53 @@ +--- +title: Publishing +description: An Overview of available distribution options for developers to make their plugins available to the end users +published: true +date: 2025-07-07T15:59:40.689Z +tags: +editor: markdown +dateCreated: 2025-07-07T15:59:38.892Z +--- + +# Publishing Options Overview + +Once your plugin is complete and tested, the next step is to **publish it** so that other players can install and use it. SE Launcher supports **two main publishing methods**, each with its own advantages and trade-offs. + +--- + +## 1. Publishing to the Official PluginHub + +This is the **recommended and most accessible** way to distribute your plugin to the community. + +### Advantages: +- Your plugin becomes **immediately available** to all users via the launcher's built-in plugin browser. +- No infrastructure or server setup required. +- Users benefit from automatic updates and trust in the official source. + +### Limitations: +- Your plugin must comply with a set of **publishing guidelines**, including naming, versioning, stability, and content restrictions. +- Submissions are subject to **manual approval** and review. + +For more information, see the full guide: +**[Publishing Guidelines for Official PluginHub](./publishing/guidelines)** + +--- + +## 2. Publishing via Self-Hosted NuGet Source + +Advanced users and organizations may choose to host their plugin on a **custom NuGet feed**. + +### Requirements: +- A **publicly accessible domain**. +- Knowledge of **server administration** and setting up a NuGet-compatible feed. +- Responsibility for **serving, updating, and maintaining** plugin packages. + +### Advantages: +- Full **control** over publishing, updates, and access. +- Ideal for **private distributions**, development builds, or alternative plugin ecosystems. + +For a step-by-step guide, refer to: +**[Distributing via Your Own Source](./publishing/custom-source)** + +--- + +Choose the method that best suits your project goals and technical capabilities. diff --git a/se-launcher/development/publishing/custom-source.md b/se-launcher/development/publishing/custom-source.md new file mode 100644 index 0000000..6b8f47d --- /dev/null +++ b/se-launcher/development/publishing/custom-source.md @@ -0,0 +1,11 @@ +--- +title: Distribution via Self-Hosted NuGet feed +description: +published: true +date: 2025-07-07T16:00:16.831Z +tags: +editor: markdown +dateCreated: 2025-07-07T16:00:15.163Z +--- + +# TBD \ No newline at end of file diff --git a/se-launcher/development/publishing/guidelines.md b/se-launcher/development/publishing/guidelines.md new file mode 100644 index 0000000..514ea0c --- /dev/null +++ b/se-launcher/development/publishing/guidelines.md @@ -0,0 +1,85 @@ +--- +title: Plugin Guidelines for Official PluginHub +description: A list of guidelines and limitations imposed by Official PluginHub of SE Launcher +published: true +date: 2025-07-08T07:45:40.991Z +tags: +editor: markdown +dateCreated: 2025-07-07T16:31:35.807Z +--- + +# Publishing Guidelines for Official PluginHub + +To ensure quality, security, and compatibility across the SE Launcher ecosystem, plugins published to the **official PluginHub** must comply with the following set of guidelines. + +Following these rules helps maintain a stable and fair environment for all players and avoids conflicts between plugins or game systems. + +--- + +## General Guidelines + +1. **Public Source Code** + The plugin must have **human-readable**, publicly accessible source code, hosted on **GitHub**. Obfuscated or minified source code is not allowed. + +2. **Performance Considerations** + Plugin code must demonstrate **reasonable performance**. + - While peak optimization is not required, any plugin that **noticeably degrades game performance** without justification may be rejected. + - For example, plugins that alter the **render pipeline** may increase GPU usage, which is acceptable if it is necessary for their function. + +3. **Mod & Script API Integrity** + Plugins **must not modify, restrict, or extend** the APIs available to in-game **mods or scripts**. + The modding environment should remain unchanged and unaffected by external plugin logic. + +4. **File System Access Limitations** + - Plugins should **only access the files required** for their function. + - **Modifying core game files, mod assets, or unrelated data** is strictly prohibited. + - Acceptable modifications may include: + - Game **session config** + - **Mod user/world configs** + - **Other plugin configs**, where applicable and justified + +5. **Multiplayer Fairness** + Plugins that **alter gameplay to give unfair advantages in multiplayer** are not allowed. + Examples: + - ❌ Not Allowed: + - Extending ore detector range + - Custom ore detectors + - Mass inventory automation (sorting, refueling, repairing, etc.) + - ✅ Allowed: + - Picking a specific number of items from inventory + - Manually triggered jump drive range adjustment + (automatic threat detection or chained jumping is **not** allowed) + +6. **No Loader Modification** + Plugins must **not alter or patch the SE Launcher itself**. + This is strictly prohibited, even for privately distributed plugins. + +7. **No External Executables** + - Plugins **must not include or invoke** external executables. + - Plugins must **not start, monitor, interfere with, or kill** other processes. + - The only allowed external action is launching **Windows Explorer** to open a file path or URL. + +8. **Native Code Requirements** + - Native assemblies (e.g. `.dll` compiled from C++) must be: + - Open source and publicly available, **or** + - From a **trusted and signed** source + - Only **NuGet-distributed** native libraries are currently supported. + +9. **No Auto-Updating Logic** + Plugins **must not implement auto-update mechanisms**. + Updates are fully managed by the SE Launcher. + +10. **Compliance with Keen Software House EULA** + All plugins must comply with the [Keen Software House EULA](https://store.steampowered.com/eula/244850_eula_1). + +--- + +## Current Limitations + +Please be aware of the following restrictions in the current launcher infrastructure: + +1. **No NuGet Dependencies** + External NuGet package dependencies are not yet supported. + +2. **Locked C# Language Version** + Plugin code must use the **default language version** defined by the current **launcher SDK**. This version is fixed and cannot be overridden. \ No newline at end of file