Safe Haskell | None |
---|---|
Language | Haskell2010 |
Atomic game state transformations.
See https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture.
- class MonadStateRead m => MonadAtomic m where
- execAtomic :: CmdAtomic -> m ()
- execUpdAtomic :: UpdAtomic -> m ()
- execSfxAtomic :: SfxAtomic -> m ()
- broadcastUpdAtomic :: MonadAtomic m => (FactionId -> UpdAtomic) -> m ()
- broadcastSfxAtomic :: MonadAtomic m => (FactionId -> SfxAtomic) -> m ()
- data CmdAtomic
- data UpdAtomic
- = UpdCreateActor !ActorId !Actor ![(ItemId, Item)]
- | UpdDestroyActor !ActorId !Actor ![(ItemId, Item)]
- | UpdCreateItem !ItemId !Item !ItemQuant !Container
- | UpdDestroyItem !ItemId !Item !ItemQuant !Container
- | UpdSpotActor !ActorId !Actor ![(ItemId, Item)]
- | UpdLoseActor !ActorId !Actor ![(ItemId, Item)]
- | UpdSpotItem !ItemId !Item !ItemQuant !Container
- | UpdLoseItem !ItemId !Item !ItemQuant !Container
- | UpdMoveActor !ActorId !Point !Point
- | UpdWaitActor !ActorId !Bool
- | UpdDisplaceActor !ActorId !ActorId
- | UpdMoveItem !ItemId !Int !ActorId !CStore !CStore
- | UpdAgeActor !ActorId !(Delta Time)
- | UpdRefillHP !ActorId !Int64
- | UpdRefillCalm !ActorId !Int64
- | UpdFidImpressedActor !ActorId !FactionId !FactionId
- | UpdTrajectory !ActorId !(Maybe ([Vector], Speed)) !(Maybe ([Vector], Speed))
- | UpdColorActor !ActorId !Color !Color
- | UpdQuitFaction !FactionId !(Maybe Actor) !(Maybe Status) !(Maybe Status)
- | UpdLeadFaction !FactionId !(Maybe (ActorId, Maybe Target)) !(Maybe (ActorId, Maybe Target))
- | UpdDiplFaction !FactionId !FactionId !Diplomacy !Diplomacy
- | UpdTacticFaction !FactionId !Tactic !Tactic
- | UpdAutoFaction !FactionId !Bool
- | UpdRecordKill !ActorId !(Id ItemKind) !Int
- | UpdAlterTile !LevelId !Point !(Id TileKind) !(Id TileKind)
- | UpdAlterClear !LevelId !Int
- | UpdSearchTile !ActorId !Point !(Id TileKind) !(Id TileKind)
- | UpdLearnSecrets !ActorId !Int !Int
- | UpdSpotTile !LevelId ![(Point, Id TileKind)]
- | UpdLoseTile !LevelId ![(Point, Id TileKind)]
- | UpdAlterSmell !LevelId !Point !(Maybe Time) !(Maybe Time)
- | UpdSpotSmell !LevelId ![(Point, Time)]
- | UpdLoseSmell !LevelId ![(Point, Time)]
- | UpdTimeItem !ItemId !Container !ItemTimer !ItemTimer
- | UpdAgeGame !(Delta Time) ![LevelId]
- | UpdDiscover !Container !ItemId !(Id ItemKind) !ItemSeed !AbsDepth
- | UpdCover !Container !ItemId !(Id ItemKind) !ItemSeed !AbsDepth
- | UpdDiscoverKind !Container !ItemId !(Id ItemKind)
- | UpdCoverKind !Container !ItemId !(Id ItemKind)
- | UpdDiscoverSeed !Container !ItemId !ItemSeed !AbsDepth
- | UpdCoverSeed !Container !ItemId !ItemSeed !AbsDepth
- | UpdPerception !LevelId !Perception !Perception
- | UpdRestart !FactionId !DiscoveryKind !FactionPers !State !Int !DebugModeCli
- | UpdRestartServer !State
- | UpdResume !FactionId !FactionPers
- | UpdResumeServer !State
- | UpdKillExit !FactionId
- | UpdWriteSave
- | UpdMsgAll !Msg
- | UpdRecordHistory !FactionId
- data SfxAtomic
- = SfxStrike !ActorId !ActorId !ItemId !CStore !HitAtomic
- | SfxRecoil !ActorId !ActorId !ItemId !CStore !HitAtomic
- | SfxProject !ActorId !ItemId !CStore
- | SfxCatch !ActorId !ItemId !CStore
- | SfxApply !ActorId !ItemId !CStore
- | SfxCheck !ActorId !ItemId !CStore
- | SfxTrigger !ActorId !Point !Feature
- | SfxShun !ActorId !Point !Feature
- | SfxEffect !FactionId !ActorId !Effect
- | SfxMsgFid !FactionId !Msg
- | SfxMsgAll !Msg
- | SfxActorStart !ActorId
- data HitAtomic
- data PosAtomic
- posUpdAtomic :: MonadStateRead m => UpdAtomic -> m PosAtomic
- posSfxAtomic :: MonadStateRead m => SfxAtomic -> m PosAtomic
- seenAtomicCli :: Bool -> FactionId -> Perception -> PosAtomic -> Bool
- generalMoveItem :: MonadStateRead m => ItemId -> Int -> Container -> Container -> m [UpdAtomic]
- posProjBody :: Actor -> PosAtomic
Re-exported from Game.LambdaHack.Atomic.MonadAtomic
class MonadStateRead m => MonadAtomic m where Source
The monad for executing atomic game state transformations.
execAtomic :: CmdAtomic -> m () Source
Execute an arbitrary atomic game state transformation.
execUpdAtomic :: UpdAtomic -> m () Source
Execute an atomic command that really changes the state.
execSfxAtomic :: SfxAtomic -> m () Source
Execute an atomic command that only displays special effects.
MonadAtomic SerImplementation | The game-state semantics of atomic commands as computed on the server. |
MonadAtomic (CliImplementation resp req) | The game-state semantics of atomic commands as computed on the client. |
broadcastUpdAtomic :: MonadAtomic m => (FactionId -> UpdAtomic) -> m () Source
Create and broadcast a set of atomic updates, one for each client.
broadcastSfxAtomic :: MonadAtomic m => (FactionId -> SfxAtomic) -> m () Source
Create and broadcast a set of atomic special effects, one for each client.
Re-exported from Game.LambdaHack.Atomic.CmdAtomic
Abstract syntax of atomic commands, that is, atomic game state transformations.
Abstract syntax of atomic updates, that is, atomic commands that really change the state. Most of them are an encoding of a game state diff, though they also carry some intentional hints that help clients determine whether and how to communicate them to players.
Abstract syntax of atomic special effects, that is, atomic commands that only display special effects and don't change the state.
Determine if a strike special effect should depict a block of an attack.
Re-exported from Game.LambdaHack.Atomic.PosAtomicRead
The type representing visibility of atomic commands to factions, based on the position of the command, etc. Note that the server sees and smells all positions.
PosSight !LevelId ![Point] | whomever sees all the positions, notices |
PosFidAndSight ![FactionId] !LevelId ![Point] | observers and the faction notice |
PosSmell !LevelId ![Point] | whomever smells all the positions, notices |
PosFid !FactionId | only the faction notices |
PosFidAndSer !(Maybe LevelId) !FactionId | faction and server notices |
PosSer | only the server notices |
PosAll | everybody notices |
PosNone | never broadcasted, but sent manually |
posUpdAtomic :: MonadStateRead m => UpdAtomic -> m PosAtomic Source
Produce the positions where the atomic update takes place.
The goal of the mechanics is to ensure the commands don't carry significantly more information than their corresponding state diffs would. In other words, the atomic commands involving the positions seen by a client should convey similar information as the client would get by directly observing the changes the commands enact on the visible portion of server game state. The client is then free to change its copy of game state accordingly or not --- it only partially reflects reality anyway.
E.g., UpdDisplaceActor
in a black room,
with one actor carrying a 0-radius light would not be
distinguishable by looking at the state (or the screen) from UpdMoveActor
of the illuminated actor, hence such UpdDisplaceActor
should not be
observable, but UpdMoveActor
should be (or the former should be perceived
as the latter). However, to simplify, we assing as strict visibility
requirements to UpdMoveActor
as to UpdDisplaceActor
and fall back
to UpdSpotActor
(which provides minimal information that does not
contradict state) if the visibility is lower.
posSfxAtomic :: MonadStateRead m => SfxAtomic -> m PosAtomic Source
Produce the positions where the atomic special effect takes place.
seenAtomicCli :: Bool -> FactionId -> Perception -> PosAtomic -> Bool Source
Given the client, it's perception and an atomic command, determine if the client notices the command.
generalMoveItem :: MonadStateRead m => ItemId -> Int -> Container -> Container -> m [UpdAtomic] Source
Generate the atomic updates that jointly perform a given item move.
posProjBody :: Actor -> PosAtomic Source