Tuesday, 26 March 2013

Lanarts Goals

So I decided to write up a post about my hopes for when I finally release 'Lanarts 1.0'. I hope outlining where the game is going encourages people to contribute.

The design philosophy:
To create a fun, dangerous, procedurally generated, co-op RPG which allows for continual character advancement without repetitive elements. The game will be very light on plot, and feature critical decisions, such as choosing between different challenges. The game will be best played end-to-end with a team of around 4-6 friends. The game will be designed with a loss-condition in mind, but one that can be made more lenient to players' liking.
 
Guiding points:

Any tedious aspects should be as streamlined and automated as possible.

The character advancement should introduce more interesting and nuanced features rather than just stat-gain. Character races and other game bonuses should be versatile enough to provide benefit to a large number of play-styles.

The game should be as data-driven as possible, allowing for easy content creation. The game should lend easily to hosting modified game content. Modified game content will happily be considered for integration into the base game.

The V1.0 goals:
  • Stable Lua API that allows for developing/customizing the game as much as possible. V1.0 will introduce a (loose) API freeze and best-effort backwards compatibility measures.
  • Well-performing game-play with at least 4 players (more is ideal).
  • A lobby server for easy match-making.
  • A flexible stat system based on character traits and abilities. This includes items with interesting effects, and a variety of 'tech-tree' style advancement options.
  • An overworld with towns, thematic dungeons, and a final boss.

What aren't my goals:
  • I'm not sure if V1.0 will have original graphics. While nice, I do not consider this a version-number assignable goal (primarily because I do not have the talent to decide when it happens.
  • I don't intend to make Lanarts a generic RPG engine. I will move towards this as much as possible, but only where it enables smooth growth of the game.

Saturday, 16 March 2013

7Day Roguelike Challenge Complete!


OK time to release.
Download: http://7drl.org/wp-content/uploads/2013/03/bughack.zip

I'm a bit exhausted from working on it so I'll just paste the README.

Welcome to BUGHACK.

The idea for the game was to include roguelike mechanics based on how ants find food through scents.

You are a leader ant who must lead worker ants to delicious harvest. Every sector you must gather a certain amount of harvest. Keep your ants safe, or you'll take damage! You must call ants out of an ant hole and then lead them to to fruit.

Press C in-game to see controls.

THE GAME IS TOO SMALL:
To fullscreen, hit F in game.
Alternatively, replace the occurrence tiles12x12_gs_ro.png in bughack.py with tiles18x18_gs_ro.png

Dependencies:
Python 2.X (32 bit is needed on windows)
SDL (included in Windows, needed on Linux)

RUNNING:
python main.py
(Or on windows, right click main.py and run with python 2)

Created by:
 Programming by ludamad (Adam Domurad), art by REZ (Clay Bullard)

Friday, 8 March 2013

7DayRL Competition!


http://7drl.roguetemple.com/img/7drl.png



OK, this will look silly in case I don't complete, but I will be joining the 7day roguelike competition!

I will be teaming up with putterson (who does occasional work on lanarts with me) and REZ (who I previously did a Halloween competition with, resulting in Carny Death Peddlers). The hope is to have a tiles-mode with ASCII.

I'll say at this point to save myself from potential foolishness that any potential failing of the competition will be due to being too ambitious with too little free time, and not because of lack of interest!

Anyway, cautiously optimistic.

I'd discuss the game idea but they're going to change a buttload -- and we'll find out soon enough, ain't it ?

So plans are to use libtcod & Python. It won't be my first game in Python but it'll be my first graphical one. So far just learning libtcod and going through the tutorials, but I find it straight-forward. It's funny how well suited libtcod is for this competition.

Monday, 4 March 2013

Lanarts Update March 4th, 2013

New release, ready for download!

It is recommended you move with WASD, melee with H, fire spells with YUIOP, mouse controls for everything else.
Mouse controls for spells are fairly suboptimal at the moment.

Additionally, 1 to 9 for inventory slots 1 through 9.
Right click is needed to drop items, however.


So it's been 2 months since I felt like compiling this thing on Windows ... damn. About time for another lanarts release !
I hope sincerely to go back to a biweekly release schedule.

Major changes:
  • Enemies now do not regen health a bit after hit. This makes enemy packs a lot less annoying. [Credit for idea goes to serprex]
  • Floating point strictness flags turned out to help a lot with the remaining syncing issues.
  • Saving the game is much more streamlined -- now you simply need to exit (via shift+escape) and the game will automatically save. Reload the game and hit Continue (or enter), and your game is loaded. I feel comfortable having this the default now since I haven't run into any save-file bugs in a good amount of time.
  • Victory screen added, you can win the game now !
  • Scoreboard added, with stats for your previous characters, whether you won, etc. Navigate it with arrow keys/pageup&down if you have a lot of entries.
Minor changes:
  • Made it easier to distinguish walls and floor in the brick&hive tileset
  • A lot more code was brought to the lua side, including the menu implementation. The scripting is becoming quite mature, and the game much more engine-like. Documentation to come !
  • Unit tests moved fully to use UnitTest++
  • Network debug mode was fixed, logging was made more verbose. Diff'ing logs proved to be very effective rooting out syncing issues.
  • Game pausing and the steps_per_draw setting work again.
  • Minor balancing to spells
  • Added key display overlay for spells, and FPS counter in corner
  • Moved the wide-open and difficult floor 4 layout to floor 7
  • More options for hosting games, and the server's options now override client options (whereas before they could be weirdly out of sync)
Special thanks to putterson for all the online & LAN testing.

Windows:
Download!

Linux:
I do not yet provide linux packages, please do kick me if they'd be useful for you.

git clone http://github.com/ludamad/lanarts --depth 1
./run.sh

If you are missing dependencies on Linux (probably the case) please run either fedora-deps.sh for Fedora, or debian-deps.sh for Debian or Ubuntu.

Feedback

Please direct any bugs and inqueries either as a github issue, a comment on this blog, a post on the #lanarts freenode channel, or an email to domuradical@gmail.com. Feedback very welcome !

Tuesday, 12 February 2013

Fedora 18+Cinnamon

So, I had told myself I'd get use to Linux prior to coming to Red Hat, but truthfully that wasn't much needed. You learn fast when you're thrown in, and its sink or swim.

So, Fedora 16 was my first Linux distribution. I liked it a lot. I liked GNOME 3 a lot. With Fedora 16's end-of-life approaching (today, in fact) it was time to jump ship. GNOME 3 was nice enough, but I decided to put some of the noise about it in perspective and try something else.

Installing


Noticeably worse - a bit sad because obviously a lot of work was put into it. The new layout shows you all your options at once, but I think stepping you through them was more user-friendly.  Partitioning was confusing but in the end, it all worked well. Once I figured out I had to click on my F16 install, and hit a 'minus sign', everything went smoothly.

GNOME 3.6 Visuals, Graphical boot loader, etc

This probably impressed me more than it should have, but everything looked really tight to me. The fedora boot loader has a graphical back-drop, the login screen looks really nice, as were the various GNOME3 visual improvements. All of it fit together really nicely. Of course, at the end of the day, I would happily turn off any of these things for a better workflow. It sure is nice when people ask 'Whats this Linux thing?', and you have something shiny to show them.

Bugs

So once I tried to get some real work, I was unhappy to find a lot of small Eclipse issues. While F18 can only be blamed for bugs in Eclipse to a limited extent, it is one of those 'too big to fail' applications these days, so its worth mentioning. Without going into detail, these included issues with Java perspective not showing up after installing Eclipse Java Tools, and various graphical glitches using Eclipse C++ Tools. A more fundamental bug occurred when I tried to turn on desktop icons in GNOME 3.6 - instant crash, and crashing whenever I logged in.

Cinnamon!
The best thing about failing to get icons working on GNOME (admittedly I didn't try hard) was the decision to try out if they worked with Cinnamon. First off, I was very impressed with how well Cinnamon integrated with the whole Fedora user experience. Not only did a single yum command and a 'cinnamon --replace' have me trying it out in seconds flat, it was very simple to make my default desktop environment (toggle on log-in).

For someone like me that found GNOME 3's visually appealing, Cinnamon was perfect. Very soon I got rid of that 'hot corner' that GNOME 3 is so centered on, and set up some settings to my liking. Overall I find it more featureful, perhaps more Windows-like, but I'm not complaining.

Some things I do miss though is the nice way of dragging windows into workspaces with GNOME 3, and the 'application-centric' alt-tab that groups windows based on application.

Anyway, that's it for now. Overall I really like it, but then again I would have just been happy to get up to date packages again. YMMV.

Saturday, 2 February 2013

A Lesson from Java's Swing

So whenever possible, I like to apply things I learn in my hobby programming to my professional programming. Conversely though, sometimes I am inspired by the design of parts of icedtea-web (the project I work on at Red Hat). To be fair, this is more the design of Java's Swing library, but it got me thinking.

The menu code in Lanarts was pragmatic but also hackish. It piggy-backed the normal event loop and each menu was a pseudo-level. That meant there was a bunch of classes that inherited from GameInst that were only part of the menu code. The menu code was created based off these objects being planted into the pseudo-level, configured with callbacks to wire the menu logic and drawing, and just enough menu placement logic code so that things were spaced sanely on different resolutions.

Taking a Swing at a better design

Although it wasn't the first time I used Swing, recently while having to assemble a dialogue box with nothing but Swing layout managers, it struck me that this could be a good approach for Lanarts user interfaces. While Swing has a large number of obscure layouts, a comment struck me that I forget the source of: "Using GridLayout and BorderLayout you can create pretty much any interface". So I coded the equivalent of these in Lua. This resulted in two small classes:

1. InstanceLine:
Arranges objects in rows, this is similar to Java's GridLayout, but is designed to be especially convenient if you just want a single row.
2. InstanceBox:
Objects are added based on relative position; a value 0 to 1 is used for x & y coordinates. Using this layout you can easily align something against the center-top of a box, and another component on the center-bottom, for example.
Using these classes nested together, flexible layouts can be created with a lot less mucking around with coordinates. The x & y positions of each menu component are now calculated each time they are drawn, instead of being fixed absolute values. This allows each layout to only store relative positions, making logic simpler. As well components can be created without their locations having to be known at the time of creation.

The GameInst structure was abandoned as well, and instead a simple event loop was created in Lua.

It was really fun to code, and ended up being a large improvement. Here is a picture of the result with debugging code turned on:


Note this looks exactly like it did before -- not bad for a complete reprogramming in Lua!

The elegance with which it could be programmed made me feel a lot more confident in Lanarts ability to act as an effective moddable engine. I was able to code it in Lua with only take very brief breaks to quickly add a missing function or two on the C++ side.

One surprising inspiration I got is to have a similar mechanism for the level generation. A nested tree of randomly generated layouts could produce very interesting results!

Thursday, 24 January 2013

Lua & Lanarts

So lately I have been making some significant progress on the Lua side of Lanarts. Here's some summary!

LuaWrap, my pet Lua binder

After much frustration with existing Lua binding solutions (manual bindings, LuaBind, SimpleLuaBinder) I decided like any arrogant programmer to simply write my own. Of course, since I wrote it from the ground up, it suits my use-case quite well.

It is fairly small (24 short source files), flexible, and does not try to control your Lua environment in any way like SLB does. As well, although some performance was traded for ease-of-use, it provides an easy to use interface to eg Lua tables that suffers no performance penalties (assuming sufficient inlining). Here's an example of binding a global variable that should compile to the same code as if written by hand:

void bind_globals(lua_State* L) {
     LuaSpecialValue globals = luawrap::globals(L);

     globals["foo"] = "bar";
     globals["baz"] = 1;
}

LuaWrap is located in the lanarts source-tree under src/luawrap/. It does not depend on any libraries other than Lua.

Rewriting the main loop

So I wanted to move more towards having Lanarts as a game engine controlled by Lua. Now I definitely treat this as the compromise that it is -- it is perfectly possible to write a game in Lua, and that is not the goal. The plan is to allow people to modify the game very flexible in Lua without worrying about the networking aspect (except possibly for very heavy modification). The hope is that will inspire experimentation with the game mechanics.

So, as a start to this direction, I rewrote the main loop in Lua. Here's a look at the inside of the loop!

function main()
    net.sync_message_consume()

    local timer = timer_create()

    if not steponly then
        game.draw()
    end

    if not game.step() then 
        return false 
    end

    if not game.input_handle() then 
        return false 
    end

    local surplus = settings.time_per_step - timer:get_milliseconds()

    if surplus > 0 then 
        game.wait(surplus) 
    end

    return true
end

Object-Oriented Lua!

Figuring I'd continue this top-down approach, I have begun working on porting some of the menu code in Lua. For the first time, this actually meant I wanted to write something object-oriented on the Lua side! Now, OOP isn't a silver bullet, and I always like to weigh the pros & cons of other solutions -- but for graphical interfaces I think object orientation makes a lot of sense.

The first task I had was to decide on an object model. Now I think this is a really cool part of Lua -- it does not impose an object model on you. I settled on a very simple syntax, a single function 'newtype' returns a table suitable for use a 'type'. After which you simply add methods to the type. A special method, the 'init' method, is used to form a 'create' function. Here's what this looks like in action!

import "utils.lua" -- imports 'do_nothing'

TextLabel = newtype()

function TextLabel:init(font, options, text)
    self.font = font
    self.options = options
    self.text = text
end

TextLabel.step = do_nothing

function TextLabel:draw(xy)
    self.font:draw( self.options, xy, self.text )
end

-- Example usage
mylabel = TextLabel.create(font, options, text)

Some things notable here that highlight features of Lua:
  1. For people coming from a Python background, 'import' seems like a Lua keyword. Actually, it's a function that is being called with a string literal. Lua allows this syntax for one-argument table & string literal functions.
  2. 'function TextLabel:draw(xy)' is equivalent to 'function TextLabel.draw(self, xy)'. The colon operator is nothing more than syntax sugar for 'pass self as first parameter'.
  3. Lua silently (for better, or for worse!) ignores extra parameters, allowing a generic 'do_nothing' function like the one used.
 Anyway, that's all for today! Just wanted to give an update as I take a break from gameplay-oriented updates, and the dreaded mess of implementing client-side prediction. Stay tuned.