Inspired by the ongoing BASIC 10Liner contest (see their english rules at the bottom of that page, and their 2023 entries)..
The first Haskell tiny games contest runs through February 2023! (<24h remaining) 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.
Rules | Games | Let's play! | Development
Submit your entries between now and end of February! sm and f-a will be your judges. See the #haskell-game Matrix or IRC chat or this repo's issue tracker for help/feedback/announcements.
Here are the contest rules for this round (HTG1):
-
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 importsbase-10-80
, allowing imports from the base packagedefault-10-80
, allowing imports from GHC's default packages, plus an optional file namedImport.hs
to gather and re-export imports (only)hackage-10-80
, allowing imports from all of Hackage, and anImport.hs
file.
-
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
-
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. -
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 (theplay
script will use this). Games which aren't straightforward to run and enjoy are incomplete. See also the runnability tips below. -
The game should be portable, running on all major platforms, ideally.
-
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).
-
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.
-
An unminified version of the code, easier to read and learn from, is optional but welcome.
-
You can update your entries freely until the contest end, 2023-02-28 11:59:59 UTC, at which time they are frozen for posterity and judging (no exceptions). If you need to share post-contest improvements, you are welcome to publish as new files in the same directory.
Here are the entries received so far!
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) |
timing (TravisCardwell) |
shoot (migmit) |
log2048 (Lysxia) |
rhythm (elderephemera) |
peyton-says (gergoerdi) |
acey-deucey (trevarj) |
flower-seeds (tristanC) |
lambda-ray (tristanC) |
7up7down (akshaymankar) |
snake (akshaymankar) |
type-and-furious (lsmor) |
shmupemup (elderephemera) |
tsp (tristanC) |
lol (hellwolf) |
space-invaders (meooow25) |
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) |
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.)
- https://tristancacqueray.github.io/blog/tiny-game-engine
- https://www.cole-k.com/2023/02/21/tiny-games-hs/
- 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.
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. Both require 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)
- hackage/brickbreaker/minify.hs (from haskell-game#63; contact @fgaz)
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.
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.
Special tips for NixOS users:
$ nix-shell -p freeglut # Or add to your global packages list
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`nix eval --impure --raw --expr 'let pkgs = import <nixpkgs>{}; in pkgs.freeglut'`/lib;