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 to inf, 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 and lan_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:

  1. 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.
  2. reload command. In the server console, you can run reload default to quickly restart the server, which you might do a lot.