I created an awesome rogue-like game in Ruby. For the GUI, I used NCurses. Since I'm using FlatRedBall as my engine of choice for Silverlight game development, I want to port this game over.

What is the best way to efficiently doing this, and what are the pitfalls I should expect?

For example, Ruby is object-oriented, like C#, and I should be able to just convert (rewrite) classes one by one. However, I will run into issues like:

  • NCurses API. I need to possibly create my own notions of a "Window", or else rewrite GUI code. It's one class, but it's BIG.
  • Mix-Ins. These are essentially aspect-oriented development. There are a couple of solutions in .NET, like dynamic classes.

What else? Also, I should mention that I want to create a FlatSilverBall (C#) application out of this. That is to say, I will be using the FlatRedBall 2D engine as my foundation. I am not interested in Curses, or any other variation that will allow me to make a console-type game.

As much as possible, I'll dump reusable and helper code, algorithms, etc. into separate projects and generate reusable DLLs.


As I see it, you have a few options:

  1. Port to IronRuby, build your ruby code as a .NET library, then rewrite the engine links in C# or IronRuby. If your game's logic is already all in Ruby, no reason not to try and preserve it as a library and then write new code to interface with it.

  2. Do a rewrite. This is probably how I would approach it. C# is not Ruby, and trying to do a direct port is likely to result in frustrations. Better to adapt what algorithms and structure you can, and then rewrite in C# so you can approach problems "the C# way" instead of trying to adapt a Ruby methodology to a different language.


While directly porting the classes, et cetera, over is possible, the biggest issue to be aware of (when discussing the problem at such as a high level as you are) is the different semantics for various operations and paradigms between two languages.

It doesn't look like you have much selection in terms of NCurses APIs for .NET (I found this, but it looked Mono-focused and thus may not meet your needs. So it sounds like you may need to rewrite that aspect of your program. System.Console has a few features that may be useful, but likely is not robust enough to replace a curses-based UI unless you were using very simple stuff.

I would be careful with porting your mix-ins. There are frameworks for aspect-oriented programming in C#, but they are generally extremely heavyweight and probably not suitable for games. Hand-rolled dynamic class generation is an option, but is still likely going to be more work than it's worth for the features and behavior you're likely getting from your mix-ins. It may be best simply to port these features as individualized objects that you aggregate inside other classes and defer to.

It's hard to provide much more direction without knowing more about specific technologies and techniques you employ in your game.

  • \$\begingroup\$ I'm not sure what other information I can provide. The source can be found here: railsrocket.com/plainrl-10-released. As for mixins, I have a design pattern I employ for compile-time checkable aspects. That's not a problem... Also, I won't be using NCurses, but FRB for the GUI. \$\endgroup\$ – ashes999 Mar 15 '11 at 15:44

There is the absolutely great libtcod you could try. Basically, it is a console emulator/Curses type console. In more detail, it is a fully fledged rogue library (i.e. dungeon generation, FoV calculation, heightmap generation..which may be useful?). It is written in C/C++, but it has wrappers for C# (and the documentation is great for all of its supported languages).

  • \$\begingroup\$ I'm not interested in Curses-type game development. That was a sad limitation of Ruby that I saw no work-around for. I'll be using .NET and FlatRedBall as my basis, a 2D engine. \$\endgroup\$ – ashes999 Mar 15 '11 at 16:42
  • \$\begingroup\$ Ah, I did not see that in the original question. \$\endgroup\$ – The Communist Duck Mar 15 '11 at 16:43
  • \$\begingroup\$ No worries. You're the second person to mention Curses in C#, so I thought I'd clarify that by editing my post a bit more. \$\endgroup\$ – ashes999 Mar 15 '11 at 16:45
  • 1
    \$\begingroup\$ You just said you weren't interested in Curses, but the main issue is Curses. What? \$\endgroup\$ – The Communist Duck Mar 15 '11 at 20:07
  • 1
    \$\begingroup\$ I'm upvoting this because libtcod is an excellent library for cross-platform console applications (particularly roguelikes), and the original question didn't have the clear "No console-like engines" requirement that was added later. \$\endgroup\$ – CodexArcanum Mar 15 '11 at 20:32

Mix-Ins. These are essentially aspect-oriented development. There are a couple of solutions in .NET, like dynamic classes.

Mixins are definitely not like AOP. You can get much of the benefit of mixins in C# using interfaces and extension methods. For example, here's a mixin and a class that includes it in your code:

# Defines functionality that any class that mixes it in can have:
module ValuableObject
  def effective_cost
    raw = self.cost # Implicit requirement on mixing-in class.
    if raw < 10000
      return raw
    elsif (raw >= 10000 && raw < 1000000)
      return "#{raw.to_s[0 ... -3]}k"
      return "#{raw.to_s[0 ... -6]}m"

# Class that mixes it in:
class Weapon < Item
  require "classes/modules/ValuableObject"
  include ValuableObject

  attr_accessor :cost

  # More stuff...

That translates directly to C# like this:

// Makes mixin's requirements on host class explicit:
interface IValuable
    int Cost { get; }

// Any class that implements IValuable will mix in these methods:
public static class ValuableExtensions
    public static string GetEffectiveCost(this IValuable valuable)
        var raw = valuable.Cost;
        if (raw < 10000) return raw;
        else if (raw >= 10000 && raw < 1000000) return (raw / 10000) + "k";
        else return (raw / 1000000) + "m";

// Class that mixes in:
public class Weapon : Item, IValuable
    public int Cost { get; set; }

    // More stuff...

With that, you can then do:

var weapon = new Weapon();

Don't reach for dynamism unless you're actually doing something dynamic.

  • \$\begingroup\$ This is essentially the pattern I use to define mixins in C#: a public interface, an implementation of that interface, and redirection ("inheritance" by composition) \$\endgroup\$ – ashes999 Mar 16 '11 at 2:59

Are you looking to have a text-based interface like typical roguelikes? If so, isn't the most obvious approach to store chars in a 2d array or other structure? Then you can concat each char to 1 single string (with newlines where appropriate) and draw that each frame with SpriteBatch.DrawString(), then when the player moves update the structure, concat the elements, and start drawing that string each frame? I've got a feeling your display code will end up a lot simpler (or at least more straightforward) for the same relative results.

Or if you're looking to ditch ASCII, just use a tile engine.

Either way, you essentially just need to replace the visual component of your game, right? I've got a feeling you may be able to whittle down your Window code since you'll no longer be dealing with Curses. Take this as an opportunity to cut/rewrite parts of the code, since though some techniques might make sense in Ruby may be a pain to manage in C# or vice versa.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.