initial commit

main
cosmonaut 2021-01-24 21:09:37 -08:00
commit 4f3fbe68ae
14 changed files with 405 additions and 0 deletions

6
archetypes/default.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

18
config.toml Normal file
View File

@ -0,0 +1,18 @@
baseURL = "http://moonside.games/docs/MoonWorks/"
publishDir = "public"
languageCode = "en-us"
title = "MoonWorks Handbook"
theme = "hugo-theme-learn"
canonifyUrls = true
relativeUrls = true
[outputs]
home = [ "HTML", "RSS", "JSON"]
[params]
themeVariant = "red"
description = "Documentation for MoonWorks"
author = "Evan Hemsley"
showVisitedLinks = false
disableBreadcrumb = false
disableNextPrev = false

48
content/Audio/_index.md Normal file
View File

@ -0,0 +1,48 @@
---
title: "Audio"
date: 2021-01-24T20:15:28-08:00
weight: 3
---
MoonWorks.Audio is implemented using the [FAudio](https://github.com/FNA-XNA/FAudio) library. The main entry point for audio-related functions is `AudioDevice`. A reference to this class is automatically created and can be retrieved from your `Game` subclass.
There are two main kinds of audio content: static and streaming. MoonWorks supports only Ogg Vorbis files by default, but you can support whatever kind of audio file you want by providing a custom decoder of your choice.
### Static Audio
Static audio is loaded completely into memory, and multiple "instances" of the audio can be created and played. This kind of audio is ideal for short sound effects that may be played simultaneously.
The trade-off is that static audio takes a lot more memory than streaming audio, since the entire sound must be stored in memory in order to be played. This kind of audio is not a good choice for things like long music tracks.
To load and play a static sound, you would do something like this:
```cs
var jumpSoundEffect = StaticSound.LoadOgg(AudioDevice, "jump.ogg");
var jumpSoundEffectInstance = jumpSoundEffect.CreateInstance();
jumpSoundEffectInstance.Play();
```
### Streaming Audio
Streaming audio is streamed from file storage over its duration, and only a small portion of the audio is stored in memory while it is played. This kind of audio is ideal for recorded dialogue and music.
The trade-off here is that streaming audio needs to be read continuously from storage, which may be slow. If you stream too much audio at once you may notice audio stuttering.
To load and play streaming sound, you would do something like this:
```cs
var music = StreamingSoundOgg.Load(AudioDevice, "my_music.ogg");
music.Play();
```
### Effects
MoonWorks.Audio sound playback can be modified with several effects, such as panning, reverb, pass filters, and more. To apply these effects, simply set the relevant properties on the sound instance.
```cs
jumpSoundEffectInstance.Reverb = 1.5f;
jumpSoundEffectInstance.Pitch = -0.25f;
jumpSoundEffectInstance.Pan = -0.5f;
jumpSoundEffectInstance.Play();
```

View File

@ -0,0 +1,5 @@
---
title: "Graphics Device"
date: 2021-01-24T20:52:59-08:00
---

10
content/Graphics/Intro.md Normal file
View File

@ -0,0 +1,10 @@
---
title: "Intro"
date: 2021-01-24T20:54:00-08:00
---
If the other MoonWorks tools have seemed simple so far, MoonWorks.Graphics may surprise you. Graphics is implemented using the [Refresh](https://gitea.moonside.games/MoonsideGames/Refresh) library. Refresh is based on Vulkan, an industry-standard cross-platform graphics API. It provides no "standard" rendering system that you can easily hook into, unlike what you may be used to with an engine like Unity. In order to render to the screen, you will need to set up, at the minimum, a Color Target, Framebuffer, a Render Pass, some Shader Modules, a Graphics Pipeline, and provide vertex data to be rendered through the pipeline.
This might sound complicated, and I can't deny that, yeah, it's complicated. But everything is complicated at first. I promise to walk you through it as best I can, and once you understand how the pipeline works, you will have total control over your rendering and you will be able to create extremely high performance games that look exactly how you want.
Let's get started!

View File

@ -0,0 +1,10 @@
+++
title = "Graphics"
date = 2021-01-24T20:51:36-08:00
weight = 4
chapter = true
+++
# Graphics
This is the big one.

75
content/Input/_index.md Normal file
View File

@ -0,0 +1,75 @@
---
title: "Input"
date: 2021-01-23T16:39:09-08:00
weight: 2
---
All input-related information can be retrieved through the `Inputs`.
This class is automatically updated with input information and a reference to it can be retrieved from your `Game` subclass.
### Buttons
There are four properties that buttons can have, and these apply to keyboard, mouse, and gamepad inputs.
`IsPressed` means that the button was pressed this frame.
`IsHeld` means that the button has been held down for at least two frames.
`IsDown` means that the button was pressed or held on this frame.
`IsReleased` means that the button is not currently being pressed.
If you wanted to check if the A button on Gamepad 0 was pressed this frame, you would do this:
```cs
if (Inputs.GetGamepad(0).A.IsPressed)
{
// do stuff
}
```
If you wanted to check if the right mouse button was not pressed, you could do this:
```cs
if (Inputs.Mouse.RightButton.IsReleased)
{
// do stuff
}
```
You can look up keyboard key states with the `Keycode` enum. For example:
```cs
if (Inputs.Keyboard.IsDown(Keycode.S))
{
// do stuff
}
```
would tell you that the S key is currently down.
## Mouse Input
In addition to the mouse buttons, there are two kinds of positional information: window-relative position and per-frame deltas.
```cs
var mouseX = Inputs.Mouse.X;
var deltaMouseY = Inputs.Mouse.DeltaY;
```
`RelativeMode` hides the mouse and does not update the position of the mouse while still returning movement deltas.
This is ideal for creating FPS-style controls. To enable it, simply do:
```cs
Inputs.Mouse.RelativeMode = true;
```
## Gamepad Input
MoonWorks assumes your gamepad has a left stick, a right stick, and two triggers. The stick axes are represented in the range [-1f, 1f] and the trigger axes in the range [0f, 1f];
```cs
var leftStickHorizontal= Inputs.GetGamepad(0).LeftX;
var rightStickVertical = Inputs.GetGamepad(0).RightY;
var leftTrigger = Inputs.GetGamepad(0).LeftTrigger;
```

22
content/Window/_index.md Normal file
View File

@ -0,0 +1,22 @@
---
title: "Window"
date: 2021-01-24T20:43:17-08:00
weight: 1
---
Window management in MoonWorks is implemented using the [SDL2](https://www.libsdl.org) library. All window management is handled through the `Window` class. A reference to this class is automatically created and can be retrieved from your `Game` subclass.
Your game is assumed to have a window and you must pass a `WindowCreateInfo` struct when creating your `Game`.
- `WindowTitle` is in the operating system.
- `WindowWidth` is how wide the window will be.
- `WindowHeight` is how tall the window will be.
- `ScreenMode` determines whether the window will be created in windowed mode, fullscreen, or borderless fullscreen.
You can change the screen mode at runtime with the `ChangeScreenMode` method:
```cs
Window.ChangeScreenMode(ScreenMode.Fullscreen);
```
Note that if you change the screen resolution, it is *your* responsibility to manage any graphics state that may need to change as a result of this change.

18
content/_index.md Normal file
View File

@ -0,0 +1,18 @@
---
title: "MoonWorks"
date: 2021-01-23T16:39:09-08:00
---
# MoonWorks
MoonWorks is a free cross-platform game development framework. Its implementation is heavily inspired by [FNA](https://fna-xna.github.io/), which is itself a free implementation of the [Microsoft XNA](https://en.wikipedia.org/wiki/Microsoft_XNA) API.
MoonWorks wraps native-code implementations in managed C# for clean high-level abstractions that still run fast. It's simple and it tries to stay out of your way as much as possible.
MoonWorks **does** provide the components you need to implement a functioning game: window management, input, graphics, 3D math utilities, and audio.
MoonWorks **does not** include things like a built-in physics engine, a GUI editor, or a standard rendering pipeline. These decisions and tools are better made per-team or per-project. In short, if you know or want to learn what a vertex buffer is, this framework is for you.
MoonWorks uses strictly Free Open Source Software. It does not have any kind of dependency on proprietary products, and it never will! I have been working professionally on games for nearly a decade and in that time I have learned that proprietary software is utterly disastrous for long-term maintenance of projects. You deserve to have the freedom to own your development process.
If all this sounds good to you, read on!

View File

@ -0,0 +1,193 @@
:root{
--MAIN-TEXT-color:#323232; /* Color of text by default */
--MAIN-TITLES-TEXT-color: #5e5e5e; /* Color of titles h2-h3-h4-h5 */
--MAIN-LINK-color:#71b986; /* Color of links */
--MAIN-LINK-HOVER-color:#317a53; /* Color of hovered links */
--MAIN-ANCHOR-color: #71b986; /* color of anchors on titles */
--MENU-HEADER-BG-color:#8ECAE6; /* Background color of menu header */
--MENU-HEADER-BORDER-color:#3E7483; /*Color of menu header border */
--MENU-SEARCH-BG-color:#4C8D90; /* Search field background color (by default borders + icons) */
--MENU-SEARCH-BOX-color: #93B7C1; /* Override search field border color */
--MENU-SEARCH-BOX-ICONS-color: #C8DCE2; /* Override search field icons color */
--MENU-SECTIONS-ACTIVE-BG-color:#023047; /* Background color of the active section and its childs */
--MENU-SECTIONS-BG-color:#219EBC; /* Background color of other sections */
--MENU-SECTIONS-LINK-color: #ccc; /* Color of links in menu */
--MENU-SECTIONS-LINK-HOVER-color: #e6e6e6; /* Color of links in menu, when hovered */
--MENU-SECTION-ACTIVE-CATEGORY-color: #777; /* Color of active category text */
--MENU-SECTION-ACTIVE-CATEGORY-BG-color: #fcf7f8; /* Color of background for the active category (only) */
--MENU-VISITED-color: #71b986; /* Color of 'page visited' icons in menu */
--MENU-SECTION-HR-color: #20272b; /* Color of <hr> separator in menu */
}
@font-face {
font-family: 'Public Sans';
src: url("../fonts/publicsans-regular-webfont.woff") format("woff");
src: url("../fonts/publicsans-regular-webfont.woff2") format("woff2");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: 'Public Sans';
src: url("../fonts/publicsans-light-webfont.woff") format("woff");
src: url("../fonts/publicsans-light-webfont.woff2") format("woff2");
font-style: normal;
font-weight: 300;
}
body {
color: var(--MAIN-TEXT-color) !important;
font-family: 'Public Sans'
}
#chapter h3 {
font-family: "Work Sans", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif;
font-weight: 300;
text-align: center;
}
textarea:focus, input[type="email"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="url"]:focus, input[type="color"]:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, select[multiple=multiple]:focus {
border-color: none;
box-shadow: none;
}
h2, h3, h4, h5 {
color: var(--MAIN-TITLES-TEXT-color) !important;
}
h2, h3, h4, h5, h6 {
font-family: "Work Sans", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif;
text-rendering: optimizeLegibility;
color: #5e5e5e;
font-weight: 400;
letter-spacing: -1px;
}
a {
color: var(--MAIN-LINK-color);
}
.anchor {
color: var(--MAIN-ANCHOR-color);
}
a:hover {
color: var(--MAIN-LINK-HOVER-color);
}
#sidebar ul li.visited > a .read-icon {
color: var(--MENU-VISITED-color);
}
#body a.highlight:after {
display: block;
content: "";
height: 1px;
width: 0%;
-webkit-transition: width 0.5s ease;
-moz-transition: width 0.5s ease;
-ms-transition: width 0.5s ease;
transition: width 0.5s ease;
background-color: var(--MAIN-LINK-HOVER-color);
}
#sidebar {
background-color: var(--MENU-SECTIONS-BG-color);
}
#sidebar #header-wrapper {
background: var(--MENU-HEADER-BG-color);
color: var(--MENU-SEARCH-BOX-color);
border-color: var(--MENU-HEADER-BORDER-color);
}
#sidebar .searchbox {
border-color: var(--MENU-SEARCH-BOX-color);
background: var(--MENU-SEARCH-BG-color);
}
#sidebar ul.topics > li.parent, #sidebar ul.topics > li.active {
background: var(--MENU-SECTIONS-ACTIVE-BG-color);
}
#sidebar .searchbox * {
color: var(--MENU-SEARCH-BOX-ICONS-color);
}
#sidebar a {
color: var(--MENU-SECTIONS-LINK-color);
}
#sidebar a:hover {
color: var(--MENU-SECTIONS-LINK-HOVER-color);
}
#sidebar ul li.active > a {
background: var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color);
color: var(--MENU-SECTION-ACTIVE-CATEGORY-color) !important;
}
#sidebar hr {
border-color: var(--MENU-SECTION-HR-color);
}
/* Overrides because the default Learn theme adds terrible heading bars to each paragraph */
div.notices p:first-child:before {
position: absolute;
top: -28px;
color: #fff;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f06a";
left: 10px;
}
div.notices p:first-child:after {
position: absolute;
top: -28px;
color: #fff;
left: 2rem;
}
div.notices.info {
border-top: 30px solid #F0B37E;
background: #FFF2DB;
}
div.notices.info p {
border-top: none;
}
div.notices.note {
border-top: 30px solid #6AB0DE;
background: #E7F2FA;
}
div.notices.note p {
border-top: none;
}
div.notices.warning {
border-top: 30px solid rgba(217, 83, 79, 0.8);
background: #FAE2E2;
}
div.notices.warning p {
border-top: none;
}
div.notices.tip {
border-top: 30px solid rgba(92, 184, 92, 0.8);
background: #E6F9E6;
}
div.notices.tip p {
border-top: none;
}
/* override highlight.js bullshit */
div.highlight pre {
background-color: #06122F !important;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.