The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Game::LevelMap - level map representation


  use Game::LevelMap;

  my $lm = Game::LevelMap->new( from_string => <<'EOF' );

  print $lm->to_string;

  # the following methods may require buffering disabled

  $lm->to_terminal( 1, 1 );

  # maybe instead there's a static border, indent
  $lm->to_terminal( 2, 2 );
  # several points on the map changed, update them
  $lm->update_terminal( 2, 2, [ 5, 2 ], [ 4, 2 ] );

  # complicated, see docs tests eg/panel-viewer
  $lm->to_panel( ... );


A small level map implementation that uses characters (or strings consisting of escape sequences or combining characters, or objects that hopefully stringify themselves properly) in an array of arrays representing a level map as might be used in a game.

  x cols
  y rows

Points use the geometric form (x,y) col,row which is backwards from what terminal escape sequences use.


These return new objects. If something goes wrong an exception will be thrown.


Returns a new object from an existing one with the current state of the level attribute. The copy is shallow; a level map of objects when cloned will have the same objects as the other object.

new level => ...

Constructor. Either the level attribute should be specified or from_string to build the level from a string representation.



Where the level map (an array of arrays) lives. Can be set and accessed directly, or set via the from_string method.


Number of columns (x) in the level map. Cannot be changed directly.


Number of rows (y) in the level map. Cannot be changed directly.


from_string string

Constructs the level map from the given string. Throws an error if that fails.

to_panel col row width height x y [ oobfn ]

Displays possibly a portion of the level map within the given width by height panel that is drawn at the offset coL row on the terminal. x and y specify where on the map the panel should center on. The width and height must be odd values for the map to center itself properly.

  my @offset = ( 1, 1 );
  my @size   = ( 79, 23 );
  $lm->to_panel( @offset, @size, $player_col, $player_row );

The optional oobfn function handles how to draw points that are out of bounds due to how the map is centered; by default this function returns the space character, though might instead use modulus math to make the level map wrap around:

      @offset, @size, 0, 0,
      sub {
          my ( $lm, $col, $row, $mcols, $mrows ) = @_;
          return $lm->[ $row % $mrows ][ $col % $mcols ];

Use the far less complicated to_terminal method if the level map is not larger than the terminal window.

Buffering should likely be disabled on the STDOUT filehandle before using this method.


Converts the level map to string form and returns it.

to_terminal col row

Prints the entire level map to standard output (assumed connected to a terminal that supports ANSI or XTerm control sequences) with the upper left corner of the map appearing at the given row and col (which must be integers greater than zero). The level map should not be larger than the terminal, though no checks are made regarding this.

Use the more complicated to_panel if the level map is larger than the terminal window, or to_string and then view that output with a pager program.

Buffering should likely be disabled on the STDOUT filehandle before using this method.

update_terminal col row points ..

Updates specific points of the level map, presumably after to_terminal has already printed the entire level map. Must use the same col and row map display offset as used in to_terminal. The points should be a list of array references.


Reporting Bugs

Please report any bugs or feature requests to bug-game-levelmap at, or through the web interface at

Patches might best be applied towards:

Known Issues

There is either too much or too little error checking.

An actual game may want to adapt code from this module and make it less generic, as usually things like the map panel size will be fixed, etc.

to_panel redraws the whole thing each time. With a buffer and change checks this might only update points that have changed, which would save on display bandwidth (which may be a concern over SSH connections).



thrig - Jeremy Mates (cpan:JMATES) <jmates at>


Copyright (C) 2019 by Jeremy Mates

This program is distributed under the (Revised) BSD License: