- Template: cart_haskell - press "Use this template" and you have a working game.
- Docker image:
ghcr.io/notnullgames/null0-cart-haskell:latest - Your code:
cart/Main.hs, compiled with wasm32-wasi-ghc (reactor mode) - Bindings:
carts/haskell/Null0.hs(baked into the docker image for you) - WASI is available, so ordinary file and stdio calls work.
building
You do not install wasm32-wasi-ghc (reactor mode) - the docker image has it, and the current null0 bindings, baked in. That is the whole point: there is nothing in your project to keep in sync with the engine.
docker run --rm --user $(id -u):$(id -g) \
-v ./cart:/src -v ./webroot:/out \
ghcr.io/notnullgames/null0-cart-haskell:latest mygameThe template wraps that in npm start, which also serves the result and rebuilds when you save.
Haskell notes
- Everything is in
IO. Each null0 call is imported through a generated C trampoline. - Carts get no environment variables, so anything reading
$PWDsees nothing.
a cart, in Haskell
This is carts/haskell/simple/Main.hs in the engine repo - the same file CI builds into the cart below, so it always compiles.
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Null0
-- required by GHC's module conventions, but never called: -no-hs-main
-- means the linker drops the usual RTS-wrapped main, and null0 only calls
-- the foreign-exported functions below
main :: IO ()
main = return ()
foreign export ccall "load" load :: IO ()
load :: IO ()
load = do
clear blue
drawCircle 100 100 50 red
-- callbacks (optional - implement, and foreign export, as needed)
-- foreign export ccall "update" update :: IO ()
-- update :: IO ()
-- update = return ()
-- foreign export ccall "unload" unload :: IO ()
-- unload :: IO ()
-- unload = return ()
-- foreign export ccall "buttonUp" buttonUp :: Int32 -> Word32 -> IO ()
-- buttonUp :: Int32 -> Word32 -> IO ()
-- buttonUp button player = return ()
-- foreign export ccall "buttonDown" buttonDown :: Int32 -> Word32 -> IO ()
-- buttonDown :: Int32 -> Word32 -> IO ()
-- buttonDown button player = return ()
-- foreign export ccall "keyUp" keyUp :: Int32 -> IO ()
-- keyUp :: Int32 -> IO ()
-- keyUp key = return ()
-- foreign export ccall "keyDown" keyDown :: Int32 -> IO ()
-- keyDown :: Int32 -> IO ()
-- keyDown key = return ()
-- foreign export ccall "mouseDown" mouseDown :: Int32 -> IO ()
-- mouseDown :: Int32 -> IO ()
-- mouseDown button = return ()
-- foreign export ccall "mouseUp" mouseUp :: Int32 -> IO ()
-- mouseUp :: Int32 -> IO ()
-- mouseUp button = return ()
-- foreign export ccall "mouseMoved" mouseMoved :: CFloat -> CFloat -> IO ()
-- mouseMoved :: CFloat -> CFloat -> IO ()
-- mouseMoved x y = return ()
carts/haskell/simple/Main.hscallbacks
A cart implements the callbacks it cares about. In Haskell they look like this:
foreign export ccall update :: IO ()See anatomy of a cart for the full list and what each one is passed.
more Haskell carts
the API, in Haskell
Every null0 function, spelled the way Haskell spells it. These are read out of the generated bindings themselves, so they match what your editor completes.
colors (7)
Tint a color with another color.
colorTint :: Color -> Color -> IO ColorFade a color.
colorFade :: Color -> CFloat -> IO ColorChange the brightness of a color.
colorBrightness :: Color -> CFloat -> IO ColorInvert a color.
colorInvert :: Color -> IO ColorBlend 2 colors together.
colorAlphaBlend :: Color -> Color -> IO ColorChange contrast of a color.
colorContrast :: Color -> CFloat -> IO ColorInterpolate colors.
colorBilinearInterpolate :: Color -> Color -> Color -> Color -> CFloat -> CFloat -> IO Colorgraphics (75)
Create a new blank image.
newImage :: Int32 -> Int32 -> Color -> IO Word32Copy an image to a new image.
imageCopy :: Word32 -> IO Word32Create an image from a region of another image.
imageSubimage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> IO Word32Clear the screen.
clear :: Color -> IO ()Draw a single pixel on the screen.
drawPoint :: Int32 -> Int32 -> Color -> IO ()Draw a line on the screen.
drawLine :: Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled rectangle on the screen.
drawRectangle :: Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled triangle on the screen.
drawTriangle :: Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled ellipse on the screen.
drawEllipse :: Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled circle on the screen.
drawCircle :: Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled polygon on the screen.
drawPolygon :: [Vector] -> Color -> IO ()Draw a filled arc on the screen.
drawArc :: Int32 -> Int32 -> CFloat -> CFloat -> CFloat -> Int32 -> Color -> IO ()Draw a filled round-rectangle on the screen.
drawRectangleRounded :: Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw an image on the screen.
drawImage :: Word32 -> Int32 -> Int32 -> IO ()Draw a tinted image on the screen.
drawImageTint :: Word32 -> Int32 -> Int32 -> Color -> IO ()Draw an image, rotated, on the screen.
drawImageRotated :: Word32 -> Int32 -> Int32 -> CFloat -> CFloat -> CFloat -> Int32 -> IO ()Draw an image, flipped, on the screen.
drawImageFlipped :: Word32 -> Int32 -> Int32 -> Bool -> Bool -> Bool -> IO ()Draw an image, scaled, on the screen.
drawImageScaled :: Word32 -> Int32 -> Int32 -> CFloat -> CFloat -> CFloat -> CFloat -> Int32 -> IO ()Draw some text on the screen.
drawText :: Word32 -> String -> Int32 -> Int32 -> Color -> IO ()Save an image to persistant storage.
saveImage :: Word32 -> String -> IO ()Load an image from a file in cart.
loadImage :: String -> IO Word32Resize an image, return copy.
imageResize :: Word32 -> Int32 -> Int32 -> Int32 -> IO Word32Scale an image, return copy.
imageScale :: Word32 -> CFloat -> CFloat -> Int32 -> IO Word32Replace a color in an image, in-place.
imageColorReplace :: Word32 -> Color -> Color -> IO ()Tint a color in an image, in-place.
imageColorTint :: Word32 -> Color -> IO ()Fade a color in an image, in-place.
imageColorFade :: Word32 -> CFloat -> IO ()Copy a font to a new font.
fontCopy :: Word32 -> IO Word32Scale a font, return a new font.
fontScale :: Word32 -> CFloat -> CFloat -> Int32 -> IO Word32Load a BMF font from a file in cart.
loadFontBmf :: String -> String -> IO Word32Load a BMF font from an image.
loadFontBmfFromImage :: Word32 -> String -> IO Word32Measure the size of some text.
measureText :: Word32 -> String -> Int32 -> IO DimensionsMeaure an image (use 0 for screen).
measureImage :: Word32 -> IO DimensionsLoad a TTY font from a file in cart.
loadFontTty :: String -> Int32 -> Int32 -> String -> IO Word32Load a TTY font from an image.
loadFontTtyFromImage :: Word32 -> Int32 -> Int32 -> String -> IO Word32Load a TTF font from a file in cart.
loadFontTtf :: String -> Int32 -> IO Word32Invert the colors in an image, in-place.
imageColorInvert :: Word32 -> IO ()Calculate a rectangle representing the available alpha border in an image.
imageAlphaBorder :: Word32 -> CFloat -> IO RectangleCrop an image, in-place.
imageCrop :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> IO ()Crop an image based on the alpha border, in-place.
imageAlphaCrop :: Word32 -> CFloat -> IO ()Adjust the brightness of an image, in-place.
imageColorBrightness :: Word32 -> CFloat -> IO ()Flip an image, in-place.
imageFlip :: Word32 -> Bool -> Bool -> IO ()Change the contrast of an image, in-place.
imageColorContrast :: Word32 -> CFloat -> IO ()Use an image as an alpha-mask on another image.
imageAlphaMask :: Word32 -> Word32 -> Int32 -> Int32 -> IO ()Create a new image, rotating another image.
imageRotate :: Word32 -> CFloat -> Int32 -> IO Word32Create a new image of a gradient.
imageGradient :: Int32 -> Int32 -> Color -> Color -> Color -> Color -> IO Word32Unload an image.
unloadImage :: Word32 -> IO ()Unload a font.
unloadFont :: Word32 -> IO ()Clear an image.
clearImage :: Word32 -> Color -> IO ()Draw a single pixel on an image.
drawPointOnImage :: Word32 -> Int32 -> Int32 -> Color -> IO ()Draw a line on an image.
drawLineOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled rectangle on an image.
drawRectangleOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled triangle on an image.
drawTriangleOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled ellipse on an image.
drawEllipseOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a circle on an image.
drawCircleOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a filled polygon on an image.
drawPolygonOnImage :: Word32 -> [Vector] -> Color -> IO ()Draw a filled round-rectangle on an image.
drawRectangleRoundedOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw an image on an image.
drawImageOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> IO ()Draw a tinted image on an image.
drawImageTintOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> Color -> IO ()Draw an image, rotated, on an image.
drawImageRotatedOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> CFloat -> CFloat -> CFloat -> Int32 -> IO ()Draw an image, flipped, on an image.
drawImageFlippedOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> Bool -> Bool -> Bool -> IO ()Draw an image, scaled, on an image.
drawImageScaledOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> CFloat -> CFloat -> CFloat -> CFloat -> Int32 -> IO ()Draw some text on an image.
drawTextOnImage :: Word32 -> Word32 -> String -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) rectangle on the screen.
drawRectangleOutline :: Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) triangle on the screen.
drawTriangleOutline :: Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) ellipse on the screen.
drawEllipseOutline :: Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) circle on the screen.
drawCircleOutline :: Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) polygon on the screen.
drawPolygonOutline :: [Vector] -> Int32 -> Color -> IO ()Draw a outlined (with thickness) arc on the screen.
drawArcOutline :: Int32 -> Int32 -> CFloat -> CFloat -> CFloat -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) round-rectangle on the screen.
drawRectangleRoundedOutline :: Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) rectangle on an image.
drawRectangleOutlineOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) triangle on an image.
drawTriangleOutlineOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) ellipse on an image.
drawEllipseOutlineOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) circle on an image.
drawCircleOutlineOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a outlined (with thickness) polygon on an image.
drawPolygonOutlineOnImage :: Word32 -> [Vector] -> Int32 -> Color -> IO ()Draw a outlined (with thickness) round-rectangle on an image.
drawRectangleRoundedOutlineOnImage :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()gui (10)
Begin a GUI window. Returns false if the window is collapsed or closed - skip its contents, but still call gui_end_window.
guiBeginWindow :: String -> Rectangle -> IO BoolEnd the current GUI window.
guiEndWindow :: IO ()A static text label.
guiLabel :: String -> IO ()A block of wrapping text.
guiText :: String -> IO ()A checkbox. Returns the (possibly changed) state.
guiCheckbox :: String -> Bool -> IO BoolA slider. Returns the (possibly changed) value.
guiSlider :: CFloat -> CFloat -> CFloat -> IO CFloatSet the current layout row - the column widths (negative for flexible), and the row height.
guiLayoutRow :: [Int32] -> Int32 -> IO ()Finish building the GUI for this frame. Called automatically at the end of update if you do not call it.
guiEnd :: IO ()Draw the GUI to an image (0 is the screen).
guiDraw :: Word32 -> IO ()input (12)
Has the key been pressed? (tracks unpress/read correctly.)
keyPressed :: Int32 -> IO BoolIs the key currently down?
keyDown :: Int32 -> IO BoolHas the key been released? (tracks press/read correctly.)
keyReleased :: Int32 -> IO BoolIs the key currently up?
keyUp :: Int32 -> IO BoolGet current position of mouse.
mousePosition :: IO Vectorsound (7)
Load a sound from a file in cart.
loadSound :: String -> IO Word32Play a sound.
playSound :: Word32 -> Bool -> IO ()Stop a sound.
stopSound :: Word32 -> IO ()Unload a sound.
unloadSound :: Word32 -> IO ()Speak some text and return a sound. Set things to 0 for defaults.
ttsSound :: String -> Bool -> Int32 -> Int32 -> Int32 -> Int32 -> Bool -> IO Word32Create Sfx sound.
sfxSound :: SfxParams -> IO Word32Create Sfx parameters.
sfxGenerate :: Int32 -> IO SfxParamstile (38)
Load a tilemap (a Tiled map, exported as JSON) from a file in cart.
loadTilemap :: String -> IO Word32Unload a tilemap.
unloadTilemap :: Word32 -> IO ()Update a tilemap's animation timers (deltaTime is in seconds).
tileUpdate :: Word32 -> CFloat -> IO ()Get the size of a tilemap, in tiles.
tileMapSize :: Word32 -> IO DimensionsGet the size of a single tile of a tilemap, in pixels.
tileTileSize :: Word32 -> IO DimensionsGet a custom property of a tilemap, by name (PROP_NONE when there is no such property.)
tileMapProp :: Word32 -> String -> IO TilemapPropGet the number of custom properties on a tilemap.
tileMapPropCount :: Word32 -> IO Int32Get a custom property of a tilemap, by index (PROP_NONE when out of range.)
tileMapPropAt :: Word32 -> Int32 -> IO TilemapPropDraw a tilemap on the screen.
tileDraw :: Word32 -> Int32 -> Int32 -> IO ()Draw a tilemap on the screen, tinted by a color.
tileDrawTint :: Word32 -> Int32 -> Int32 -> Color -> IO ()Draw a tilemap on an image.
tileDrawOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> IO ()Render a whole tilemap to a new image.
tilemapImage :: Word32 -> IO Word32Get the number of layers in a tilemap. Layers are numbered depth-first, so the children of a group layer have their own indexes too.
tileLayerCount :: Word32 -> IO Int32Get the index of a layer of a tilemap, by name (-1 when there is no such layer.)
tileLayerIndex :: Word32 -> String -> IO Int32Get the name of a layer of a tilemap.
tileLayerName :: Word32 -> Int32 -> IO StringGet the kind of a layer of a tilemap.
tileLayerType :: Word32 -> Int32 -> IO Int32Get the size of a layer of a tilemap, in tiles.
tileLayerSize :: Word32 -> Int32 -> IO DimensionsGet whether a layer of a tilemap is visible. Drawing a layer that Tiled marked hidden draws nothing.
tileLayerVisible :: Word32 -> Int32 -> IO BoolGet a custom property of a layer of a tilemap, by name (PROP_NONE when there is no such property.)
tileLayerProp :: Word32 -> Int32 -> String -> IO TilemapPropGet the number of custom properties on a layer of a tilemap.
tileLayerPropCount :: Word32 -> Int32 -> IO Int32Get a custom property of a layer of a tilemap, by index (PROP_NONE when out of range.)
tileLayerPropAt :: Word32 -> Int32 -> Int32 -> IO TilemapPropDraw a single layer of a tilemap on the screen.
tileDrawLayer :: Word32 -> Int32 -> Int32 -> Int32 -> IO ()Draw a single layer of a tilemap on the screen, tinted by a color.
tileDrawLayerTint :: Word32 -> Int32 -> Int32 -> Int32 -> Color -> IO ()Draw a single layer of a tilemap on an image.
tileDrawLayerOnImage :: Word32 -> Word32 -> Int32 -> Int32 -> Int32 -> IO ()Render a single layer of a tilemap to a new image.
tileLayerImage :: Word32 -> Int32 -> IO Word32Get the gid of the tile at a column/row in a tilemap layer.
tileGetTile :: Word32 -> Int32 -> Int32 -> Int32 -> IO Int32Set the gid of the tile at a column/row in a tilemap layer. Swapping a gid is how a cart keeps changing state in the map itself.
tileSetTile :: Word32 -> Int32 -> Int32 -> Int32 -> Int32 -> IO ()Draw a single tile from a tilemap on the screen.
tileDrawTile :: Word32 -> Int32 -> Int32 -> Int32 -> IO ()Get a copy of the image of a single tile in a tilemap.
tileImage :: Word32 -> Int32 -> IO Word32Get a custom property of a tile of a tilemap, by name (PROP_NONE when there is no such property.) These come from the tileset, so every tile with this gid shares them.
tileGidProp :: Word32 -> Int32 -> String -> IO TilemapPropGet the number of custom properties on a tile of a tilemap.
tileGidPropCount :: Word32 -> Int32 -> IO Int32Get a custom property of a tile of a tilemap, by index (PROP_NONE when out of range.)
tileGidPropAt :: Word32 -> Int32 -> Int32 -> IO TilemapPropGet the number of objects on an object-layer of a tilemap.
tileObjectCount :: Word32 -> Int32 -> IO Int32Get an object from an object-layer of a tilemap.
tileObject :: Word32 -> Int32 -> Int32 -> IO TilemapObjectGet the index of an object on an object-layer of a tilemap, by name (-1 when there is no such object.)
tileObjectIndex :: Word32 -> Int32 -> String -> IO Int32Get a custom property of an object of a tilemap, by name (PROP_NONE when there is no such property.)
tileObjectProp :: Word32 -> Int32 -> Int32 -> String -> IO TilemapPropGet the number of custom properties on an object of a tilemap.
tileObjectPropCount :: Word32 -> Int32 -> Int32 -> IO Int32Get a custom property of an object of a tilemap, by index (PROP_NONE when out of range.)
tileObjectPropAt :: Word32 -> Int32 -> Int32 -> Int32 -> IO TilemapProputilities (5)
Get system-time (ms) since unix epoch.
currentTime :: IO Word64Get the change in time (seconds) since the last update run.
deltaTime :: IO CFloatGet a random integer between 2 numbers.
randomInt :: Int32 -> Int32 -> IO Int32Get the random-seed.
randomSeedGet :: IO Word64Set the random-seed.
randomSeedSet :: Word64 -> IO ()