Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added docs/.nojekyll
Empty file.
11 changes: 11 additions & 0 deletions docs/Getting-started/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
### Making a Game

If you want to make a game, check out the [First Devcade Game](Getting-started/first-game) page. This will help you make your first game for Devcade, including getting you familiar with some [Monogame](https://www.monogame.net/) basics.

### Using the API

If you want to work with the Devcade API, check out the [API](Internals/API/) page. This will give you all the information you need to make requests to the API, and which end points to use.

### Building a Devcade Cabinet

If you want to make your own Devcade machine, check out the [Hardware](Hardware/) page. This page includes a bill of materials and instructions that were followed when making the first Devcade machine.
7 changes: 7 additions & 0 deletions docs/Getting-started/first-game.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Making your first Devcade game

So, you want to make a Devcade game? Well you chose the right place.

### What makes a Devcade game?

Most Devcade games are made with the Monogame framework.
Empty file.
6 changes: 6 additions & 0 deletions docs/Hardware/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Hardware

There are a few main components to the Hardware involved for running Devcade:
* The [DCU, or Devcade Compute Unit](Hardware/installing-dcu)
* The [Arcade Cabinet](Hardware/cabinet)
* The [Gamepad](Hardware/gamepad)
1 change: 1 addition & 0 deletions docs/Hardware/cabinet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Cabinet
1 change: 1 addition & 0 deletions docs/Hardware/gamepad.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Gamepad
175 changes: 175 additions & 0 deletions docs/Hardware/installing-dcu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@

# Setting up a Devcade cabinet

## Table of Contents
- [Installing an OS](#installing-debian-11)
- [Network Configuration](#configuring-network)
- [APT Configuration](#fixing-apt)
- [Sources](#sources-list)
- [Packages](#package-setup)
- [Dotnet](#dotnet-sdk)
- [Misc Setup](#other-misc-setup)
- [Devcade Onboard Setup](#installing-onboard)
- [Clone](#clone-the-repo)
- [Environment](#environment-vars)
- [Daemons](#summoning-daemons)
- [X setup](#x-setup)
- [.xinitrc](#xinitrc)
- [Xinput](#xinput)
- [Pulseaudio](#pulseaudio-setup)
- [Daemons](#arcane-daemonology)


## Installing Debian 11

The Devcade project should theoretically run on just about any linux distro if set up properly. Our distro of choice for this guide will be Debian 11. Boot to the installer and proceed installing normally except for the following settings:

- User: `devcade`
- Force UEFI Mode
- Use Entire Disk
- Everything on 1 partition

## Configuring Network

Get MAC address and other info with `ip a`

Other network configurations will depend on your specific network setup. For example, we create a record in our network management system and reboot the computer to obtain DHCP.

## Fixing Apt

### Sources list

Edit `/etc/apt/source.list` and change (as needed):

* Remove the local cdrom:// source
* Uncomment the official Debian repositories
* Add bullseye main repository
* `apt update`
* `apt upgrade`


### Package Setup

Install optional but useful packages:

* `apt install openssh-server`
* `apt install neofetch`
* `apt install vim`
* `apt install datadog-agent`

Install required packages:

apt install git xorg xterm compton openbox pulseaudio

### Dotnet SDK

[Add Microsoft repositories](https://learn.microsoft.com/en-us/dotnet/core/install/linux-debian#debian-11) and install the 6.0 version of the SDK. This is the version that most everything Devcade is written in and is guaranteed* to work with the source code. Future versions of the SDK might introduce breaking changes.

`apt install dotnet-sdk-6.0`


## Other Misc Setup

Add devcade to sudoers file (optional, highly recommended)

usermod -aG sudo devcade
echo "devcade ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers


## Installing onboard


### Clone the repo

Find a nice home for the onboard somewhere in your filesystem (like $HOME/git)

cd ~
mkdir git
cd git
git clone https://Github.com/ComputerScienceHouse/devcade-onboard
cd devcade-onboard

### Environment vars
<!-- TODO -->
Setup a .env file according to the .env template in the repo (coming soon). Then run the following:

cp .env ~/.env
echo "source /home/devcade/.env" >> ~/.bashrc

This will source the environment variables used by Devcade every time you login.

### Summoning Daemons

From the onboard directory, initialize the xlogin submodule by running:

git submodule update --init --recursive

To build the onboard program and put it in the correct place, run
<!-- TODO Update idiot naming →
./idiot/update_onboard.sh
cp idiot/.xinitrc /home/devcade
mkdir -p /home/devcade/.config/openbox && cp idiot/rc.xml /home/devcade/.config/openbox

To install xlogin do the following:

cd idiot/xlogin
sudo make install
sudo systemctl enable --now xlogin@devcade

You may also need to do:

cd /home/devcade/publish
chmod +x onboard

## X Setup

### .xinitrc

The .xinitrc file is by default setup to use HDMI-2. If your monitor is not plugged into the second HDMI port (HINT: it probably won't be) you’ll encounter errors and need to edit the .xinitrc file with the correct output type. The file onboard.log should have the output of xrandr, which will include the correct display adapter (HINT: it’s the only one that has resolutions listed)

With a correctly configured display adapter in the .xinitrc it should _Just Work™_

### Xinput

// TODO


## PulseAudio Setup

PulseAudio is another thing that should Just Work™.

If it doesn’t, use the following commands to fix which audio sink is selected.

* `pacmd list-cards` or `pactl list cards`
* `pacmd list-sinks` or `pactl list sinks`
* `pactl set-default-sink [NAME]`

The `[NAME]` option will be the name of the audio source, which is the ENTIRE string after the ‘Monitor Source’ line in the sink information. For example the soundbar currently used in the first cabinet is:

alsa_output.usb-Lenovo_Lenovo_USB_Soundbar-00.analog-stereo

If you have driver issues or encounter issues other than the sink not being set correctly: cry, pray, and despair, in that order.


## Arcane Daemonology

Once the computer is fully configured, the final step in the process is to set up a systemd service to automatically login and launch the onboard on boot. The only two things this requires are creating a service and editing the .bashrc

Create a service file at `/etc/systemd/system/getty@tty1.service.d/override.conf`. This may require creating a directory.
```
[Service]
Type=Simple
ExecStart=
ExecStart=-/sbin/agetty --autologin devcade --noclear %I 38400 linux
```

Then, add the following to the .bashrc of the devcade user:

```sh
if [[-z “$DISPLAY” ]] && [[ $(tty) = /dev/tty1 ]]; then
. startx
logout
fi
```

The machine will now login to the devcade user on boot and launch the onboard program. The onboard program will also relaunch every time it closes. To use a shell again, switch to a different tty or ssh into the machine.
153 changes: 153 additions & 0 deletions docs/Internals/API/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# API

- Download project and run `npm install`
- Use `npm run dev` to start the development server.
- If a `.env` file does not currently exist in the repo root directory, create one with:
```
# Express API Environment Variables
API_PORT=<api port>

PSQL_PORT=<psql port>
PSQL_USER=<psql user>
PSQL_PASS=<psql password>
PSQL_URI=<psql uri>

# Python Helper Environment Variables
S3_ACCESSKEYID=<aws s3 access key id>
S3_SECRETACCESSKEY=<aws s3 secret access key>
S3_ENDPOINT=<s3 endpoint uri>
S3_GAMES_BUCKET="devcade-games"
S3_SAVES_BUCKET="devcade-saves"
```

# Podman

First, build the container.
```
podman build . --tag devcade-api
```

You can run the container on your local machine with
```
podman run --rm -it --name devcade-api -p 8277:8277 --env-file=.env devcade-api
```

# API GET Routes

## Downloading A Game
- Route: `api/games/download/<existingGameId>`
- Downloads a game zip containing a single game directory

```javascript
/// Sample Usage in JavaScript using Axios

const axios = require('axios');

axios.get(`<api_url>:<port>/api/games/download/${<existingGameId>}`)
.then(res => {
// response logic
}).catch(err => {
console.log(err);
});
```

## Downloading A Game's Icon and Banner
- Route: `api/games/download/medias/<existingGameId>`
- Downloads a zip containing the banner and icon images for a game

```javascript
/// Sample Usage in JavaScript using Axios

const axios = require('axios');

axios.get(`<api_url>:<port>/api/games/download/medias/${<existingGameId>}`)
.then(res => {
// response logic
}).catch(err => {
console.log(err);
});
```

## Get Available Games List

### Getting Game Objects
- Route: `api/games/gamelist`
- Returns a JSON list containing the following object:

```javascript
{
"id": "<game uuid>",
"author": "<CSH username of author>",
"uploadDate": "<date string of upload date>",
"name": "<game title>",
"hash": "<hash value of game files used for game versioning>"
}
```

- This list can be deserialized using the Newtonsoft.Json nuget library in C#/.NET

```
/// Sample Usage in JavaScript using Axios

const axios = require('axios');

axios.get('<api_url>:<port>/api/games/gamelist')
.then(res => {
// response logic
}).catch(err => {
console.log(err);
});
```

### Listing Game Ids
- Route: `api/games/gamelist/ids`
- Returns a JSON list containing game uuid strings

```javascript
/// Sample Usage in JavaScript using Axios

const axios = require('axios');

axios.get('<api_url>:<port>/api/games/gamelist/ids')
.then(res => {
// response logic
}).catch(err => {
console.log(err);
});
```

# API POST Routes

## Uploading A Game
- Route: `api/games/upload`
- Takes a game zip and uploads it to the database

```javascript
/// Sample Usage in JavaScript using Axios

const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');

const upload = async () => {
try {
const file = fs.createReadStream('./zip.zip');
const title = 'GameName';

const form = new FormData();
form.append('title', title);
form.append('file', file);

const response = await axios.post(
'<api_url>:<port>/api/games/upload',
form,
{ headers: { ...form.getHeaders(), }
})
if (response.status === 200) {
return 'Upload complete';
}
} catch (err) {
throw err;
}
}
```
Loading