Liquorice: Algorithmic Doom map generation

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

A system for constructing maps for the computer game Doom by writing algorithms to describe the geometry. A Liquorice program is a series of instructions to move a virtual "turtle" or "pen", which define the walls, floors, rooms and monsters as it goes.


[Skip to Readme]

Properties

Versions 0.0.1, 0.0.1
Change log None available
Dependencies base (>=4.11.1 && <4.13), binary, bytestring, HTF, mtl [details]
License GPL-3.0-only
Copyright © 2020 Jonathan Dowland
Author Jonathan Dowland
Maintainer jon+hackage@dow.land
Category Game
Home page https://jmtd.net/doom/liquorice/
Bug tracker https://github.com/jmtd/liquorice/issues
Source repo head: git clone https://github.com/jmtd/liquorice/
Uploaded by jmtd at 2020-03-06T15:11:23Z

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for Liquorice-0.0.1

[back to package description]

Liquorice

Liquorice is a system for constructing maps for the computer game Doom by writing algorithms to describe the geometry. A Liquorice program is a series of instructions to move a virtual "turtle" or "pen", which define the walls, floors, rooms and monsters as it goes.

More specifically, Liquorice is an embedded domain-specific language (eDSL) within the pure functional programming language Haskell.

Quick example

-- simple example, triangle (for orientation); unique texture per line
import Liquorice.Monad
import Liquorice.Render

main = buildWad "example1.wad" $ runWadL $ do
    mid "ZZWOLF1"
    draw 128 0
    mid "ZZWOLF2"
    draw 0 128
    turnaround
    mid "ZZWOLF3"
    draw 128 128
    rightsector 0 128 160
    turnaround
    step 64 32
    thing

More detailed example

See examples/birds.hs, for an example program that generates a complete playable map. The map targets Doom 1 / The Ultimate Doom (map slot E2M8), and requires a doom engine with raised engine limits, such as Crispy Doom.

The generated PWAD, with nodes, ready to play: birds.zip

birds.hs is a re-implementation/transformation of "Bird Cage" for WadC.

Getting Started

For Doom novices

Doom's engine source code was open-sourced in 1996, but you need a copy of the game's data files to use them. You can buy The Ultimate Doom and Doom II at Gog, amongst other places. Failing that, you could try FreeDoom, a free-content game for Doom engines.

Examples of powerful open source engines include Crispy Doom, Eternity Engine and GZDoom.

For Haskell novices

Evaluation

The commands that a typical Liquorice program will use are predominantly monadic, and so make use of Haskell's "do-notation" for ordering. Internally, the majority of these monadic functions are wrappers around pure equivalents which transform an input Context type into an output, e.g.:

xoff :: Int -> Context -> Context
xoff x c = c { paletteXoff = x }

place :: Int -> Int -> (Context -> Context) -> Context -> Context
place x y fn c = c & step x y
                   & fn
                   & step (-1 * x) (-1 * y)

The pure functions can be combined using the infix operator & (from Data.Function), or the more usual composition operator (which reads back-to-front). However, the monadic versions are probably more user- friendly, and so the separate pure implementations might go away or stop being explicitly exported at some point. We also probably need to use the monadic versions if we want to introduce randomness or debug IO in the middle of a program.

A series of monadic Liquorice statements are converted into a final Context via runWadL. A Context is written to an output PWAD file via

buildWad :: FilePath -> Context -> IO ()

Internally, buildWad first converts a Context into an intermediate data structure WadMap, which closely resembles the binary structure of a PWAD. (WadMap itself is a specialisation of Wad, imposing the presence of map specific lumps)

Pros/Cons

Pros:

Cons:

Code overview

The following three source files are the ones that you will want to import as modules to your Liquorice program:

These are back-end implementation details:

Author

Liquorice was created by Jonathan Dowland and is distributed under the terms of the GNU Public License, version 3 (see COPYING).

The design of Liquorice is heavily influenced by Wad Language (WadC), which in turn owes a debt to LOGO.

See also