hellwolf / tiny-games-hs

Rules for & examples of tiny haskell games

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Haskell Tiny Game Jam

The first Haskell tiny games contest has taken place in February 2023. Inspired by the BASIC 10Liner contest (see their english rules at the bottom of that page, and their 2023 entries). Your mission: make a playable game in 10 lines of 80 characters of Haskell. The prize.. glory! Also fun, learning, and advancing Haskell's suitability for game dev and programming in the small.

The contest ended 2023-02-28 23:59:59 UTC and is now in judging phase.

Rules

Entries were submitted in the last three weeks of February 2023. sm and f-a are your judges. See the #haskell-game Matrix or IRC chat or this repo's issue tracker for help/feedback/announcements.

Here were the contest rules for this round:

  1. You can submit any number of entries to the official repo, haskell-game/tiny-games-hs. Each should be a playable game or amusement in one haskell file of up to 10 lines of up to 80 characters each, in one of the following categories:

    • prelude-10-80, allowing no imports
    • base-10-80, allowing imports from the base package
    • default-10-80, allowing imports from GHC's default packages, plus an optional file named Import.hs to gather and re-export imports (only)
    • hackage-10-80, allowing imports from all of Hackage, and an Import.hs file.
  2. The entry can be a script (runghc, stack, cabal, ...) or a small program requiring compilation, but not a multi-file project. Our ideal is a self-contained executable 10 line program that just works, like BASIC programs. Here are some templates to give ideas: prelude/template1, base/template1, default/template1, hackage/template1

  3. Unlimited comments are permitted after line 11. The game's category/gamename (author) info should appear here, plus any essential info like player controls, so that the game is usable to someone seeing just this file.

  4. Achieving programs that "just work" is a core principle and part of the challenge. The script or program must either be reliably runnable via shebang line (these use up your line count, but improve runnability; env -S is allowed) or contain a reliable build/run command line with all needed options, in the comments (the play script will use this). Games which aren't straightforward to run and enjoy are incomplete. See also the runnability tips below.

  5. The game should be portable, running on all major platforms, ideally.

  6. A square thumbnail (screenshot) must be provided for the repo README - either a static png (which will be hyperlinked) or an animated gif (which should not be, so as not to break Github's player overlay).

  7. A README file is optional but makes browsing your game more pleasant for website visitors. Feel free to include animations, or discussion of the game/code/your experience.

  8. An unminified version of the code, easier to read and learn from, is optional but welcome.

  9. You can update your entries freely until the contest end, 2023-02-28 23:59:59 UTC, at which time they are frozen (in the contest branch) for posterity and judging (no exceptions except minor updates at judges' discretion, eg metadata fixes). Also the last commit received before deadline has been tagged with the pre-deadline tag. If you need to share post-contest improvements, you are welcome to keep publishing updates in the main branch. The main version is the one that will be presented to players.

Games

Here are all the entries!

prelude-10-80


guess1

(sm)

pure-doors

(tristanC)

fifteen

(bradrn)

chess

(fizruk)

sudoku

(elderephemera)

matchmaking
(migmit)

tiny-brot
(tristanC)

mini-othello
(hellwolf)

one-dot

(OsePedro)

expressit

(Greg8128)

life

(Rens van Hienen)

call-by-push-block
(cole-k)

companion

(Greg8128)

hangman

(kukimik)

quine

(tristanC)

base-10-80


timing

(TravisCardwell)

shoot

(migmit)

log2048

(Lysxia)

rhythm

(elderephemera)

peyton-says

(gergoerdi)

acey-deucey

(trevarj)

flower-seeds

(tristanC)

lambda-ray
(tristanC)

7up7down

(akshaymankar)

snake

(akshaymankar)
woosh.caves
(Kindaro)
woosh.forest
(Kindaro)

default-10-80


type-and-furious

(lsmor)

shmupemup

(elderephemera)

tsp
(tristanC)

lol
(hellwolf)

space-invaders

(meooow25)
swish.easy
(Kindaro)
swish.survival
(Kindaro)

lc

(byorgey)

hackage-10-80


guess2

(sm)

wordle

(halogenandtoast)

ski

(sm)

guesscolor

(TravisCardwell)

bulls-n-cows

(akadude)

hallway-to-hell
(juliendehos)

1234-hero

(gelisam)

crappy-flappy

(gergoerdi)

pong

(gergoerdi)

minesweeper

(Greg8128)

pong2

(sm)

brickbreaker

(fgaz)

lazy-march
(tristanC)

balances

(sm)

vaders

(gergoerdi)

tetris

(gergoerdi)

short-guess

(RimuhRimu)

hexescape

(nevrome)

snake-lemma

(gergoerdi)

subpar-hexagon

(gergoerdi)

Let's play!

You will need a suitable version of GHC (9.2.5+ or 9.4.4+ recommended), and stack (or cabal). See https://www.haskell.org/get-started/. Once Haskell is installed, and if you have bash, you can run ./play in this repo:

or:

If you don't have bash, cd into each */GAME directory and try running GAME.hs. If that fails, look for running clues in that file, a readme, or the play script. You can also run ./play GAME -h to view a game's source code and readme.

The lol entry is a meta "game" that colourises other games. It works with most games but may cost a little performance. (Hint: each extra "lol" argument modifies the effect.)

Development

Tips for developers while the jam was in progress, and for future jams.

Runnability

  • Avoid requiring problematic GHC versions. In particular GHC <9.2 doesn't work well on mac. If you specify a GHC version/stackage snapshot, the current release is ideal (GHC 9.2, lts-20).
  • env -S in the shebang line doesn't work on older GNU/Linux systems, but we allow it (see haskell-game#25).
  • stack scripts can seem to hang at first startup while downloading snapshot info. For prelude/base/default categories, using --resolver=ghc-9.2.5 avoids this (see haskell-game#38).
  • stack scripts can use --verbosity=error to silence the "Selected resolver" output. (Or --verbosity=info to show dependency building progress.)
  • If using packages which require compilation (gloss) or more speed, use stack script --compile or stack script --optimize. (Downsides: creates .o and .hi files; a compiled binary with newer timestamp than source can cause confusion.)
  • cabal scripts are also welcome; they don't have --compile and require more lines (unless you use env -S)
  • On mac, Terminal and iTerm 3.4 render emojis very slowly; iTerm 3.5 beta or VS Code terminal work better.

Minifying

Here are some minifiers you can try; either or both may be able to turn your game into a brick of inscrutable code no more than 80 characters wide.

  • hackage/brickbreaker/minify.hs (from haskell-game#63; contact @fgaz)

    This minifier requires that you first add curled braces and semicolons throughout your code to make it white space insensitive.

  • minify.hs (from haskell-game#14; contact @kindaro with issues/feedback)

    Features

    • Will automatically add curly braces for you so long as you put the line module Main where into your source file. (This line will then be automatically removed, so you lose no space.)
    • Will automatically replace variables and constructors surrounded with curly braces {example} with single letters, for extra minification.

Animations

Here's one way to make animated GIFs or APNGs for your README (see also ski/Makefile):

# Install Noto Emoji font, required by agg to show emojis
$ asciinema rec game.cast
$ agg -v --cols 80 --rows 25 --font-family 'Essential PragmataPro' --font-size 16 game.cast game.lg.gif
$ gifsicle -V --lossy=50 -k8 -O2 -Okeep-empty game.gif -o game.gif
$ gif2apng game.gif game.png

agg doesn't show colour emojis yet. The Noto Emoji glyphs are monochrome and less pretty, but will give the idea. (asciicast2gif which predates agg does show colour emojis, but doesn't convert ansi-terminal-game output well.)

Shrinking the gif, eg with gifsicle, is recommended for repo longevity and page load times. It helps gif2apng a lot also.

APNGs are preferable if you can manage it: they will not be obscured by Github's gif player button, they can be hyperlinks, and they can have smaller file size. https://sourceforge.net/projects/gif2apng works well, it can be built from its source tarball.

Freeglut

You may encounter the following error when playing some of the games:

xxx: user error (unknown GLUT entry glutInit)

That usually means that you should install "freeglut" library using your system package manager.

Using Nix

A flake.nix is provided, just run nix develop . to have a reproduciable tiny game environment!

Experience reports

About

Rules for & examples of tiny haskell games


Languages

Language:Haskell 92.7%Language:Shell 5.6%Language:Nix 1.3%Language:Makefile 0.5%