Skip to content

Commit

Permalink
Migrate website docs into main repo
Browse files Browse the repository at this point in the history
The website kept getting out of date - seems easier to keep everything
in one place. Also might encourage more contributions/fixes if docs
are in the main repo.
  • Loading branch information
17cupsofcoffee committed Mar 28, 2024
1 parent 6799ff2 commit fb4ada6
Show file tree
Hide file tree
Showing 14 changed files with 1,299 additions and 6 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

Tetra is a simple 2D game framework written in Rust. It uses SDL2 for event handling and OpenGL 3.2+ for rendering.

* [Website](https://tetra.seventeencups.net)
* [Tutorial](https://tetra.seventeencups.net/tutorial)
* [API Docs](https://docs.rs/tetra)
* [FAQ](https://tetra.seventeencups.net/FAQ)
* [Installation Guide](/docs/installation.md)
* [Distribution Guide](/docs/distributing.md)
* [Examples](/docs/examples.md)
* [Tutorial](/docs/tutorial/)
* [FAQ](/docs/faq.md)

## Status

Expand Down
69 changes: 69 additions & 0 deletions docs/distributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Distributing

> [!NOTE]
> This page is a work in progress. It's especially missing information on Mac and Linux, as I'm not sure what the idiomatic ways of distributing games are on those platforms!
>
> If you have knowledge of these platforms, or other experience distributing games written in Rust, please [contribute](https://github.com/17cupsofcoffee/tetra-www/edit/main/docs/distributing.md)!
This page lists some of the things that should be taken into consideration when distributing a game built with Tetra.

## Required

### Build in Release Mode

By default, Cargo builds projects in debug mode, with very few optimizations. When you plan on distributing your game, you should make sure to run `cargo build` with the `--release` flag, to ensure that the final executable is as optimized as possible. There are [benchmarks in the FAQ](/faq/#benchmarks) which show that this makes a significant different to the performance!

### Include SDL 2.0

Tetra uses a C library called SDL 2.0 to interact with platform-specific functionality (such as windowing and input). Unlike Tetra's Rust dependencies, SDL is usually dynamically linked, meaning that the library needs to be present on the end user's machine for your application to run. Therefore, it is usually good practice to bundle SDL with your game when distributing it.

On Windows, the easiest way to do this is to include `SDL2.dll` in the same folder as your game's executable. You will probably have a copy of this file already if you followed the [installation guide](./installation.md), but if not, you can obtain it via the '[Runtime Binaries](https://www.libsdl.org/download-2.0.php)' section of SDL's website.

Alternatively, you can choose to [statically link SDL into your game](/faq/#can-i-static-link-sdl) - however, this comes with [some tradeoffs](https://hg.libsdl.org/SDL/file/default/docs/README-dynapi.md) that need to be taken into account, so make sure you understand them before switching.

### Include Software Licenses

Tetra is provided under the terms of the [MIT License](https://opensource.org/licenses/MIT). One of the terms of this license is that you must include [the license text](https://github.com/17cupsofcoffee/tetra/blob/main/LICENSE) alongside 'all copies or substantial portions' of the library. Similar terms apply to many of Tetra's dependencies, including [the Rust standard library](https://github.com/rust-lang/rust/blob/master/COPYRIGHT), so it is important to make sure you've fulfilled these requirements when distributing your game to the public.

In practice, this usually means adding a screen to your game that displays open source licenses, or providing text files alongside the executable.

> [!TIP]
> [Embark Studios](https://www.embark-studios.com) has created a tool called [`cargo-about`](https://github.com/EmbarkStudios/cargo-about/) which can help you automate the arduous task of gathering these license files and outputting them into a template.
>
> Note, however, that it [does not currently provide license info for the Rust standard library](https://github.com/EmbarkStudios/cargo-about/issues/16) - you will need to obtain this yourself.
## Optional

### Change the Game's Icon/Metadata

By default, an application built by Cargo won't have any sort of icon or metadata, which can look somewhat unprofessional.

On Windows, you can add these via the [`embed-resource`](https://crates.io/crates/embed-resource) or [`winres`](https://github.com/mxre/winres) crates, which can be used via a `build.rs` script in your project. Alternatively, you can call directly into the `rc` command line tool included in the Windows SDK, or use an GUI application such as [ResEdit](http://www.resedit.net/).

On Mac, icons and metadata can be added by creating an Application Bundle, also known as a `.app`. Full details on the structure of these bundles can be found in [Apple's documentation](#change-the-game-s-icon-metadata).

On Linux, icons and metadata are generally provided via a [`.desktop` file](https://specifications.freedesktop.org/desktop-entry-spec/latest/) placed in `/usr/share/applications/` (for everyone on the machine) or `~/.local/share/applications` (for a single user). This will also make your game appear in the user's 'Applications' list.

> [!TIP]
> You may also want to consider using something like [AppImage](https://appimage.org/) to package your game and its metadata for distribution - this works in a similar manner to creating an Application Bundle on Mac.
### Hide the Console Window

On some platforms, applications built with Rust will display a console window while running by default. This can be useful while debugging, but is usually undesirable for the final release.

On Windows, you can hide this window by adding the `windows_subsystem` attribute to your `main.rs`:

```rust
// To hide the console in all builds:
#![windows_subsystem = "windows"]

// To hide the console in release builds only:
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
```

> [!WARNING]
> When `windows_subsystem = "windows"` is applied, your application will no longer be able to read from `stdin` or write to `stdout`/`stderr`, as Windows does not attach them by default for GUI applications. Amonst other things, this means that you cannot log errors via `println!` or by returning them from `main` - no output will be displayed, even if the game is run from a command line.
>
> Make sure you have some other way of logging out fatal errors, otherwise it will be very difficult to diagnose the cause of crashes!
On Mac, packaging your game as an Application Bundle (`.app`) as described in ['Change the Game's Icon/Metadata'](#change-the-game-s-icon-metadata) will prevent the terminal window from being displayed.
37 changes: 37 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Examples

Tetra has a fairly large suite of examples - to try them out, clone the repository and run:

```bash
cargo run --example example_name
```

You can also click on the name of the example below to view the source code.

| Name | Category | Description |
| --- | --- | --- |
| [`hello_world`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/hello_world.rs) | Basic | Opens a window and clears it with a solid color. |
| [`texture`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/texture.rs) | Graphics | Loads and displays a texture. |
| [`shaders`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/shaders.rs) | Graphics | Uses a custom shader to render a texture. |
| [`canvas`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/canvas.rs) | Graphics | Uses a custom render target to apply post-processing effects. |
| [`mesh`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/mesh.rs) | Graphics | Draws a custom mesh using vertex data. |
| [`animation`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/animation.rs) | Graphics | Displays an animation, made up of regions from a texture. |
| [`text`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/text.rs) | Graphics | Displays text using a TTF font. |
| [`nineslice`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/nineslice.rs) | Graphics | Slices a texture into nine segments to display a dialog box. |
| [`scaling`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/scaling.rs) | Graphics | Demonstrates the different screen scaling algorithms. |
| [`camera`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/camera.rs) | Graphics | Demonstrates how to use a camera to transform the scene. |
| [`interpolation`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/interpolation.rs) | Graphics | Demonstrates how to interpolate between updates. |
| [`shapes`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/shapes.rs) | Graphics | Demonstrates how to draw primitive shapes. |
| [`stencil`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/stencil.rs) | Graphics | Demonstrates how to use stencil buffers. |
| [`audio`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/audio.rs) | Audio | Plays back an audio file. |
| [`keyboard`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/keyboard.rs) | Input | Moves a texture around based on keyboard input. |
| [`animation_controller`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/animation_controller.rs) | Input | Moves a sprite around, with the animation changing based on keyboard input. |
| [`mouse`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/mouse.rs) | Input | Moves a texture around based on mouse input. |
| [`gamepad`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/gamepad.rs) | Input | Displays the input from a connected gamepad. |
| [`text_input`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/text_input.rs) | Input | Displays text as it is typed in by the player. |
| [`file_drop`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/file_drop.rs) | Input | Loads a file that the user drags and drops into the window. |
| [`events`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/events.rs) | Input | Shows what events can be fired by the engine. |
| [`error_handling`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/error_handling.rs) | Error Handling | Demonstrates how custom error types and error reporting crates can be used in a Tetra game. |
| [`bunnymark`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/bunnymark.rs) | Benchmark | Benchmarks rendering performance by rendering lots of bunnies. |
| [`ecs`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/ecs.rs) | Integration | Demonstrates how ECS (entity component system) libraries can be used with Tetra. |
| [`tetras`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/tetras.rs) | Game | A full example game (which is entirely legally distinct from a certain other block-based puzzle game *cough*). |
108 changes: 108 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# FAQ

## General

### Will Tetra be written in pure Rust eventually?

Probably not - SDL2 is a stable and well-tested foundation for building games, and it runs on basically every platform under the sun, so I'm hesitant to replace it. That's likely to remain the only non-Rust dependency, however.

If you're looking for a similar engine that _is_ pure Rust, [GGEZ](https://github.com/ggez/ggez) and [Macroquad](https://github.com/not-fl3/macroquad) are good options.

### Do I have to install SDL manually?

It's possible to have your project automatically compile SDL2 from source as part of the build process. To do so, specify your dependency on Tetra like this:

```toml
[dependencies.tetra]
version = "0.7"
features = ["sdl2_bundled"]
```

This is more convienent, but does however require you to have various build tools installed on your machine (e.g. a C compiler, CMake, etc). In particular, this can be a pain on Windows - hence why it's not the default!

### Can I static link SDL?

If you want to avoid your users having to install SDL2 themselves (or you having to distribute it as a DLL), you can specify for it to be statically linked:

```toml
[dependencies.tetra]
version = "0.7"
features = ["sdl2_static_link"]
```

This comes with some trade-offs, however - make sure you read [this document](https://hg.libsdl.org/SDL/file/default/docs/README-dynapi.md) in the SDL2 repository so that you understand what you're doing!

## Graphics

### Why am I getting a black screen?

Tetra currently targets OpenGL 3.2, so if your hardware does not support this, you might have trouble running games written with the framework. You can check your version of OpenGL by enabling Tetra's debug output - add `.debug_info(true)` to your `ContextBuilder`, run your game, and then look at the console.

If your OpenGL version is 3.2 or higher and you're still getting a black screen, that may indicate a bug - I currently only have access to a Windows machine with a reasonably modern graphics card, so it's not outside the realms of possibility that something that works for me might be broken for others! Please submit an issue, and I'll try to fix it and release a patch version.

### Does Tetra support drawing custom meshes?

Yes - the `Mesh` API has been available since 0.5.4.

### Does Tetra support drawing primitive shapes?

Yes - since 0.5.8, `Mesh` has constructors for basic shapes and there is a `GeometryBuilder` type that can be used to build more complex shapes without manipulating raw vertex data. For more complex/custom use cases, the third party [`lyon`](https://github.com/nical/lyon) crate can be used to generate vertex data.

Note that primitive shape drawing currently isn't batched, so drawing too many generated shapes at once may be slow.

If that's all too complicated and you just want to draw simple rectangles, you could also [create a solid colored `Texture`](https://docs.rs/tetra/0.7.0/tetra/graphics/struct.Texture.html#method.from_data) and then draw that. If you create a 1x1 solid white texture, you can use the `scale` and `color` `DrawParams` to draw multiple rectangles of varying sizes/colors/transparencies in a single draw call.

### Does Tetra support high-DPI rendering?

Tetra added basic support for high-DPI rendering in 0.5.4, which can be enabled via [`ContextBuilder::high_dpi`](https://docs.rs/tetra/0.7/tetra/struct.ContextBuilder.html#method.high_dpi). You may also need some platform-specific configuration/packaging - see the docs for `ContextBuilder::high_dpi` for more info.

## Performance

### Why is my game running slow?

Cargo builds projects in debug mode by default. This can lead to your game running slowly, as the compiler does not fully optimize your code.

Optimizations can be enabled by passing `--release` when building/running your project, but this increases build times quite significantly and removes debug info from the binary, meaning you cannot easily debug or profile your code.

To work around this, add one of the following snippets to your `Cargo.toml`:

```toml
# To enable optimizations in debug mode for Tetra only (requires Rust 1.41):
[profile.dev.package.tetra]
opt-level = 3

# To enable optimizations in debug mode for all dependencies (requires Rust 1.41):
[profile.dev.package."*"]
opt-level = 3

# To enable optimizations in debug mode for the entire project (works with all Rust versions):
[profile.dev]
opt-level = 3
```

Choosing one of the first two options is preferred, as they will not slow down rebuilds of your game's code.

You should also make sure to build with `--release` when distributing your game, so that the final binary is as fast as possible.

#### Benchmarks

The impact of compiler optimizations can be observed by running the `bunnymark` example both with and without the `--release` flag. This example adds 100 new sprites to the screen every time the user clicks, until rendering conistently drops below 60fps.

These were the results when I ran it against Tetra 0.2.9 on my local machine:

| Configuration | Bunnies Rendered |
| ------------- | ---------------- |
| Debug | 3200 |
| Release | 230000 |

For reference, my system specs are:

- CPU: AMD Ryzen 5 1600 3.2GHz
- GPU: NVidia GeForce GTX 1050 Ti
- RAM: 8GB DDR4

## Miscellaneous

### Why is it called Tetra?

I'm terrible at naming projects, and [this](https://www.youtube.com/watch?v=g3xg28yaZ5E) happened to be playing when I was typing `cargo new`. I wish there was a better origin story than that :D
81 changes: 81 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Installation

To get started with Tetra, you'll need several things installed, some of which are only needed on certain platforms:

* **All platforms:**
* The latest stable version of Rust
* The SDL 2.0 development libraries
* **Linux:**
* The ALSA development libraries

## Installing Rust

Installing Rust is pretty simple - just go to [the website](https://www.rust-lang.org/tools/install) and download the Rustup toolchain manager.

Note that if you're developing on Windows with the default toolchain, you'll also need to install the [Microsoft Visual C++ Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017). This is used for linking your code together.

## Installing SDL 2.0

Tetra uses a library called SDL for windowing and input, so you will need to have its runtime and development libraries installed in order for your project to compile.

### Windows

1. Go to [SDL's GitHub releases page](https://github.com/libsdl-org/SDL/releases) and download the version of the development libraries that corresponds to your Rust toolchain.
* If you're using the MSVC toolchain, download `SDL2-devel-2.xx.x-VC.zip`.
* If you're using the GNU toolchain, download `SDL2-devel-2.xx.x-mingw.zip`.
2. Inside the .zip file, open the `SDL2-2.xx.x/lib/x64` folder and extract `SDL2.lib` and `SDL2.dll` to the root of your Cargo workspace.
* If you're on a 32-bit system, use the files in `SDL2-2.xx.x/lib/x86` instead.

You will also need to distribute `SDL2.dll` with your game - see the [distributing guide](./distributing.md) for more details.

You can also automatically compile SDL2 from source as part of the build process - see [Do I have to install SDL manually?](./faq.md/#do-i-have-to-install-sdl-manually) for more details.

### Mac

The easiest way to install SDL is via [Homebrew](http://brew.sh/):

```bash
brew install sdl2
```

You will also need to add the following to your `~/.bash_profile`, if it is not already present.

```bash
export LIBRARY_PATH="$LIBRARY_PATH:/opt/homebrew/lib:/usr/local/lib"
```

> [!WARNING]
> If you're building your game on Catalina, make sure that you use SDL 2.0.12 or higher - there is a
> [bug in earlier versions](https://hg.libsdl.org/SDL/rev/46b094f7d20e) which causes the OpenGL
> viewport to not scale correctly. See [issue #147](https://github.com/17cupsofcoffee/tetra/issues/147)
> for more information.
### Linux

The SDL development libraries are distributed through most Linux package managers - here are a few examples:

```bash
# Ubuntu/Debian
sudo apt install libsdl2-dev

# Fedora/CentOS
sudo yum install SDL2-devel

# Arch Linux
sudo pacman -S sdl2
```

## Installing ALSA (Linux only)

On Linux, ALSA is used as the audio backend, so you will need the ALSA development libraries installed. Similar to SDL, you can find these libraries on most Linux package managers:

```bash
# Ubuntu/Debian
sudo apt install libasound2-dev

# Fedora/CentOS
sudo yum install alsa-lib-devel

# Arch Linux
sudo pacman -S alsa-lib
```
Loading

0 comments on commit fb4ada6

Please sign in to comment.