search:   
Merry Prankster GamesBy gdunbar      

Merry Prankster Games

Page:   1 2 »»

Friday, July 3, 2009


Today, how to call a C++ function from your Lua script.

The previous installments of this tutorial are here:



As you may recall from previous installments of this tutorial, the goal of the tutorial is for our C++ game code to call into a Lua script to determine whether the player can open a door or not. Today, we'll call a Lua script, which will then call back into C++ code to get the player's Lockpicking level, to determine whether or not the player can open the door.

First, let's update our Lua script:

char *szLua =
"x = GetLockpickLevel() "
"return ( x > 7 ) ";


Previously, the script just did "x = 8"; now we call a function to get the player's Lockpicking level. As you'll see below, this is a C++ function.

Here's the C++ function:

int lua_GetLockpickLevel( lua_State *luaState )
{
    lua_pushinteger( luaState, 6 );
    return( 1 );
}


Lua C++ (or C) functions always get the lua_State as their one parameter; this is the object that allows us to manipulate or examine the Lua virtual machine. As you can see, we use this state to push the return value onto the Lua stack, via lua_pushinteger. (In this case, I'm returning a fixed value of 6). Lua C++ functions return an integer, simply the number of return values. Since I pushed one return value onto the stack, I return 1.

One last step, we need to tell Lua about the lua_GetLockpickLevel function, so Lua knows what C++ function to call. We do this right after initializing the Lua state:

    lua_register( lState, "GetLockpickLevel", lua_GetLockpickLevel );


Build and run the code, and you should get the message "Door still closed", since the player's Lockpick skill of 6 doesn't allow him to open the door (the Lua script requires greater than 7). Here's the complete listing of luatest.cpp:

// luatest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <lua.hpp>
#include <iostream>

char *szLua =
"x = GetLockpickLevel() "
"return ( x > 7 ) ";

int lua_GetLockpickLevel( lua_State *luaState )
{
    lua_pushinteger( luaState, 6 );
    return( 1 );
}

int _tmain(int argc, _TCHAR* argv[])
{
    lua_State *lState;

    lState = luaL_newstate();
    luaL_openlibs( lState );

    lua_register( lState, "GetLockpickLevel", lua_GetLockpickLevel );

    int iStatus = luaL_loadstring( lState, szLua );
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }
    iStatus = lua_pcall( lState, 0, 1, 0 );
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }

    int iRet = (int) lua_toboolean( lState, -1 );
    if( iRet )
    {
        std::cout << "Door opened!" << std::endl;
    }
    else
    {
        std::cout << "Door still closed." << std::endl;
    }

    lua_close( lState );

    return 0;
}


So, we called a Lua script, and it called C++. We're done, right? Not so fast! Right now, lua_GetLockpickLevel returns a fixed value of 6. In a real game, we would want to look in some structure or class to get that value. Since all it has access to is the lua_State, how can it get the "real" value? Find out in the next thrilling installment of "RPG Anvil: The Lua Tutorial"!


Comments: 0 - Leave a Comment

Link



Wednesday, July 1, 2009


Today, how to call a Lua script from your game.

The previous installments of this tutorial are here:



As you may recall from previous installments of this tutorial, the goal of the tutorial is for our C++ game code to call into a Lua script to determine whether the player can open a door or not. Today, we'll call a dummy Lua script, just to demonstrate how to call into Lua.

First, we need a script to call. We'll put this into a fixed string, up near the top of our luatest.cpp file.

char *szLua =
"x = 8 "
"return ( x > 7 ) ";


Astute readers may notice that this script always returns true. In later installments, we'll replace the line "x = 8 " with code that calls back into C++. But, walk before you run, grasshopper.

We need to initialize Lua before we call into it; something like this:

    lua_State *lState;

    lState = luaL_newstate();
    luaL_openlibs( lState );


This creates a lua_State object, ready to make Lua calls. You could think of a lua_State as a little virtual Lua computer for use by our program. It maintains its state until destroyed, so we can manipulate the Lua virtual computer in our C++ code as much as we want without having to worry about reinitializing variables each time or whatever.

We can load our script into the lua_State as such:

    int iStatus = luaL_loadstring( lState, szLua );
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }


See the Lua documentation for other ways to load scripts; you can load them directly from files if desired.

To run the script:

    iStatus = lua_pcall( lState, 0, LUA_MULTRET, 0 );
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }


Be sure to check for errors, because if you make an error in your script, Lua will usually give you a decent error message so you can fix the script. (This is a big advantage over my previous, self-designed scripting language, where any syntax errors had to be painstakingly determined by hand).

To check the return value of the script, do:

    int iRet = (int) lua_toboolean( lState, -1 );
    if( iRet )
    {
        std::cout << "Door opened!" << std::endl;
    }
    else
    {
        std::cout << "Door still closed." << std::endl;
    }


And last, cleanup the lua_State, freeing any associated memory:

    lua_close( lState );


Build and run your code, and you should get "Door opened!" on the screen. Hint: Put a breakpoint on the "return 0;" and you can view the message in the console window before it gets shut down.

Here's the entire luatest.cpp file to this point:

// luatest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <lua.hpp>
#include <iostream>

char *szLua =
"x = 8 "
"return ( x > 7 ) ";

int _tmain(int argc, _TCHAR* argv[])
{
    lua_State *lState;

    lState = luaL_newstate();
    luaL_openlibs( lState );

    int iStatus = luaL_loadstring( lState, szLua );
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }
    iStatus = lua_pcall( lState, 0, LUA_MULTRET, 0 );
    if( iStatus )
    {
        std::cout << "Error: " << lua_tostring( lState, -1 );
        return 1;
    }

    int iRet = (int) lua_toboolean( lState, -1 );
    if( iRet )
    {
        std::cout << "Door opened!" << std::endl;
    }
    else
    {
        std::cout << "Door still closed." << std::endl;
    }

    lua_close( lState );

    return 0;
}



So, that all fine and dandy, but our "real" script still needs the Lua script to be able to call back into C++ code to determine the player's Lockpicking level. Next time!

Comments: 0 - Leave a Comment

Link



Monday, June 29, 2009


Today, how to get Lua and link it with your game.

The previous installment of this tutorial is here:



Lua is available at http://www.lua.org/. As of this writing (June 25, 2009), the latest version is 5.1.4. There are various binary packages available, however, I recommend that you just download the source code (lua-5.1.4.tar.gz for me). Unpack this using your favorite unpacking utility; I put mine into C:\dev\lua-5.1.4.

Now, we'll make a project for this tutorial:

  • Fire up Visual Studio. I'm using Visual Studio 2005; your steps will likely vary somewhat if you're using a different version.

  • File/New/Project.

  • Pick a "Visual C++"/Win32/"Win32 Console Application". Call it luatest.

  • In "Application Settings", be sure we're doing "Console Application".

  • You can turn off ATL and MFC if you want to, though it shouldn't matter.

  • If you build and run at this point, you should get a Console Application that opens a console window, and then exits.


Next, we need to add the Lua files. Open the project properties, and go to "Configuration Properties"/"C/C++"/General. Add the Lua directories to "Additional Include Directories"; something like:

"C:\dev\lua-5.1.4\etc";"C:\dev\lua-5.1.4\src"

One more annoying step in the project properties. Lua uses the C-library string function calls like strcpy, and Microsoft doesn't like those anymore. The easiest way to deal with this is in the project properties, under "Configuration Properties"/"C/C++"/Preprocessor. Under there, add to "Preprocessor Definitions":

_CRT_SECURE_NO_WARNINGS=1

The easiest way to include the Lua sources are just to add the files. You can fool around with building Lua as an additional library (or even DLL), but I wouldn't bother. To do this, add the Lua source files to your project's "Source Files". There is a list of the files in C:\dev\lua-5.1.4\etc\all.c; you want all of those files except for lua.c.

And, even though we're not going to call into Lua yet, let's include the header files just for kicks. To your luatest.cpp, just under:

#include "stdafx.h"


Add:

#include <lua.hpp>


At this point your luatest.cpp should look something like this:

// luatest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <lua.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}



This should build cleanly. You can run your Lua-enabled app, which should fire up a console window, do nothing, and then exit. Congratulations!

Next: Calling a Lua script.

Comments: 0 - Leave a Comment

Link



Friday, June 26, 2009


Forgive the grandiose title; this post should really be entitled "A Quick Tutorial on Integrating Lua as a Simple Scripting Language into a Windows C++ RPG Engine". But that's too long and boring, so I've gone with "The Lua Tutorial" even though there are many far better Lua Tutorials (http://lua-users.org/wiki/TutorialDirectory) available.

So, for those who haven't been following, I'm working on an RPG, which by necessity has a game engine behind it. The game engine is entitled SENG, and supports single-player party-based RPG play. The engine is Windows only, using DirectX and C++ as the foundations. Part of the philosophy of the SENG engine is that most of the story and level logic is data driven; that is, run from scripts within the level files. For instance, when your party has a conversation with someone, the conversation is all driven through scripts. My initial work on the SENG engine had a LISP-like scripting engine, except minus the parentheses. It was dirt-easy to create and support in the engine, but the power of the scripts was pretty limited, and the authoring of scripts was cumbersome and error prone.

I set out to look for some alternative, such as beefing up my scripting engine to be more LISP-like, or using XML syntax, but I kind of wanted to get out of the business of authoring scripting languages. Not to mention that having a custom scripting language would be a big pain if anyone but me ever wants to author scripts. After some investigation, I settled on Lua (http://www.lua.org/) as my scripting language.

From the Lua manual (http://www.lua.org/manual/5.1/manual.html):

Quote:
Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight scripting language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++).


From my perspective, the winning features of Lua:

  • Small, easy to integrate.

  • C-like syntax.

  • Full featured, robust logic.


As I've done the integration, all of these features have been borne out.

During this work, I've looked through various documentation and tutorials, all of which have been pretty good. However, I was struck by the absence of a simple tutorial or document, "Here are the basic steps to integrate Lua with your C++ engine". So, that's the point of this tutorial. I'm not going to get into the details of writing Lua scripts at all, nor any advanced usage; see the official documentation http://www.lua.org/docs.html for that.

The feature I'm going to demonstrate in this tutorial is simple. The game has a script, stored in a string, that it wants to call to determine whether the player is allowed to unlock a door or not. The script, in turn, calls back into the game to see if the player's Lockpick Skill Level is greater than 7, and returns TRUE if it is, or FALSE otherwise.

Notes: How the script has been loaded into the string is completely irrelevant; in my case they are included in XML files but that doesn't matter for this tutorial. Obviously the example script is very simple (comparing a number to 7), but once you've gone through the tutorial, it should be clear how to incorporate more complex logic, like also allowing the player to unlock the door if he has a key, or has completed some quest. Further, it should also be apparent that the script can be called from the game engine for other actions beyond trying to open a door; my engine does for conversation, object activation, and quest logic.

Next: How to get Lua and link it with your game.


Comments: 2 - Leave a Comment

Link



Thursday, June 25, 2009
I've spent the last week moving from Washington to California, so not much progress on any front. I do have some links of interest to post.

First, a nice post by Andrew Doull on burnout, and the avoidance thereof:

http://roguelikedeveloper.blogspot.com/2009/06/day-in-life-of-roguelike-developer.html

While he's talking specifically about roguelike development, I found it very applicable to indie game development. Hitting burnout is a reality for indie developers; it's just natural to feel some malaise when working on a project, in your spare time, for months if not years. My particular flavor is to want to move on to the next project with the current project incomplete, but there are certainly other types of burnout that I hit sometimes too. Andrew has a good set of tips (starting with "Burnout is a natural part of the creative cycle, and something you should take in your stride. It’s not the end of the world, or coding, as you know it."); definitely a worthwhile read.

The next set of links are on dungeon/level design. I found all of these interesting an informative, and while I'm not in a level designing phase right now, I wanted to save them around for when I am.

A really nice post by Melan on the Enworld forums "Dungeon layout, map flow and old school game design":

http://www.enworld.org/forum/general-rpg-discussion/168563-dungeon-layout-map-flow-old-school-game-design.html

A good set of resources for developing urban levels, from Paul the Ink Knight:

http://inkknight.blogspot.com/2009/04/free-urban-adventure-resources.html

Last, a couple of posts by Coyote on dungeon design:

http://rampantgames.com/blog/2009/06/rpg-design-somebody-call-dungeon.html
http://rampantgames.com/blog/2009/06/dungeon-makeover-extreme-edition.html

That's all for now. I'm currently working on incorporating Lua as the scripting language for SENG, replacing my existing LISP-like language. It seems pretty easy to do, though the documentation is scattered enough that I may write up a quick tutorial on how I did things. Now, if I can just get some more boxes unpacked, maybe I can take a break and actually work on it...


Comments: 0 - Leave a Comment

Link



Tuesday, June 16, 2009
One of the goals of the SENG engine is to provide interesting tactical combat. My favorite RPGs have combat systems that you need to play well to beat, as opposed to some other RPGs where combat is mostly a perfunctory click-fest (no matter how thrilling).

In the "To The World Tree" demo (http://www.prankster.com/ttwt), I felt that the tactical combat didn't have as many options and choices as it should. Spellcasters had a lot of interesting spells to cast, but Fighters and Rogues were pretty limited. I've added some stuff which makes Fighters more interesting (the Powers system), and some stuff for Rogues (Singing Powers, mostly). Time to add something that will make both of them more interesting in combat.

So, I've added a Flanking system to combat. Attack someone, and you leave yourself open to augmented attacks from anyone else. Further, casting a spell or shooting a bow leaves you open to flank attacks from anyone. In this screenshot:



You can see Celeste shooting a bow from the back row, and getting a Flanking bonus on the Goblin Wimp because he is busy attacking TestNancy. Meanwhile, one of the Goblin Wimps is getting a Flanking bonus on TestNancy, since she's attacking the other goblin. (Look at the text messages at the bottom to see who is flanking who).

Flanking gives a 50% boost to attack success and damage. There is also an Improved Flank Skill which gives even greater bonuses; this is a proficient skill for Rogues, so it is a particularly interesting character build option for them. This 50% bonus (or greater with the Improved Flank Skill) is not a huge deal, but definitely could make the difference between victory or defeat in a closely matched fight.

The other big tactical combat change I want to put into effect is to make the different weapon types "interesting". Swords are accurate, Axes are less accurate but do more damage, and Staves are weaker offensively but give a defensive bonus. I'll work on that next.



Comments: 2 - Leave a Comment

Link



Thursday, June 11, 2009


So, I've been working on the manual for "Untitled SENG Game" for the past couple of weeks. The main purpose of this project has really been to get the updates I've made to the RPG system codified; I've changed the code a ton, and while I have chicken-scratched notes on all the updates, it's nice to have a systematically written document with how this system works, for my benefit if not for anyone else.

You can see the manual here:

http://members.gamedev.net/gdunbar/blog/2009_06_11/rules.htm

Notes:

  • The "Game System" section is the one to look at; the "Playing the Game" section is still based on the old "To The World Tree" demo I did two years ago. Even though the UI has changed greatly, I don't want to update that section until I have a game (and fresh screenshots) to go with it.

  • The "Game System" section is all based on live code; it all works (plus or minus bugs) in the game. This isn't just a vaporware document.

  • All of the tables, skill lists, spell lists, etc are auto-generated by the game code. This was the other big purpose of documentation project.

  • The spell lists and faction lists are game-dependent, and are just for testing purposes. All of the code for the various spell types, and for factions, are done, but the data needs to be filled in as I design the game world.


Any comments or questions on the manual would be welcome.

I'm getting there with the game engine. Still a few more changes to make until I've got all of the engine features to make the game I want.


Comments: 0 - Leave a Comment

Link



Thursday, June 4, 2009
So I've made a number of changes in the way the SENG RPG system works over the past few months. I'm finally getting around to putting those changes into the documentation. That may seem like a task that should wait until there's actually a game to go with it, but right now all I have is a big text file with vague notes on the changes I've made. Moving it into the real documentation is as much for my benefit as anyone else, so that I have a definitive place to look when I'm trying to remember how something is supposed to work.

Also as part of the documentation I've been moving things like spell descriptions, formerly only available in-game, into the manual as well. These are auto-generated by a program (that shares most of its source code with the game code itself). So, a spell description in-game might look like this:



Whereas in the manual, in HTML format, it might look something like this (well, sort-of; I can't get all the formatting into this post):

Touch of Fear

Type: Spell
Skill: Void Magic
Level: 0
Cost: 40
Attribute: Intelligence

Inflicts a penalty to statistics:

  • Attack Points

  • Damage Points


Attack Points: 20
Damage Points: 20
Saving Throw: Fortitude

This spell chills the heart of one enemy, hindering the effects of that beings attacks for a time.


Optimistically, I'll say I'm about halfway done with making these updates. Perhaps I'll post the manual here when I've finished up the changes.



Comments: 0 - Leave a Comment

Link



Wednesday, June 3, 2009
A bunch of links this week.

First, Shamus talks about how to get started with programming, and how to get started with graphics programming specifically:

http://www.shamusyoung.com/twentysidedtale/?p=3519

The first, and very valid, point that he makes is that if you want to learn to program, starting with graphics programming is a difficult way to do things. In addition to just learning how to program, you'll also have to learn a bunch of math and computer graphics theory. Math with things like geometry, trigonometry, linear algebra. Computer graphics involves stuff like polygonal primitives, texturing, lighting, animation, etc. Unlike Shamus, I did go to college to get a CS degree, and almost every CS or math class (or even physics) I took has some relevance towards graphics programming.

When I was first programming back in the early 80s as a Jr High student, the school had a lab with some Color Computers. Inspired by "classics" such as Pyramid 2000:



I took to programming text adventures in BASIC (the Color Computer booted directly to BASIC). That was a great way to learn; simple enough for a Jr High kid to actually do it, but I could still make something "interesting" in just a short period of time. The key lesson for me was just to learn that a computer exactly follows whatever instructions you give it, and to learn how to turn my thoughts and plans into those instructions.

I'm not sure what the modern equivalent of that is; I'm completely out of touch. Making a match-3 game or Tetris-clone in Java? Something in Flash? I just don't know. Shamus recommends C++ for learning graphics programming, which I think is a terrible idea. Too much complexity, too much rope to hang yourself with.

Next, Coyote has an article on cursed items in RPG design:

http://rampantgames.com/blog/2009/06/rpg-design-cursed-items.html

He describes the 3 types of cursed item:

  • Out-and-out cursed items. The items that look like a nice magic item but is really completely negative. Like sword that looks like a Longsword +3, but starts attacking you as soon as you wield it. Popular in old-school D&D, not so much anymore.

  • Mixed-blessing cursed items. So, maybe this time the Longsword +3 is a nice item, but every once in awhile it attack the wielder instead of the target. Items like this have always interested me, if done well.

  • Story items. By taking the Longsword +3, now the player has to go on a quest to find the Holy Grail. These items are used to move the plot or quests along in the plot of a game. A valid tool in a game designers workshop, though they can seem heavy handed and arbitrary if not done well.


Anyways, good article.

While searching for a picture of a cursed item (didn't find anything good), I ran across this article about cursed items:

http://inkknight.blogspot.com/2009/04/give-your-cursed-items-reason-to-exist.html

Also well done.

Last, Jeff Vogel discusses "Addiction Based Design":

http://rpgvault.ign.com/articles/986/986323p1.html

MMORPGs tend to be the heaviest users of addiction based design; after all, they get a monthly fee if they keep you coming back:



RPGs in general, though, also feature luring the player on with the promise of "just one more level", "just one more item", and so forth. Diablo 2 perfected the formula, but any RPG designer should keep this in mind when designing his game. After all, making the player want to keep playing is our goal, and we should use any tool we can!


Comments: 3 - Leave a Comment

Link



Friday, May 29, 2009
Coyote blogs about programmer art (and tools to make it) here:

http://rampantgames.com/blog/2009/05/programmer-art.html

For those who don't know, programmer art is the half-baked (or even less) art that programmers make to test out their pre-release games. In the big-company game world, this art is then later replaced with the "real" art made by real artists, but in the indie world, this often ends up being the art that ships with the game. As such, saying a game features "programmer art" is a hoity-toity way of saying it's ugly.

Anyways, no one makes uglier art than me! For the most part my process seems to be similar to Coyote's, but I use totally different tools!

3D modeling

Coyote uses Blender (http://www.blender.org/), which I got as far as downloading (it is open-source and free). However, I found it completely baffling; the learning curve was too steep for my simple (and time-limited) brain. I use Milkshape 3D (http://www.milkshape3d.com, which is not free but was only like $30 or something. Milkshape is pretty intuitive and simple to use, and is certainly sufficient for my basic needs.



I only use Milkshape for basic modeling; I have my own custom tool for doing character modeling and animation. I do this because the SENG graphics engine has a system for scaling skeletons, and hot-plugging models and textures. This allows me to do things like swap in a new torso model when the character dons a new breastplate. Or use the same model for chainmail and platemail, but just with a different texture. Or allow the player to select his character's exact hair color by coloring the texture that he uses for a head. These are important both for flexibility and to allow me to create a wide variety of game content with a minimum of art creation.



Image Editing

Coyote uses GiMP (http://www.gimp.org/) for image editing and Genetica (http://www.spiralgraphics.biz/gen2tour/index.htm) for texture creation. GiMP is an open-source image-editing program; like a free version of PhotoShop. I use Corel's Paint Shop Pro (http://www.corel.com/paintshoppro), which does about the same thing. I had used it before, so buying it for $80 (or whatever) was worth it to me to avoid learning a new tool.



Genetica looks neat, but pricey! I can achieve all of my rudimentary texturing needs in Paint Shop Pro, so I don't see the need to spend money on a tool like that.

Level Editing

Coyote uses level editing tools like Quark (http://quark.planetquake.gamespy.com/) and Torque Constructor (http://www.garagegames.com/products/constructor). SENG is a tile-based engine, so such tools don't really apply; I have my own level editor for constructing levels. The level editor shares most of its code with the game engine, so the levels are rendered just the same in-game as in the editor. One of the advantages of using tiles to build levels is that level editing is simpler than in the full 3D environment (at least once you've built a reasonable set of tiles).



So, there's another developer's perspective on programmer art tools; interesting that I use a different tool in every case than he does. I do think every tool mentioned in his post (as well as mine) is pretty mainstream and established, and will work just fine for your indie dev art needs.


Comments: 0 - Leave a Comment

Link



Sunday, May 24, 2009
The latest change I've made to the SENG engine is to add a Faction feature. Mechanically, a Faction is a group that your character can affiliate with, granting additional powers and benefits. In this screenshot:



The main character (TestNancy) has initiated conversation with Celeste, and Celeste is offering to enter TestNancy into the Faction "Thunder Chickens". Hopefully it's obvious that the "Thunder Chickens" are a test Faction; otherwise you guys have a far lower opinion of my game design skills than I would hope!

The main benefit of a Faction is the additional powers that the Faction grants. Each Faction has a number of ranks (I think 4 will work well), which are granted based on in-game achievements and scripting. Typically the character will find the Faction chief or lord high muckety-muck, and that leader will assign quests or other tasks to attain ranks. Once the character has attained a rank, he gains powers (spells and such) if he has the requisite skills. Here's a screenshot that show the powers granted by my test Faction:



In addition, a character's Faction affiliation is accessible in scripting (such as conversation), so that character can be offered special items for sale, or addition quests, or other benefits. That is all done through scripting so there isn't really a screenshot to show.

Once I've moved to the real game design, the test Factions like "Thunder Chickens" will go away, and Factions will represent more conventional organizations like:

  • Worship of Gods.

  • Guilds, like a Thieves' Guild.

  • Orders of Magic.

  • Clans, houses, Kingdoms, or other political entities.


Right now I'm limiting the main character to a single Faction; I could see a game where it might make sense to affiliate with more than one group, but I don't want to go that route right now. Careful game design should make it seem reasonable to the player.

That's all coded and working; another feature to check off. Next I'm continuing to work on game engine stuff like this; I have a whole long list.

Comments: 1 - Leave a Comment

Link



Thursday, May 21, 2009
Coyote discusses hit points here:

http://rampantgames.com/blog/2009/05/rpg-design-in-defense-of-hit-points.html

Hit points originated in the wargaming world, and came into role-playing games in the very first one, Dungeons and Dragons.

From http://en.wikipedia.org/wiki/File:D%26d_Box1st.jpg:



Coyote raises the point that hit points are unrealistic, arbitrary, and gamey. A valid point, though I can't think of an RPG (PnP or computer) that I've played where damage handled differently, _and_ where the damage system actually contributed interesting tactical or strategic decisions.

I do remember the MechWarrior games had a more complex scheme where different parts of your mech (like a giant, human-piloted robot) had damage (and heat, I think) calculated separately, which was moderately interesting. You could do things like try to shoot the legs off of an opposing mech to immobilize it. The MechWarrior games had a far more tactical/action focus than more RPGs, though; even a tactics-heavy RPG like Icewind Dale still has storyline, character development, and exploration aspects far beyond what I remember of MechWarrior.

From http://www.microsoft.com/Games/mechwarrior4/:



Coyote ultimately comes to the conclusion that hit points are a pretty good way of modelling damage in an RPG, and I tend to agree. To paraphrase Winston Churchill: It has been said that hit points are the worst form of modelling damage, except all the others that have been tried.


Comments: 2 - Leave a Comment

Link



Tuesday, May 19, 2009
The latest update to SENG is a rework of the way stealth and sneaking works. Sneak now shows up as an ability on the Abilities screen (formerly known as "Spells"):



Then, the player can activate sneak in the main HUD through the action buttons, down in the lower right corner of this screenshot:



The player can enter sneak mode as long as he isn't in sight of a non-friendly creature (and isn't in combat). In this shot you can see TestNancy's Sneak score (in "Special Statistics"):



If she comes within range (150 feet, I believe) of a non-friendly creature with a higher Observation score than her Sneak score, she is spotted and the Sneak ability is turned off. Sneak is based on the Sneak skill level and Personality attribute of the character; Observation is based on the Observation skill level and Intelligence attribute. Coming within 50 feet of a creature gives that creature a bonus to Observation.

So that's pretty simple, and, to the player, not much different than how it worked before. However, internal to the code, I replaced the old hack-o-rama implementation, with 4 boolean values per character, and special-case code galore, with a new implementation, sharing code and functionality with the Powers system. I'm really happy with the way it came out.

Next, I'm working on the Faction system, to handle things like Guilds and Deity worship.


Comments: 2 - Leave a Comment

Link



Monday, May 11, 2009
Jeff Vogel of the Bottom Feeder (http://jeff-vogel.blogspot.com) had a series of posts a little while ago about the cost of indie games:

http://jeff-vogel.blogspot.com/2009/04/indie-games-should-cost-more-pt-1.html

http://jeff-vogel.blogspot.com/2009/04/indie-games-should-cost-more-pt-2.html

He describes how there has been a trend for the independent game developers and publishers to sell their games for lower and lower prices, not just lower than big-publisher retail games, but at lower than bargain-bin prices. He decries this trend, and gives a series of reason why he will continue to prices his games based on his existing policy. (If you don't know, he makes old-school indie RPG games, and prices them somewhere in between retail games and bargain games. Around $30).

My experience on this matter comes from when I was running a play-by-email game, Atlantis (http://www.prankster.com/project/index.htm), in the mid-nineties. I designed and wrote Atlantis 2.0, and ran it as a free playtest, and then upgraded it to Atlantis 3.0, and ran it as a commercial game. Later I moved on to other things and released the source code as an open-source project.

Atlantis could (and still can) be played completely through the text interface, but there is at least one graphical client. Here's a screenshot (from http://www.geocities.com/pbemah/):



When it came time for me to price the game, there was a small but long-standing play-by-paper-mail gaming industry, where a turn of the game would cost $5.00 or more. Some of these companies were starting to move into supporting Internet play. There were also a small set of email companies that had similiar games, generally costing $2.50 to $5.00 per turn. I actually talked to one of the competitors, and he suggested that I price things on a similar line, even though the actual cost of supporting additional players in a running game was really low. His points were:

  • The audience you're shooting for is one with disposable income, professionals and the like. Dirt poor students and teenagers aren't going to be interested in paying _any_ money for a game. For the audience, money isn't really the determining factor in playing a game as long as the costs are within reason.

  • There is a huge difference in mindset between the player who will play your game for free, versus one who will pay _any_ money (no matter how nominal). In indie game terms, once a player has decided it's worth $5.00 to play your game, most of those players would probably be willing to pay $20.00 to play your game.


Based on the low cost of actually supporting any number of players, I decided to price the game at $1.00 per turn, well below the market rate. I knew that I was probably optimizing for getting the maximum number of players, versus making profits. In retrospect, I probably was also a bit nervous about my product, moving into a established market with games that I knew were really polished and fun (having played them myself).

I did get a pretty decent number of players (I think about 250 at the peak), though my competitors were getting similar numbers. I suspect that I would have gotten almost the same marketshare had I charged the going rate of $2.50 per turn, though it's impossible to know for sure. The people that played _really_ wanted to play, and, while I don't think they were made of money or anything, a few extra bucks a month wouldn't have made a big difference. Looking back, $2.50 would have been an appropriate price based on the service I was providing and the enjoyment the players got out of the game.

Interestingly, my low-cost game did not have significant impact on the other games in the market; some people played several games at once, but I didn't see migrations from the other games. The players of the other games were perfectly happy with the game they were getting for their money. Reflecting this to the purchase of indie games, I think the worry of other games undercutting your pricing is overblown. If your game stands up, people will pay a fair price, and conversely, if your game doesn't match the competition, a low price won't save it.

So in the end I agree with Vogel; have confidence in your game, find your market, and charge real money for your game. Those players who have gone to the lengths to find and play (and not pirate) your "road less travelled" indie game will (for the most part) be happy to pay you a fair price to play it.


Comments: 2 - Leave a Comment

Link



Wednesday, April 29, 2009
Well, I know I keep promising to blog on my medium-term plans for "Untitled SENG Game", but I guess that is too boring for me, because I never get to it. Instead, today I'll blog on the dev changes I've been making lately.

I've been vaguely unsatisfied with the way the interface for the action system works. Here's a screenshot (click for the full size):



If you see the UI element in the lower right corner, with "F1" through "F10" labelled on some icons. I call that the "Action Element"; it is how you access non-default actions like casting spells, drinking potions, etc.

The old behavior was that if you left-click in the main game interface, it performs a default action. For instance, click on a monster in the interface, and your current character will attack the monster. Right-click on in the interface, and your character performs whatever action is current selected in the Action Element. So, if you have a spell in the action element (say under F7), and you right-click on a monster, your character will cast the spell on the monster.

That was functional, but I don't like it for the following reasons:

  • In all of the dialogs (like inventory), right-click means "give me more information", whereas in the main interface, right-click means "take an action".

  • In fact, the general Windows app has "right-click for a list of options", not an immediate action.

  • For things like potions, you had to go select the action in the Action Element, then right-click somewhere. The player will figure this out, but it's a little confusing at first.

  • Same for spells that don't need a target to activate; for instance the new Powers system I'm introducing. (In fact, Powers were so clunky to use that they were the impetus for this change.)
  • I want to have a way to display an informational dialog about a monster (or other in-game element). I could have made an "info" action, but that would be pretty clunky.


So, I decided to tweak this for a more functional mechanism. Now:

  • Left-click means perform the default action (attack, talk, whatever), with an exception (as per the next bullet in this list).

  • If you first click on a icon in the Action Element (or hit the appropriate function key), then left-click performs that action.

  • Right-click means "display a dialog about the clicked thing".


There are still a couple of kinks I'm working out. For instance, if you select a spell, then click to cast the spell, what happens to the Action Element? Should the spell still be selected (so clicking again casts it again), or should it get auto-unselected, so you have to click the Action Element again to cast the spell again? I'm leaning towards auto-unselect, since I believe the player usually doesn't want to perform the same action twice in a row. But I'm not totally sure yet.

This seems a lot more consistent and discoverable than the previous incarnation. Full testing will have to wait until I have some more complete prototypes to try out, but I'm happy thus far in my limited testing.


Comments: 2 - Leave a Comment

Link

Page:   1 2 »»

All times are ET (US)

 
S
M
T
W
T
F
S
2
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

OPTIONS
Track this Journal

 RSS 

ARCHIVES
July, 2009
June, 2009
May, 2009
April, 2009
March, 2009
February, 2009
January, 2009
December, 2008
November, 2008
October, 2008
September, 2008
August, 2008