next_inactive up previous

A C++ interpreter of the Teeny Weeny Microgame Engine LRFC


CVS Revision: $Id: teeny-cpp.lyx,v 1.6 2005/02/24 22:01:22 sgbeal Exp $

URL: not yet formally online

Distribution policy: Public Domain

Authors:, with support from the members of


1 Overview and background

This document explains how to use teeny-cpp (hereafter simply called teeny). Teeny is an interpreter based on the Teeny Weeny Microgame Engine LRFC (simply called the LRFC - Lesser RFC [Request for Comments]), and aims to be the reference implementation for that LRFC. The LRFC is available from the same place you can find this document, in the teeny-cpp source code bundle.

This implementation is coded in C++ and provides all of the REQUIRED or SUGGESTED features from the Teeny LRFC. In addition it provides a multitude of other features, mostly via the same command-language interface proposed by the LRFC. The deceptively simple user interface of teeny-cpp should not belie the flexibility of the back-end it is built on - it can be extended in a surprising number of ways rather easily, including via plugins. It's usage of libs11n for serialization support provides nearly unlimited flexibility for loading and saving data, for example.

What does that mean? It means that this is software for playing boardgames with. Which games? Almost any you want - the abstractness of the Teeny LRFC leaves it open for use with a wide variety of board-style games.

Teeny is part of a years-long (with no end in sight) experimentation process involving development of the so-called Universal Boardgame Protocol, an idea championed by James McCann which proposes specification for defining a common approach to sharing boardgame-related data between disparate applications and environments. Teeny is a distant relative of QUB, the Q Universal Boardgame (; though the two share no actual code, they are both important steps in our search for the ultimate needs of the UBP...

1.1 Main features

Teeny is, despite it's primitive appearance, relatively powerful. Some of the more significant features include:

And some notable, but relatibely minor features/notes:

And of course no software is complete without a TODO list...

1.2 License

The vast majority of the source code involving Teeny, including this documentation, is released into the Public Domain. The source code exceptions to this rule are few, far-between, and clearly noted. No licenses used by these sources require that users of these sources modify their own licenses if they utilize said sources. i.e., no GNU GPL'd code.

That said: teeny-cpp links with libeshell, which optionally links with libreadline_cpp, which optionally uses with GNU Readline. If your environment uses GNU Readline then your copy of eshell will ''indirectly'' use GNU Readline, and therefor falls under the GNU GPL, which means that your copy of Teeny does, too. As far as i am aware, only your binaries, not your sources, are GPLd, because neither Teeny nor eshell know if readline is linked in or not (they have no clue what readline even is).


1.3 Building and installing

Teeny is built on top of a number of other libraries:


All of those libs except ncurses are available from:


The following libs aren't necessary to use teeny, but will enhance the usability of teeny's console mode significantly:

The editline and readline_cpp libraries are available on the s11n site - see the URL above.

Build steps:

Install those libs in the following order, following the installation instructions which come with each one:

For the libs which come from, use the same configure/installation ''prefix'' for each one (the -prefix=/dir option passed to the configure scripts). Make sure that the dir PREFIX/bin is in your $PATH and that PREFIX/lib is in your $LD_LIBRARY_PATH (or equivalent) before continuing. You don't HAVE to use the same build prefix for each, but doing so simplifies things (i.e., saves us several manual steps, including linker/header headaches). i highly recommend using $HOME as the prefix, in any case.

Now to build teeny...

tar xzf teeny-VERSION.tar.gz

cd teeny-VERSION
Now we have to ''install'' the build tools which teeny uses (the same ones as s11n and eshell, unsurprisingly). You need do ONE of the following:

ln -s /path/to/libs11n-all-YYYY.MM.DD/toc .

export TOC_HOME=/path/to/libs11n-all-YYYY.MM.DD/toc

(or equivalent for your shell)
Now configure the source tree:

./configure -prefix=/same/prefix/as/s11n/and/eshell
If that doesn't work then teeny will not build on your machine without some effort on your part. Read the error messages, and please send me a mail if the configure script seems broken (that's certainly a possibility!). If s11n and eshell build, then teeny will almost certainly build unless your curses is significantly different than mine (ncurses 5.4).

If configure works, then build the sources:


(optionally: make install)
The main binary is ./cpp/teeny-cpp, which you can run directly from the cpp subdir if ''.'' and PREFIX/lib are in your $LD_LIBRARY_PATH. Several game scripts, which can be loaded from the application with the source FILENAME command, can be found under games/*.eshell (generated by the build process). Please read the comments in the scripts before sourcing them!

1.4 Software architecture overview

teeny-cpp is based primarily on 3 ''local'' parts, plus gets a wide variety of support from ''external'' layers/parts which will not be discussed here (e.g., ncurses, s11n, eshell, the classloader...).

The layers/parts:

  1. Teeny.*pp: define some basic data structures suitable for the operations laid out by the LRFC. Most of this code could be re-used as-is in other source trees. It does depend on libs11n, but only in relatively small areas which should be easy to remove (the Serializable interface and it's required two functions). Aside from the classes defined in these files, there are a few namespace-scope free functions which are used by the remaining code to get at shared copies of the Teeny structures. The reason is simply that teeny-cpp is designed around having exactly ONE copy of the structures, as opposed to managing multiple boards/games at once. The underlying classes, however, are not designed as Singletons, so that they may be used in multi-game environments.
  2. cursesui.*pp, nc*.*pp: defines the Curses-specific aspects of the API. Relies on the data structures from (1) and have an ''indirect'' dependency (via the command interface only) on (3).
  3. eteeny.*pp: defines the majority of the teeny-related libeshell command handlers (those which are not 100% specific to the curses UI). This code has a direct dependency on (1) and (2). Where possible/feasible, the command handlers work in both console and curses modes, but some commands necessarily invoke curses behaviours, which may mess up the screen if run from console mode.
Note that there are currently NO guarantees about the stability of ANY of the above APIs. It is all experimental at this point.

1.5 Notes on data file format(s)

The vast majority of the file i/o support done by this code is handled by libs11n. That means:

See the s11n docs for why it is a Good Thing to not know what data formats we rely on.

2 Interacting with teeny-cpp

Teeny has two major modes of operation - console mode and curses mode - plus an additional ''source'' mode, used in reading in script files.

The console mode is similar to traditional Unix shells, which are operated via entering commands at a text-mode prompt. The usability of this prompt depends on whether you are using a fully functional libreadline_cpp or not: without it you will not have any advanced command editing features, which makes the console significantly more difficult to use. The console mode is provided by libeshell, and is described in detail in the libeshell library manual.

Curses mode provides a colorful UI with shortcuts for many operations. Some of the commands provided by teeny only work properly when curses mode is enabled (via the 'teeny-curses' command), but they also work from console mode when practical. Teeny's curses mode does nothing ''special'' with the terminal, but does assume that you have features like color and that you have some ''reasonable'' amount of screen space.

At it's core, teeny operates by taking ''commands'' from the user in the following form:

command [arguments...]
Where these commands come from is, from the point of view of the core software, completely irrelevant.

These commands are passed off to their associated ''handler'' function (which are coded in C++). These handlers do things like add/remove Actors to/from the game board, load/save files, etc.

The curses UI of course wraps much of this up behind hotkeys, and also provides much of it's own logic, not available via the console mode. The curses UI is fairly self-explanatory, and will not be detailed much here. The subtleties of the console interface are described in the libeshell library manual, and will differ depending on your underlying line-input implementation (e.g., whether your have GNU readline support or not).

Teeny starts up in console mode by default, but can be told to jump directly to curses mode by starting it with the ''-tc'' (teeny-curses) command-line parameter. From the console mode you may use the command ''teeny-curses'' (predefined alias==''tc'') to switch to curses mode, and Ctrl-D or F10 to shut down curses mode. If you start teeny-cpp with the -tc option then exiting curses also exits the application, otherwise exiting curses mode simply takes you back to console mode. You may switch freely between console and curses modes.

To enter a command from the curses UI, tap the F2 or ''.'' key to get an input prompt. Command entry is much more comfortable from console mode, however, if your libeshell is built with GNU Readline support. The colorful curses UI is rather tempting, if only because it's so much prettier than the console ;). In practice it is common to switch between console and curses mode during a session, while spending most of the actual ''play time'' in curses mode.

Achtung: when switching between console and curses modes there may be times when the terminal gets confused about whether it is ''raw'' or ''cooked'' mode. If your keystrokes suddently disappear or stop responding, you may need to restart the application, or sometimes you can resolve the problem by restarting curses mode once or twice. This probably normally appears only when using curses-based commands from console mode.

3 Commands

Teeny is very ''command-centric'', and most of it's behaviours are internally controlled by passing it stringified command lines. This is, not coincidentally, the same model called for by the Teeny LRFC.

All of of the commands listed as REQUIRED or SUGGESTED in the LRFC are implemented here. See the LRFC for the descriptions of the core commands, which will only be briefly described below. Some commands internally have different names than the LRFC specifies, but the app provides aliases to hide these differences. That is, all unless the user re-aliases these, all LRFC-specified commands should work as the LRFC defines them to.

All commands related to Teeny have a prefix of ''teeny-''. The underlying shell framework, eshell, also provides a number of built-in commands. Use the ''help'' or ''?'' commands to get brief help text for each command. Many commands will show usage text when run without any options. Enter ''help COMMANDNAME'' to see the brief help for a single command.

From curses mode, use the '?' key to show a short description of the available hotkeys, or enter help as a command to see the command help.

3.1 Variables and aliases

As described in the libeshell manual, commands may contain variable references (e.g., ${VARNAME}). As of libeshell version 2005.2.20, ''tilde-home'' expansion should also work for most commands which need it, but is not performed by default because it interferes with clients who don't want it. Use the built-in commands 'set' and 'unset' to set and unset environment variables and 'alias' to alias commands. Examples:

set MYVAR=''my value''

echo $MYVAR or ${MYVAR}

unset MYVAR

alias mv=''teeny-actor move''

mv 10 10 A

alias mv=

# ^^^ undefines alias for 'mv'. We don't yet have an 'unalias' command.
Aliases are persistent across application sessions but environment variables are not. You may use the -session=FILENAME command-line option to specify a session file. The default session file is ~/.teeny/teeny-session.s11n.

Using variables, aliases and the 'source' built-in command you may execute any number of commands via very few keystrokes. For example, i often have a scratch-file where i write teeny commands, and alias ''x'' to ''source scratchfile''. Or i map the Meta-1key in the UI to ''source scratchfile'' (Try Meta-M from the curses UI.)

3.2 Command descriptions

This section describes the more important top-level commands.

Not all of the commands work properly when in console mode. If your console goes all wahoonie shaped all of the sudden, you've run a curses-mode command from the console. To get the curses back to normal, exit console mode (Ctrl-D) or start curses mode.

Most of these commands will show some usage text when run without any options. Many are demonstrated in the demo game scripts under the games subdir of the source tree.

The Commands:

3.2.1 Builtin eshell command

libeshell, off of which teeny-cpp is based, comes with a number of builtin commands to emulate many common shell operations. The commands which are especially useful, or have a different meaning, in teeny, are listed below.

This is one of the most commonly-used commands. It allows you to give short or more memorable names to commands. To remove an alias assign it an empty value (sorry, eshell's lazy-ass maintainer (me) hasn't yet coded an unalias command).

This eshell-standard command reads in a file of eshell commands and dispatches them one at a time. Teeny games can be distributes as such scripts.

exit | quit | logout
These eshell-standard commands work only from console mode, and not from scripts nor from the curses UI. This is a limitation of the eshell input loop mechanism.

This eshell-standard command can be used to help automate repetative or commonly-performed options by hiding them behind a simple/simplistic menu interface. Works with or without curses mode, adapting to the input technique used by either. See the eshell library manual for full details on the emenu command.

cd and pwd
Use these to traverse your directories. You may need to do this before sourcing a given script, e.g., if it uses resources in that directory and expects to be sourced from there.

This deceptively simple command is not so useful in interactive mode but is handy in scripts. For example, it can be used to tell the players which actors represent what units types.

3.2.2 Actors

teeny-actor (several options)
Implements all LRFC-specified Actor commands, plus some additions, like relative-coordinate moves. If a coordinate part has a + or - prefix then that coordinate is moved relative to the current position. Relative moves work only for in-play Actors, and cannot be used to add new Actors.

3.2.3 Game Board

teeny-board (several options)
Provides subcommands for manipulating the size and Terrain of the board. One interesting extension subcommand (non-LRFC) is rotate, which rotates the board in 90-degree increments. Doing this sometimes helps to get a better perspective on a board, especially because most console fonts aren't square, and thus 10x10 board appears to be taller than it is wide. Seeing the board from multiple angles might help bridge this ''perception gap'', or may simply provide a more comfortable viewing angle. All coordinates in the board are translated by rotation, so it actually changes the location of all Actors and Terrains (the same relative locations, of course).

3.2.4 Save/load game state

teeny-load FILENAME

teeny-save FILENAME
Loads/saves the state of the game using libs11n. Note that the flat-file format suggested by the LRFC is not supported, mainly because the command script support fills this role nicely and is more powerful. The exact file format(s) used by this whole library are undefined and may change on any invocation of this app (no kidding): libs11nlite handles all of these gory details for us (see for more detail than you could possibly care to know...).

The ''game state'' includes all content of the game board, including Actors, Terrain and curses attribute information for the current colormap (any number may be defined at once). Note that several other commands have load/save subcommands, but those work on individual elements of game data, and have nothing to do with these ''overall game state'' commands.

3.2.5 Curses mode

All of the commands listed here, except where specified, require the activation of curses screen mode. If run from console mode they will make the terminal go haywire. To fix it, try entering curses mode (command ''tc'') and exiting it. If that fails, you may need to exit teeny (Ctrl-D), type 'reset' from your shell (if the terminal is still not behaving properly), and then re-run teeny when 'reset' is finished reseting your terminal to a sane state. Sorry about all that.

The commands...

Starts curses mode. The alias ''tc'' is predefined for this command. If you redefine this alias, your definition will be overwritten on each app startup.

teeny-curses-macro (several options)
Defines, lists, loads and saves macros for use with the curses UI. This does not require that curses mode be active, despite the ''curses'' in the name. If you are tempted to define and call macros outside the context of the curses UI, consider using aliases instead: the effect is the same and simpler to use from the console or scripts. Currently the UI reserves the macro names ''meta-[0-9]'' (case-sensitive), and the list of reserved names may be expanded in the future.

teeny-curses-setattr (many options)
Sets curses-related attribute information for Actor/Terrain Avatars, including colormap definition and serialization. Note that when changing existing attributes on an Avatar it is often necessary to use the reset subcommand to reset the attributes. If you don't do this you may get ''mixed'' colors with unpredictable results. The general rule is: if the colors look completely weird, do a reset.

teeny-curses-freeze (1|0)
(Un)freezes updates to the curses view of the game board. Pass 1 to freeze (disable) updates and 0 to unfreeze (re-enable) updates. This is useful in game scripts which do a lot of board/color operations, as these operations cause lots of screen updates. Internally we always try to keep the UI in sync with the real game state, and the ''batch'' nature of Teeny's command language essentially requires us to do updates after every command. The freeze option is essentially a workaround for that.

teeny-curses-wait-on-key ''STRING''
This causes a small dialog to pop up, showing the given string. The dialog goes away, and processing continues, when the user presses any key.

teeny-curses-redraw (all|board)
An internal command to redraw parts of the screen. Intended primarily to be mapped to hotkeys. If the UI is frozen (see above) then this does nothing.

3.2.6 Looping over Avatar ranges

teeny-foreach-avatar VARNAME from START_AVATAR to END_AVATAR COMMAND [arguments...]
Performs simple loops over ranges of Actor/Terrain Avatars. In the COMMAND/arguments string you may use \$VARNAME (note the leading slash) to expand the name of the current avatar. This does not require curses mode, though the command it calls might. This command is useful when setting, e.g., colors on ranges of avatars: teeny-foreach-avatar AV from A to Z teeny-curses-setattr \$AV color white on black. Via clever use of this command calling the source command, you can mostly simulate ''blocks'' of commands for a given loop - simply choose a consistent foreach VARNAME naming convention and reference that variable from your scripts.

3.2.7 Interactively setting environment variables

teeny-readvar VARNAME [VARNAME_2...VARNAME_N]

Interactively assigns a value to the environment variable named VARNAME by prompting the user to input it's value.

3.3 Game creation via scripts

Laying out a new game by hand via the UI can be done, but is very tedious. See the files games/Demo*.sh in the teeny source tree for some ideas on how layout games with scripts. Such scripts can be hand-written or generated from other code, such as in the case of the demo scripts. Such scripts have access to most of the functionality of the user interface, and can even prompt for input to a limited degree.

Use the 'source' command to read these scripts into teeny. The demo scripts require that curses mode be activated before sourcing them, because they make heavy use of the curses-only features. This is not a general requirement, however. Complete games can be set up and played without the curses interface, though doing so would be admittedly quite tedious.

4 Customizing the Environment

While somewhat physically limited, the teeny environment may be customized in a number of ways, as described in this section. The curses UI itself is severly limited, but by applying or extending various commands, a surprising amount can be done with it.

One of the TODOs is to clean up the key-to-handler system, such that it can be configured more easily. Currently most keys are hard-coded to their handlers. Many effects brought on by hotkeys can also be achieved via commands, so the natural thing to do is to make all non-app-reserved keys available for mapping to commands (kinda like emacs...).

4.1 Environment variables

The following environment variables influence teeny in certain ways.

4.2 Dice

The UI provides a very simple ''dice roller'', which may be ''rolled'' with the 'd' (dice) hotkey and configured via the 'D' (configure dice) hotkey. Alternately, you may configure them by setting the following environment variables:

set TEENY_DICE_SIDES=number_of_sides_per_die

set TEENY_DICE_COUNT=number_of_dice_to_roll
Regardless of which configuration technique you use, the next time you use the 'd' hotkey the new settings will be used. To make the changes persistent across application seessions, put the set commands in your init.eshell file, as described below, or in another script then source that script.

Rolling dice gives the individual die rules, the total, and the average, all sent to the console.

TODO: add ''named'' dice support, just like we do for the curses colormaps and EDeck.

4.3 Meta-KEY hotkeys

The ''Meta'' key is your Alt or Escape key, depending on your terminal. Try both - they both might work. If neither work on your terminal then the curses UI will not be usable for you. If that happens, try altering the terminal settings (how this is done is terminal-dependent).

As a technical side-note: at the curses level the meta are handled differently than most keystrokes - they come across as a key 27 (Escape) followed some milliseconds later by the metad key.

You may program the Meta-ALPHANUMERIC keys to arbitrary call command strings. Use the Meta-M hotkey or the teeny-curses-macro command to do this. Macros are not inherently persistent across sessions, but may be saved and loaded with the teeny-curses-macro save command. In fact, you can can assign a macro to save your macros. Simply assign the following command to one of your macro keys:

teeny-curses-macro save $TEENY_HOME/macros.s11n
If you want to load your macros, the command syntax is:

teeny-curses-macro load $TEENY_HOME/macros.s11n
Of course, you may use another filename if you like.

To load your macros automatically at app startup, see the next section.

To see the list of current macros. tap Meta-M, then tap ENTER.

When programming the macros via the command interface, keep in mind that the curses UI uses the naming convention ''meta-KEY'', like ''meta-9'' or ''meta-R''. It uses lower-case ''meta-'' and a case-sensitive key name. This is a ''published convention'' and not an ''internal implementation detail'', so clients may rely on these mappings. By mapping macros to these keys you may directly influence the macros as activated via the UI. The following commands map macros for saving and loading a macro file, assuming that TCM is an alias for teeny-curses-macro:

TCM define meta-8 TCM load ${TEENY_HOME}/macros.s11n

TCM define meta-9 TCM save ${TEENY_HOME}/macros.s11n

4.4 Running code automatically at startup: ~/.teeny/init.eshell

This file is read by teeny-cpp at startup, using the 'source' command. It may contain any eshell-usable code.

Do NOT call the teeny-curses command from your init script(s), because that is a normal command and will cause the script to stop processing until curses mode exits (at which point the script will continue).

A sample init file:

# load the meta-[0-9] macros:

teeny-curses-macro load $TEENY_HOME/macros.s11n

# set the number/sides of dice for the 'd' command in curses UI:




# load eshell_deck plugin and some cards:

dlload eshell_deck

alias cards='deck MyCards'

cards load $TEENY_HOME/

cards shuffle

dlload teeny_actor_automove

alias TAM=teeny-actor-automove
Remember that you may also source other files from your init script:

source $TEENY_HOME/myinit.eshell

4.5 Colormaps and curses attributes

The teeny-curses-setattr command allows manipulation of almost all curses-related attributes by their string names (instead of the bitmaps it internally uses). Run this command without any options to see the full list of subcommands and their options. To save typing, for the rest of this section we will assume that:

alias tcs=teeny-curses-setattr
The color model in this app is pretty straightforward: we map Avatars (Terrain or Actors) to a flag type (which happens to be ulong, but this is a curses implementation detail). The current colormap may be set using the 'tcs colormap NAME' command. NAME may be any single token, and named colormaps are persistent within a session but not across sessions unless saved using the 'tcs save' command. All setattr subcommands are performed on the current colormap, except for save and load, which both affect the whole set of maps available via teeny::nc_attr_maps(). Note that saving the whole game state via the teeny-save command is different: it saves only the current colormap, and remembers/restores the name of the colormap when loading. Either form of loading will overwrite an existing in-memory colormaps with the same name(s).

When setting the colormap the UI's board is updated to reflect the color/attribute mappings for all on-board Terrains and Actors. Any Terrain with no attributes will show up using the same attributes as the board's base curses panel. Any Actors without attributes inherit, for rendering purposes, those of the Terrain they are currently on.

Colormap is actually a bit of a misnomer: colormaps also contain curses attribute information for flags like ''bold'', ''dim'', ''reverse'', ''underline'', and ''standout'', all of which may be set via the tcs command.

Curses works with colors in pairs, and thus teeny-cpp does as well. Unlike the curses API, however, it provides a human-readable interface into these pairs. e.g., instead of COLOR_PAIR(2) it allows us to use ''red on black''. The actual pair numbers and string mappings are set at compile-time, defined in ncpalette.hpp, and may be curses-version dependent (and thus might not be portable across systems). The app builds and internally installs a complete 64-color palette (which appears to be the limit of ncurses 5.4) and provides a function to look up the color pairs by name. The palette includes all combinations of color-on-color, given the 8 primary colors supported by curses: black, red, green, yellow, blue, magenta, cyan, white. Foreground colors may change when bolded, providing for an effective 16 foreground colors, but background colors apparently cannot be changed this way (anyone know how?).

When setting/resetting curses attributes on an Avatar it may happen that you see ''weird'' colors or strange output characters. This is normally the result of applying logically exclusive flags on top of each other (e.g., two sets of colors). You may get rid of this behaviour by doing one of the following:

tcs AVATAR raw 0
or it's equivalent:

tcs AVATAR reset
Then you need to toggle the colors/attributes you wish to set. Annoying, yes, but i don't know a better solution at the moment.

To colorize all Avatars within a range, try:

teeny-foreach-avatar AV from a to z teeny-curses-setattr \$AV color white on blue
One especially useful command which i use often is a loop which resets the attributes of all Avatars:

teeny-foreach-avatar AV from ! to ~ teeny-curses-setattr \$AV reset

(That's my meta-0 macro!)
That resets the attributes for all Avatars in the whole LRFC-legal range of [ASCII 33 .. ACSII 126], harmlessly skipping the few characters in that range which aren't actually LRFC-legal Avatars.

See the demonstration scripts in the games subdir of the source tree for many other examples of using tcs.

As a final note: while using attribute information to indicate unit states may be very useful, it is not portable to other LRFC interpretations, as it relies on curses-specific details. Thus, e.g., if you use the ''underline'' attribute to flag units which are in a certain state, that info will be lost if the game is loaded by any LRFC-compliant client other than teeny-cpp. The moral of the story is: use curses attributes only if you don't care about LRFC compatibility.

5 Plugins

Teeny's underlying libraries provide support for loading DLLs, so teeny takes advantage of that to provide a form of plugin support. You may open arbitrary DLLs with this command:

dlload DLLNAME
(Use ''dlload'' without arguments to get a short usage text and see the current library path.)

DLLNAME may be an absolute or relative path, or a basename, without directory or extension, if can be found in the current library path (aka ''classpath''). The classpath defaults to the value of the macro eshell_SHARED_LIB_PATH, from eshell_config.hpp, but can be changed by passing -classpath=DIR1:DIR2... to the application at startup.

DLLs written for use with eshell will, when opened, map in their new commands. After opening a DLL, use '?' to check for any new commands. Your own DLLs may do whatever you would like them to do. Place DLL startup code in some statically-initialized area of your DLL so that it will be called when the DLL is opened. For an example see cpp/EDeck.cpp in the teeny source tree. This loading technique does not directly use any symbols in DLLs, so we don't need any special ''export'' process to plug a DLL in to our application.

5.1 eshell_deck

This DLL comes with teeny-cpp and provides a very abstract interface for a ''deck'' of objects. It maps the command ''deck'', which must be passed a DECKNAME argument plus a command name. The DECKNAME argument is a single-token string, like ''MyDeck''. The plugin applies no meaning to the deck name, but naming them allows us to have arbitrarily many decks in play at once and perform operations on each one individually.

This plugin operatates identically in curses and console/script modes.

Deck commands:

Imports file FILENAME, where each line of input is one ''card'' in the ''deck''.

deck DECKNAME shuffle
Randomly shuffles all cards in the given deck.

deck DECKNAME draw [COUNT, default=1]
Draws the given number of cards from the top of the deck. If the deck does not have enough cards to fulfill the whole request then it does nothing but complain. When this happens, draw what you can, then load and shuffle the list again (if appropriate for your game).

deck DECKNAME clear
Removes the given deck fro m memory.

It is useful to alias commands for a given deck, to avoid having to give the deck's name for every command:

alias mydeck='deck MyDeck'

mydeck load mycards.txt
Some potential uses for a deck:

5.2 teeny_actor_automove

This plugin allows us to create ''movement maps'' with which we can semi-randomly move Actors around the board. This means that we can apply some basic movement logic to arbitrary Actors, which enhances the solitaire playability of teeny.

Automove has no concept of Terrain at the moment, and has no way to validate whether a move is valid vis-a-vis specific game rules. It is supplied mainly for solitaire game players (like myself) who want some way of telling an Actor, ''just move in that general direction, and surprise me once in a while...'' It works the same in console-, script- or curses modes.

To use it, load the plugin then use the teeny-actor-automove command (try aliasing it to something shorter, like TAM). Run it without arguments to see all of the subcommands and options.

A movement map is described as a 9-cell vector (conceptually a 3x3 matrix), each cell of which contains a probability for moving in a given direction. We determine a movement direction by fetching a random number and comparing it to the weights in the map, as described below.

The environment may hold any number of movement maps, each with a unique name. The plugin defines several maps when it plugs in, which you can view with this command:

teeny-actor-automove list
All defines maps will be listed, including their weight values, as described below.

The possible movement directions are listed here, including their positional offsets in each movement map (not coincidentally, also their C++ enum values):

UpLeft = 0 Up = 1 UpRight = 2
Left = 3 NoMove = 4 Right = 5
DownLeft = 6 Down = 7 DownRight = 8

To define a command, each cell is given a positive integer value which represents it's overall weight/probability. See below for details on how this is calculated.

We define maps using the define subcommand. An example:

alias am='teeny-actor-automove MostlyMoveForward'

am define 30 30 30 20 10 20 5 5 5
If you give fewer than 9 digits then define will fail and leave the named map unmodified. If you give more arguments the extras are silently ignored.

We move an in-play Actor using this map with the 'move' subcommand:

There are other commands for manipulating a map, like rotate and reverse, as well as load and save (both of which operate at both the single map and map list levels).

To move an actor, the algorithm simply picks a number between 1 and (total of all map cells) and chooses the appropriate direction based off of the weights of each cell. An example:

Using the above-defined map, let's assume the random number is 97. We would check like this:

Is 97 <= than UpLeft weight? If yes, move UpLeft, else try...

Is 97 <= than (UpLeft+Up)? If yes, move Up, else try...

is 97 <= than (UpLeft+Up+UpRight)? If yes, move UpRight, else try...
and so on.

To execute the move we simply dispatch the command 'teeny-actor move ...'.

The movement happens in increments of one step and if the dispatched 'teeny-actor move' command fails then automove stops immediately (this normally indicates out-of-bounds movement or stomping another actor). Thus when requesting more than one move (via move's optional count argument) you may not get that many.

6 Winding down...

The Teeny LRFC and the source code based around it are all experimental and very open to feedback. The main goal of the LRFC is to provide a definition for a ''portable'' gameboard backend which can be supported by a wide variety of environments. The purpose of teeny-cpp is to implement the core LRFC and provide a number of features on top of that. Despite it's extensions, it's core data structures are, and will remain, LRFC-compatible.

If you would like to contribute any feedback, please feel free to contact the mainainer(s) at the address(es) given at the top of this document.

About this document ...

A C++ interpreter of the Teeny Weeny Microgame Engine LRFC

This document was generated using the LaTeX2HTML translator Version 2002-2-1 (1.70)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html -no_subdir -split 0 -show_section_numbers /tmp/lyx_tmpdir59645aFvGd/lyx_tmpbuf0/teeny-cpp.tex

The translation was initiated by stephan on 2005-02-27

next_inactive up previous
stephan 2005-02-27