Sunday, May 28, 2006

Cracker sandwiches are always a bad idea, this is a universal constant

What did I achieve this weekend? Nothing, apart from a sunburn.

I need to increase my time-management foo, there may be some progress tomorrow morning.
I'm working on getting layers on my map in the hackishly cheapest way possible. But i also want to do so that I can edge ever so slightly to the correct way of doing things.

My todo list has the tile problem and timing on it. After that I'll do the quadtree. So the layers should have be done this weekend - I'll see if I can do it by wednesday.

Oh also check out one of the google notebooks I've been playing with.

So in closing:

Weekly goal: A hours programming EINFALL a day.
By Wednesday goal: Layers

EDIT: Monday
Did around 1/2 a hour this morning and about an hour now. Layers are basically in, though saving and loading isn't. Layers are quite cleanly implemented but the tile class is quite messy.

EDIT: Tuesday
Did around 1/2 this morning and about 40 minutes now (if I'm generous). Tile layers are loading and saving. So next up is having houses. Also the tile class needs cleaning but that's such a lot of work, that I'm avoiding it :D

EDIT: Wednesday
Did about 50minutes this morning. No programming, just organizing tiles - pitfully little was accomplished. It seems doubtful I'll do anything this afternoon as I'm teaching English in about 10 minutes.

Also Java - hey Java why don't you have delegates? Godamnit! Makes programming in you so bothersome.

EDIT: Thursday
Slept late no morning. And no evening either :( No evening tomorrow either but mayve I'll get some stuff done tomorrow. So I've dumped LuaJava in favour of Python (under Jypthon). LuJava is too fiddly, to be totally clear it's too much of a C wrapper not enough Java-tasting. The C# Lua interface though is excellent. I briefy looked at Ruby (longingly) but projects are rather basic at the moment.

Wednesday, May 24, 2006

Savage Mythologies



Here's the demo, it's GDI should work anywhere. Whatelse ... oh it still doesn't swap parent nodes, but I don't think that matters for a cross style movement pattern.

X
XOX
X


Press the left mouse button to move the tank, press the right mouse button to place a poorly drawn mountain. Be amazed at the tanks path finding abilities.

Oh there's no timing - so the tank will whip from location to location as fast as computerably possible.

Also this is the reason google note book is useful / a good idea.

Tuesday, May 23, 2006

Swimming with sacred pigs

So there's an excellent firefox plugin from google, called Google Notebook. I'd advise you get it. It allows to copy little bits of websites that you want to remember, then you can search them and sort them into a logical order etc etc. A bit like the scrapbook extension - which I also use, but that keeps whole pages which I read later (at school). I've tried to write something like google note book a few times on my own.

Imagine having a notebook for your RPG game, then every piece of info on the web that gives you an idea you can throw it in there. Excellent - this is a really exciting plugin. Especially if it's extend to find related items in other peoples books.

A* Library still playing with what functions go in what interfaces - also I have a little GDI tank that you can move around a screen by clicking on a tile, it's quite neat. There's no timing so the tank just goes to the tiles as fast as possible.

The next step on EINFALL is refactoring the tile - a big job, or hacking in layers - a small job but not very pretty. Should get done this weekend either way.

Sunday, May 21, 2006

Admire my fancy tile work



Not too bad! I drew those tiles a while back, too jungly for grass really. This is double buffered GDI, I want to try and make something almost game like with my pathfinding library.

(which still hasn't been tested on more that 10x10 tiles :D )

Saturday, May 20, 2006

Sun

Today is shockingly beautiful, very sunny. This calls for sitting on the balconey and drinking coffee later today.

I've fixed the first of my two menu bugs. I wasn't closing a filestream - duh, so I was defaulting to the default texture. Next up is the "why do the planets turn blue problem".

If I get these two things done I may go off on a tangent and do something totally uneinfall related.

Wheeee: Fixed the blue planet problem.

So it took about 2hours total. Why have I been unable to make myself do it until now though? :D Grrrr. Still happy with that. The next big task is refactoring the tile.

*Refactor the tile
-It should be serialized
-It can be much lighter
-But it requires quite a lot of work, therefore I might just add a layer concept and come back to it later.

*Add local regions
-Basically each map will have a quadmap to reduce collisions.
-Also regions will exist for buildings, so it's easy to tell when your in or out.

EDIT:
The player is now placed on the map that his setup file says he should be placed at. This should have been done in stage 2 but by that time I'd forgotten what one of the todo's actually meant :D There is no saving of where the player travels too during the game though!

See I still love you.

The Basic Lua scripting tutorial has been updated to LuaInterface 1.3. The question of when I'll get round to the others, though, that remains unanswered :D

Scripting with Lua in C#

Contents

  • What to get?

  • Installing

  • Basic Use of Lua

  • A notch, a crank, knarc, ahctona!

  • But wait! There's more amazing where that came from!



Lua allows us to easily add scripting to our game. It's a well known, widely used standard (it was used in Balders Gate). Once added it can process both compiled and uncompiled Lua scripts giving a good combination of flexibility and strength. The greatest advantage to Lua is how simply we can insert it into our C# programs. Well, hopefully now your convinced so let's get cracking.

What to get?


LuaInterface 1.3

Installing



Unzip LuaInterface 1.3 (or later version that you may have been able to download). Put it somewhere safe such as in the Visual Studio directory or some place your unlikely to accidentally delete.

Now boot up visual studio. Create a new C# Console Project.

Now go to the Solution Explorer window.

Play with my options!

(If you can't see it use this
Press me! Press me! and it should pop up!) Take your mouse over to the References icon and right click.

Choose add reference. This should all be pretty standard fare for starting a new project. We're just recovering the basics here in case you're reading this tutorial as a seperate chunk.

Press my buttons

Carefully survey your options and then choose "Browse". Then browse to where you unzipped LUA and go into the bin folder ... and select LuaInterface.dll. My copy of this .dll file is at the following location C:\LuaInterface\bin\LuaInterface.dll.

Once you have chosen this .dll file it will pop up in the the "Selected Components" part of the window. Confirm the selection and we're ready to go. I'm sure there's a method of playing with Visual Studio where you can avoid the "Browse" button all together and have the reference preloaded in, ready to select but after a few minutes fiddling I couldn't find it :(

Your game and your game players are going to need access to the Lua dll files. So you need to have them in project directory. My version of the console application executable that we're working on is currently located here: junk\Visual Studio Projects\ConsoleApplication3\bin\Debug

Open up that directory. Also open up the directory of were you installed Lua. Go into the bin\ directory and copy across (to project directory):


  
luanet.dll


Your working directory should end up looking a little like this:

The lua net dll

That concludes setting up Lua to work with this project. Not too painful.

Basic Use of Lua



Let's write some code. We want to make a C# program that's interfaces with Lua and we want to do it soon, very soon indeed.

using System;
using LuaInterface;

namespace ConsoleApplication
{
class Class1
{
static void Main(string[] args)
{

}
}
}


The above is our class skeleton. The only thing worth noting at the moment is that we're using the LuaInterface reference. We'll concentrate on the main method an make a small program that uses Lua.


  
static void Main(string[] args)
{

Lua lua = new Lua();


Here we create a Lua interpreter. We can create as many as we wish and they will all be independant. But for now we'll only have one.



Next we create some global variables. Remember we're programming in a scripting language so we're creating Lua global variables not C# global variables. In actual use this "programming" would be done ahead of time and then loaded in from a file. Curently we're doing it directly in the code just to get a feel of what's happening.



lua["num"] = 2;
lua["str"] = "a string";


This creates two Lua global variables. One is called num the other is called str. Note that the variables both hold different types. This is a feature of Lua it is not a strongly typed language in fact it's dynamically typed. Variables can be anything (though Lua only has a few data types). But I don't want to get pulled in to a distracting explanation of how Lua works as a programming language quite just yet. First I'd quite like to get it hooked up to C#.



Now we made these Lua varaibles let's get C# to read them. Now as you really should know by now C# is a strongly typed language. So we need to cast the variables.



double num = (double) lua["num"];
string str = (string) lua["str"];


Note that we must cast to a double here. An int won't cut it as Lua is storing double information. Now we've read this information out from the Lua interpreter, next let's read it out to the screen to see if everything is agreeable.



Console.WriteLine("str:" + str +"\tnum:" + num);
Console.ReadLine();

Agreeable indeed!


Okay so far not very exciting but we're still only getting a feel of what's going on. So let's crank it up a notch next and do something cool.


A notch, a crank, knarc, ahctona!



Okay grip the arms of your chair tightly and get ready to script!



First let's create two functions we might like our brand new scripts to make use of.


  
public void DanSays(string s)
{
Console.WriteLine("Dan>" + s);
}

public void ThorSays(string s)
{
Console.WriteLine("Thor>" + s);
}


Feel free to insert your own name instead of Dan or Thor. So now we have two cool functions bursting with game playing potential.



Let's hook them into Lua - so out main method will look like below:


 
class Program
{
static void Main(string[] args)
{
Program program = new Program();

Lua lua = new Lua();

//Register our C# functions
lua.RegisterFunction("DanSays" , program, program.GetType().GetMethod("DanSays" ));
lua.RegisterFunction("ThorSays", program, program.GetType().GetMethod("ThorSays"));



This lets the Lua scripting language make calls to our two C# functions. Incredibly easy isn't it? So in the Lua language we just make calls to DanSays("with a nice string here") or ThorSays("with an equally nice string here") and they will call the C# equivalents!



The RegisterFunction function



The RegisterFunction's first argument is what you'd like to name the function in Lua. Here we chose the same name because it's so simple. But in future function registration we might want to make the Lua name more simple or descriptive than our C# name.



The second argument is the object where the method is stored. Note the word object. That's why we have to instantiate our Program program. So if we have a class called person "Class Person" and it has a method talk then it allows us to do something like.


   
Person pete = new Person();
Person jeff = new Person();
pete.talk("Hello");
jeff.talk("Hello");


We can the register these talk functions seperately.



The third parameter uses reflection - something I currently know nothing about. All I know is that's it's magic like pixey dust and elevators. It magically gets all the knowledge about the method - it's arguments and so forth. Then Lua can call it effectively. You have to pass in a string of the methods name and that's it. Great!


The DoString function


Add this to the end of our main method.



lua.DoString("DanSays('Hello'); ThorSays('Hi! Dan')");
Console.ReadLine();


DoString executes a line of Lua code in string form. Wonderbar!


Dan and Thor have a bit of a chin-wag

But wait! There's more amazing where that came from!



So we've got a pretty groovy scripting language all by doing relatively little.



But now let's arrange it into a bit more of a game like usefullness. Go to your working directory for this project. The place where you copied all those dll files (mine is: My Documents\Visual Studio Projects\ConsoleApplication3\bin\Debug).



Okay create a new directory all call it "scripts"


A script directory.

Now in the scripts directory I've created a simple text file called "Thursdays"



It has the following not-so-witty-banter.


DanSays("Hey, Thor!");
ThorSays("Hi Dan! You know Thursdays . . . ");
DanSays("*sigh* yeah, Thor, I know Thursdays.");
ThorSays("Named after me you know!");
DanSays("Yeah, I know.");


Okay. So in scripts\Thursdays.txt with have some future-award-winning dialogue. It's written in Lua but only using custom functions designed by us because we're cool and groovy designers.

Back to El Code



Make your main method match mine pictured below:

  
static void Main(string[] args)
{
Class1 c1 = new Class1();

Lua lua = new Lua();

//Register our C# functions
lua.RegisterFunction("DanSays", c1, c1.GetType().GetMethod("DanSays"));
lua.RegisterFunction("ThorSays", c1, c1.GetType().GetMethod("ThorSays"));


lua.DoFile("scripts/Thursdays.txt");
Console.ReadLine();
}


This fine piece of programming hereafter known as "ScriptRunner3000" will run any script we call Thursdays - without recompling - yes you heard me correctly - without recompiling!

Of course if we want to get really fancy we could write some code to enumerate all the files in scripts and then produce a menu allowing you to choose which you'd like to use. But this is much more of a proof of concept deal. Anyway the output:

The extended edition

Now the script can be tinkered with to our hearts extent and the exutable will show those changes without having to be run. Of course it's a lot more powerful than it is here. We can uses Lua's code constructs like loops and structures and all those niceities - wasn't putting a scripting engine in really simple? :o


Now you should brush up your Lua!


Globals



Lua is simple and powerful I just wanted to show persistancy of globals then maybe we'll end this tutorial here. But later come back to really really groovy things like coroutines.

  
static void Main(string[] args)
{
Class1 c1 = new Class1();

Lua lua = new Lua();

lua.DoFile("scripts/Thursdays.txt");

string b = (string) lua["name"];
Console.WriteLine("Name:" + b);
Console.ReadLine();

}


If in Thursdays.txt we now include the line name = "rabbits" then the above code will outpt rabbits. See the scope isn't lost in the file which is super groovy and allows us to easily insert scripts into the game loop - yay!

Source Code


Download the source code.

References used



  • LuaInterface: User’s Guide by Fabio Mascarenhas

  • LUA 5.0 Reference Manual (avaliable from www.lua.org)

Tuesday, May 16, 2006

Tomorrow is today!

I've been a bit lax with EINFALL of late, so I thought this morning I hit up my todo list and see what I could accomplish. Not much is the answer :D

There's some bugs in the world selection screen - bugs with worlds being named incorrectly (probably very simple bug, but that doesn't mean it doesn't need fixing). Oh and the world displays themselves tend to mess up after you've played on the world. So I very much want to fix both those bugs.

This morning I only followed the execution chain to find out where the worlds are loaded and to make sure I wasn't doing anything stupid in the intialization. So far so good. I rewrote one function. I may continue tomorrow morning.

Monday, May 15, 2006

A game is a series of interesting choices

So Sid Meier tell's us, and he should know! He's developed some excellent games. Of course I don't think he intended to include all games in this definition, rather just the one's he likes. (Remember that sports game on the ... nes? You had to keep pounding and mashing the controller buttons to make your guy run fast or throw the hammer far or whatever - strangely fun, perhaps only to nine years but still no choices there.)

I thought, "Well, interesting choices?" how about we take that to it's logical, if rather extreme conclusion. You're given a description and then three choices to choose from.


[Description]
1. Interesting Choice 1
2. Interesting Choice 2
3. Interesting Choice 3


Even more limited than a text game! It's a belief of mine that constraints actually encourage creativity. In fact let me show you that this game can infact be more powerful than a text game. Please withhold your gasps of utter astonishment.


You're in your room, your bed to more precise.
The covers are warm, and covered in vomit.
The vomit is cold.
Your head is throbbing in an almost pleasant way.

1. Open the nightstand and grab the asprin.
2. Grab the phone you can see on the floor and call Angela.
3. Stand up fast, hold hands to face and realize what happened last night.


Who's Angela? We don't know! Ooh! But we can still pick it, I guess that makes it an interesting choice. Getting the asprin isn't really an interesting choice - maybe rewrite that one. Still the extra information we get in the choices is something we could never know in the supposed freedom of a text game.

I'd be suprised if such games don't exist already. (Just in case they don't I hereby name then "Dan's Wonderful Gaming Insight Games" or the simpler if somewhat hard to pronounce DWGIG :D )

So I started coding up a simple console based version, that will function as both an editor and player. Once I finish it - finally a project that's on a scale simple enough that I can finish - I'll upload it with some example games.

EDIT:

Here's a simple editor and a single interesting choice that isn't resolved - sorry :D I'll probably play with this at school and then upload what I come up with.

EDIT 2:
I forgot to mention but I finished my path finding library and it works rather well. I may upload it here at some point - probably in the distant future when I move to a different type of blog.

Sunday, May 14, 2006

Type and C# and Switching

Ladies, gentlemen, sometimes we want to switch on type but we can't do it.

Let's say you have a messaging system and you want to send messages to your entities. Also you want to be able to add as many messages as you want without changing any code. Well then you might use a message or dispatch system.


switch(entityMessage.GetType())
{
case typeOf(MessagePoke):
{
MessagePoke poke = (MessagePoke)entityMessage;

if(poke.PokedBy == "A magic wand")
{
TurnIntoAFrog();
}
}

case typeOf(messageTalkTo)...
case typeOf(messageSetOnFire)...
case typeOf(messageMusicPlaying)...
case typeOf(messageWeatherConditions)...

default:
{
//just ignore the message
}
}


The entity just chooses which messages it will recognise and handles them. (I mentioned this in passing on a comment on a gamedev blog by Trapper Zoid - here. See the very last comment by Balaam.)

So let's say you want the above - where messages are classes and you want to handle certain messages according to whatever class they are. Well then we want to swap on type but in C# you can't swap on type.

We can't swap on type? Why? Well there is a fine article that explains why here.

So how can we do the switch? We can switch on strings, so we can switch on the class name and possibly the namespace if we want to support lots and lots of message like the below code:


interface Messsage { ... }

namespace WeaponMessages
{
touchedBy : Message { ... }
}

namespace SocialMessages
{
touchedBy : Message { ... }
}


So if we want the full namespace of the object.


object.GetType().FullName; //WeaponMessages.TouchedBy [lots of extra information]


If we want the just the name


object.GetType().Name; //TouchedBy


Are we having fun yet?

If we want the string from the actually class then we code, like so.


typeOf(TouchedBy).FullName;
typeOf(TouchedBy).Name;


And with that we can form a dispatch or message system. Let's rewrite the the example we had at the start.


switch(enityMessage.GetType().Name)
{
case "MessagePoke":
{
MessagePoke poke = (MessagePoke)enityMessage;

if(poke.PokedBy == "A magic wand")
{
TurnIntoAFrog();
}
}

case "MessageTalkTo"...
case "MessageSetOnFire"...
case "MessageMusicPlaying"...
case "MessageWeatherConditions"...

default:
{
//just ignore the message
}
}


What's with the constant strings? Why don't we write typeof(messageTalkTo).Name? Well, it's not "constant", it could change! Therefore we need to write out the strings.

And that's how you could do a dispatch message system. Next post will probably be why you might want a message system.

Wednesday, May 10, 2006

A spaniard in the making

I continue to fool around with the path finding library.

Last time the library required you pass in a list of nodes. Nodes can be through to be tiles, in games like FFT, Advance Wars, Civilization or planets in games like master of orion.

The only thing I required of these nodes was that they knew their neighbours. But this proved to be a problem. Generally in tile based games a single tile does not know it's neighbours. So that meant to use the function - all tiles had to be translated to some intermediate state that did know about neighbouring tiles. Potenitally a rather time consuming translation.

This is how it currently works. But I've decided a much better way is to require two objects 1.) The Nodes 2.) The Node Neighbour Knower.

The Node Neighbour Knower knows when give a node, what those tiles neighbours are. This makes much more sense. Even if all the nodes knew their neighbours it's easy to write a small Node Neighbour Knower class that calls the nodes neighbours function. Ha say that seven times quickly. Where maps know about neighbours rather than tiles, as is probably the more common case, then we can just make the map implement INodeNeighbourKnower and not worry about costly transformations. Cheers all round.

I have several small game ideas perculating you can be sure in the year 2760 when I finsh EINFALL, that I will then make a smaller, rather than larger game.

Recently I added the tag "gamedev" to my del.icio.us inbox and it's really started to pick up a lot more sites. If only so much of what is to be read on the web wasn't rubbish.

I'm going to alter the code in my path finding library and then I'm going to bed.

EDIT:
My path-finding library is absoulutely generic mad. Luckily most of my generic flourishes are invisible to the library user. Still need to actually put some pathfinding in there :D

Oh and I booted up EINFALL and when in search of the city - to find it nicely generated, so that's good. It's very basic, so basic I'm not actually going to put up screen shots :D

This weekend I'm going to be pretty buzy but hopefully I'll get some time sunday. I want to build up my path finding library (this isn't getting sidetracked, as EINFALL will need it later) and probably trying to remove the tearing in EINFALL - this will probably done by stepping through the code and seeing what it does, I imagine this will be eye opening. I have VTune installed but I have no idea how to use it.

Tuesday, May 09, 2006

anyone can now access the datasphere

Recently I've been playing with path finding and building a path finding library in C#.

I'm really not sure how good it is - it's modular, Final Fantasy Tactics and Master of Orion could both use it but it requires some massaging of the data. Still poking at it, haven't made any decisions yet. I'll probably document it here when I do.

Oh I finished code complete, a while back. Excellent book. I recommend it.

Supposedly the game's generating cities and using the correct textures. Once I confirm this is actually this case. I'll upload a screen shot, that will show dissapointing building outlines :D then I'll get to work on making the menu more robust - it does some strange things now and again.

Oh and totally replacing the tile too.

I've read nothing too interesting lately :( I really must finish the mathematics book :D

Thursday, May 04, 2006

Legs are made of food.

It suddenly becomes clear why cities aren't being created.



public void Write(ITileMapCommand command)
{
// Use region data and construction knowledge and shell map

//DANGER
// For now we always assume the center of city
// There's no method at all for using other shellmaps that
// the city might cover.
//DANGER

// Need access to the shellmap.

}


No code!

EDIT: Going to be in Osaka for the next few days.

Wednesday, May 03, 2006

Of course nothing like that happened.

Hey look what I wrote over here.

This morning I got multi textures sets loading on single maps. The tile maps load / save code is pretty hacky but it works. It will stripped out and soon and replaced with serialization. World creation is working again but the cities while being built don't seem to appearing - something to look into.

... oh maybe because I'm adding the tile textures only after the tiles are created! Might try that now.