Safe Haskell | None |
---|---|
Language | Haskell2010 |
Rollback and replay based game networking
Synopsis
- runServerWith :: forall input. (Eq input, Flat input) => ServiceName -> Maybe SimNetConditions -> ServerConfig -> input -> IO ()
- runServerWith' :: forall input clientAddress. (Eq input, Flat input, Show clientAddress, Ord clientAddress) => (NetMsg input -> clientAddress -> IO ()) -> IO (NetMsg input, clientAddress) -> Maybe SimNetConditions -> ServerConfig -> input -> IO ()
- data ServerConfig = ServerConfig {}
- defaultServerConfig :: Int -> ServerConfig
- runClientWith :: forall world input. Flat input => HostName -> ServiceName -> Maybe SimNetConditions -> ClientConfig -> input -> world -> (Map PlayerId input -> Tick -> world -> world) -> IO (Client world input)
- runClientWith' :: forall world input. Flat input => (NetMsg input -> IO ()) -> IO (NetMsg input) -> Maybe SimNetConditions -> ClientConfig -> input -> world -> (Map PlayerId input -> Tick -> world -> world) -> IO (Client world input)
- data ClientConfig = ClientConfig {}
- defaultClientConfig :: Int -> ClientConfig
- data Client world input
- clientPlayerId :: Client world input -> PlayerId
- clientSample :: Client world input -> IO world
- clientSample' :: Client world input -> IO ([world], world)
- clientSetInput :: Client world input -> input -> IO ()
- clientStop :: Client world input -> IO ()
- data SimNetConditions = SimNetConditions {}
- newtype Tick = Tick Int64
- newtype PlayerId = PlayerId {
- unPlayerId :: Word8
- data NetMsg input
- type HostName = String
- type ServiceName = String
Server
:: forall input. (Eq input, Flat input) | |
=> ServiceName | The server's port number e.g. |
-> Maybe SimNetConditions | Optional simulation of network conditions. In production this should be
|
-> ServerConfig | The |
-> input | Initial input for new players. Must be the same across all clients and the server. |
-> IO () |
Run a server for a single game. This will block until the game ends, specifically when all players have disconnected.
:: forall input clientAddress. (Eq input, Flat input, Show clientAddress, Ord clientAddress) | |
=> (NetMsg input -> clientAddress -> IO ()) | Function to send messages to clients. The underlying communication protocol need only guarantee data integrity but is otherwise free to drop and reorder packets. Typically this is backed by a UDP socket. |
-> IO (NetMsg input, clientAddress) | Blocking function to receive messages from the clients. Has the same reliability requirements as the send function. |
-> Maybe SimNetConditions | Optional simulation of network conditions. In production this should be
|
-> ServerConfig | The |
-> input | Initial input for new players. Must be the same across all clients and
the server. See |
-> IO () |
Run a server for a single game. This will block until the game ends, specifically when all players have disconnected.
data ServerConfig Source #
Configuration options specific to the server.
ServerConfig | |
|
Instances
Eq ServerConfig Source # | |
Defined in Alpaca.NetCode.Internal.Server (==) :: ServerConfig -> ServerConfig -> Bool # (/=) :: ServerConfig -> ServerConfig -> Bool # | |
Ord ServerConfig Source # | |
Defined in Alpaca.NetCode.Internal.Server compare :: ServerConfig -> ServerConfig -> Ordering # (<) :: ServerConfig -> ServerConfig -> Bool # (<=) :: ServerConfig -> ServerConfig -> Bool # (>) :: ServerConfig -> ServerConfig -> Bool # (>=) :: ServerConfig -> ServerConfig -> Bool # max :: ServerConfig -> ServerConfig -> ServerConfig # min :: ServerConfig -> ServerConfig -> ServerConfig # | |
Read ServerConfig Source # | |
Defined in Alpaca.NetCode.Internal.Server readsPrec :: Int -> ReadS ServerConfig # readList :: ReadS [ServerConfig] # | |
Show ServerConfig Source # | |
Defined in Alpaca.NetCode.Internal.Server showsPrec :: Int -> ServerConfig -> ShowS # show :: ServerConfig -> String # showList :: [ServerConfig] -> ShowS # |
:: Int | Tick rate (ticks per second). Typically |
-> ServerConfig |
Sensible defaults for ServerConfig
based on the tick rate.
Client
:: forall world input. Flat input | |
=> HostName | The server's host name or IP address e.g. |
-> ServiceName | The server's port number e.g. |
-> Maybe SimNetConditions | Optional simulation of network conditions. In production this should be
|
-> ClientConfig | The |
-> input | Initial input for new players. Must be the same across all clients and
the server. See |
-> world | Initial world state. Must be the same across all clients. |
-> (Map PlayerId input -> Tick -> world -> world) | A deterministic stepping function (for a single tick). Must be the same
across all clients and the server. See |
-> IO (Client world input) |
Start a client. This blocks until the initial handshake with the server is finished.
:: forall world input. Flat input | |
=> (NetMsg input -> IO ()) | Function to send messages to the server. The underlying communication protocol need only guarantee data integrity but is otherwise free to drop and reorder packets. Typically this is backed by a UDP socket. |
-> IO (NetMsg input) | Blocking function to receive messages from the server. Has the same reliability requirements as the send function. |
-> Maybe SimNetConditions | Optional simulation of network conditions. In production this should be
|
-> ClientConfig | The |
-> input | Initial input for new players. Must be the same across all clients and
the server. See |
-> world | Initial world state. Must be the same across all clients. |
-> (Map PlayerId input -> Tick -> world -> world) | A deterministic stepping function (for a single tick). Must be the same
across all clients and the server. See |
-> IO (Client world input) |
Start a client. This blocks until the initial handshake with the server is finished.
data ClientConfig Source #
Configuration options specific to clients.
ClientConfig | |
|
Instances
Eq ClientConfig Source # | |
Defined in Alpaca.NetCode.Internal.Client (==) :: ClientConfig -> ClientConfig -> Bool # (/=) :: ClientConfig -> ClientConfig -> Bool # | |
Ord ClientConfig Source # | |
Defined in Alpaca.NetCode.Internal.Client compare :: ClientConfig -> ClientConfig -> Ordering # (<) :: ClientConfig -> ClientConfig -> Bool # (<=) :: ClientConfig -> ClientConfig -> Bool # (>) :: ClientConfig -> ClientConfig -> Bool # (>=) :: ClientConfig -> ClientConfig -> Bool # max :: ClientConfig -> ClientConfig -> ClientConfig # min :: ClientConfig -> ClientConfig -> ClientConfig # | |
Read ClientConfig Source # | |
Defined in Alpaca.NetCode.Internal.Client readsPrec :: Int -> ReadS ClientConfig # readList :: ReadS [ClientConfig] # | |
Show ClientConfig Source # | |
Defined in Alpaca.NetCode.Internal.Client showsPrec :: Int -> ClientConfig -> ShowS # show :: ClientConfig -> String # showList :: [ClientConfig] -> ShowS # |
:: Int | Tick rate (ticks per second). Must be the same across all clients and the server. Packet rate and hence network bandwidth will scale linearly with this the tick rate. |
-> ClientConfig |
Sensible defaults for ClientConfig
based on the tick rate.
clientPlayerId :: Client world input -> PlayerId Source #
The client's PlayerId
clientSample :: Client world input -> IO world Source #
Sample the current world state.
. First, This will estimate the current tick based on ping and clock synchronization with the server. Then, this extrapolates past the latest know authoritative world state by assuming no user inputs have changed (unless otherwise known e.g. our own player's inputs are known). If the client has been stopped, this will return the last predicted world.
clientSample' :: Client world input -> IO ([world], world) Source #
Sample the world state. First, This will estimate the current tick based on ping and clock synchronization with the server. Then, the world state will be rollback and inputs replayed as necessary. This returns:
- New authoritative world states in chronological order since the last sample time. These world states are the True world states at each tick. This list will be empty if no new authoritative world states have been derived since that last call to this sample function. Though it's often simpler to just use the predicted world state, you can use these authoritative world states to render output when you're not willing to miss-predict but are willing to have greater latency. If the client has been stopped, this will be an empty list.
- The predicted current world state. This extrapolates past the latest know authoritative world state by assuming no user inputs have changed (unless otherwise known e.g. our own player's inputs are known). If the client has been stopped, this will return the last predicted world.
clientSetInput :: Client world input -> input -> IO () Source #
Set the client's current input.
clientStop :: Client world input -> IO () Source #
Stop the client.
Common Types
data SimNetConditions Source #
Settings for simulating network conditions. Packets in both the send and
receive directions are randomly dropped or delayed by `simPing/2` plus some
random duration between `-simJitter` and simJitter
.
Instances
Eq SimNetConditions Source # | |
Defined in Alpaca.NetCode.Internal.Common (==) :: SimNetConditions -> SimNetConditions -> Bool # (/=) :: SimNetConditions -> SimNetConditions -> Bool # | |
Ord SimNetConditions Source # | |
Defined in Alpaca.NetCode.Internal.Common compare :: SimNetConditions -> SimNetConditions -> Ordering # (<) :: SimNetConditions -> SimNetConditions -> Bool # (<=) :: SimNetConditions -> SimNetConditions -> Bool # (>) :: SimNetConditions -> SimNetConditions -> Bool # (>=) :: SimNetConditions -> SimNetConditions -> Bool # max :: SimNetConditions -> SimNetConditions -> SimNetConditions # min :: SimNetConditions -> SimNetConditions -> SimNetConditions # | |
Read SimNetConditions Source # | |
Defined in Alpaca.NetCode.Internal.Common | |
Show SimNetConditions Source # | |
Defined in Alpaca.NetCode.Internal.Common showsPrec :: Int -> SimNetConditions -> ShowS # show :: SimNetConditions -> String # showList :: [SimNetConditions] -> ShowS # |
The game is broken into discrete ticks starting from 0.
Instances
Either a host name e.g., "haskell.org"
or a numeric host
address string consisting of a dotted decimal IPv4 address or an
IPv6 address e.g., "192.168.0.1"
.
type ServiceName = String #
Either a service name e.g., "http"
or a numeric port number.