PICO-8 Work in Progress

My last blog entry was about a fantasy console called PICO-8. Since then, I’ve been having quite a bit of fun playing around with the thing.

I’m pretty bad and drawing even “programmer graphics”, but when you only have 8×8 pixels and 16 colors, it doesn’t really matter… it isn’t going to be a masterpiece anyway!

Below is a GIF of the game I’ve been working on. It is coming along nicely considering that I haven’t really gotten a chance to put that much time into it. It is an old-school RPG, similar in style to the very early Ultima games.

So far, I’ve got the overland map and travel working, and I’ve put together a town map system that isn’t limited by the built-in map size of the PICO console (essentially unlimited town maps, though given the size of the game I don’t really need that many – but I need more than will fit into the built-in map editor).

My next project is to implement dungeons, and then flesh out the character generation and game system (stats, monsters, items, etc). Then I can populate the towns with NPCs, add quests, and the like.

pico_adventure

The beginnings of an old-school RPG for PICO-8.

Nothing actually playable at this time, but I’m getting there. Working with PICO really reminds me of coding on the Commodore 64 (though LUA is much more advanced than C=64 Basic, and alot less tedious than 6502 assembler!) In fact, this is the kind of thing I put together on a regular basis on the Commodore.

 

Fun with PICO-8

I backed the CHIP Kickstarter about a year ago, and as the shipment date for my pledge level approaches (late May, and they say they are on time), an update was posted indicating that a CHIP specific version of PICO-8 will be included with PocketCHIP. I had never heard of PICO-8, but once I knew what it was, I immediately went over and purchased a copy though their Humble store.

PICO-8_3

PICO-8’s editors are all built into the console. Here is the sprite editor used to create graphics for your games.

PICO-8 is described on the Lexaloffle website as a “Fantasy Console”, and is essentially a self-contained “emulator” for a console that never actually existed. The console is designed with extremely limited hardware/software specifications, intended to mimic a classic 8-bit environment. Developers can create custom cartridges that can be shared with other users or played on the web through the Lexaloffle forums. Each cartridge is limited to 32k, contains up to 128 8×8 pixel sprites, and a 128×32 cell world map.

PICO-8 includes a complete development environment within the program, including code editor, sprite editor, map maker, sound effects editor, and music track editor. With the full version (not the web player) you can switch over to the code and resources for any cartridge you are playing and begin editing. You can start from scratch and create your own cartridge entirely, or modify an existing game to change it in any way you wish.

Code is based on the LUA syntax, without the LUA libraries. There is a provided API that lets you play sound, display sprites, and draw maps in addition to the standard pixel and shape-oriented drawing tools.

Continue reading

Game Music – Thoughts and Resources

Kotaku had a post the other day: The Moment that Changed How I View Music in Games. When I saw the title, my first though was that for me, it was the Opera scene in Final Fantasy (3 or 6 depending on if you use the English or Japanese numbering of the titles.) I was pleasantly surprised to open the article and find that the author was talking about exactly that.

For those unfamiliar, the article above goes into good detail about the sequence, but in short there is a portion of the game where you are tasked with learning a song for an in-game opera (unrelated to the rest of the story) and “perform” it by selecting subsequent lines of the lyrics.

This was long before the days of voice in games, but the developers did a fantastic job of actually making it seem like the song was being sung by the performer (considering the hardware available at the time!) In the twenty years since what I played as Final Fantasy III on the SNES was released, I still occasionally find myself humming Maria’s song.

When it comes to games, music seems to fall into a handful of categories. First there are the games where the music either really fits well and is used at the right times. To me, these are games like the Ultima series (you can listen to many of the Ultima tunes at Auric’s Ultima Moongates) and the Morrowind, Oblivion, and Skyrim games (music by Jeremy Soule – you’ve no doubt heard music composed by Mr. Soule, as he has composed music for just about every kind of game you can think of.) If I pop in a CD with the theme from the Plane of Time (EverQuest) on it, I can easily recall countless hours spent in that zone.

By the same token, I know that most of my guildies in EQ had turned their music off a few days after starting to play the game. That’s a shame, because some of the music was very good, but it also got pretty repetitive at times. That is a danger in any MMO though, where the developer does not really have any way of matching the pacing of the music to the action happening in the game.

The second category of game music, to me anyway, is music that fits well in the game but goes almost unnoticed by the player. This is good in some ways – it doesn’t distract the player from the game – but it is almost like a movie score. It is there to support what is happening on the screen and not meant to overshadow it. As such, if you remember it at all it is on a subconscious level.

Third would be rhythm or music based games. In these games,  the music is an obvious attraction and may be popular music being used as the basis for the game (Rock Band, Guitar Hero, etc) or perhaps original or generated music integrated into the game, along the lines of the Bit.Trip series. In both types of games, the music is fundamental to the game, though in the case of the former you may not associate the songs with the game – you already know the songs.

Finally, there are games where the music just doesn’t seem to fit. I’m not going to call out any specifics here, but we all know games like this, where the music is best turned off and left off.

For the indie developer, when working on a game, music is nearly a requirement these days, and finding or generating good music can be quite a task. If you are a small (or one person) team, you need to not only be able to write the code and generate the graphics, now you need songs too.

One source I’ve found for music for my own projects is OpenGameArt.org – one of my favorite sites. Yup, OGA contains not just graphics, but music and sound effects too. There are some really talented people uploading music to OGA, that fit any number of genres, to 8-bit chiptunes, fantasy scores, and sci-fi inspired music.

Many of the tracks have been released as CC0 (Public Domain) and can be used in anything you want to create. Others have non-PD but generally friendly licensing terms – be sure to check the licenses before you include them in your project – but definitely take a listen.

 

A PowerShell Snake Game

As a network administrator, PowerShell is just one of those tools that, once you use it, you can never imagine doing a lot of admin tasks without it.

Interested in Powershell games? Check out my new Powershell Match Three game

 

Given it’s similar structure to other languages, I picked up on PowerShell pretty quickly, and while doodling around with it decided to try using it for something for which it was really never intended. After all PowerShell is awesome for automating data loading, updating Active Directory attributes, generating reports or extracting data to build a dynamic HTML snippet to be served up by a web page, but there are GAMES to be considered!

So here is my PowerShell game. The classic “Snake” computer game, allowing you to use the arrow keys on the keyboard to hunt down and eat apples (stunningly represented by a red @ sign – I know, the graphics are impressive!)

Powershell_Snake

 

Below is the (fairly heavily commented) result (along with a .ZIP file to download the script at the bottom of the page in case copying and pasting from a website isn’t for you – and does that ever work right?)

The script utilizes PowerShell’s RawUI functionality to position the cursor to write individual characters. Each segment of the snake’s body is stored in an array, but when the snake moves forward, the only “drawing” that takes place is to remove the last block of the tail and draw the new head block.

In most games, you would clear and redraw the entire screen after every frame, but given the interpreted nature of PowerShell, it just isn’t fast enough to do that. Even this method is pushing it once the snake grows a bit. Things get slower over time as more blocks need to be checked to determine if the snake has run into itself. The code here could be improved upon – for example, it should be possible to determine a general slowdown rate as the snake grows and adjust the sleep near the end of the script (that delays between each frame) to eliminate at least some of the lag. Since this was a project for an hour of free time, I didn’t go that far with it.

Update: See the comments for Dave Wyatt’s update that changes the way the tail is checked for his and removes the slowdown completely 🙂

I do have a couple more ideas for games that could be written in PowerShell when considering the speed restrictions, so we’ll just have to see if they every make it into .PS1 files. In the mean time, enjoy chasing the apple…

#requires -version 2

#
# Powershell Snake Game
# Author : Kurt Jaegers
#

#
# Draws the snake to the screen, including cleaning up the last segment of the tail
#
function DrawTheSnake
{
 
  # Erase the tail segment that is disappearing
  $rui.cursorposition = $tail[0]
  write-host -foregroundcolor white -backgroundcolor black -NoNewline " " 
 
  # Shift all of the tail segments down one
  for ($i=0; $i -lt ($tailLength - 1); $i++)
  {
    $tail[$i].x = $tail[$i+1].x
    $tail[$i].y = $tail[$i+1].y
  }
 
  # Set the last segment of the tail to the current position
  $tail[-1].x = $coord.x
  $tail[-1].y = $coord.y
  
  # Draw all segments of the snake  
  for ($i=0; $i -lt $tailLength; $i++)
  {
    $rui.cursorposition = $tail[$i]
    write-host -foregroundcolor white -backgroundcolor white -NoNewline " "
  }

}


#
# Generate a random location for the apple, making sure it isnt inside the snake
#
function MoveTheApple
{ 
  $ok = $true;
  do 
  {
    $script:apple.x = get-random -min 2 -max ($rui.WindowSize.width - 2)
    $script:apple.y = get-random -min 2 -max ($rui.WindowSize.height - 2)
    $ok=$true
    for ($i=0; $i -lt $tailLength; $i++)
    {
      if (($tail[$i].x -eq $apple.x) -and ($tail[$i].y -eq $apple.y))
      {
        $ok=$false;
      }
    }
  } While (!$ok)
}

#
# Draw the apple to the screen
#
function DrawTheApple
{
  $rui.CursorPosition = $apple
  write-host -foregroundcolor red -backgroundcolor black "@"
}

#
# Check to see if the snake hits the apple
#
function CheckAppleHit
{
  # if the x/y of the head matches the x/y of the apple, we hit the apple
  if (($tail[-1].x -eq $apple.x) -and ($tail[-1].y -eq $apple.y))
  {
    # relocate the apple
    MoveTheApple
    
    $score += 500
    
    # Add to the snake's length
    $script:tailLength++
    $script:tail += new-object System.Management.Automation.Host.Coordinates
    $script:tail[-1].x = $coord.x
    $script:tail[-1].y = $coord.y
  }
}

#
# Check to see if the snake's head hits the walls of the screen
#
function CheckWallHits
{
  if (($coord.x -eq 0) -or ($coord.y -eq 0) -or ($coord.x -eq $host.ui.rawui.windowsize.width-1) -or ($coord.y -eq $host.ui.rawui.windowsize.height-1))
  {
    cls
    write-host -foregroundcolor red "You lost! Score was $score"
    exit
  }
}


#
# Draw a fence around the edges of the screen
#
function DrawScreenBorders
{
  $cur = new-object System.Management.Automation.Host.Coordinates
  $cur.x=0
  $cur.y=0
  
  for ($x=0; $x -lt $host.ui.rawui.windowsize.width; $x++)
  {
    $cur.x=$x
    $cur.y=0
    $host.ui.rawui.cursorposition = $cur
    write-host -foregroundcolor black -backgroundcolor white -nonewline "#"

    $cur.y=$host.ui.rawui.windowsize.height-1
    $host.ui.rawui.cursorposition = $cur
    write-host -foregroundcolor black -backgroundcolor white -nonewline "#"
    
  }
  
  for ($y=0; $y -lt $host.ui.rawui.windowsize.height-1; $y++)
  {
    $cur.y=$y
    $cur.x=0
    $host.ui.rawui.cursorposition = $cur
    write-host -foregroundcolor black -backgroundcolor white -nonewline "#"

    $cur.x=$host.ui.rawui.windowsize.width-1
    $host.ui.rawui.cursorposition = $cur
    write-host -foregroundcolor black -backgroundcolor white -nonewline "#"
    
  }  
}

function CheckSnakeBodyHits
{
  for ($i=0; $i -lt $tailLength -1; $i++)
  {
    if (($tail[$i].x -eq $coord.x) -and ($tail[$i].y -eq $coord.y))
    {
      cls
      write-host -foregroundcolor red "You lost! Score was $score"
      exit
    }
  }
}

# ---------------------------------
# ---------------------------------
# Main script block starts here
# ---------------------------------
# ---------------------------------

# Grab UI objects and set some colors
$ui=(get-host).ui
$rui=$ui.rawui
$rui.BackgroundColor="Black"
$rui.ForegroundColor="Red"
cls

# write out lines to make sure the buffer is big enough to cover the screen
for ($i=0; $i -lt $rui.screensize.height; $i++)
{
  write-host "" 
}
$coord = $rui.CursorPosition
$save = $coord
$cs = $rui.cursorsize
$rui.cursorsize=0
$score = 0

$done = $false

$before = 0
$after  = 15
$dir = 0

$coord.X = $rui.screensize.width/2
$coord.y = $rui.screensize.height/2

$coord.x = 80
$coord.Y = 15
$apple = new-object System.Management.Automation.Host.Coordinates
DrawScreenBorders;
MoveTheApple;

$tail = @()
$tailLength = 5

for ($i=0; $i -lt $tailLength; $i++)
{
  $tail += new-object System.Management.Automation.Host.Coordinates
  $tail[$i].x = $coord.x
  $tail[$i].y = $coord.y
}

while (!$done)
{
  
  if ($rui.KeyAvailable)
  {
    $key = $rui.ReadKey()
    if ($key.virtualkeycode -eq -27)
    {
      $done=$true
    }
    if ($key.keydown)
    {
      # Left
      if ($key.virtualkeycode -eq 37)
      {
        $dir=0
      }   
      # Up
      if ($key.virtualkeycode -eq 38)
      {
        $dir=1
      } 
      # Right
      if ($key.virtualkeycode -eq 39)
      {
        $dir=2
      }
      # Down
      if ($key.virtualkeycode -eq 40)
      {
        $dir=3
      }
    }
  }
  
  if ($dir -eq 0)
  { 
    $coord.x--;
  }
  
  if ($dir -eq 1)
  {
    $coord.y--;
  }
  
  if ($dir -eq 2)
  {
    $coord.x++;
  }
  
  if ($dir -eq 3)
  {
    $coord.y++;
  }

  DrawTheApple;
  DrawTheSnake;
  CheckWallHits;
  CheckSnakeBodyHits;
  CheckAppleHit;

    
  start-sleep -mil 100
  
  $score += $tailLength;
  
}

$rui.cursorsize=$cs

Download Snake.zip – PowerShell Snake Game

  • Advertisement