I moved to a new URL! Check it out!

posts tagged with: csharp

Dev Log: More Data Driving

Dev Log: More Data Driving
How far is too far when it comes to making data driven code? Right now I'm wrestling with this question. I have a bunch of stuff defined in my xml which is all well and good for some parts of this game, but then I came to think of spells and abilities and how to make them data driven... but I think to truly do that would require some sort of scripting!

I was looking into Lua or using some form of Python for scripting in my game, but ultimately I've decided to hold off on that sort of thing. It sounds really fun, especially when I start to consider the modding possibilities of a game that uses a lot of scripting and data driven stuff... but it feels like a large burden to take on very early on in a project (even though getting Lua set up in C# is incredibly easy!)

As I slowly pick away at these systems everything is becoming a little bit more clear with each day of work. I'm still learning the ins and outs of C# and the power of reflection. One thing I started looking into today is custom attributes. It seems like a powerful way to combine data driven and engine driven stuff into one. I think by using custom attributes I could define a lot of data right in a class itself, and I would be mostly doing this in instances where I wouldn't want this kind of data exposed to the end user.

For example right now I have my stat class set up with a Dictionary where the enum StatType is the key, and a float is the value. This is all fine, but it means that in the constructor of my stat manager class I have to define all of those stats by doing Add(StatType, value) a bunch of times. An alternative way to do this might be to define the stats as just floats in the class itself, and apply custom attributes to each one like [Stat] or [CoreStat] or [DerivedStat]. I'm going to spend a little time experimenting with this stuff and we'll see how it turns out!

Dev Log: Fun with Stats

Dev Log: Fun with Stats
I haven't made much progress on my system to set up triggers and actions for Enchantments, but I did make some progress on my player stats system. I coded up a pretty generic Stat class that allows StatMods to be applied. Check it out!
class Stat {

public float BaseValue;
public string Name;

public bool Capped;
public float Cap;

public List<StatMod> StatMods { get; private set; }

bool needsUpdate = false;
float cachedValue;

public Stat(string name, float basevalue = 0) {
Name = name;
BaseValue = basevalue;
Cap = BaseValue * 2;
StatMods = new List<StatMod>();
cachedValue = basevalue;
}

public Stat(float basevalue) : this("", basevalue) { }

public StatMod AddMod(StatMod mod) {
StatMods.Add(mod);
needsUpdate = true;
return mod;
}

public StatMod RemoveMod(StatMod mod) {
StatMods.Remove(mod);
needsUpdate = true;
return mod;
}

public void ClearMods() {
StatMods.Clear();
cachedValue = BaseValue;
}

public float FinalValue {
get {
if (needsUpdate) {
float v = BaseValue;
var m = 1;
foreach (var s in StatMods) {
v += s.Add;
}
foreach (var s in StatMods) {
v += BaseValue * s.Multiply;
}
cachedValue = v;
needsUpdate = false;
}
if (Capped && cachedValue > Cap) return Cap;
return cachedValue;
}
}

public static implicit operator float(Stat stat) {
return stat.FinalValue;
}


}

class StatMod {
public float Multiply = 1;
public float Add;

public StatMod(float add = 0, float multiply = 0) {
Multiply = multiply;
Add = add;
}
}
I'll probably add this into the Utility folder of Otter at some point. Basically you can make a stat, like new Stat(10), then apply modifiers and get the final modified value back. You can also treat it as a float and it will spit out the modified value as well.

Multiply might not work the way you think at first though. Setting Multiply to 1 in a StatMod actually means to Add 100% of the stat to itself. For example, a stat of 100 with a multiplier mod of 1 will calculate as 200. It's as if the mod is saying "BaseStat +100%" when you set it to 1. So 0.5f would be interpreted as +50%, -0.5f would be -50%, and so on.

Modifiers will always be applied with addition, then multiplication. For example if a stat had a base value of 100, and then you apply a modifier with Add set to 50, and then another modifier with Multiply set to 1, then the final result will be 300. It applies the +50, and then the +100%. It doesn't matter which order they're applied in.

Now I'll get back to work on my dumb trigger and action system that I have no idea how to implement right now, yahoo!

More Otter Updates

More Otter Updates
Whoops! I really let myself go on the blog updating schedule. I've been still cranking away at some updates for Otter.

Image

The latest update that I've pushed includes some new stuff for rendering Images. Images can now be drawn by using only a specific source rectangle from the Image with the function Draw.ImagePart(). This resulted in me also making Draw.ImageWaveX() and Draw.ImageWaveY(). You can see those two functions in action up there in that image. Yeah, I know a shader can also do this, but I thought it'd be fun to do it an old fashioned way as well.

I've gone through and fixed some bugs in the new StateMachine<>() class as well. The new StateMachine<> lets you use any key you want to keep track of states, and if you use an enum for the states then it will automatically populate the states from the names of the enums and the matching names of functions. For example, if you have an enum with the name "Walking" the StateMachine will look for functions named "EnterWalking" "UpdateWalking" and "ExitWalking" to correspond with that state. This means less boilerplate code for getting a state machine up and running.

There's been some other minor clean up of bugs and I've been tinkering with things as I chip away at my next big project. The latest version of Otter is always available here. I wonder if anyone will use it for the upcoming Ludum Dare! That would be super cool.

Otter Updates: Rich Text

Otter Updates: Rich Text
The RichText class I posted about is now available in the latest update for Otter. That means you can do things like this:

Image

With just a string with mark up codes, like this:

"{shadow:2}I can levitate {color:f00}birds{color:fff} but {waveAmpY:5}{waveRate:5}nobody cares..."

Also included in the latest update are a bunch of minor fixes for things that I've stumbled across, and also a minor change in how the update loop works... if this breaks anything then I'll change it back, but so far it looks fine.

The other thing I added in these latest updates is the PixelCollider class. So far the PixelCollider can only work against other PixelCollders, BoxColliders, and GridColliders. I'll be adding the other types of collision soon, but for now that should be enough to get by on for most cases where you want to use pixel colliders.

You can find Otter on the internet, and if you're using it you should totally register and post in the forums!

All the King's Men

All the King's Men
Over the weekend I went to a local game jam in Phoenix to try out making a game using Otter. I was fully prepared to face the reality that Otter would have major problems preventing me from using it for this jam... but everything turned out way better than I expected. Check out the first game ever made using Otter!

Download


All the King's Men v1.0 - Windows (6mb)

Apologies to Mac and Linux people, I don't have a solid way to get builds for anything but Windows right now.

There's a readme included in the download that has some more info in it as well.

Screenshots


Image


Image


Image


What's Next


Eventually I would like to open source All the King's Men, but right now I need to figure out what kind of license I should use for it. Open sourcing a game is a little different than open sourcing a framework. I want to maintain control of the distribution of the game, but also allow people to look at and use the code for their own projects. Basically I just don't want people to edit the game slightly and then re-release it as their own work, or something sneaky like that. I'm sure whatever license I choose won't actually prevent that from happening if someone really wants to do that, but I guess I would still feel slightly better by using the right thing.

I also recorded a time lapse of the production of the game during the 48 hour game jam, so once I put that together I'll release that as well!

If you have any feedback then leave a comment, or stop over to the Otter forums.

Otter Updates: Effects!

Otter Updates: Effects!
Another round of Otter updates are here! I'm getting ready to go to a game jam for the weekend so I wanted to make sure I was equipped for making rad special effects for whatever I end up making (if I end up making a game, even.)

Image


* Added the Particle entity. It can be used to easily create particles with simple effects.

* Added the Flash entity. It can be used to easily create screen flashes.

* Added the ImageSet graphic. This is used by the Particle entity right now. Think of it as a very very simple SpriteMap. You can render one image from a set of images (a sprite sheet) but there's no automatic animations.

* Added various window options to the Game class.

I have a few more fixes I want to do before the jam starts including a small fix to the Axis class and possibly changes to the StateMachine class to use enums for states, but I don't know if I'll be able to get to those before the jam starts in just a couple hours.