Archive for the ‘Uncategorized’ Category

Knights update (December 2014)

Tuesday, December 9th, 2014

Hi everyone, I haven’t done a Knights update for a while so I thought I would just check in to let people know I am still here :)

Unfortunately, I haven’t had much time to work on Knights recently, so there haven’t been any changes to the codebase to report.

However, I did take the time to update the Knights web page. In particular I added a couple of review quotes, which I’ll reproduce here because they are a great description of the game:

This game is fun. It isn’t at first because there’s just so much to take in, but stick with it for an hour or two and I promise you this is one of the best games ever created.

(Steven Pearson)

If any other convincing is necessary that this is one of those multi-player games to play with friends while drinking beer, then consider this: how many other Amiga games let you bash through a door with an axe in a “Here’s Johnny!” style just before you bury the axe in your opponent’s skull?

(Adrian Simpson / Amiga Point of View)

Those are better than anything I could write :) so I have added them to the home page. Hopefully the new page will give people a bit more of a clue of what Knights is all about, and maybe tempt them to download…

In other news, the game must be becoming a bit more popular because it has been added to two Linux distributions (that I am aware of): OpenSUSE and Rogue Class Linux. This is great news and hopefully will lead to more people trying out the game.

(If anyone knows of other Linux distributions that carry Knights, please let me know and I will add them to the website.)

As for future work… well, I don’t have any specific plans but here are some things I would like to do:

  • Bug fixes (there are always bugs that can be fixed… although I think most of the major ones have been squished by now)
  • Adding stuff to the Lua API perhaps?
  • Some day I want to make a (working) map editor for Knights… (although this is probably unrealistic at the moment, due to lack of time).

As always, if anyone has any “requests” for future Knights changes/improvements, please let me know.

In the meantime, Merry Christmas :)

For more information about Knights, please visit http://www.knightsgame.org.uk/

Knights update (August 2014)

Thursday, August 21st, 2014

I’ve decided to start doing update posts on a semi regular basis (perhaps once every 1-2 months) to let people know what is going on with Knights. Each post will include a summary of what has been done since the previous update and a brief look forward at future plans.

So without further ado…

Progress since last update

There was actually an update post back in June. So what has happened since then? Basically, there have been two releases of Knights, which have achieved the following:

  • Updated the Knights codebase so that it works with the latest version of Visual Studio. (This briefly introduced a bug with WinXP compatibility, but that is now fixed.)
  • Made some changes to daggers, and re-introduced “gate squishing”, as requested by KnightRider.
  • Other bug fixes (too many to list here).

Goals for the next couple of months

I think I’ve mentioned this before, but I want to work on improving the front page of the website: not only to make it look better, but also to highlight the features of the game a bit more and try to make it more obvious what is good about the game and why someone should download it :)

As regards the game itself I think the next things to work on are the following:

  • Potions: KnightRider correctly points out that the original Knights had two different sorts of regeneration potions; I intend to add this to the PC version as well (it shouldn’t be too difficult).
  • Moo pointed out some issues with the Lua API, which I want to look into.
  • There is also still a backlog of bugs (thankfully, none of them serious). I want to keep chipping away at these, therefore I’m aiming to get at least one or two resolved before the next update (in 1-2 months time).

For more information about Knights please visit http://www.knightsgame.org.uk/.

Knights version 25 released

Tuesday, August 5th, 2014

I am pleased to announce release 25 of Knights. This is a relatively minor release, the two main changes are:

  • Fixed the problem where the game would not run on Windows XP.
  • More fixes to daggers (as requested by KnightRider).

As always you can get the game from the download page.

About Knights

Knights is a multiplayer dungeon bashing game. Players must explore randomly generated dungeons and compete to solve various quests. For more information please visit http://www.knightsgame.org.uk/.

Knights update

Monday, June 16th, 2014

I haven’t done a Knights update for a long time so I thought I would briefly let people know what’s been going on.

Over the last 2-3 months I have been doing the following:

  1. Moving the Knights server to a new VPS (instead of the home server we had previously). This has delivered better ping times and faster website performance for Knights players.
  2. Updating the Knights codebase so that it works with the latest Visual Studio version. I also investigated using SFML or SDL2 for graphics, but that work is on hold for now (see previous post for details).
  3. Behind the scenes, I have been writing some scripts to help auto-generate the HTML pages for the website. (Previously, I had been manually editing HTML files, which is a pain; now I can just edit “template files” and then use my script to generate the HTML and upload, which is much easier.) This should make it much easier for me to change and update the website in the future.

I have also been thinking recently about updating the game’s website. The design of the front page basically hasn’t changed since the game was first released and it is looking a bit “dated” at this point. I would like to try to improve the style/look of the page and also try to “sell” the game a bit more, highlight what’s good about the game, that sort of thing. Hopefully this will persuade more people to download it :)

There are also some bug fixes to do (such as the “dagger bug” reported by KnightRider) which I have not forgotten about.

For those who are interested, I have written a “todo list” for Knights, which looks like this:

  1. Fix gate squishing bug (#194).
  2. Fix dagger throwing.
  3. Update the website front page.
  4. Make the official game server show up as “knightsgame.org.uk” instead of “vps.solarflare.org.uk” (I’ve been wanting to do this for a long time, it will require a new server config option though).
  5. Fix the Linux makefile (at the moment it doesn’t quite work right when building the knights server on Linux).
  6. I got a code warning from the new Visual Studio (about “incorrect API usage” in one part of my code), I want to investigate what is going on there.
  7. There is a bug with LAN broadcasts which I want to fix.
  8. I’m planning to write a patch for SFML and send it back to the developers (this relates to something I found while investigating SFML for Knights graphics).
  9. I also want to add a “–pidfile” option to the Knights server (this will make it slightly easier to install the server on Linux machines, it is something that came up while setting up the new server).

As you can see there are quite a few small fiddly tasks (which you always get in game development) mixed in with more interesting things like bug fixes and website updates.

As most people know by now I don’t get a great deal of time to work on Knights, but hopefully I should be able to get the first two items on the list (the bug fixes) done in roughly the next two weeks. At that point I’ll do a new release of the game (so players can have the benefit of the bug fixes) and then continue working my way down the list…

I’ll try to do blog updates more frequently as well :)

About Knights

Knights is a multiplayer game in which players must run around randomly generated dungeons and solve various quests. For more information please visit http://www.knightsgame.org.uk/

More graphics library stuff…

Sunday, March 23rd, 2014

Here is a quick update on Knights development.

Unfortunately I have still been struggling with graphics libraries for what feels like ages now.

Last time I posted that I was trying out SFML and have been doing quite well with it. Unfortunately I have found what seems to be a fatal problem – SFML is completely unable to detect keypresses of the “backquote” key (that is, the key above TAB). This is important for Knights because we use that key as a chat key. Unfortunately I haven’t found any way to work around this, so it looks like we won’t be able to use SFML for Knights right now.

I also looked into SDL 2. However, I found the rendering performance to be very slow. It seems that to get decent performance out of SDL 2, you have to be making direct OpenGL calls in your code (instead of relying on the so-called “SDL_Renderer” layer). Unfortunately this would be quite a lot of work (especially since I don’t really know any OpenGL at the moment…) so this is not really feasible for me right now.

Therefore I think the plan will have to be:

  1. I will keep Knights as it always was — i.e. using DirectX on modern windows machines, and using SDL (version 1 – which uses software rendering) on Linux or older versions of Windows.
  2. I have made a few changes to my DirectX code — in particular I have removed the dependencies on D3DX and D3DCOMPILER. This should mean that the code will run on any modern Windows machine without any “DirectX runtime library” downloads being required. (I have also put in some simple UTF-8 text handling, but that is another story…)
  3. At some point I will get in touch with the author of SFML to see if the keyboard handling can be improved. That would eventually mean that I could switch Knights over to using SFML on all platforms. Not only would this bring hardware accelerated graphics to Linux (finally!), it would also mean that I only have one lot of graphics code to maintain instead of two, which will make things easier. This is a longer-term goal though.

Knights ADF available

Saturday, March 1st, 2014

I got contacted a couple of months back by someone who said “I would love to play the original Knights on my old Amiga 500 but I can only transfer ADF Files to it“.

I had no idea people still played Knights on old Amigas (anyone remember setting up the piece of cardboard to divide the screen in two? :) ) but I was happy to help, so I made a bootable ADF from the Aminet version of Knights and sent it to him. The ADF file is now available for download. Enjoy :)

Note that to use this you will need either a real Amiga or an emulator. Regular users will probably want to check out the PC version available from http://www.knightsgame.org.uk/.

Knights T-shirt now available!

Saturday, March 1st, 2014

Thanks to forum member Julian this awesome Knights T-shirt is now available!

Knights T-shirt

It has the “Winner” screen on the front and a screenshot and Amiga Knights logo on the back.

You can buy the T-shirt here:

http://www.cafepress.com/cp/customize/product2.aspx?number=1260489969

See also the forum thread:

http://www.knightsgame.org.uk/forum/index.php?topic=245

Investigating SFML for graphics…

Saturday, March 1st, 2014

So, recently I bought a new laptop. And with it being a new year and all, I thought this might be a good opportunity to get back to some Knights development (something that, sadly, I haven’t had much time for these last few months). So, I installed the latest Visual Studio onto the laptop, set up the Knights code directory, and prepared to do some coding…

… and immediately hit a problem. The game would not build. Partly this was because the Microsoft compiler now supports C++11 (the latest version of the C++ language), which caused a few incompatibilities with my code (admittedly this was mostly my fault though!). And partly it was because Microsoft have changed the way DirectX works – in particular, “D3DX” is no longer a supported technology. Unfortunately for me, I had some code that was using D3DX… which now no longer compiles. Grr. (At least on Linux, once you get your code working, it tends to stay working… :( )

Well, I could just fix my DirectX code, but I thought it would be better in the long run to bite the bullet and set up a proper cross-platform solution for graphics. (The initial reason why I added DirectX support to Knights was just as a quick way of testing out hardware-accelerated graphics on Windows; it was never meant as a permanent solution.)

So, if one is looking for a modern 2D graphics library there seem to be two choices: SDL2 and SFML. I had a look at both of these, it seems to me that they both do roughly the same thing, but they have different kinds of API – SFML tries to be more modern and object-oriented and so on, while SDL is more “old school” with low-level C-style functions and structs and things. Personally I prefer the former, so I decided to try out SFML.

I have to say, I was not disappointed – SFML was very easy to set up and integrate into the game and seems to work very well. Performance was much faster than software rendering, although admittedly slightly slower than I got from my DirectX code (not sure why this is; presumably it’s just the overhead of having an extra library in between you and the graphics card; in any event, it’s not that big a deal and I think it’s a price worth paying given how easy to work with SFML is).

I also had some small keyboard handling problems with SFML (e.g. it seems the ` key – the “team chat” key in Knights – is not recognized, but I think I can work around that).

Overall, therefore, I hope to have the SFML integration work done in the next few days, which means the next version of Knights will support fast hardware-accelerated graphics in both Windows and Linux. (As a side note, there is also a problem on some Windows machines where the Knights DirectX graphics doesn’t work if you don’t have the right DirectX runtime libraries installed… that should also be fixed by the move to SFML.)

For more information about Knights please visit http://www.knightsgame.org.uk/.

 

Knights new version coming soon…

Wednesday, December 19th, 2012

Just a quick Knights update here. I have been away from Knights for a while (sorry about that) but I do have a bit of spare time over Christmas and I intend to use it to make a new Knights release.

The plan is to include the following features (the numbers refer to Trac):

  • Implement the “Monster Proposal
  • #215 – Add GetRespawnFunction to Lua API
  • #203 – Error message or warning if Lua “prefix” forgotten
  • #206 – Update manual to refer to new Boost version
  • #164 – Ability to cycle each observer window independently

Hopefully I can get this done fairly quickly, as I know some people on the forum have been waiting for a new release for some time now…

After that I’d ideally like to get the map editor up and running again, as this would complement the Knights Lua scripting features nicely. This could really open the door for people to make new rooms or maybe even entire custom maps for Knights. That will be a task for next year though :)

About Knights

Knights is a multiplayer dungeon bashing game. Players must explore randomly generated dungeons and compete to solve various quests. For more information please visit http://www.knightsgame.org.uk/.

Notes on Lua/C++ error handling

Monday, September 3rd, 2012

This is a technical post about how to handle Lua errors in C++ code.

Background

Recently I added support for Lua scripting in Knights. During this process I found out that there are several “gotchas” in terms of how to correctly handle Lua errors in your C++ code. I’m writing this blog post (1) as a way of documenting the issues I found, and (2) because it might be helpful to other programmers who run into similar issues.

I will present this as a series of problems that can occur, and possible solutions to each.

Problem 1: C++ destructors may not called when doing a “longjmp”

The scenario:

Your C++ code calls a Lua API function. Something goes wrong and a Lua error is generated. This causes Lua to do a “longjmp” through your code. Your C++ code contains at least one local variable with a non-trivial destructor.

The problem:

The problem in this scenario is that “longjmp” does not guarantee that destructors will be called. Clearly, this is bad news if you were relying on the destructor to clean up memory or other resources.

Example code:

int MyFunction(lua_State *lua)
{
   std::vector<int> v(10);
   // ...
   lua_call(lua, 0, 0);  // call some lua function
   // ...
   return 0;
}
void Foo(lua_State *lua)
{
   lua_pushcfunction(lua, &MyFunction);
   int result = lua_pcall(lua, 0, 0, 0);
   // ...
}

Discussion:

Imagine that the lua_call above (in MyFunction) results in a Lua error being raised.

At first sight this appears perfectly OK. Lua will handle the error by doing a longjmp. As per the specification of lua_pcall, the stack will be unwound back to the lua_pcall statement in Foo. An error code will be returned into “result”, and execution will continue, with an error message sitting on top of the Lua stack.

The problem is that, on some compilers at least, longjmp() does not call C++ destructors as it unwinds the stack. On such a compiler, the destructor for vector “v” would not be called, and we would have a memory leak.

Indeed, the C++ standard says this:

The function signature longjmp(jmp_buf jbuf, int val) has more restricted behavior in this International Standard. A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.

(Note: I have seen different wording for this in different places; the above comes from a Stack Overflow answer).

If you think about it, this means that most C++ programs that use longjmp would have undefined behaviour. Considering that Lua uses longjmp ubiquitously for error handling, this is not ideal :)

The solution:

The easiest solution is to compile Lua as C++. (In Visual Studio, use option /TP; in GCC, compile the code with g++ instead of gcc.) When Lua is compiled as C++, it uses try/catch instead of setjmp/longjmp for error handling. Problem solved.

Of course, compiling Lua as C++ might not always be practical. For example, we might be working with an external Lua library that has already been compiled as C, or we might want to disable C++ exception handling for performance reasons. In these cases, the only real solution is “don’t do that”; in other words, don’t create stack objects in such a way that destructors would need to be called if there was a Lua error. Of course, this requires some careful programming; if you are going down this route, it would be worth reading this mailing list thread where the issue and some possible solutions are discussed.

What does Knights do?

In Knights I opted to compile Lua as C++. This is the simplest solution, and the overheads of exception handling have not proved to be a problem in practice (remember that Knights is only a simple 2D game with low CPU and RAM requirements in any case).

Problem 2: C++ exceptions should not propagate through Lua

The scenario:

We have written a C++ function and made it available to Lua (via lua_pushcfunction or lua_pushcclosure). Our C++ function can throw exceptions.

The problem:

If Lua calls our C++ function then there is the risk that an exception might be thrown and propagate up through the Lua source code. This is a problem because Lua is written in C, and therefore cannot be assumed to be exception safe in the C++ sense. Although we cannot know for sure that throwing an exception through Lua will be unsafe, we should err on the side of caution and assume that it is unsafe unless proven otherwise.

Example code:

int MyFunction(lua_State *lua)
{
   throw std::runtime_error("Boo!");
}
void Test(lua_State *lua)
{
   lua_pushcfunction(lua, &MyFunction);
   lua_pcall(lua, 0, 0, 0);
}

This code will cause a std::runtime_error to propagate up through the Lua implementation, which is a bad idea for the reasons mentioned above.

The solution:

There is only really one solution, which is to ensure that C++ functions exposed to Lua do not throw exceptions (i.e., they should have the nothrow guarantee).

The simplest way to ensure that is to enclose each function in a try/catch block, e.g.

int MyFunction(lua_State *lua)
{
   // This function is to be exposed to Lua
   try {
      // insert code here
   } catch (std::exception &e) {
      luaL_error(lua, "C++ exception thrown: %s", e.what());
   } catch (...) {
      luaL_error(lua, "C++ exception thrown");
   }
}

This code converts any C++ exception thrown into a Lua error. (If the exception is derived from std::exception, we construct a more useful Lua error message by calling std::exception::what(); otherwise, we just use a generic error message.)

What does Knights do?

One objection to the above is that it would be tedious to write those try/catch clauses in each and every function that we wish to expose to Lua. In Knights, I addressed this by defining a wrapper function “PushCClosure” that is a replacement for lua_pushcclosure. This automates the task of wrapping the enclosed C++ function in a try/catch block. Those interested in the implementation of PushCClosure may wish to refer to its source code.

Problem 3: Avoiding Lua “panics”

The scenario:

C++ calls a Lua API function, and the Lua API function raises a Lua error. Unfortunately, the C++ code did not call Lua in the so-called “protected mode” and therefore, Lua “panics”.

The default action after a panic is for Lua to abort the program. Clearly, this is undesirable in production code.

Example:

The following code illustrates the problem. The code is supposed to read the contents of the global variable “EXAMPLE” and return it as a std::string.

std::string Example_Bad(lua_State *lua)
{
   lua_getglobal(lua, "EXAMPLE");           // push value of EXAMPLE onto the stack
   const char *c = lua_tostring(lua, -1);   // read stack top (as char *)
   std::string result = c ? c : "";         // store to a std::string
   lua_pop(lua, 1);                         // restore the stack
   return result;
}

Discussion:

The problem with the above code is that the calls to either lua_getglobal or lua_tostring might raise an error. For example, a maliciously-minded user might write the following:

local m = {}
function m.__index(tbl, key)
   error("Boo!")
end
setmetatable(_G, m)

Then, the call to lua_getglobal will execute the __index metamethod, which in turn raises an error. The C++ code does not handle the error, and the program aborts.

The solution:

Unfortunately, there is no way to directly check for errors from a Lua API function. Instead, you are supposed to call the Lua API in “protected mode” if you care about error handling. (This often traps beginners, who just write Lua API calls without thinking about what happens when there is an error.)

Calling Lua in “protected mode” is, unfortunately, somewhat tedious. You have to wrap your use of the Lua API inside a lua_pcall, as follows:

std::string Example2_Good(lua_State *lua)
{
   // Create a dummy struct which will be used for the pcall.
   struct Pcall {
      std::string result;  // Will hold the result.

      static int run(lua_State *lua) {
         // Read the pointer to the Pcall struct.
         Pcall *p = static_cast<Pcall*>(lua_touserdata(lua, 1));

         // Get the global "EXAMPLE" and store it in the Pcall struct.
         lua_getglobal(lua, "EXAMPLE");
         const char *c = lua_tostring(lua, -1);
         if (c) p->result = c;

         // Done.
         // (Note there is no need to pop the stack, 
         // Lua will do that for us when we leave the function.)
         return 0;
      }
   };

   Pcall p;
   lua_pushcfunction(lua, &Pcall::run);
   lua_pushlightuserdata(lua, &p);
   int result = lua_pcall(lua, 1, 0, 0);

   if (result != LUA_OK) {
      // Handle error here (e.g., throw C++ exception).
      // Don't forget to pop error message off the Lua stack.
   } 

   // Operation was successful. Return the result.
   return p.result;
}

As you can see, the general idea is to create a local struct, with a static “run” method, and then lua_pcall that method. A pointer to the struct is passed as the sole Lua argument; this allows you to read from and/or write to the struct from within the “run” method.

Importantly, neither lua_pushcfunction nor lua_pushlightuserdata can raise Lua errors, therefore they are safe to call outside of the pcall wrapper.

Note: Panic Functions

An alternative strategy would be to install a panic function, using lua_atpanic. However, it’s not really recommended to use panic functions for regular, everyday error handling. (For one thing, one is never quite sure what is left behind on the Lua stack after a Lua panic.) Instead it is better to use the lua_pcall method as described above.

What does Knights do?

In Knights I don’t currently wrap Lua API calls in a lua_pcall. (The exception is when I call Lua functions, where I do generally use lua_pcall instead of lua_call.) Therefore, if any top-level API calls trigger a Lua error, then a Lua panic occurs.

In Knights I have set up a panic function that throws a C++ exception. When this exception is caught, Knights assumes that the lua_State is unusable and closes it as soon as possible. The server then resets itself and execution continues.

While this method works, it is not particularly pleasant because any clients connected to the server do not receive any explanation of what happened. Their connections are just immediately closed when the Lua panic is handled.

Some time I would like to modify Knights to wrap all uses of the Lua API inside lua_pcall wrappers, as described above. This would ensure clean handling of all Lua errors. (The panic function would be kept, but it would only be there as a “backup” in case I ever forgot to put a lua_pcall wrapper in some place where it was needed.)

Further Reading

The Lua wiki has a page on Lua/C++ error handling:
http://lua-users.org/wiki/ErrorHandlingBetweenLuaAndCplusplus

Here is another blog post on this topic:
http://julipedia.meroh.net/2011/01/error-handling-in-lua.html