diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index fbc32e2..f1f2d69 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,10 +1,10 @@
-name: Build Documentation
+name: Build and Deploy Documentation
on:
- push:
- branches:
- - 'main'
+ push:
+ branches:
+ - 'main'
- workflow_dispatch:
+ workflow_dispatch:
permissions:
contents: read
@@ -18,36 +18,36 @@ concurrency:
cancel-in-progress: false
jobs:
- build:
- environment:
- name: github-pages
- url: ${{ steps.deployment.outputs.page_url }}
- runs-on: ubuntu-latest
- steps:
- - name: Clone Repository
- uses: actions/checkout@v4
- with:
- submodules: recursive
-
- - name: Setup .NET SDK
- uses: actions/setup-dotnet@v4
- with:
- dotnet-version: '8.0.x'
-
- - name: Restore dotnet tools
- run: dotnet tool restore
-
- - name: Run Build
- run: dotnet docfx docfx.json
-
- - name: Setup Pages
- uses: actions/configure-pages@v5
-
- - name: Upload artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: '_site'
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
\ No newline at end of file
+ build:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Clone Repository
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+
+ - name: Setup .NET SDK
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '8.0.x'
+
+ - name: Restore dotnet tools
+ run: dotnet tool restore
+
+ - name: Run Build
+ run: dotnet docfx docfx.json
+
+ - name: Setup Pages
+ uses: actions/configure-pages@v5
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: '_site'
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
\ No newline at end of file
diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
new file mode 100644
index 0000000..0893ea5
--- /dev/null
+++ b/.github/workflows/pullrequest.yml
@@ -0,0 +1,47 @@
+name: Test Build Documentation
+
+on:
+ pull_request:
+ branches:
+ - 'main'
+
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ concurrency: ci-${{ github.ref }}
+ steps:
+ - name: Clone Repository
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+
+ - name: Setup .NET SDK
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '8.0.x'
+
+ - name: Restore dotnet tools
+ run: dotnet tool restore
+
+ - name: Run Build
+ run: dotnet docfx docfx.json
+
+ complete:
+ runs-on: ubuntu-latest
+ needs: test
+ name: Test completion task
+ steps:
+ - run: echo "Tests Complete"
\ No newline at end of file
diff --git a/README.md b/README.md
index 5f08a7a..9a83ce7 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,10 @@ With your environment setup properly, the following explains how to build from s
git clone https://github.com/MonoGame/monogame.github.io.git
```
-2. Install npm dependencies
+2. Install DotNet dependencies
```sh
- npm install
+ dotnet tool restore
```
3. Optional Steps
@@ -29,10 +29,13 @@ With your environment setup properly, the following explains how to build from s
`git submodule update --init --recursive`
-4. Run a local build and serve it with hot reloading. The site is full DocFX now so a single build command will do:
+4. Run a local build and serve it. The site is full DocFX now so a single build command will do:
`dotnet docfx docfx.json --serve`
+> [!NOTE]
+> Docfx hosting does not support hot reload, so to refresh the hosted site you will need to stop the agent (ctrl-c) and run the above command again to refresh pages
+
## Document styling
The use of DocFX with the updated MonoGame docs site has afforded the use of some custom stylings to improve consistency and more stylized docs:
@@ -53,6 +56,9 @@ The use of DocFX with the updated MonoGame docs site has afforded the use of som
As an example of a document written using the above notes, please refer to the [HowTo: Create a Render Target tutorial](https://github.com/MonoGame/docs.monogame.github.io/blob/feature/docsmigration/articles/monogame/howto/graphics/HowTo_Create_a_RenderTarget.md)
+> [!TIP]
+> No additional text is needed at the bottom of document pages as the licenses and requirements are automatically added by the DocFX build system
+
## LICENSE
The MonoGame project is under the Microsoft Public License except for a few portions of the code. See the [LICENSE](LICENSE) file for more details.
diff --git a/api/index.md b/api/index.md
index 0774770..02e8a4c 100644
--- a/api/index.md
+++ b/api/index.md
@@ -7,4 +7,4 @@ Welcome to the **MonoGame** reference documentation!
This area provides detailed information on each class and method in the API.
-Please view the [documentation](../articles/) for how to get started and step-by-step guidance.
\ No newline at end of file
+Please view the [documentation](../articles/index.md) for how to get started and step-by-step guidance.
\ No newline at end of file
diff --git a/articles/getting_started/1_setting_up_your_development_environment_unix.md b/articles/getting_started/1_setting_up_your_development_environment_unix.md
index f217860..ff7ee2d 100644
--- a/articles/getting_started/1_setting_up_your_development_environment_unix.md
+++ b/articles/getting_started/1_setting_up_your_development_environment_unix.md
@@ -58,7 +58,7 @@ sudo apt install wine64 p7zip-full curl
Create wine prefix:
```sh
-wget -qO- https://raw.githubusercontent.com/MonoGame/MonoGame/master/Tools/MonoGame.Effect.Compiler/mgfxc_wine_setup.sh | bash
+wget -qO- https://monogame.net/downloads/net6_mgfxc_wine_setup.sh | bash
```
If you ever need to undo the script, simply delete the `.winemonogame` folder in your home directory.
diff --git a/articles/getting_started/1_setting_up_your_development_environment_windows.md b/articles/getting_started/1_setting_up_your_development_environment_windows.md
index a7e4fe0..c94a3b8 100644
--- a/articles/getting_started/1_setting_up_your_development_environment_windows.md
+++ b/articles/getting_started/1_setting_up_your_development_environment_windows.md
@@ -26,7 +26,8 @@ When installing Visual Studio, the following workloads are required depending on
![Visual Studio optional components](images/1_installer_vs_components.png)
> [!WARNING]
-> Targeting Windows
+> **Targeting Windows**
+>
> If you are targeting the standard Windows DirectX backend, you will also need [the DirectX June 2010 runtime](https://www.microsoft.com/en-us/download/details.aspx?id=8109) for audio and gamepads to work properly.
### Install MonoGame extension for Visual Studio 2022
diff --git a/articles/preparing_for_consoles.md b/articles/preparing_for_consoles.md
new file mode 100644
index 0000000..36e2fd6
--- /dev/null
+++ b/articles/preparing_for_consoles.md
@@ -0,0 +1,119 @@
+---
+title: Preparing for consoles
+description: How to get your game ready to run on consoles.
+---
+
+# Preparing for consoles
+
+If you would like to port your game to consoles, there are some best practices to follow if you want to avoid running into issues while porting.
+
+MonoGame for gaming consoles uses a dedicated .NET runtime that is not maintained by Microsoft. Therefore, a 100% accuracy and reliability is not guaranteed. Moreover, the console runtime makes use of `ahead-of-time` native compilation (AOT), which means that some .NET features will not, and cannot work on consoles.
+
+This article explains the most common pitfalls and suggested guidelines to optimize your chances of having a smoother porting experience.
+
+> [!NOTE]
+> *Gaming consoles are restricted to registered developers and are not publicly available nor publicly documented. To get access to those platforms, please contact your console account manager(s). MonoGame documentation for closed platforms is available in their respective repositories.*
+
+## No use of runtime reflection
+
+The main show stopper when it comes to porting a .NET game to consoles, is the use of runtime [reflection](https://learn.microsoft.com/en-us/dotnet/fundamentals/reflection/reflection).
+
+Reflection is, at large, unsupported in an AOT context. Which means that anywhere you or a third party library uses reflection, your game will crash.
+
+In order to make sure that your game abides to that rule, you can try to publish an AOT'd version of it for desktop computers and verify how it fares.
+
+To publish with AOT:
+
+- Add `true` to your `.csproj`.
+- Then run `dotnet publish` from the command-line/terminal.
+
+This will nativily compile your game in a fashion similar to consoles. The output executable will be in your output folder, within a sub-folder nammed `publish`.
+
+From there, you can try running this executable. If it does not start or crashes later on, you likely are using reflection or another unsupported feature in a AOT runtime.
+
+Native executables can debugged by:
+
+- Starting an empty Visual Studio with no code.
+- Opening the compiled exe.
+- Then hitting "Start debugging".
+
+It should show you on which C# lines it crashed.
+
+It is important to note that you should test every aspect of your game, and not just if it starts. Run through all the menus/screens, scene transitions and gameplay.
+
+Another way to make sure that everything is safe is to enable `true` in your `.csproj`, and then **rebuild** (not just build) your game and check the build output for AOT warnings. Those warnings will tell you which parts of your code might trigger crashes or unexecpted results when running on AOT compilation. You should seek to resolve all of them.
+
+## No runtime compilation / IL emit
+
+Generating code at runtime is a scenario that is also not supported in AOT contexts, it is also forbidden by console manufacturers.
+
+Like reflection, trying to make a `PublishAot` build is a good way to verify that your game is compliant because any use of IL emit will crash.
+
+## No use of dynamic assembly loading
+
+Loading assemblies at runtime with `Assembly.Load()` is not supported.
+
+## Third party libraries
+
+Many third party libraries heavily rely on using reflection or IL emit, this is a common practice for JSON or XML parsers for example (and they are the most common source of third party incompatibilities).
+
+It is advised to choose very carefully the libraries that you are using when porting to consoles. If you do not select them with this in mind, you might run into a situation in which you will have to rewrite entire chunks of data handling.
+
+The best way to make sure if they will work, is to search if they are **"AOT-compatible"**, or try to compile with the `true` setting in your `.csproj` and check if there are any warnings related to those libraries.
+
+For example, here are some parsing libraries known for their compliance with AOT compilation and good handling of memrory:
+
+- [TurboXML](https://github.com/xoofx/TurboXml)
+- [TinyJSON](https://github.com/zanders3/json)
+
+On the contrary, Newtonsoft JSON is known to be unsupported (there are modified forks around, but we overall recommend to not use it for games).
+
+## Native libraries
+
+If you are using native libraries, make sure that they provide builds for consoles, or make sure that you can compile and run them on consoles yourself.
+
+Even though a library might be open-source, it is unlikely they will just compile and run on consoles.
+
+It is suggested to only use native libraries that have been proven to run on consoles.
+
+## LINQ
+
+While LINQ mostly works on consoles, it should be noted that due to AOT compilation, LINQ queries can not be optimized and performance can be very slow.
+
+Moreover, LINQ is very garbage-prone and if your game has stuttering issues you might want to reduce your usage of LINQ.
+
+## Avoiding garbage generation
+
+Even though your game has good performance on PC and does not show stutters, you might want to be very cautious about how your game handles memory.
+
+The garbage collector is slower on consoles and if your game generates a lot of garbage memory, there will be visible stutters.
+
+To verify that your game is not too garbage-prone, you can run Visual Studio's Perfomance Profiler (`Debug/Performance Profiler...`) and check the **".NET Object Allocation Tracking"** tool.
+
+From there, you can check which parts of your code generate garbage and you can pinpoint where to optimize.
+
+In order to avoid garbage, here are some best practices:
+
+- Only use strings as const. Do not use strings dynamically (e.g. string concatenation, patterns...), this is the most common source of garbage.
+- Avoid allocating anything with the `new` keyword during your game loop, e.g. pre-allocate everything ahead of using them during gameplay.
+- Pool your dynamic objects, e.g. do not destroy your projectiles or particles, instead place them into another "unused" list and reuse them instead of creating new instances when needed.
+- Avoid using LINQ.
+- If you are using collections, initialize them with a large enough capacity to avoid their internal data structure being silently recreated.
+- Mind your foreach loops, depending on the data you are looping on, the loop might create garbage when duplicating an item. Or better yet, use a for loop for tigher control.
+
+## Do not rely on system calls
+
+If your game calls directly to system functions, like kernel, win32 or unix commands, you might want to get rid of them.
+
+## Consider I/O to be asynchronous
+
+Saving player data/settings, or unlocking achievements are operations that should be considered asynchronous.
+
+Most, if not all consoles, consider system accesses to be asynchronous. Even though it is not on PC, you should prepare your game to handle asynchronous operation (e.g. consider saving game data in a thread which will not block the game).
+
+If you consider all your I/O and system operations as asynchronous, you will likely be spared some headache.
+
+## Suggestions
+
+If you have other tips or suggestions when building for consoles, then let the MonoGame team know by raising an issue and we will improve this article even further over time.
+
diff --git a/articles/toc.yml b/articles/toc.yml
index b0ab4a1..38aa1ae 100644
--- a/articles/toc.yml
+++ b/articles/toc.yml
@@ -58,6 +58,8 @@
href: migrate_xna.md
- name: Packaging
href: packaging_games.md
+- name: Preparing for consoles
+ href: preparing_for_consoles.md
- name: Samples and Demos
href: samples.md
- name: Community Tutorials
@@ -65,6 +67,6 @@
- name: Help and Support
href: help_and_support.md
- name: Contributing to documentation
- href: contributing
+ href: contributing.md
- name: MonoGame
href: monogame/Index.md
\ No newline at end of file
diff --git a/docfx.json b/docfx.json
index d9c7c5b..a96e10b 100644
--- a/docfx.json
+++ b/docfx.json
@@ -19,6 +19,12 @@
"EnumSortOrder": "alphabetic"
}
],
+ "rules": {
+ "InvalidFileLink": "error",
+ "InvalidBookmark": "error",
+ "UidNotFound": "error",
+ "ReferencedXrefPropertyNotString": "error"
+ },
"build": {
"content": [
{
@@ -34,7 +40,8 @@
"foundation/**/*.md",
"toc.yml",
"*.md"
- ]
+ ],
+ "exclude": [ "_site/**", "README.md" ]
}
],
"resource": [
diff --git a/external/MonoGame b/external/MonoGame
index 40452a4..940eb9b 160000
--- a/external/MonoGame
+++ b/external/MonoGame
@@ -1 +1 @@
-Subproject commit 40452a45c261a4a32c63e1c6c35e5f2676c1dfc2
+Subproject commit 940eb9bf3b77a176c429ca528c49eb2f72fbf865