Purely functional Haskell "Magic: The Gathering" card model and game engine.
MtgPure is a showcase of how to make an elegant purely functional "Magic: The Gathering" DSL model and rules engine.
ScrambleverseEffect
.src/MtgPure/Client/Terminal.hs
src/MtgPure/Engine/Fwd/Api.hs
src/MtgPure/Engine/Fwd/Impl.hs
src/MtgPure/Engine/State.hs
src/Demo/MtgPure/Gameplay.hs
$ cabal install fourmolu # for code generation ; add to PATH if needed
$ cd src
$ runhaskell MtgPure/Model/Object/ToObjectN/CodeGen.hs
$ cd ..
$ cabal build
$ cabal repl
ghci> :m +MtgPure MtgPure.AllCards MtgPure.Cards MtgPure.Model.BasicLandType MtgPure.Model.LandType MtgPure.Model.Recursive
ghci> :i allCards
allCards :: [AnyCard] -- Defined in `MtgPure.AllCards'
ghci> :i island
island :: Card OTLand -- Defined in `MtgPure.Cards'
ghci> compare island island
EQ
ghci> print island
Card "Island" $ ElectCardFacet $ LandCharacteristic [] [BasicLand Island] $ LandSpec []
ghci> island == (Card "Island" $ ElectCardFacet $ LandCharacteristic [] [BasicLand Island] $ LandSpec [])
True
ghci> island == (Card "Island" $ ElectCardFacet $ LandCharacteristic [] [BasicLand Mountain] $ LandSpec [])
False
ghci> mainDemoGameplay -- runs Demo.MtgPure.Gameplay
Notes:
-Wno-type-defaults
so the Show
instances for cards don't need to constantly specify Num
types when Integer
is good enough for authoring. (Too much noise adding annotations for Integer
or even Int
or an alias I
.)src/MtgPure/Model/Object/ToObjectN/Instances.hs
imports large generated files and will take a while to compile, hence the -fobject-code
flag to cache the result inside the ghci-compiled.bat
script.
-fobject-code
with ghci
seems to require quitting and reentering ghci
in order to get it to pick up the right runtime behavior after making code changes.Demo.MtgPure.Gameplay
https://user-images.githubusercontent.com/6971794/220497420-c35cd250-41be-44b8-bd27-16a470732c1c.mp4
App.AnsiInspector
Contributions may or may not be accepted. If you are concerned about your time being wasted, please open an issue first to discuss. Entry-level contributions would probably be for card definitions or tests. More advanced contributions would be for the engine or model design.