all repos — xrxs @ 940791631c398464e63264313f5872851d88b974

experimental networked application/game server with 9p

README.md (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# xrxs

`xrxs` is an experimental game server using the Plan 9 protocol `9p`.

The client is intended to be a specialized [uxn](https://wiki.xxiivv.com/site/uxn.html) ROM that can load other ROMs (possibly preserving its own code to maintain a common menu system or interface to `xrxs`).

## design

This is the working structure of the 9p filesystem:

* `/ctl`: Write-only control file for inputing system commands
  * `login PW`: Authenticate with `xrxs` -- password is hashed against realm password hash
  * `load CART`: Load a cartridge
  * `chunk TYPE N`: Load data of type TYPE and chunk number N
  * `create REALM`: Create a new realm (start a new game) -- must have a cartridge loaded
  * `protect PW`: Protect the curent realm with a password if you are the master.
  * `transfer USER`: Transfer ownership of the realm to another user.
  * `enter REALM`: Join an existing realm
  * `leave`: Leave the current realm
  * `unload`: Unload the cartridge
  
* `/users`: Read-only; Self and others in the realm are readable from here, one per line. It contains only yourself before joining a realm. Your username on your machine is used as your username in `xrxs` -- if your name is taken, you will get an error on attaching.

* `/carts`: Available game/app cartridges for this server, read only; Carts are listed per line upon reading the file. It is backed by files on the server in a directory structure like `carts/CART_NAME/{CART_NAME.rom, data/, realms/}`.
  
* `/slot`: After loading the cartridge, its ROM is read from here; Read-only.

* `/data/`: Any supporting data that comes with the cartridge will be found here; They are in three parts: `sprite`, `audio`, and `text`. Because `uxn` is limited to 64-128kb input files, the filesizes of these data blobs should be 64kb max, and the `chunk` command should be used to page different files into the service when needed. The files on the server should be like `TYPEN` where `TYPE` is one of `sprite`, `audio`, and `text`, and `N` is any sequence of characters (canonically a nonnegative integer). When first loading the cartridge, `N == 0`. Issuing the command `chunk TYPE XXX` will attempt to load data from file `carts/CART_NAME/data/TYPEXXX` into the correct data file. If `TYPE` is not one of `sprite`, `audio`, or `text`, or the ifle `TYPEXXX` doesn't exist in the data directory, the `chunk` command does nothing.

* `/realms`: Open/saved realms, read-only. Realms and their associated universe are backed by real files on the server so that they can be preserved across service instantiations, in a directory structure like: `carts/CART_NAME/realms/REALM_NAME/{realm, universe}`. Realms can either be solo, open, or protected; Open or protected realms can have limited member numbers. Depending on the cartridge, these settings can be user-managed or managed by the cartridge itself. Realms are listed per line upon reading the file like: `REALM_NAME 1 4 1`. First would obviously be the name of the realm. The first number is number of members, second is member limit, third is 1 if protected, 0 if not. `0 1 1` represents a protected solo realm that is empty (saved game with password). `0 1 0` represents an unprotected solo realm that is empty (saved game with no password).

* `/universe`: Write here to update serverside state for this cart/realm; Read from here to get the complete current state. This is backed by a key-value-pair list on the server.

* `/scope`: Write here to tell the server the names of the `Atom`s (key/value pair of a `Universe`) you're interested in (one per line), and read from here to retrieve their values (one per line). In many cases this will be preferrable to fetching the entire `Universe`.
  
* `/random`: Read-only, get a random number from 0 to 99.

* `/grandom`: Read-only, get a random number from 0 to 99 -- These are doled out on a per-realm basis, and the number stays the same until everyone in the realm has had a chance to read it. If you've already read it this round or aren't in a realm, it will be empty.

## realm format

Each realm directory on the server should have the following files:

  * `realm`: Basic data for the realm, file should contain only the maximum number of members, the master's name, and the password hash, if any (otherwise 0), separated by spaces.
  * `universe`: The actual game state for the realm as key value pairs, one per line, like `KEY = VALUE`; limit 15 characters for keys, 63 for values.
  
The realm should be synchronized to disc when realm membership, limit, or password change. Fenagling some periodic autosave should be possible...