Using RogueSharp with RLNET Console

People have asked me if it is possible to use RogueSharp without using MonoGame. They’ve also asked how to use RogueSharp to make a classic ASCII game. Though MonoGame is a great framework there are plenty of other ways to create games in C#. Today I’m going to show how to use RogueSharp with RLNET which is a lightweight API to help quickly create tile-based games for .NET.

Large Cavern

Large Cavern

Goal

In this tutorial we’ll get RogueSharp and RLNET added to a brand new project. We’ll render the console which will be a cave-like map and intercept keyboard commands to be able to move the player represented by an ‘@’ through the ASCII cave. We’ll calculate field-of-view and render what the player can see as well as what they have previously explored. Best of all we’ll do this in just a few lines of code.

Creating a new Console Project

I’ll be using Visual Studio for this Project.

  1. Go to the File menu and choose New -> Project…
  2. From Templates choose Visual C# -> Windows Desktop -> Console Application
  3. Give it any name and location that want.
Console Application

Console Application

Adding NuGet Packages

Both RogueSharp and RLNET are available via NuGet and are easy to add to our project.

  1. Right click on the project (the name of your project will be whatever you named it in step 3 above)
  2. Choose Manage NuGet Packages… from the context menu.
Manage NuGet Packages

Manage NuGet Packages

Now you should be able to choose Online -> nuget.org and search for RogueSharp and RLNET. Click Install for both packages. As of this writing the latest version of RogueSharp is 2.0.0.0

Adding Nuget Packages

Adding Nuget Packages

Adding a Font File

RLNET needs a special font file like libtcod uses. If you aren’t familiar with this and want to know more about it there is good information here.

But for our purposes just right click and download this image and place it in your project directory.

Save to project directory

Save to project directory

Once the file is in your project directory, you should be able to Right Click on your project in Visual Studio and choose Add -> Existing Item… Choose the image that you saved and it should show up in the project. Make sure to set the Properties of this file to Copy always.

Set Copy Always

Set Copy Always

The Code

Because I’ve already produced a bunch of tutorials for RogueSharp and RLNET has it’s own set of tutorials I’m not going to explain each step. The code is only about 100 lines with comments and extra spacing and hopefully my comments are sufficient to help you out. Just copy and paste the code block below into Program.cs

using RLNET;
using RogueSharp;

namespace RogueSharpRLNetSamples
{
  public class Program
  {
    // The screen height and width are in number of tiles
    private static readonly int _screenWidth = 50;
    private static readonly int _screenHeight = 50;
    // The starting position for the player
    private static int _playerX = 25;
    private static int _playerY = 25;
    private static RLRootConsole _rootConsole;
    private static IMap _map;

    public static void Main()
    {
      // Use RogueSharp to create a new cave map the same size as the screen.
      _map = Map.Create( new CaveMapCreationStrategy<Map>( _screenWidth, _screenHeight, 45, 4, 3 ) );
      // This must be the exact name of the bitmap font file we are using or it will error.
      string fontFileName = "terminal8x8.png";
      // The title will appear at the top of the console window
      string consoleTitle = "RougeSharp RLNet Tutorial" ;
      // Tell RLNet to use the bitmap font that we specified and that each tile is 8 x 8 pixels
      _rootConsole = new RLRootConsole( fontFileName, _screenWidth, _screenHeight, 8, 8, 1f, consoleTitle );
      // Set up a handler for RLNET's Update event
      _rootConsole.Update += OnRootConsoleUpdate;
      // Set up a handler for RLNET's Render event
      _rootConsole.Render += OnRootConsoleRender;
      // Begin RLNET's game loop
      _rootConsole.Run();
    }

    // Event handler for RLNET's Update event
    private static void OnRootConsoleUpdate( object sender, UpdateEventArgs e )
    {
      RLKeyPress keyPress = _rootConsole.Keyboard.GetKeyPress();
      if ( keyPress != null )
      {
        // Check for the Up key press
        if ( keyPress.Key == RLKey.Up )
        {
          // Check the RogueSharp map to make sure the Cell is walkable before moving
          if ( _map.GetCell( _playerX, _playerY - 1 ).IsWalkable )
          {
            // Update the player position
            _playerY--;
          }
        }
        // Repeat for the other directions
        else if ( keyPress.Key == RLKey.Down )
        {
          if ( _map.GetCell( _playerX, _playerY + 1 ).IsWalkable )
          {
            _playerY++;
          }
        }
        else if ( keyPress.Key == RLKey.Left )
        {
          if ( _map.GetCell( _playerX - 1, _playerY ).IsWalkable )
          {
            _playerX--;
          }
        }
        else if ( keyPress.Key == RLKey.Right )
        {
          if ( _map.GetCell( _playerX + 1, _playerY ).IsWalkable )
          {
            _playerX++;
          }
        }
      }
    }

    // Event handler for RLNET's Render event
    private static void OnRootConsoleRender( object sender, UpdateEventArgs e )
    {
      _rootConsole.Clear();

      // Use RogueSharp to calculate the current field-of-view for the player
      _map.ComputeFov( _playerX, _playerY, 50, true );

      foreach ( var cell in _map.GetAllCells() )
      {
        // When a Cell is in the field-of-view set it to a brighter color
        if ( cell.IsInFov )
        {
          _map.SetCellProperties( cell.X, cell.Y, cell.IsTransparent, cell.IsWalkable, true );
          if ( cell.IsWalkable )
          {
            _rootConsole.Set( cell.X, cell.Y, RLColor.Gray, null, '.' );
          }
          else
          {
            _rootConsole.Set( cell.X, cell.Y, RLColor.LightGray, null, '#' );
          }
        }
        // If the Cell is not in the field-of-view but has been explored set it darker
        else if ( cell.IsExplored )
        {
          if ( cell.IsWalkable )
          {
            _rootConsole.Set( cell.X, cell.Y, new RLColor( 30, 30, 30 ), null, '.' );
          }
          else
          {
            _rootConsole.Set( cell.X, cell.Y, RLColor.Gray, null, '#' );
          }
        }
      }

      // Set the player's symbol after the map symbol to make sure it is draw
      _rootConsole.Set( _playerX, _playerY, RLColor.LightGreen, null, '@' );

      // Tell RLNET to draw the console that we set
      _rootConsole.Draw();
    }
  }
}

If you run your project now you should see something like this:

RougeSharp and RLNET Starter Project

RougeSharp and RLNET Starter Project

Here is the link to the final code on BitBucket

Additional Fun

The eleventh Seven Day Roguelike Challenge is nearly upon us! I urge you to participate. If you don’t like RogueSharp or C# there are plenty of other RogueLike libraries out there for most languages.

There are also more .NET console libraries that should work well with RougeSharp. Why don’t you give them a try, or go further with RLNET. If you haven’t used C# before maybe try it for your 7DRL this year.

  • SadConsole – Works with MonoGame! I haven’t tried it yet but want to soon.
  • Malison – I have not tried this one yet either but it looks promising.
  • RLNET – What we used in this tutorial.

5 thoughts on “Using RogueSharp with RLNET Console

  1. Joe

    Are you planning on expanding on this tutorial? I would really like to learn more on how to generate a enemy that stalks the player (pathfinding?) aswell as a simple battle system!

    Reply
    1. Faron Bracy Post author

      Hi Joe,

      Thank you for checking out this blog and RogueSharp. My tutorial on pathfinding might have what you are looking for. https://roguesharp.wordpress.com/2014/06/09/tutorial-4-roguelike-pathfinding-using-roguesharp-and-monogame/ It uses MonoGame instead of RLNet for the display but all of the pathfinding is done with RogueSharp and it should work the same way. The combat tutorial is here -> https://roguesharp.wordpress.com/2014/08/30/tutorial-6-roguelike-combat-using-roguesharp-and-monogame/ though it is very simple and has a lot of room for improvement. I hope these tutorials help but let me know if they are not what you were looking for or if you find them difficult to translate to working with RLNet instead of MonoGame.

      –Faron

      Reply
      1. Joe

        Thanks for your fast answer Faron! I’ve been looking at your other tutorials and tried to translate them to RLNET. But I’m failing pretty hard. Any fast tips?

  2. Joe

    Thanks for your fast answer Faron! I’ve been looking at your other tutorials and tried to translate them to RLNET. But I’m failing pretty hard. Any fast tips?

    Big thanks for this btw, been looking for C# tutorials like these for ages.

    Reply
    1. Faron Bracy Post author

      Hi Joe,
      There are two ways to work with pathfinding in RogueSharp. One way is the Pathfinder class and the other is using the GoalMap class. I just did a pre-release version of RogueSharp 3.0 today which has a more robust version of GoalMaps. You’ll want to see these two posts (just posted today) -> https://roguesharp.wordpress.com/2015/10/04/roguesharp-3-0-pre-release-goal-maps/
      https://roguesharp.wordpress.com/2015/10/04/using-goalmaps-in-roguesharp/

      The sample code here uses RLNet and shows how to use GoalMaps for both pathfinding and also avoidance (you can make monsters run away from the player) https://bitbucket.org/FaronBracy/roguesharprlnetsamples/src/0cbcd866875e64f6456d5fe08c86602d5f9591b9/?at=GoalMap

      I know this isn’t 100% what you were looking for but I hope it helps get you started in the right direction. As always, thank you for visiting and I’m glad you are finding the tutorials helpful.

      –Faron

      Reply

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.