Pages

Saturday, October 5, 2013

Introducing Last Legend

The project I'm working on right now is an online, old-school RPG called Last Legend. I'm planning a series of posts on the concept, the technical aspects, etc. - this post is about the idea, where it came from, and the road to getting to its current conception.

The "t" is a sword. Not the most original thing you're going to see today.

Last Legend has existed in some form for a little over a year, as I've been playing around with the concept and trying to get it just right. The idea is to recreate the feeling of the classic Final Fantasy series (i.e. 1-6) and turn it into something that can be played with your friends. (The name Last Legend, if you didn't catch it, is a thinly-veiled reference to Final Fantasy.) These were my favorite games growing up. Some remakes have featured a half-assed multiplayer mode where player 2 can control certain characters, but only during battle. If these games had been remade with a proper multiplayer mode I would've loved them, thus the inspiration for Last Legend.

The idea behind Last Legend dates back to July of 2012. While working full time over the summer, I decided to try to create an online RPG for National Game Development Month in my "spare time." Needless to say, I bit off a little more than I could chew, but I did in fact have a playable client/server demo by the end of the month that could be played over a local network. You could fight, gain experience, raise your skills, and die. You could attack anyone, including other players or NPCs, but if you attacked a non-enemy you'd be marked as a criminal - this meant that you'd be killed on sight by guards, and other players could attack you without penalty. Upon your death, the mark would be removed. An early bug removed the mark a little too early in the death process, resulting in the guard that killed you getting a mark himself. The guards would turn on him, and the one who delivered the final blow would get a mark himself. Thus an eternal battle of guards would commence. You could even join in yourself for some sweet XP - just don't make any killing blows.

The game was originally written in Python. Because my time was limited, I saved time designing the UI by combining wxPython and PyGame in the same application - a feat that proved difficult and was rife with platform inconsistencies. For networking, I threw in Twisted. Any Python programmers out there will note that all three (wxPython, PyGame, and Twisted) have their own main loops and want to "own" the entire application. Getting them to play nicely together was not an easy task. (If you're wondering, it was wxPython that was the neediest of the three, so its main loop won out - I would run that and call the update functions of Twisted and Pygame manually.)

PyGame on the top left, wxPython surrounding it, and Twisted behind the scenes. Don't try this at home! (I also can't recommend throwing a bunch of town guards into the sea, but when you're a level 100 ogre, you can pretty much do what you want.)

Eventually, I had issues getting everything to work properly on Windows (I develop on Linux) and was hitting up against a maximum framerate of about 20 FPS so I decided to scrap the wxPython portions and rewrite them using PyGame. This led to a focus on simpler gameplay, with streamlined stats and skills and a simple, more retro-style interface:

Goddamn spiders with their goddamn poison damage.

The original game was also a bandwidth hog and really only feasible to play over a local network. After the elimination of wxPython, I did some major rewrites of the networking portions, implementing my own TCP protocol to transfer data between players and the server to try to minimize the amount of bandwidth required to play. The same protocol exists in the current version of the game, which I'll go into more detail about later.

A few things about the game still just didn't feel right. One was the battle system - right click on an enemy, and your character will approach them and start attacking; press a number to change the type of attack you're using or use special abilities, and then just watch the charge-up/attack cycle typical of so many similar RPGs to play out. It felt like a simplified modern RPG and didn't evoke the classics I was trying to emulate. The class and stat/ability system also felt too complex and out of place. Finally, the smoothing algorithm I used (2xsai, which you can see in the previous two screenshots) and other graphical tricks that weren't possible in the SNES days, while cool in isolation, detracted from the nostalgic feeling I was trying to capture. The more I thought about these problems, the more I realized that in order to be true to my original vision, a fairly substantial rewrite of the game mechanics was going to be necessary.

Additionally, although I fought admirably, I ran up against some insurmountable problems using Python. Performance was one issue - the game ran just fine as long as everything was stored in memory. As soon as I tried to back up the game state to a permanent store like a database or the hard drive while the game was running, everything slowed to a crawl. I also knew that in the end I'd face the difficult prospect of packaging the application. While solutions like py2exe, py2app, etc. are great, they're trivially easy to decompose into actual Python source code if you know what you're doing, and for an online game, I thought this was too much of a security concern to accept. I am working on a project that aims to build a Python interpreter that can be statically linked against with custom builtin-packages and contributed to another that tries to bring PyGame to the browser via Java (ha), but I don't know how successful these will be or how long they will take, and didn't want these experiments to hold up the game.

With that in mind, and with many fundamental changes to make, I decided to move development to Haxe, the language I'm using now. One big benefit is its focus on cross-platform functionality from a single code base. There will be a flash client, lowering the bar for interested players to try the game out. I also love the performance of compiled Haxe code, the relative ease of writing code in the language (it's like AS3 plus a bunch of modern features that AS3 lacks like typedefs, enums, generics, comprehensions...), and the accessibility of the Haxe developers and developers of major libraries. I love Python and PyGame, but for my purposes it feels like a major step up.

The current game, running in the browser on Flash. The code for both the client and server are written in Haxe.

I plan on also releasing the code for the Python version - both the PyGame-only rewrite, as well as the old wxPython UI code - under an open source license. I'm waiting until the game is completed and released so that I can make sure there's nothing sensitive in the old codebase that could cause problems for the new if it was to get out. If anyone out there is interested in using PyGame and Twisted to create a (probably simple) multiplayer game, I hope you'll find it useful.

No comments:

Post a Comment