Roguelike tutorial in C/C++

I stumbled upon something neat: Beginner’s Guide to Roguelikes in C/C++. Craig Stickel has been writing a tutorial on how to write own roguelike in C/C++. Currently all the articles are from the point of view of C, but judging on the index page, C++ stuff is on the horizon.

What I really like about the articles is that they always have something tanglible at the end. So if you stick to it, read the article through and code, you’ll end up with a new feature. Constant progress is very important when learning something new after all. He also provides full source code, so in case of copy/paste error, you can still get the program up and running.

Maybe I should try to write something similar in the future, when I have a bit more ready for my own project. Could do it from the point of view of using pyherc as a platform to create roguelike game. There are beginnings of the documentation online already, but should polish up things a lot more before it’s useful as a platform.

42 thoughts on “Roguelike tutorial in C/C++

  1. Hi! I also have found this tutorial from the RogueBasin site (maybe, you know about it). But I couldn’t compile it! I tried to do that with MinGW compiler and MS VIsual Studio 2010 Express. I think the major troube is in the library used. I constantly get the “unresolved reference to …”.

    Can you get me some tips about that? Unfortunately, there is no contact information about author of that tutorial.

    • Hi Sergey,

      Thanks for checking out the guide! As the author of the guide, I apologize for the confusion you’ve experienced. I’m actually porting the whole guide over to the MinGW compiler, but this doesn’t help you out in the near term. I’d like to see if I can help you get things going: could you tell me a bit about your code? Did you download it directly from the website or did you build it yourself? If you did the latter, could you post your code somewhere, or email it to me?

      • Easely! =) I’ve downoladed both article1.cpp and console.zip from your site http://www.kathekonta.com/rlguide/index.html (tried only article 1). I use MinGW compiler. I tried to compile it firstly by leaving the library with it original name in the same folder as article1.cpp. Then moved to /mingw/lib folder and renamed it to libcosole.a that I can use gcc option -l (-lconsole). But in both ways compiler shows me errors like …undefined reference to ‘Win32Console::SetTitle(char const*)’ and so on. I’ve checked the contents of a console.h header, it includes windows.h header, which also present in /mingw/include folder.

        So that it is… thanks in advance for any ideas. =)

    • Hmm… well for starters, I know one of the problems I had with MinGW was getting it to look for the library in the right place. You’re on the right track for the library import “-lconsole”. I did find for my computer that my compiler needed a “-L.” (without the quotation marks) with the rest of the command line options in order to tell the linker to look in the root directory of my project. Have you tried that?

      • Oh, yes, the option -L. also was tried, but again no success. I’ve searched inside GCC reference manual from GNU site, but there’s so many options and variants, that I couldn’t understand which librariy names GCC will search for if I put this option in my command-line. Maybe, the order of options and input and output names plays the role? Another idea is that my problem is in MinGW installation as a whole (because it doesn’t see windows.h). It would be nice if you give me some link to RTFM (or, even better, maybe you’ll include this info in your new verison of tutorial) how to build applications, which is depends on Windows headers, with MinGW… =)

      • I gave this an another (not very succesful try). I have article1.cpp, Console.h and ConsoleLib.lib in a directory. I used command “gcc -Lc:\programming\rltut -lConsoleLib article1.cpp -o article1.exe” to try to compile the tutorial. I end up with errors:

        article1.cpp:(.text+0x1e): undefined reference to `Win32Console::SetTitle(char const*)’
        article1.cpp:(.text+0x3a): undefined reference to `Win32Console::Clear()’
        article1.cpp:(.text+0x56): undefined reference to `Win32Console::Position(int, int)’
        article1.cpp:(.text+0x5b): undefined reference to `vtable for Win32Console’
        article1.cpp:(.text+0xd7): undefined reference to `Win32Console::~Win32Console()’
        article1.cpp:(.text+0xfa): undefined reference to `Win32Console::Win32Console()’
        collect2: ld returned 1 exit status

        compiler seems to find Console.h just fine, because I get different kind of error (article1.cpp:7:58: fatal error: Console.h: No such file or directory) if I rename it.

        If I rename ConsoleLib.lib to something else, I end up with error message:

        mingw32/bin/ld.exe: cannot find -lConsoleLib
        collect2: ld returned 1 exit status

        So the compiler seems to find both .cpp and .h file and linker seems to find resulting .o file and ConsoleLib.lib. But for a reason or another, linking fails and exe is not being produced.

  2. Unfortunately I’m not that familiar with C/C++. In theory I know how to read it, but that’s about it. I give it a try though, but couldn’t get the program of the first article to compile with MinGW. There’s probably something wrong with the way I tried to link the Console library.

    • Sorry guys, I was out of the country this past week for work. Tuukka, is the library named libConsole.a or something like that? I seem to remember that GCC expects any library specified with the -l option to follow the “libXxxxx.a”. I could have named my library incorrectly, hence why it can’t find it. What happens on your machines when the console library is renamed to libConsole.a and you use the “-L. -lConsole” command line options? This worked for me.

      • Library itself is named “ConsoleLib.lib” and header for it is “Console.h”. Compiler/linker seems to find it with that name, since if I rename it to something else, I get error “mingw32/bin/ld.exe: cannot find -lConsoleLib”.

        I renamed the library to “libConsole.a” and tried compiling with command “gcc -L. -lConsole article1.cpp -o article1.exe”. Result was those familiar undefined references. To my understanding article1.cpp gets compiled into object file just fine, but linker does not find function calls it is looking for in libConsole.a.

        Could the problem be in the MinGW installation itself?

      • I’m going to be tied up for the next couple of days, but I am planning on buildng up the project from scratch and see if I can replicate this error. I’m making the assumption that you two have been using Eclipse CDT + Mingw? Is that correct?

        • That would be really great if you could have a look at that. If it helps any, I could try compiling the console library on my machine to see if it has any effect on errors or not.

          I have been using plain MinGW on old Windows XP machine without Eclipse.

  3. 2tuturto: I think it’s a kind of error with windows functions, which prototypes are in windows.h headar in MinGW include directory. But the interesting fact is that if I make a little test program with string like #include in it, MinGW compiles .exe file from it without any complaints. I don’t call any Windows API functions in my test, though…

    • Interesting theory. I haven’t tried to compile any other programs than the article 1 from roguelike tutorial. I was wondering if there is something wrong with my installation of MinGW, like missing environment variable or something.

  4. Alright, I think I have a solution. From my understanding, the problem came from me trying to make a static library that could share across many different compilers. I’ve updated the Console Library download package on the website to include static libraries for MSVC and GCC compilers. Feel free to download it from the website: http://www.kathekonta.com/rlguide/index.html

    For MinGW, I believe all you’ll need to do is copy the “Console.h” and “libConsole.a” files from the downloaded zip into your project directory, and make sure your command line looks something like the following:

    g++ -Wall -c -omain.o
    g++ -L. -lconsole main.o -oTest.exe

    For now these libraries are only for windows boxes (aka I do most of my personal development on a crappy WinXP netbook) but I have a iibrary almost 90% complete for the Raspberry Pi. My hope is that I’ll be able to release that, three more articles, and polish up my examples over this Christmas break.

    At any rate, please let me know if this works for all of you. Again, I apologize for the frustration you all went through, and thank you so much for your patience!

    • Thanks, I got quite a bit further now. I downloaded the new version and compiled article one with:

      g++ -c -omain.o article1.cpp
      g++ -L. -oConsole_Test.exe main.o -lconsole

      The program compiles and I can run the resulting exe. Instead of “@” the screen displays “8.96831e-044”, but I can move it around just fine. Kind of fascinating really.

      I don’t really know what could cause this. Changing @ in the source code results to different strings on screen, so maybe somewhere the char gets converted to something else and displayed as a number?

      This almost makes me feel like learning C/C++ again.

      • What you’re seeing is the ASCII code for ‘@’ being typecasted as an IEEE 754 float for some stupid reason. Maybe replace the ‘@’ in the code with “@” (single quotes to double quotes) until I can push a fix out.

        Wow… that’s embarrassing… 🙂

  5. Ok, I got the same problem, I’ve been trying to get rid of it many ways but I just can’t figure out how to do this… I use Dev-cpp btw.

    • Hi Max,

      Are you seeing the same problem as Tuukka? Or are you having difficulties getting the project to build? I’d like to help you, but I don’t want to hijack his website for my troubleshooting. 🙂 Feel free to email me at DOT AT gmail DOT com. I’d love to help you get things going!

      – Craig

      • I know I actually should have mailed, but I want people to see this:

        I kept having that same problem Tuukka had over and over, then I tried something different. Some people will hate to do this, but it actually helped me to switch IDE. I used dev cpp for quite a long time, but I tried codelite for a change and everything seems to be building and running just fine.

        Furthermore I want to thank you for putting effort in making this tutorial, It’s great! And people who don’t know much about cpp and want to get into the language without reading the boring books, should read and try to make the roguelike of your tutorial, it teaches you the basics + you actually make something. I’d advise you to also check out libtcod, just because it already has a algorithm for generating the dungeons.

        • Thanks for the comments and the encouragement, Max.

          My hope was if I did things properly people wouldn’t be forced to switch compilers. 🙂 Do you like codelite? I haven’t had any experience with it, myself. I’m an embedded developer, professionally, and do most of my work with these crappy 3rd party IDE’s. The guide was written with Eclipse CDT (MinGW) and I normally run things by an old version of MSVC++ 6.0 to check for “legacy” support (which should be DevCpp compatible… I’m a little surprised it didn’t work).

          I’ve looked at libtcod before – and maybe it’s just the jaded old-school coder in me – but I found that the architecture and design promoted poor coding habits. Not that I should talk, mind you, because the Guide does the same thing, but my plan is to progressively clean things up so that readers can feel the difference between good code and bad code. We’ll see if I can actually make that happen.

          At any rate, thanks for the info! I’m polishing up a new batch of articles for the end of the month (knock on wood), so I’ll run them by DevCpp and see what’s up.

          Cheers,
          – Craig

        • Really good to hear that you got it working (this blog must be useful for something). I downloaded CodeLite too and tried with that, but ended up with the same result as before (that funny IEEE float moving around on screen). If I have more time during the weekend, I’ll try to tinker with it and see if there is some setting in CodeLite or MinGW that I have overlooked and that could cause this behaviour.

  6. I know next to nothing about C/C++, but I was wondering something. The IConsole has << operator overloaded for different types like char, double and float. Is it possible that for some reason wrong version is being called? Instead of calling the one that outputs char, the program ends up calling the one that outputs float? Part of the number being displayed is '@' and part what ever random bits happen to be next to it in the memory?

    I tried looking for compiler and linker settings, with no luck really and different types being outputted to console didn't really change much (some didn't output anything, while others outputted that familiar IEEE float).

    • You are exactly right. A few days ago, I caught the overloaded operator << ( char ) behaving a little wierd; compilers may have skipped over it entirely. I think I've corrected that side of things… but the two compilers I use for testing can't replicate the problem for some reason. I've got a fix ready, would you be willing to try the fix on your box?

  7. Alright! Thanks in large part to the people here, a whole new wave of articles have just been posted to the guide. I’d love to hear what you all think of it and if there are any improvements or if anything was really confusing. I’m trying something a little different with Article Eight, an I hope that it wasn’t too difficult to follow.

    Thanks to Sergey and Max for their input (and bug posts, I’m sorry to say) and to Tuukka for generously hosting this conversation and for testing a fix for the console library.

  8. Oh, it seems like I’ve lost a connection with the topic, but I hope to get back on track! =)

    Anyway, thanks a lot to Craig and other people for great work! Lot of new information, I need to review the whole discussion — but it’s excellent! =)

  9. Pingback: New articles at Beginner’s Guide to Roguelikes in C/C++ « Engineer's Journey

  10. Hi! I tried to compile this code in MCVC 2012 and I got a few errors. It is saying the same stuff as tuturto said, mainly that it can’t reference the code. I copied the .lib folder to “C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib” and the .h file to “C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include”

    • Hi Austin,-

      First off, thanks for checking out the guide and trying the examples.

      About your request for 64-bit libraries… I apologize but I don’t have any and, unfortunately, it’s going to be staying that way for the foreseeable future: I don’t have access to a 64-bit system to develop or test upon so I can’t guarantee any semblance of quality. This sucks, but my 64-bit cpu gave up the ghost and I’m S.O.L. for a replacement this year.

      I’m sorry for the difficulty getting the examples compiling. I have an idea and I was wondering if you could try something: it might be easier for you to just add the library file and the header file to your project rather than trying to copy it into your compiler’s library collection. A lot of times, MSVC adds only a handful of libraries to your project by default and expects you to specify more exotic ones in your project settings. I’ve seen this with the winsock32 libraries which – while included in your install – are not normally linked in to your project unless you explicitly tell the project to use it.

      This should do two things: 1) help keep your IDE’s install clean and 2) adding these files to the project should implicitly tell the compiler/linker that you want to use them when building the project.

      I hope this helps you. Lemme know if it works!

      – Craig

  11. Hi Craig,

    realised you haven’t been posting for a while and was just checking to see if everything’s ok.

    the fix for MSVC++ 12 doesn’t work for me so that’s a problem.

  12. Does anyone know whats going on here? Everything compiles and runs without any errors but when It actually runs i get a terminal window and a square terminal window with a lengthy error msg saying “assertion failed” and i have no idea whats wrong, I’m using Code::Blocks (mingw) with the gcc compiler. Also the program stops working instantly.

    • Craig has been quite silent in his blog (http://blog.kathekonta.com/), but hopefully he’s around and would drop by to help us with these. In the meantime, could you post the whole error message Colby? If nothing else, we can have a look at it and wonder what’s going on.

      • My sincerest apologies for the disappearance. I wouldn’t share this on my blog, (but I always feel amongst friends on Tuukka’s site) the last four months have been hellish. Between the record flooding in my city, a death in the family, almost loosing a nephew, a health scare and two back-to-back crunch times at work … well, things have been a little hairy.

        Things have stabilized and gotten back to normal (ish) so I’m starting back up again. It seems like the greatest barrier to people getting into roguelikes is the console library, so the first order of business is that I’m completely re-writing the console library to be compatible with MSVC++ 2008, 2012 and MinGW and will be releasing it as open-source. This new library will have more intelligent negative path handling, which will hopefully make everybody’s lives easier. I’m afraid this will take me a week or two to get to release-quality however.

        In regards to the “assertion failed” thing I can shed some light: the first thing the library does at initialization is seek out your program’s STDOUT and STDIN handles and “asserts” that they exist. These assertions are performed whenever the console library attempts any operation using those streams so that your program doesn’t randomly crash.

        It seems like it’s having a hard time accessing these handles: are you using Win 8 or a 64-bit build? Anything like that?

        Thanks for checking out the guide and giving it a shot!

        – Craig

  13. So, I did it! I mean I’ve read all articles that are present in the tutorial at the moment. But I did some deviations. I used plain C and curses library (gcc+ncurses under Linux and MinGW+pdcurses on Windows). All works almost fine despite that there are no classes for actor with constructors and destructors etc.

    Now I’m trying to implement a testing for busy tile when monster or PC moves. Again, it works, but, for example, grass tile appears ocassionally on a tile where it wasn’t before.

    Thanks a lot for so informative and clear explanations, and I’m waiting for new parts! =)

    • Ha ha, congratulations Sergey! So glad to hear!

      As mentioned above, I’m trying to release a new console library so more people can reach the level that you have achieved. Once that is done, I’m tackling new articles – including a better implementation of actor storage to make it easier to associate their position with the rest of the map.

  14. Great to have you back Craig. I’m looking forward on seeing more parts in your roguelike tutorial. Hopefully things will be calmer from now on for you.

  15. Hay I have a problem with line 147 on article9.cpp.
    The build says:
    Warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    Can some on help I haven’t even touched the code, and Code::Blocks has the gcc source file

    • To me the reason for warning looks to be that sItemIndex[] is being initialized with ITEM_TYPE structures and item name is passed in as a string literal. In ITEM_TYPE definition (line 68), p_szName has been declared as a char *, which is not a constant. The code should still work just fine, even with the warning. If you would want to get rid of the warning, you could try editing line 72 to read:

      const char * p_szName; // Name of the item type

      That declares p_szName as a const, which is compatible with string literal. Of course, after this there is no way of changing name of the item anymore, which may or may not be what you want.

      Hope this helps, I didn’t have time to test this by myself. If there’s still problems, let us know and we’ll see what we can do. Craig is much more knowledgeable than me when it comes to C/C++. His blog is at http://blog.kathekonta.com/ and you might be able to contact him faster there than here.

Leave a reply to tuturto Cancel reply