Introduction
Here's the documentation for Spaceships v1.1.1. Right now this documentation is pretty incomplete.
If you have any questions, answer them here on Lemmy. If you don't have an account on Lemmy, create one here on Spaceships Lemmy or another instance.
Screenshots
Here are some screenshots of the game:
Links
- Website: https://spaceships.me
- Download: https://spaceships.me/download
- Documentation: https://spaceships.me/docs
- Source code: https://codeberg.org/rustydev/spaceships
- Lemmy: https://lemmy.spaceships.me
- Development blog: https://lemmy.spaceships.me/c/blog
- Help and support: https://lemmy.spaceships.me/c/help
How to play
Joining a game
To start a game, you first need to start a server or join an already existing server. See the "Hosting a server" section for more information about starting a server.
If the game server is hosted on the local network, joining the game is done by clicking "Play" and then "Local" under. Then click "Search LAN" and if everything works well, the game server will pop up and you can then click "Play".
If the game server is hosted on the internet (or on the local network but the above instructions don't work for some reason), instead click "Enter Address" and enter the IP address or domain name in the "Host" section. The "Game ID" section can be left blank unless the server administrator tells you to set it to a particular value.
You can also play Spaceships in a singleplayer mode where you can immediately join a local game (where nobody else can join) to test things out. Playing Spaceships only makes sense with other people, it won't be fun at all doing it by yourself (this might change in the future if I create bot players).
Playing a game
The goal of the game is simple, you're a spaceship and you need to kill other spaceships by firing bullets at them to diminish their health and eventually destroy them. At the moment there isn't anything beyond that. The server keeps track of a list of scores, which are the number of kills each player has. If you leave the game, your score will be reset.
Controls
To move around, use WASD or the arrow keys. To change the direction you're looking in and where bullets will be fired from, move the mouse. Bullets are shot by pressing the left mouse button or spacebar. You can hold down these buttons to easily fire multiple bullets at a time. These controls can be changed by pressing the "Settings" button while in the title screen.
You can zoom the camera in and out by scrolling (or by pressing 'J' and 'K'), and you can reset to the default zoom by pressing the middle mouse button.
Health
Your health is displayed in the health bar at the bottom of your screen, with the number of bullets also displayed above that. The health bars of other players are displayed right above them. After getting shot, players slowly regenerate their health.
Ammo
You have a finite amount of bullets (unless the server is configured to provide you infinite), which are reset when you die. Periodically during the game, ammo crates are spawned which supply the player collecting them with a random amount of bullets.
Powerups
Additionally, powerups are periodically spawned which give the player collecting them a temporary effect. These effects either last for 30 seconds or happen immediately (teleportation) and are listed as follows:
- Speed. This is the green powerup which increases your movement speed.
- Reload. This is the yellow powerup which increases your reload speed, making you shoot faster.
- Health. This is the pink powerup which increases your health and makes you regenerate health faster. The increase of health that this powerup provides can increase your health above the usual limit and make your health bar blue.
- Damage. This is the red powerup which increases the damage of your bullets.
- Forcefield. This is the blue powerup which provides a forcefield that deflects bullets fired by other players.
- Teleportation. This is the purple powerup which teleports you to a random place on the map. Unlike the others, this can be disadvantageous depending where you teleport...
Here are these six powerups:
Hosting a server
Right now hosting a server is only possible using the command line.
There are many different worlds that you can create, a few of them are provided in the configs/
directory. Feel free to modify them or create your own. I haven't yet wrote documentation on how exactly things are configured, see the source code (and in particular src/net/server/config.rs
) for more information.
To start a server, simply run ./spaceships server configs/CONFIG.ron
, replacing configs/CONFIG.ron
with the exact configuration to use. On Windows, you would run ./spaceships.exe server ...
.
The server program outputs logs to the terminal (in particular, stderr), which include information about players joining and leaving the game. The server also provides a simple REPL interface which allows more advanced configuration.
If you're running an internet server with an associated domain name, if users want to connect to the server by entering the domain name you will need a valid TLS (also called SSL) certificate. To run the server to use this certificate, run ./spaceships ... --cert-path PATH --key-path PATH
, replacing PATH
with the paths of the certificate and private key. These paths are to files in the PEM format.
Requesting server info
This game is licensed under the GNU AGPLv3, which requires that any user interacting with the game over the network can get a copy of the exact version of the game running on the server. If you want to know the exact version of a server and if it's a fork, run ./spaceships info HOST
, where HOST
is the domain name or IP address of the server.
Server configuration
The long-term goal of Spaceships is to support configuration of everything in the game, including the physics, weapons, other objects and the goal of the game (how players can actually "win"), similar to how games like Luanti currently are.
Right now Spaceships isn't there yet, but game servers are pretty configurable.
If you find any errors in this documentation, which are likely if I forget to update this in future versions, make an issue here.
Get started
The documentation here is incomplete. I recommend first taking a look at files in the configs/
directory attached with your distribution of the game, or at https://codeberg.org/rustydev/spaceships/src/branch/main/configs for examples of what a config file looks like. These can be used as a template for creating your own server config.
These configuration files are in the RON (Rusty Object Notation) format. See the link for more information.
The complete schema of the config files is available inside src/net/server/config.rs
, with some (but not enough) code comments explaining things.
Example
Here's an example of a very simple configuration file that's an infinite world with no blocks in it.
Config(
world_size: (inf, inf),
lan_discovery: LanDiscovery(
name: "Empty",
desc: "An empty map.",
),
blocks: Blocks(
block_size: 1,
grid_size: (0, 0),
ops: [ Constant(0) ],
),
)
Now here's an explanation of each of these fields:
world_size
: This specifies the width and height of the world. Players cannot go outside this space. In this example, both the width and height are set toinf
, which configures an infinite world.lan_discovery
: The first chapter of this documentation briefly goes over LAN discovery as a way to easily join game servers hosted on the local network. Here,lan_discovery.name
andlan_discovery.desc
set the displayed name and description of the game server respectively.blocks
: This consists of three fields, each for configuring the physical blocks in the world that constrain the players' movement.blocks.block_size
: This is an integer that sets how large each block is in the game.blocks.grid_size
: This sets the width and height of the grid which contains these blocks. The number of blocks in this grid cannot exceed 220.blocks.ops
: This specifies a list of operations that are performed on block maps stored on a stack to produce a final block map.
Spawning, ammo crates and powerups
To configure these, see the fields with the events
prefix. See the full schema for more information.
Special areas
Introduced in v1.1.0 is the ability for the server to send an arbitrary list of rectangles of arbitrary position, size and colour to the clients, which the clients should render these in the world. These are designed for highlighting regions of the world where custom server-side configuration can perform certain actions. Right now the two special areas implemented in this game are portals and effect zones, though more special areas can be added in the future and those special areas can still be compatible with older clients.
Here's an example of how to add special areas that are just decorative:
Config(
...
special_areas: SpecialAreas(
areas: [
( pos: Vec2(15, 15), size: Vec2(4, 4), colour: (127, 255, 0, 63) )
],
),
)
Portals
Portals allow players (but not bullets) to teleport from one location to another. Portals can either be sinks (you enter these), sources (you leave these), or bidirectional (you can go both ways). Portals are expressed in the config as a directed graph, with nodes being the portals and edges being the possible transitions between portals. If a node has more than one outgoing edge, players entering that portal will teleport to a random outgoing neighbour of that portal.
It is a desirable feature to allow the velocity of players to change after they leave the portal, like if they entered a horizontal portal and leave a vertical portal. To do this, special_areas.portals.out.rotation
can be set to either D0
(default for no rotation), D90
, D180
or D270
.
When specifying portals, make sure that the player isn't inside a block or outside the world border if they are at the portal's centre. If you don't ensure this, it might be possible for players to teleport inside a block.
Example
Config(
...
special_areas: SpecialAreas(
portals: [
Portal(
p0: Vec2(-4.5, -3.0), p1: Vec2(1.5, 0.5),
out: [PortalLink(
index: 1,
rotation: D90,
), PortalLink(
index: 2,
)],
),
Portal( p0: Vec2(12.5, -9.5), p1: Vec2(14.5, -1.5) ),
Portal(
p0: Vec2(22, 22), p1: Vec2(24, 23),
out: [PortalLink(
index: 0,
)],
),
],
),
)
Effect zones
An effect zone is a region where players get effects applied to them (the same effects that powerups give) while there. These effects can persist for an arbitrary amount of time when the player leaves the effect zone.
Example
Config(
special_areas: SpecialAreas(
effect_zones: [
EffectZone(
p0: Vec2(15, 15),
p1: Vec2(19, 19),
effect: Speed,
time: 5,
power: Some(4), // Very fast!
),
]
),
)
Stability
I make no guarantees about the stability of this schema between versions. I hope that backwards compatibility works just fine between changes in the patch version (third number of the version), but I won't be too careful about ensuring this.
Advanced configuration
Everything that can be configured right now through the server config is just a small sample of what you can actually configure. If you want to add something like an effect zone but for giving players ammo, it's possible to modify the server source code without needing all players to update their game to your specific fork.
Here's a list of ideas that can be implemented for custom server-side configuration that unmodified clients can play with:
- Recoil: When players fire bullets, the server can decrease the player's velocity by a small amount in the opposite direction of the fired bullet.
- Stealing ammo: When a player kills another player, an ammo crate might spawn containing all ammo that player had.
- Player-player collision: Right now the game's physics don't support collision between players. However, this functionality can be hacked on by the server arbitrarily controlling the players' positions and velocities.
Even more advanced configuration would require forking the game, such as if you want to add a new type of weapon.
Tips
Here are some tips to be more efficient when customising a game server:
- Right-click to print position. When in the world, you can right-click (or whatever you choose to bind it to) and the position your cursor's pointing at will be printed to stderr. This can be very helpful when placing special effects.
reload
command. In the server console, you can runreload default
to quickly restart the server, which you might do a lot.
Server console
When starting the server, you have access to a console that allows addition and removal of game servers, without restarting the entire process. Complete documentation for these particular commands isn't provided here but instead available by running help
in this console. Instead what is documented here is game ids and basic usage of running multiple game servers on the same process.
When using this console, I recommend redirecting stderr to a file (or /dev/null) to avoid the logs from distracting you as you write your commands.
Game ids
A spaceships server can run multiple different game servers on the same UDP port. When a player joins the game, the client includes a game id in the request it makes to the server to play the game. The server then takes this id and checks its "routing table" to find a game server the player can join. Game ids are either entered manually when manually entering the address, or automatically with LAN discovery.
The exact mapping of game ids to game servers is up to the server. It is possible to have multiple game ids mapped to the same server.
One game server can be configured to be the default, if it has game id "default". Here, if the user entered a game id that doesn't match any explicit rule in the routing table, the player will join this default server. When you start a server without specifying a game id, it will be configured to be the default server.
Private servers
Game ids can be used to have the server accessible over the internet but restrict who can join the game by requiring users enter a password. Here, the game id is the password. This works because over the internet, it is not possible for clients to gain access to this routing table.
However if the client is on the local network, by default the game id is exposed locally and anyone on the local network can find it out by using LAN discovery. If this is a problem, you can completely disable LAN discovery by adding --lan-discovery disabled
through command line arguments.
Examples
Here are some examples. Lines beginning with $
indicate a shell, while lines beginning with >
indicate the server console.
Multiple servers
Here is an example of how to host multiple game servers on the same process.
$ ./spaceships server maze:configs/maze.ron
> add cave:configs/cave.ron
> add white_noise:configs/white_noise.ron
> route add white_noise noise
> add configs/empty.ron
After running all of this, the game ids maze
and cave
are mapped to the servers with configs configs/maze.ron
and configs/cave.ron
respectively. Game ids white_noise
and noise
are mapped to a single server with config configs/white_noise.ron
. Finally, all other game ids are mapped to configs/empty.ron
by default.
Hosting a private server
Here is how to run just a single server only accessible through a hard to guess game id.
$ ./spaceships server I-L0v3_sP4c35h1p5:configs/private.ron
Make sure that no colons are present in the password or the game will instead be accessible at multiple, possibly easier to guess, game ids. To ensure that everything is working fine after starting the server, run status
and if it prints something like as follows:
> status
Showing status for all game servers:
0: {"I-L0v3_sP4c35h1p5"}
path = configs/private.ron
player count = 0/8
The important part is that only one game id is listed on the third line.