LambdaHack-0.11.0.1: A game engine library for tactical squad ASCII roguelike dungeon crawlers

Safe Haskell | None
Language | Haskell2010

Game.LambdaHack.Atomic

Contents

- Re-exported from Game.LambdaHack.Atomic.CmdAtomic
- Re-exported from Game.LambdaHack.Atomic.HandleAtomicWrite
- Re-exported from Game.LambdaHack.Atomic.PosAtomicRead
- Re-exported from Game.LambdaHack.Atomic.MonadStateWrite

Description

Atomic game state transformations, their representation and semantics.

See https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture.

Synopsis

- data CmdAtomic
  - = UpdAtomic UpdAtomic
  - | SfxAtomic SfxAtomic
- data UpdAtomic
  - = UpdRegisterItems [(ItemId, Item)]
  - | UpdCreateActor ActorId Actor [(ItemId, Item)]
  - | UpdDestroyActor ActorId Actor [(ItemId, Item)]
  - | UpdCreateItem Bool ItemId Item ItemQuant Container
  - | UpdDestroyItem Bool ItemId Item ItemQuant Container
  - | UpdSpotActor ActorId Actor
  - | UpdLoseActor ActorId Actor
  - | UpdSpotItem Bool ItemId ItemQuant Container
  - | UpdLoseItem Bool ItemId ItemQuant Container
  - | UpdSpotItemBag Bool Container ItemBag
  - | UpdLoseItemBag Bool Container ItemBag
  - | UpdMoveActor ActorId Point Point
  - | UpdWaitActor ActorId Watchfulness Watchfulness
  - | UpdDisplaceActor ActorId ActorId
  - | UpdMoveItem ItemId Int ActorId CStore CStore
  - | UpdRefillHP ActorId Int64
  - | UpdRefillCalm ActorId Int64
  - | UpdTrajectory ActorId (Maybe ([Vector], Speed)) (Maybe ([Vector], Speed))
  - | UpdQuitFaction FactionId (Maybe Status) (Maybe Status) (Maybe (FactionAnalytics, GenerationAnalytics))
  - | UpdSpotStashFaction Bool FactionId LevelId Point
  - | UpdLoseStashFaction Bool FactionId LevelId Point
  - | UpdLeadFaction FactionId (Maybe ActorId) (Maybe ActorId)
  - | UpdDiplFaction FactionId FactionId Diplomacy Diplomacy
  - | UpdDoctrineFaction FactionId Doctrine Doctrine
  - | UpdAutoFaction FactionId Bool
  - | UpdRecordKill ActorId (ContentId ItemKind) Int
  - | UpdAlterTile LevelId Point (ContentId TileKind) (ContentId TileKind)
  - | UpdAlterExplorable LevelId Int
  - | UpdAlterGold Int
  - | UpdSearchTile ActorId Point (ContentId TileKind)
  - | UpdHideTile ActorId Point (ContentId TileKind)
  - | UpdSpotTile LevelId [(Point, ContentId TileKind)]
  - | UpdLoseTile LevelId [(Point, ContentId TileKind)]
  - | UpdSpotEntry LevelId [(Point, PlaceEntry)]
  - | UpdLoseEntry LevelId [(Point, PlaceEntry)]
  - | UpdAlterSmell LevelId Point Time Time
  - | UpdSpotSmell LevelId [(Point, Time)]
  - | UpdLoseSmell LevelId [(Point, Time)]
  - | UpdTimeItem ItemId Container ItemTimers ItemTimers
  - | UpdAgeGame (EnumSet LevelId)
  - | UpdUnAgeGame (EnumSet LevelId)
  - | UpdDiscover Container ItemId (ContentId ItemKind) AspectRecord
  - | UpdCover Container ItemId (ContentId ItemKind) AspectRecord
  - | UpdDiscoverKind Container ItemKindIx (ContentId ItemKind)
  - | UpdCoverKind Container ItemKindIx (ContentId ItemKind)
  - | UpdDiscoverAspect Container ItemId AspectRecord
  - | UpdCoverAspect Container ItemId AspectRecord
  - | UpdDiscoverServer ItemId AspectRecord
  - | UpdCoverServer ItemId AspectRecord
  - | UpdPerception LevelId Perception Perception
  - | UpdRestart FactionId PerLid State Challenge ClientOptions SMGen
  - | UpdRestartServer State
  - | UpdResume FactionId PerLid
  - | UpdResumeServer State
  - | UpdKillExit FactionId
  - | UpdWriteSave
  - | UpdHearFid FactionId (Maybe Int) HearMsg
  - | UpdMuteMessages FactionId Bool
- data HearMsg
  - = HearUpd UpdAtomic
  - | HearStrike (ContentId ItemKind)
  - | HearSummon Bool (GroupName ItemKind) Dice
  - | HearCollideTile
  - | HearTaunt Text
- data SfxAtomic
  - = SfxStrike ActorId ActorId ItemId
  - | SfxRecoil ActorId ActorId ItemId
  - | SfxSteal ActorId ActorId ItemId
  - | SfxRelease ActorId ActorId ItemId
  - | SfxProject ActorId ItemId
  - | SfxReceive ActorId ItemId
  - | SfxApply ActorId ItemId
  - | SfxCheck ActorId ItemId
  - | SfxTrigger ActorId LevelId Point (ContentId TileKind)
  - | SfxShun ActorId LevelId Point (ContentId TileKind)
  - | SfxEffect FactionId ActorId ItemId Effect Int64
  - | SfxItemApplied Bool ItemId Container
  - | SfxMsgFid FactionId SfxMsg
  - | SfxRestart
  - | SfxCollideTile ActorId Point
  - | SfxTaunt Bool ActorId
- data SfxMsg
  - = SfxUnexpected ReqFailure
  - | SfxExpected Text ReqFailure
  - | SfxExpectedEmbed ItemId LevelId ReqFailure
  - | SfxFizzles ItemId Container
  - | SfxNothingHappens ItemId Container
  - | SfxNoItemsForTile [[(Int, GroupName ItemKind)]]
  - | SfxVoidDetection DetectKind
  - | SfxUnimpressed ActorId
  - | SfxSummonLackCalm ActorId
  - | SfxSummonTooManyOwn ActorId
  - | SfxSummonTooManyAll ActorId
  - | SfxSummonFailure ActorId
  - | SfxLevelNoMore
  - | SfxLevelPushed
  - | SfxBracedImmune ActorId
  - | SfxEscapeImpossible
  - | SfxStasisProtects
  - | SfxWaterParalysisResisted
  - | SfxTransImpossible
  - | SfxIdentifyNothing
  - | SfxPurposeNothing
  - | SfxPurposeTooFew Int Int
  - | SfxPurposeUnique
  - | SfxPurposeNotCommon
  - | SfxRerollNothing
  - | SfxRerollNotRandom
  - | SfxDupNothing
  - | SfxDupUnique
  - | SfxDupValuable
  - | SfxColdFish
  - | SfxReadyGoods
  - | SfxTimerExtended ActorId ItemId CStore (Delta Time)
  - | SfxCollideActor ActorId ActorId
  - | SfxItemYield ItemId Int LevelId
- handleUpdAtomic :: MonadStateWrite m => UpdAtomic -> m ()
- data PosAtomic
  - = PosSight LevelId [Point]
  - | PosFidAndSight FactionId LevelId [Point]
  - | PosSmell LevelId [Point]
  - | PosSightLevels [(LevelId, Point)]
  - | PosFid FactionId
  - | PosFidAndSer FactionId
  - | PosSer
  - | PosAll
  - | PosNone
- posUpdAtomic :: MonadStateRead m => UpdAtomic -> m PosAtomic
- posSfxAtomic :: MonadStateRead m => SfxAtomic -> m PosAtomic
- iidUpdAtomic :: UpdAtomic -> [ItemId]
- iidSfxAtomic :: SfxAtomic -> [ItemId]
- breakUpdAtomic :: MonadStateRead m => UpdAtomic -> m [UpdAtomic]
- lidOfPos :: PosAtomic -> Maybe LevelId
- seenAtomicCli :: Bool -> FactionId -> PerLid -> PosAtomic -> Bool
- seenAtomicSer :: PosAtomic -> Bool
- class MonadStateRead m => MonadStateWrite (m :: Type -> Type) where
  - modifyState :: (State -> State) -> m ()
  - putState :: State -> m ()
- newtype AtomicFail = AtomicFail String

# Re-exported from Game.LambdaHack.Atomic.CmdAtomic

data CmdAtomic Source #

Abstract syntax of atomic commands, that is, atomic game state transformations.

Constructors

UpdAtomic UpdAtomic | atomic updates
SfxAtomic SfxAtomic | atomic special effects

#### Instances

Instances details

Show CmdAtomic Source # |
Instance details Defined in Game.LambdaHack.Atomic.CmdAtomic Methods showsPrec :: Int -> CmdAtomic -> ShowS Source # show :: CmdAtomic -> String Source # showList :: [CmdAtomic] -> ShowS Source #

data UpdAtomic Source #

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 it to players.

Constructors

UpdRegisterItems [(ItemId, Item)] |
UpdCreateActor ActorId Actor [(ItemId, Item)] |
UpdDestroyActor ActorId Actor [(ItemId, Item)] |
UpdCreateItem Bool ItemId Item ItemQuant Container |
UpdDestroyItem Bool ItemId Item ItemQuant Container |
UpdSpotActor ActorId Actor |
UpdLoseActor ActorId Actor |
UpdSpotItem Bool ItemId ItemQuant Container |
UpdLoseItem Bool ItemId ItemQuant Container |
UpdSpotItemBag Bool Container ItemBag |
UpdLoseItemBag Bool Container ItemBag |
UpdMoveActor ActorId Point Point |
UpdWaitActor ActorId Watchfulness Watchfulness |
UpdDisplaceActor ActorId ActorId |
UpdMoveItem ItemId Int ActorId CStore CStore |
UpdRefillHP ActorId Int64 |
UpdRefillCalm ActorId Int64 |
UpdTrajectory ActorId (Maybe ([Vector], Speed)) (Maybe ([Vector], Speed)) |
UpdQuitFaction FactionId (Maybe Status) (Maybe Status) (Maybe (FactionAnalytics, GenerationAnalytics)) |
UpdSpotStashFaction Bool FactionId LevelId Point |
UpdLoseStashFaction Bool FactionId LevelId Point |
UpdLeadFaction FactionId (Maybe ActorId) (Maybe ActorId) |
UpdDiplFaction FactionId FactionId Diplomacy Diplomacy |
UpdDoctrineFaction FactionId Doctrine Doctrine |
UpdAutoFaction FactionId Bool |
UpdRecordKill ActorId (ContentId ItemKind) Int |
UpdAlterTile LevelId Point (ContentId TileKind) (ContentId TileKind) |
UpdAlterExplorable LevelId Int |
UpdAlterGold Int |
UpdSearchTile ActorId Point (ContentId TileKind) |
UpdHideTile ActorId Point (ContentId TileKind) |
UpdSpotTile LevelId [(Point, ContentId TileKind)] |
UpdLoseTile LevelId [(Point, ContentId TileKind)] |
UpdSpotEntry LevelId [(Point, PlaceEntry)] |
UpdLoseEntry LevelId [(Point, PlaceEntry)] |
UpdAlterSmell LevelId Point Time Time |
UpdSpotSmell LevelId [(Point, Time)] |
UpdLoseSmell LevelId [(Point, Time)] |
UpdTimeItem ItemId Container ItemTimers ItemTimers |
UpdAgeGame (EnumSet LevelId) |
UpdUnAgeGame (EnumSet LevelId) |
UpdDiscover Container ItemId (ContentId ItemKind) AspectRecord |
UpdCover Container ItemId (ContentId ItemKind) AspectRecord |
UpdDiscoverKind Container ItemKindIx (ContentId ItemKind) |
UpdCoverKind Container ItemKindIx (ContentId ItemKind) |
UpdDiscoverAspect Container ItemId AspectRecord |
UpdCoverAspect Container ItemId AspectRecord |
UpdDiscoverServer ItemId AspectRecord |
UpdCoverServer ItemId AspectRecord |
UpdPerception LevelId Perception Perception |
UpdRestart FactionId PerLid State Challenge ClientOptions SMGen |
UpdRestartServer State |
UpdResume FactionId PerLid |
UpdResumeServer State |
UpdKillExit FactionId |
UpdWriteSave |
UpdHearFid FactionId (Maybe Int) HearMsg |
UpdMuteMessages FactionId Bool |

#### Instances

Instances details

Show UpdAtomic Source # |
Instance details Defined in Game.LambdaHack.Atomic.CmdAtomic Methods showsPrec :: Int -> UpdAtomic -> ShowS Source # show :: UpdAtomic -> String Source # showList :: [UpdAtomic] -> ShowS Source #

data HearMsg Source #

Symbolic representation of text messages about heard noises, sent by server to clients and shown to players and used by AI.

Constructors

HearUpd UpdAtomic |
HearStrike (ContentId ItemKind) |
HearSummon Bool (GroupName ItemKind) Dice |
HearCollideTile |
HearTaunt Text |

#### Instances

Instances details

Show HearMsg Source # |
Instance details Defined in Game.LambdaHack.Atomic.CmdAtomic Methods showsPrec :: Int -> HearMsg -> ShowS Source # show :: HearMsg -> String Source # showList :: [HearMsg] -> ShowS Source #

data SfxAtomic Source #

Abstract syntax of atomic special effects, that is, atomic commands that only display special effects and don't change `State` nor client state.

Constructors

SfxStrike ActorId ActorId ItemId |
SfxRecoil ActorId ActorId ItemId |
SfxSteal ActorId ActorId ItemId |
SfxRelease ActorId ActorId ItemId |
SfxProject ActorId ItemId |
SfxReceive ActorId ItemId |
SfxApply ActorId ItemId |
SfxCheck ActorId ItemId |
SfxTrigger ActorId LevelId Point (ContentId TileKind) |
SfxShun ActorId LevelId Point (ContentId TileKind) |
SfxEffect FactionId ActorId ItemId Effect Int64 |
SfxItemApplied Bool ItemId Container |
SfxMsgFid FactionId SfxMsg |
SfxRestart |
SfxCollideTile ActorId Point |
SfxTaunt Bool ActorId |

#### Instances

Instances details

Show SfxAtomic Source # |
Instance details Defined in Game.LambdaHack.Atomic.CmdAtomic Methods showsPrec :: Int -> SfxAtomic -> ShowS Source # show :: SfxAtomic -> String Source # showList :: [SfxAtomic] -> ShowS Source #

data SfxMsg Source #

Symbolic representation of text messages sent by server to clients and shown to players.

Constructors

SfxUnexpected ReqFailure |
SfxExpected Text ReqFailure |
SfxExpectedEmbed ItemId LevelId ReqFailure |
SfxFizzles ItemId Container |
SfxNothingHappens ItemId Container |
SfxNoItemsForTile [[(Int, GroupName ItemKind)]] |
SfxVoidDetection DetectKind |
SfxUnimpressed ActorId |
SfxSummonLackCalm ActorId |
SfxSummonTooManyOwn ActorId |
SfxSummonTooManyAll ActorId |
SfxSummonFailure ActorId |
SfxLevelNoMore |
SfxLevelPushed |
SfxBracedImmune ActorId |
SfxEscapeImpossible |
SfxStasisProtects |
SfxWaterParalysisResisted |
SfxTransImpossible |
SfxIdentifyNothing |
SfxPurposeNothing |
SfxPurposeTooFew Int Int |
SfxPurposeUnique |
SfxPurposeNotCommon |
SfxRerollNothing |
SfxRerollNotRandom |
SfxDupNothing |
SfxDupUnique |
SfxDupValuable |
SfxColdFish |
SfxReadyGoods |
SfxTimerExtended ActorId ItemId CStore (Delta Time) |
SfxCollideActor ActorId ActorId |
SfxItemYield ItemId Int LevelId |

#### Instances

Instances details

Show SfxMsg Source # |
Instance details Defined in Game.LambdaHack.Atomic.CmdAtomic Methods showsPrec :: Int -> SfxMsg -> ShowS Source # show :: SfxMsg -> String Source # showList :: [SfxMsg] -> ShowS Source #

# Re-exported from Game.LambdaHack.Atomic.HandleAtomicWrite

handleUpdAtomic :: MonadStateWrite m => UpdAtomic -> m () Source #

The game-state semantics of atomic game commands. There is no corresponding definition for special effects (`SfxAtomic`), because they don't modify `State`.

For each of the commands, we are guaranteed that the client, the command is addressed to, perceives all the positions the command affects (as computed by `posUpdAtomic`). In the code for each semantic function we additonally verify the client is aware of any relevant items and/or actors and we throw the `AtomicFail` exception if it's not. The server keeps copies of all clients' states and, before sending a command to a client, applies it to the client's state copy. If `AtomicFail` is signalled, the command is ignored for that client. This enables simpler server code that addresses commands to all clients that can see it, even though not all are able to process it.

# Re-exported from Game.LambdaHack.Atomic.PosAtomicRead

data PosAtomic Source #

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. Also note that hearing is not covered because it gives very restricted information, so hearing doesn't equal seeing (and we assume smelling actors get lots of data from smells).

Constructors

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
PosSightLevels [(LevelId, Point)] | whomever sees all the positions, notices
PosFid FactionId | only the faction notices, server doesn't
PosFidAndSer FactionId | faction and server notices
PosSer | only the server notices
PosAll | everybody notices
PosNone | never broadcasted, but sent manually

#### Instances

Instances details

Show PosAtomic Source # |
Instance details Defined in Game.LambdaHack.Atomic.PosAtomicRead Methods showsPrec :: Int -> PosAtomic -> ShowS Source # show :: PosAtomic -> String Source # showList :: [PosAtomic] -> ShowS Source #
Eq PosAtomic Source # |
Instance details Defined in Game.LambdaHack.Atomic.PosAtomicRead Methods (==) :: PosAtomic -> PosAtomic -> Bool Source # (/=) :: PosAtomic -> PosAtomic -> Bool Source #

posUpdAtomic :: MonadStateRead m => UpdAtomic -> m PosAtomic Source #

Produce the positions where the atomic update takes place or, more generally, the conditions under which the update can be noticed by a client.

The goal of this mechanics is to ensure that atomic commands involving some positions visible by a client convey similar information as the client would get by directly observing the changes of the portion of server state limited to the visible positions. Consequently, when the visible commands are later applied to the client's state, the state stays consistent --- in sync with the server state and correctly limited by visiblity. There is some wiggle room both in what "in sync" and "visible" means and how they propagate through time.

E.g., `UpdDisplaceActor` in a black room between two enemy actors, with only 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` in similar cotext would be (or the former should be perceived as the latter). However, to simplify, we assign 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.

iidUpdAtomic :: UpdAtomic -> [ItemId] Source #

All items introduced by the atomic command, to be used in it.

iidSfxAtomic :: SfxAtomic -> [ItemId] Source #

All items introduced by the atomic special effect, to be used in it.

breakUpdAtomic :: MonadStateRead m => UpdAtomic -> m [UpdAtomic] Source #

Decompose an atomic action that is outside a client's visiblity. The decomposed actions give less information that the original command, but some of them may fall within the visibility range of the client. The original action may give more information than even the total sum of all actions it's broken into. E.g., `UpdMoveActor` informs about the continued existence of the actor between moves vs popping out of existence and then back in.

This is computed in server's `State` from before performing the command.

lidOfPos :: PosAtomic -> Maybe LevelId Source #

What is the main map level the `PosAtomic` refers to, if any.

seenAtomicCli :: Bool -> FactionId -> PerLid -> PosAtomic -> Bool Source #

Given the client, its perception and an atomic command, determine if the client notices the command.

seenAtomicSer :: PosAtomic -> Bool Source #

Determine whether the server would see a command that has the given visibilty conditions.

# Re-exported from Game.LambdaHack.Atomic.MonadStateWrite

class MonadStateRead m => MonadStateWrite (m :: Type -> Type) where Source #

The monad for writing to the main game state. Atomic updates (`UpdAtomic`) are given semantics in this monad.

Methods

modifyState :: (State -> State) -> m () Source #

putState :: State -> m () Source #

#### Instances

Instances details

MonadStateWrite CliImplementation Source # |
Instance details Defined in Implementation.MonadClientImplementation Methods modifyState :: (State -> State) -> CliImplementation () Source # putState :: State -> CliImplementation () Source #
MonadStateWrite SerImplementation Source # |
Instance details Defined in Implementation.MonadServerImplementation Methods modifyState :: (State -> State) -> SerImplementation () Source # putState :: State -> SerImplementation () Source #

newtype AtomicFail Source #

Exception signifying that atomic action failed because the information it carries is inconsistent with the client's state, (e.g., because the client knows too little to understand the command or already deduced the state change from earlier commands or is confused, amnesiac or sees illusory actors or tiles). Whenever we know the failure is logically impossible, we don't throw the `AtomicFail` exception, but insert a normal assertion or `error` call, which are never caught nor handled.

Constructors

AtomicFail String |

#### Instances

Instances details

Exception AtomicFail Source # |
Instance details Defined in Game.LambdaHack.Atomic.MonadStateWrite Methods toException :: AtomicFail -> SomeException Source # fromException :: SomeException -> Maybe AtomicFail Source # displayException :: AtomicFail -> String Source # backtraceDesired :: AtomicFail -> Bool Source #
Show AtomicFail Source # |
Instance details Defined in Game.LambdaHack.Atomic.MonadStateWrite Methods showsPrec :: Int -> AtomicFail -> ShowS Source # show :: AtomicFail -> String Source # showList :: [AtomicFail] -> ShowS Source #