Wednesday, December 5, 2012

When relative paths go bad

Problem:
Relative urls on your website are suddenly using the wrong domain.

Cause:
It’s XSS (sort of).
<base> element will change the target of all relative urls on the page.
<base> is supposed to be in <head>, but Chrome (and possibly other browsers) will respect it when in <body>.

Solution:
Add <base> to the blacklisted elements on all of your user inputs.
Check existing user content. 
Use absolute urls.

Monday, November 19, 2012

BlogPost blogPost = BlogPostFactory.MakeBlogPost(NewBlogPostOptions.BlogPostWithAbsurdTitle)

Don't leak useless implementation details in your variable, method, or class names. Just don't.

Sure, the name may be accurate and true, but so what? I don't need to see the class name 5 times in one line - that just clutters up the place. It also makes it harder to see similarities in code and opportunities for refactoring. These kinds of names also go against the entire point of polymorphism: you don't need to know the type, just it's capabilities. Hungarian notation obviously falls into this category of cluttering up the place with implementation details. I rarely need to know the exact type or inner working of something. What I need to know is the intent.

There is one place where a name should leak implementation details though: choosing a strategy. Not just the Strategy Pattern, but even between different methods that all do the same thing but in a different way. I'm thinking of things like depthFirst vs breadthFirst, MaximizeBenefitStrategy vs MinimizeCostStrategy vs MinimizeRiskStrategy, or calculateLevenshteinDistance vs calculateJaroWinklerDistance. These seem like good implementation leaking names to me since when I choose one, I need to choose the exact details. Of course they could be wrapped in intention revealing names which would be used most of the time:

public double PercentSimilarTo(this string myself, string other)
{
    var longest = (double)Math.Max(myself.Length, other.Length);
    return EditDistanceCalculations.CalculateLevenshteinDistance(myself, other) / longest;
}


Try it for a few weeks and see what happens. I think that replacing implementation revealing names with intention revealing names is one of the easiest ways to improve code.

var p = new Bp()

Don't use abbreviations in your variable, method, or class names. Just don't.

Sure, you save 2 or 3 seconds, and a few characters on the screen, but so what? You, or whoever is looking through your code, loose even more time when you have to look around to find out that cs is an array of Customers. Then you have to spend time trying to figure out why you have this array. Are they delinquent customers? New customers? Customers who have a birthday today? What's the intent of this thing? This is especially bad with primitives or collections of primitives because they have even less inherent meaning. It's also bad when the same variable is used for multiple things. If cs is an array of customer indexes on one line, an array of page numbers on another, and x, y, and z coordinates for an airplane on another line then you can't give it a good name and it should be split into three separate variables: customerIndexes, pageNumbers, and airplaneCoordinate.

Worst names:
cs
arr
sb
awos

Bad names:
custs
array
stringBuilder
accounts

Good names:
birthdaysToday
selectedIndexes
warningMessage
accountsWithoutOwners


A name is more than just a unique identifier: it's a way to express intent and meaning. The compiler doesn't care what you use - it's just as fine with zhqxv as it is with unwantedLocationNames - but I know which one I'd prefer.

I can only think of one reason to have a one character or abbreviated name: if it's a well known and commonly accepted part of that domain. Gui and hud may be acceptable names within a user interface domain and x and y sound acceptable when talking about cartesian coordinates. If you look at it a certain way, i and j could be considered valid names within the "looping through a collection with an index" domain, but even then, there's probably a better name.

Try it for a few weeks and see what happens. I think that replacing abbreviations with real, intention revealing names is one of the easiest ways to improve code.

Wednesday, October 31, 2012

What's next?

When planning ahead or deciding what to do next, how do you choose?

Work stack
By work stack I mean that when you think of something new, start working on it; when you're done, go back to what you were working on. If you've ever worked with someone who bursts into the room and shouts with joy, "I just got a great idea! Drop everything and work on this now!" then you'll be familiar with the result: you end up going nowhere. These constant interruptions are highly disruptive and cause unfocused thrashing and churning. The product owner doesn't get what they want because their next idea interrupts any progress on the current idea and they don't get what they need because the focus is always on something else. Most of the time is wasted on incomplete, buggy, useless features. I have nothing positive to say about doing things this way because in my experience, it's by far the most wasteful. This is like trying to swim across a river by jumping in and moving your arms and legs in every direction as fast as you can: you might make it across but you'll probably just suffer and die.

There's also a more subtle and personal work stack too. This is where you see something near what you're working on and you decide to take a short detour to fix it or clean it up. If you're especially prone to this then you can end up wandering from one little detour to another and not accomplishing what you set out to do. I've found that I've gotten much better at avoiding this by focusing on finishing one feature before starting on another and setting aside time specifically to refactor and payoff technical debt.

Work queue
A work queue is the opposite: new ideas are added to the end of the list and you'll get to it after you finish everything before it. This sounds a lot like Big Design Up Front and suffers the main drawback too: solutions you come up with probably will be bad since you know the least at the beginning of the project. If you have a long list then when you learn something new, it will be a long time until you can benefit from it. I think human nature and our eagerness to implement new ideas makes it just about impossible to stick to this method - which is for the best.

Horizontal slice: Front end first
You could try the tiered architecture approach and do the outside first. This gives early visible progress but there's a lack of functional progress. Unfortunately, non technical people often don't see the difference between "gui is done" and "app is done". Having such a large disconnect between the customer and team is a recipe for disaster.

Horizontal slice: Back end first
You could try the tiered architecture approach and do the outside first. This gives early functional progress but there's a lack of visible progress. Very few users understand the difference between "non existent app" and "98% of the use cases have passing automated tests". If the person paying your bills doesn't think they're getting anything for their money then it doesn't matter how close you are to really being done because you won't get a chance to finish.

Minimum cost
How about doing the smallest and easiest things first? This has a lot of good things going for it: you make quick and early progress, you're always doing the easiest work available, and you'll probably spend most of your time on things you enjoy and are good at. But as you go you'll find that everything becomes more difficult and risky since you've been putting it off. You may not have a usable product for a long time and what you do have will probably be missing important functionality. Or you can spend a lot of time and only too late discover that the hard parts will be too expensive and the whole thing was a waste of time. Unfortunately for those who prefer the easy way, the hard parts are often what solve the real problem and make software worth it.

Maximum cost
How about doing the most difficult or risky things first? This also has a lot of good things going for it: solving hard problems (or even working on them) can boost morale, you reduce risk over time, the pieces you work on will become easier over time, and if it's too difficult, risky, or expensive you cut your losses before making a huge investment. But there are downsides. Just like when working the minimum cost first, you may not have a usable product for a long time and what you do have will probably be missing important functionality. You'll also be making a lot of long term solutions to hard problems that may be bad since you know the least at the beginning of the project. And possibly the biggest drawback is that difficult problems require skilled teams with skilled people who work well together, which you may not have at the beginning.

Important and urgent first
It seems like thinking about things first works best so far. Hopefully that's not too surprising. Maybe we should try using two variables to categorize things instead of putting things on a high-to-low, inside-to-outside, or newest-to-oldest spectrum? You could use an importance and urgency matrix with 4 quadrants: high importance and high urgency, high importance and low urgency, low importance and high urgency, and low importance and low urgency. Everything that needs to be done is placed in one of those quadrants and you come up with some rules about working the important before the non-important and the urgent before the non-urgent. Sounds good in theory but from what I've seen, it really devolves into two categories: "get to it when we can" and "ignore". Eventually someone will say "this is very high importance!" and someone else will say their task is "critical importance" and another becomes "ultra critical importance" and before you know it, you get importance inflation where the only way to get something worked on is to say we're all going to die unless it gets done by tomorrow. Unfortunately, the difference between Important and Urgent (and sometimes even Nice To Have, or Just Putting Words Together With No Clear Thoughts) seems impossible for some people to understand.

Maximum value
Take your to do list, order it by how much value you'll get from each thing, and call it a backlog. By focusing on the most valuable things first you'll get usable software sooner and as we know, "working software is the primary measure of progress." One of the best things about the list as a developer is that the opportunity cost is clear and can't really be argued. Lets say someone tells me that a certain issue needs to be handled asap. Since two things can't be at the top of the list at the same time, I can ask them what items I should move down the list to make room for it. Should I delay the bugfix that's costing us thousands of dollars a day? How about the feature that the CIO himself asks be about each morning and evening? Or maybe the feature that will prevent our largest client from leaving in a month? Suddenly their request isn't as important as they thought is was. The biggest downsides are that deciding the relative value of things takes discipline and knowledge and that some clients have an all or nothing mentality. The idea that even the tiniest feature might be left out or is less valuable is unacceptable to them.


I've found that I'm most productive and happy when I change it up to maintain flow. I'm almost always trying to focus on maximum value but sometimes visible progress, easy wins, or tackling tough problems soon is important. After all, working software is the primary measure of progress but not the only.

Saturday, October 20, 2012

October 2012 challenge, Day 20

Well, I failed.

I got the core mechanics and everything done in just a couple days but I only had a few hours a week to work on music, sounds, graphics, and extra content. That just didn't happen. So, as tough as it is for me, I've admitted that I should cut my losses and stop worrying about it.

Retrospective time!

I should start learning the language, tool chain, graphics, music, and sound before committing to a project. I hadn't used haxe before (but I'm somewhat familiar with Actionscript) so the language, libraries, and compilation process and quirks took some time to get. Despite 6 or so years of piano lessons, I don't know anything about making good computer music either. Pixel graphics wouldn't fit the theme and good looking graphics are beyond what I can do. I had some good luck with procedurally generated plant graphics, but couldn't quite integrate it with my game code due to how the rendering code worked.

I should stop planning on spending all of my time working on a project with so many unknowns . I have less time than I expected and it's not sustainable. After a week of nothing but work, sleep, and this project, my place was a mess and it was hard to stay focused. If I picked a smaller project - like a platformer or turn based strategy - then I think I would have had a better chance of finishing. I can do old-school graphics and sound effects so that's what I should stick to.

I should continue writing well factored code and trying short term projects like this. Breaking it down into pieces that I could prioritize and implement in a couple hours helped me get started and make early progress. The simple and clean code meant that I could change my mind, try something different, and generally make progress much faster than some of the messier code bases I've crapped out.

If I follow these simple plans, then I'll be much better equipped for the next ludum dare.

Wednesday, October 10, 2012

October 2012 challenge, Day 10

I only had a few hours to program over the weekend but I managed to get saving and continuing to work - which took much longer than I expected. If you're looking for advice on how to save objects to the SharedObject with Flash or haxe and nme, I ended up relying on the Memento Pattern.

Here's the relevant part of the Fruit class:

public function toMemento():Dynamic
{
 return {
  x:x,
  y:y,
  vx:velocity.x,
  vy:velocity.y,
  maxSpeed: maxSpeed,
  maxAge: maxAge,
  type: type,
  plantType: plantType,
  age: age,
 };
}

public static function fromMemento(o:Dynamic):Fruit
{
 var c = new Fruit(o.x, o.y, o.type);
 c.velocity.x = o.vx;
 c.velocity.y = o.vy;
 c.maxSpeed = o.maxSpeed;
 c.maxAge = o.maxAge;
 c.age = o.age;
 c.plantType = o.plantType;
 return c;
}

One place where this was tricky was with the creatures' needs. Each creature has a list of needs that implement the Need interface. Since I don't know the real class at design time, it has to be handled differently. When creating the memento for needs, the class name is included and when converting the memento to the real object, a separate class takes the memento, looks at the need field, and has a switch statement that tells the appropriate class to create an instance from the memento. Here's the relevant part of the NeedToEatFruit class:

public function toMemento():Dynamic
{
 return {
  need: "NeedToEatFruit",
  target: target == null ? null : target.toMemento(),
 }
}

public static function fromMemento(o:Dynamic):Need
{
 var n = new NeedToEatFruit();
 n.target = o.target == null ? null : Fruit.fromMemento(o.target);
 return n;
}

Apart from that, I made some simple placeholder graphics for the plants and got the basic plant lifecycle to work. There's twelve species of plants. Some float to the surface, some are buoyant enough to float around, and others are planted in place. The simple ones are just a sprite but the more complex ones grow separate leaves. They can reproduce by budding, spores, seeds, or fruit. When a fruit-eating animal eats a fruit, it will wait 5 seconds or so then drop a seed of that plant. And that's why the Creature class has a pooCountdown field.
Next up is animal graphics, lifecycle, and more needs as well as changing the world structure. It's currently Perlin noise but when targeting the mac, it runs out of memory trying to make it. Really odd.

Friday, October 5, 2012

October 2012 challenge, Day 5

If you look at it a certain way, then I'm almost done. If you look at it the real way, then all that's left is the stuff I'm not good at.

After some late night work, pre-work work, and lunchtime work, I've got the core ideas working so now it's mostly a matter of adding content (graphics, sound, music, more game objects, etc) and fine tuning it. I'm sure there will be a round of performance optimizations, a round of cross-platform hacks, a round of feedback from beta testers, a round of panicked hacking, and a round of October 30th surprises. But not today. Today is good.

I don't want to give away too much of what the game is about (October is only 17% done after all) but here's the AI for other creatures:

package;

class CreatureController
{
 public function new()
 {

 }

 public function update(creature:Creature):Void
 {
  var lowestScore = 1.0;
  var lowestNeed = creature.needs[0];

  for (i in 0 ... creature.needs.length)
  {
   if (creature.needScores[i] > lowestScore)
    continue;

   lowestScore = creature.needScores[i];
   lowestNeed = creature.needs[i];
  }

  lowestNeed.update(creature);
 }
}

And here's a screenshot:

It's hard to see but there's two different background colors. The large squares are plants, the medium squares are animals, and the tiny squares are fruits. The green bar is your happiness. Later the squares will be things that look like what they are.

Thursday, October 4, 2012

October Ludum Dare challenge accepted

"Make a game — Take it to Market — Earn $1"

I'm in. I just got haxe setup on my computer and I'm ready to start working on an idea I've had for some time.

Things I still need to do:

  1. Make the game.
  2. Make it not suck.
  3. Make it look good.
  4. Make it sound good.
  5. Make an attractive website for it.
  6. Make sure it works on iPhone, iPad, and Android.
  7. Submit to the Apple App Store.
  8. Submit to the Android Market.
  9. Submit to some flash game site.
That's only nine things. I can do nine things in one month.

Thursday, August 30, 2012

Objectives that don't suck

It seems that most résumés have a generic objective copied from one of many "how to write a résumé" articles. You know the kind; "To utilize and expand my skills in blah blah blah". I think that's lame. Why start your résumé with some vague cookie-cutter bullshit that you copy-and-paste then forget about? My objective is "To work on a project that users want to use and maintainers want to maintain.". It's nothing fancy but it's honest and to the point and I actually believe it. I'm glad when something I create is useful to others and they want to use it. I'm glad when someone, usually myself or a coworker, is able to extend or change it to do something else.

But not everyone wants those things. Recent experiences with clients who are more concerned with making sure the software looks like it works rather than actually works reminded me that working software is the primary measure of progress. Because of that, I updated my objective to say "To create working software that users want to use and maintainers want to maintain." Even more true and even more to the point. And that's something I care about.

What's your resume objective? Do you actually believe it and try to live up to it?

Friday, August 24, 2012

Easier object setup in ActionScript

I recently thought of something that will make it easier when I'm creating instances with different values in ActionScript and thought I'd share it. It's sort of a mix of default parameter values and optional parameters and it makes it much more convenient to setup instances of things that are slightly different.

Let's suppose I have a Weapon class with some basic stats:

class Weapon
{
 public var name:String;
 public var attack:int    = 10;
 public var defense:int   = 10;
 public var speed:Number  = 1.0;
 public var heavy:Boolean = false;
 public var tags:Array    = ["weapon"];
 
 /* skipping constructor and a "describe" function that prints the values */
}

And assume I have some other code that creates a bunch of instances. They're mostly the same but ideally I could just specify what's different than the default. Something like this:

var weapons:Array = [
 new Weapon("stick"),
 new Weapon("sword", { attack: +2, defense: +2 } ),
 new Weapon("club",  { speed: -0.25, heavy: true } ),
 new Weapon("knife", { attack: -2, tags: ["sharp"] } )
];

for each (var weapon:Weapon in weapons)
 trace(weapon.describe());

It would be really cool if I could get something like this as the output:

stick = { attack=10, defense=10, speed=1, heavy=false, tags=weapon}
sword = { attack=12, defense=12, speed=1, heavy=false, tags=weapon}
club = { attack=10, defense=10, speed=0.75, heavy=true, tags=weapon}
knife = { attack=8, defense=10, speed=1, heavy=false, tags=weapon,sharp}

Well, wish no more because it's possible. Here's the function that makes it happen. It takes two things and expands the first by the second. It could be improved to handle other types, but this is enough to get started with.

public function expand(receiver:Object, expansions:Object):Object
{
 if (receiver == null || expansions == null)
  return receiver;
  
 for (var property:String in expansions)
 {
  if (receiver[property] == null)
   continue;
  
  var value:Object = expansions[property];
  
  if (value is Number || value is int)
  {
   receiver[property] += value;
  }
  else if (value is Array)
  {
   for each (var element:Object in value)
    receiver[property].push(element);
  }
  else
  {
   receiver[property] = value;
  }
 }
 
 return receiver;
}

Just use it in the constructor or some section external to the object like a Factory.

public function Weapon(name:String, values:Object = null)
{
 this.name = name;
 Util.expand(this, values);
}

I'm sure I'm not the first to do something like this but I think it's a more convenient way to create things. If I ever find myself working on a 7 day long project and need a quick way to add content, this could be useful....

Sunday, July 29, 2012

Notes for the next Game Jam I go to

I'm rarely a fan of posts that are in list form (e.g. "Top 10 tips for writing top 10 lists") but I seem to be in "list making mode" right now so expect some lists in this post.



I recently went to a local Game Jam. What's a game jam? I'd describe it as an event where people meet and come together to attempt to prototype an innovative game idea, fiting a common theme, and then share their results, no matter how embarrassingly incomplete, with others. All within a few hours.

Here's what I wanted to get out of it, from most important to least important:
  1. Meet cool people. I program at home and with coworkers all the time; this is a chance to meet others.
  2. Work together. I can work by myself any day.
  3. Fit a theme. I can follow my own ideas any day.
  4. Prototype a mechanic or idea. Because doing something boring is boring.
  5. See something cool. It can be really inspiring to see something created in such a short time.
  6. Show something cool. I need to share what I come up with more often.
  7. Make a game. Another thing I can do on my own time.
  8. Network/connect. If it happens, it happens; if not, I'm fine without it.

I'm sure everyone has their own criteria and there's probably someone with the exact opposite list writing a blog post right now about how they went to a game jam and ran into someone who spent all his time socializing and coding and didn't even bring business cards to hand out.

I certainly met some cool people, saw some really neat games, and even got a few business cards from other local developers and artists. The other things? Well... maybe next time. I was looking at the team I was on and the other teams and it seems like there's three things you need to do to accomplish the things on my list:
  • Pick an acceptable team
  • Pick an acceptable idea
  • Contribute

Notice I said "acceptable" team and idea. Not even "great", not even "good", just acceptable. You only have a few hours and everyone there will be quite impressed if your game is a slight variation of "avoid the red squares and collide with the green squares."

If those three things can make a gam jam experience good, then I suppose the opposite would probably lead to a less fun time:
  • Actively break up the team
  • Push or accept an idea that totaly misses the point of a game jam
  • Contribute nothing but your dumb idea

Yup, those were the three things I ran into. I suppose I should have stepped up and tried to keep the team together, make sure we we're doing something worth doing, and make sure everyone had something to do. So, if you're the proactive type of person, the three things you really need to do to prevent someone from sabotaging your efforts to accomplish the things on my list are:
  • Pick (and maintain) an acceptable team
  • Pick (and maintain) an acceptable idea
  • Contribute (and help others)

Here's another list of random observations:
  • UnityScript sucks. Not thoroughly statically typed, not thoroughly dynamically typed. If you have to explicitly cast every time you get something from an array then your language has the worst of both worlds. And that's the easy way. I had to sum an array of floats and since floats are primitive, I couldn't cast them. I looked online for about 15 minutes and in the end, I had to convert the object to a string then parse it as a float.
  • Pick a team you can quickly get started with. When you only have 6 hours you don't want to spend the first 2.5 hours downloading and setting up Unity and Dropbox.
  • Teams that stick to the spirit of game jam do better than people sitting near each other half-working toward a dumb idea.
  • Dropbox sharing made integration easy but also more painful: you constantly get updates in the background but when someone is stuck on a compiler error or obvious bug, everyone knows within thirty seconds. Ultimately, instant feedback, and help from others, was a better way of maintaining progress on such a short iteration.
  • Control-z is good enough version control if you're only programming for one session.
  • Unity may be better for weeklong or monthlong jams, but not good at all for 6 hour jams. The best games used Flixel.
  • Working in teams would be better without all the other people. I really hate to say it but I've never been a fan of teamwork and it rarely works out. Sometimes it does, but the end results are mostly beyond my influence and usually disappointing. It always reminds me of high school group projects.
  • Whatever you create is going to be buggy and incomplete and almost certainly not even fun. That's ok. Everyone there is in the same situation and we're all there to have a good time. There was definitely an air of cooperation and support. It was fun and strangely adventurous to see what so many small groups of people could come up with under such constraints.


I still plan on going to the next game jam in my area - I'm just going to do it differently.

Monday, June 18, 2012

Continuous Deployment: Doing the mundane several times a day

I'm a huge fan of Continuous Integration, as well as Continuous Delivery, and I think it should be used to it's full advantage - especially in enterprise or other non-trivial projects. Even if you can't do the impossible 50 times a day, you can reap the benefits with fairly low effort. Here's how I managed to do the mundane several times a day.



I recently got a new job and one of the things I did on my very first day was set up a Continuous Integration server. Most of them support similar features but I chose Jenkins because it seems like the most popular open source choice. Jenkins was a breeze to work with. Just download it, install it, start it from the command line, and point your web browser at it. You can add new projects, configure it, download new plugins, and even install it as a Windows service right from the web page. Easy-peasy.

The first thing I did was automate the build process for the project I inherited. Just a batch file that told MsBuild to rebuild the entire solution.

After that I set up a very basic integration job for the project I inherited. Initially the Jenkins job just compiled the project but after a couple days I added a file with two solution-wide msbuild targets: one for the developers that calls code inspection tools and prints the results to the console and one for the integration server that does the same code inspection then dumps the results to an xml file. Once you download the Violations plugin and configure your Jenkins job, it will show a nice chart of how many code inspection warnings you have over time. Let me tell you this right now: it's nice to have a physical measurement of how your changes affect the quality of the codebase. Real nice. For our first code inspection tool I chose the standard in the .NET world: FxCop. FxCop can't tell if the overall architecture or design is good or bad but it has an extensive library of rules regarding more minor (although still important) things like following the naming conventions, disposing IDisposable instances, avoiding unnecessary casts, and many other "in the small" best practices. There are a couple I disagree with (like making a method static if it doesn't affect any instance fields) but it's easy enough to disable those rules. FxCop won't make a bad product great, but if you set aside time to fix a few warnings each day, it can nudge you toward cleaner code.

After a couple weeks I was able to start writing some unit tests and add those to the integration build. The NUnit plugin for Jenkins will take the results and make a few nice charts that show your current test runs as well as test runs over time. Again, charting progress over time really gives these things more meaning.


The second thing I did with Jenkins involves the deployment process. We don't deploy directly to production but we do have a nightly deployment process for the project I'm working on. We make a setup.msi file, zip it, send it to the client, and send an email of the changes. It takes several minutes to do by hand and it's easy to forget to update the product version, forget what changes are being deployed, or not notice what time it is and have to do it all when you realize it's time to go home. That's why the deployment (even if it's just deploying for testing) should be automated and that's where the real fun comes in. It took a few days to get it worked out but the entire process can now be done by an MsBuild target and here's what it does:
  1. Update the msi settings. A custom inline task reads a file, increments the ProductVersion, sets a new Guid for the ProductCode, then saves over the original vdproj file and updates source control. I later found out that many other people have had to do similar things.
  2. Build the solution. Do a full clean then rebuild the msi and all it's dependancies with devenv since msbuild doesn't like the vdproj project type.
  3. Zip the resulting setup files with today's date in the filename using the MsBuild Community Tasks.
  4. Copy the file to a shared folder.
  5. Update PivotalTracker. We've been trying out PivotalTracker and it's working so well for us that I can't recommend it enough. Not only is it incredibly easy to use and not only does it provide just enough project management to get the job done without getting in the way, but it's dead-simple to integrate with external tools. We have another custom inline task to use PivotalTracker's awesome web api to change every story with a status of FINISHED to DELIVERED. The response from PivotalTracker is a list of the stories that were delivered. Anyone looking at our project page in PivotalTracker will soon see what has been delivered and is ready for review.
  6. Parse the results. Using another Community Task, get the names of all the stories that were just delivered. As usual, someone on StackOverflow ran into the same problem I did and got a great answer.
  7. Send out a notification. Email me a link to the newly shared file with a list of the names of the stories that were delivered. I then tweak the email and resend it to the people involved in reviewing the changes.
And finally, the whole thing is an automated Jenkins job that runs at 5:00pm every day.


It's not perfect and there's a lot more that could be done (like more unit tests, other code inspection tools, and making our build tasks shared across multiple projects) but even while getting familiar with a new codebase and researching the various parts to this process, I managed to improve the project codebase and process while still providing value to the customer. And that, in my experience, is the real double win of relying on a Continuous Integration server:
  • Quick feedback that, when diligently followed, provides value to the company by making the codebase better and better every day.
  • Powerful tools that, when properly used, automate technical chores so we can spend more time providing value to the customer.

Tuesday, June 12, 2012

Scaling monster difficulty: iryrwarosh and beyond

More vague notes about rogulikes; this time about monster difficulty or Power Curve.

In I Rule, You Rule, We All Rule Old-School Hyrule there are two ways that creatures become deadlier over time: natural selection and big monsters. By natural selection I mean that every time something dies, a new random creature (monster or goblin) is born. This means that if you killed a bunch of Mountain Monsters there would be fewer of them and slightly more of everything else. If you avoided a certain type then there would be more of them since you're killing fewer of them. Subtle - but given enough time it would probably make a difference. Of course what new creature get's spawned is chosen at random so you can't have extinctions but you don't get a runaway top predator either. This also means that you're never safe or bored because the world is always crowded. The second way is that each new monster had a small chance to be a "big monster" with extra health and a few other perks. The chance of being born a big monster increases each time a new monster was created. If you played long enough, all monsters would be born big.

Both of these were affected by the fact that creatures who bump into each other attack each other. Imagine a region with two types of monsters: one type who always attack their neighbors and do extra damage, and another type that are pacifists. Over time the aggressive ones would dominate. If the passive creatures had spikes and heavy armor then the aggressive ones might end up impaling themselves into being the smaller population though. Likewise, if everything was killing everything else then you would soon see big monsters whereas a pacifist world would take much longer before they appeared.



I'm happy with those but there were a few other ideas that didn't make it into the game.

Goblins are scattered around and use a random weapon but my original idea was that they would belong to local clans that learn over time. If a clan found that spears did more damage than swords then new goblins to that clan would be more likely to start with spears. If light armor was better than heavy armor then they would tend to use that. This way each clan could have preferences based on their local monsters and they would tend to use weapons and armors that foil the player the most effectively. Also if something sucked then no one would use it.

The rivals are also a growing threat that could have been much better. They seek out hearts and heart containers so they tend to be healthy and gain hearts over time. This also means there's fewer power ups lying around for the player to pick up too. They don't use their items' special abilities though and can't pick up better items either. I tried to avoid having things be clearly better or worse but there are some exceptions. Spike Armor is clearly better than Heavy Armor but your rivals will just ignore it if they find it. They also don't learn. They're hard coded to fear some monster traits more than others - like poison, spiked, and double attack - but maybe there are traits they should fear more? Or ones that should be attracted to instead of afraid of? One rival feature that I'm proud of is that they don't know more about monster traits than you. They see the same monster description that you do. This means that monsters with the Mysterious trait (the ones that don't show what traits they have) are a complete mystery to them. If a player were to bump into a mysterious monster and get a notice that it's spiked, they would probably stop hitting it. Rivals don't learn though. Rivals that did learn would be a growing challenge.



Since the player can go anywhere in the overworld and I don't know which random monsters will be available, I can't fine tune stats and placement and difficulty ramps and experience tables the same way that most designers can. Instead I have to fine tune the rules and mechanics of how things tend to progress over time. Here's a game mechanic view of how iryrwarosh handles making opponents stronger over time.

A creature born for every creature lost. A slow positive feedback loop where things that are hard to kill tend to dominate in the long run. On the other hand, it could be exploited to make the world safer by only exterminating the most dangerous things. (like modern real life: few lions but lots of chickens)

Big monsters that become more common over time. A timer based positive feedback loop that can only be slowed by pacifism. On the other hand, a world with big monsters has more chances for fame so the game would end sooner.

Clans that adapt to use what is most effective in their daily encounters. It would have been a local positive feedback loop that would lead to clans optimized for what they've encountered. On the other hand, if their environment changes or the player's tactics change, they could fare poorly until they've had enough time to adjust. (again like our life - changing climate and changing politics have affected groups of people all the way back since when northern Africa was a lush forest)

Smarter rivals that intelligently use what they find. I think to truly be useful they would need to keep data from past games or play very cautiously until they understand what to fear and what to attack. It would be really cool though. I was only able to put a few hours into the AI for my 7DRL but my next roguelike will have more intellegent rivals that increase in difficulty over time.


Wednesday, June 6, 2012

Extract Method or Extract Class?

There's been a recent mini-revolution to what I think about refactoring.

For a few years now my most common refactoring was Extract Method. Got a big method? Extract sub methods. Got a deeply nested method? Extract each level into a new method. Got any other problem? You should probably look for methods to extract.

I've change my mind; these days I'm all about Extract Class, or more accurately Replace Method With Class. Got a big method? Cut out it's body and paste it into a new method on a new class. Got a deeply nested method? Well... I guess Extract Method still works better for that one. Got any other problem though? Just pick the largest method (or #region for you C# folks) and extract it to a new class.

Why the sudden change of mind? Recent real world experience that is best explained with bulleted lists within a matrix:



Extract Method Extract Class
Mess Unless there's a lot of duplication that you can quickly remove, the class size stays about the same.  Immediately reduces the class size by moving code to a new class. The compiler will tell you what it depends on and what depends on it.
Power You get a new method:
  • you can call it with different parameters
You get a new class:
  • you can instantiate it with different parameters
  • you can subclass and override it
  • you can pass it around
  • you can move related behavior to the same class
  • you can shift the burden of resolving dependancies to an IOC container or factory
Concepts Small, local, procedural:
  • encapsulates a local series of statements
  • tends to aid in procedural thinking
  • few design patterns are simple methods
Large, project-wide, object oriented:
  • encapsulates a bounded-context-sized role or responsibility
  • tends to aid in object oriented thinking
  • many design patters are objects
  • moves responsibility to the new class thereby increasing cohesion of the original class

or, in prose form: Extract Class immediately reduces the amount of code you have to worry about, improves cohesiveness of the remaining class, and gives you familiar object oriented techniques to work with.

Of course it's good to see if related methods could be extracted into a new class after extracting a method and it's probably good to break up the monster method after hiding it in a new class. I just found it much easier to make progress when I relied on extracting large methods to new classes first.

Thursday, May 31, 2012

Reminder: SOLID roguelike code is good roguelike code

I have the strong suspicion that roguelike worldgen code tends to be very procedural. Even with object oriented languages, worldgen code has a natural tendency to turn into a large procedural class with procedural methods modifying procedural data in a very procedural way: little if any polymorphism and little if any interaction among objects with single well-defined responsibilities and behavior. But I recently refactored some worldgen code of mine and it's now several small classes that interact to build a world. It's of course much easier and safer to extend too. Here's how you too can turn procedural worldgen code into SOLID worlgen code.

The core idea is taken from an excellent post by the most excellent Mark Seemann where he introduces the concept of a Customization to his project AutoFixture. Here's the interface for a customization to a fixture:

public interface ICustomization
{
  void Customize(IFixture fixture);
}

And here's how it's used:

var fixture = new Fixture()
  .Customize(new DomainCustomization());

Neat. The ICustomization basically represents an arbitrary change to the default behavior of a fixture. This is very much like worldgen code - if you look at it a certain way. Start with a blank map, add a bunch of customizations, and you end up with an interesting world. One customization makes a lake, another adds a river, another adds a mountain, and on and on and on.

I took this idea and created a similar actionscript interface:

public interface Feature
{
  function addTo(grid:WorldGrid):void;
}

The various world features - lakes, rivers, towns, caves, fields, forests, etc - are each represented by a single class that implements Feature. Most are just a few lines but some are more complex and actually encapsulate logic that is only relevant to that feature. Creating a world with these features is also straightforward:

var grid:WorldGrid = new WorldGrid(width, height);
grid.add(new Shore());
grid.add(new Lake());
grid.add(new Lake());
grid.add(new Island());
// etc.

I wasn't sure if restructuring things like this would do much good or not but I'm convinced it has. Being able to add new features without touching existing code is such a great feeling that I'm trying to find more places to try out this ICustomization idea. What if customizations could change the overall world parameters like temperature or creature spawn rate? Could the core gameplay itself be customized and so that new features and subsystems like identification or poison be added just as easily?

None of this is new or difficult or all that remarkable on it's own. "Something that represents arbitrary changes" is a simple idea that won't revolutionize the roguelike world or the programming industry. You don't even have to learn any new acronym or framework or principle or anything else really. It's more like a reminder - which I need from time to time - of what happens when you consistently apply the Extract Class refactoring: good clean code.

Friday, May 25, 2012

First Flash Roguelike step

After all the trouble I had with getting my Java 7DRL applet to run in the browser, I've decided to check out Flash for my next rogulike. I've used flash before so I figured it would be easy enough and after getting the AsciiPanel.as repo on github, I was able to play around a bit. Here's version 0.1 of my next roguelike project which will be the successor to I rule, you rule, we all rule old-school Hyrule.


Some things to note:

  • The overworld is completely connected - you won't start in a place that's blocked since every tile is connected to every other tile.
  • There's underworld dungeons. They're only one room right now but it's a start.
  • I have some ideas on how to improve on the original game while still keeping the spirit the same.
  • The current working title is much shorter.
  • Once I clean up the worldgen code a bit more, I'll put the source on Github and add it to the RogueBasin.

Saturday, May 19, 2012

Revolutions and revelations in how I program

I've been a professional software engineer for about 6 years now but I've been programming on my own for a few years more than that. Although nearly all of my opinions have changed, and often changed back again, there are a few changes that really stand out.

Polymorphism for different choices. One of the earliest things I noticed was that any method I wrote tended to either make a decision or do something. This newly forming idea that each class and method should do only one thing led me to the habit of classifying methods as "doers" and "deciders". I don't remember where I first saw it - probably on the original wiki at c2.com - but seeing switch statements and if statements replaced by polymorphism really blew my mind. For a long time I tried to do everything I could with subclassing and implementing interfaces just to see what was possible. My code slowly began to be broken into objects that actually did things ("doers"), objects that decided what implementations would be used to do things ("deciders"), and objects that controlled an overall algorithm or flow ("managers") with not a single enum or switch statement in sight. Using polymorphism for conditionals makes code much easier to understand and abstracts unnecessary details.

Design patterns for familiarity. At first I resisted design patterns since none of them actually did anything. I had already seen code where only a small portion actually did work and the majority was excess plumbing and was dead-set on not writing anything like that. It took a while before I realized that the design patterns don't help with solving the domain problems; they help with solving the code problems. They help you identify and structure the pieces of your code that need to work together - they weren't useless baggage at all. In fact I had already stumbled upon the Strategy pattern (my "doers"), the Abstract Factory (my "deciders") and the Template pattern (similar to my "managers"). I've never found a need for some of them (Flyweight? Prototype? Memento?) but I began to see that my code was already doing the things some of the patterns were doing. By extracting those parts into their own classes that followed the pattern names and structures, my code was much cleaner and self-evident. This also broke me away from the naive view that a class represents a real-world noun and realize that a class actually represents a well defined and clearly named role or responsibility. Preferably a single responsibility that is familiar. Design patterns make common responsibilities and structures clear and easy to understand.

Immutability and higher order functions for safety and conciseness. Haskell has taught me a lot of really cool things like monads, monoids, functors, the beauty of concise language, and how to get the most out of the type system. Unfortunately the languages I use on a regular basis are no where near as concise or powerful. Fortunately all modern languages support some variation of higher order functions and immutability. Until Haskell I had never seriously thought about mutating state. After Haskell I became obsessed with it and came to the same conclusions as just about everyone else: eliminating mutable state eliminates many bugs and eliminating accessibility of mutable state eliminates many bugs. Concise code, meaning code that does one and only one thing with minimal boilerplate, is also easier to read, understand, and fit in your head - meaning even fewer places for bugs to hide.

Constructor injection for explicit dependancies. I used to have the constructor set up all the dependencies, wrongly thinking that's what everyone means by information hiding and designing for reuse. Just new-up an instance and start using it: you don't even have to know what it's using behind the scenes. How easy to use! How nice and thoughtful of me! At least until you need it to behave slightly different or need to use it in a slightly different context. Then you have problems. The kind of problems that are only solved by rewriting existing code - a bad and dangerous thing. But by making dependencies explicit you know what's going on. By making dependencies part of the constructor, you can change the behavior to suit the context without rewriting. And by thinking about dependencies as its own concept, your objects become much easier to use. Whether you use an IOC container or just use poor-man's dependency injection, identifying dependancies and making them explicit makes for code that has fewer surprising side effects and is easier to extend.

Refactoring for working with legacy code. I was aware of refactoring but wasn't sure how to apply it to most of the code that I had to work on in a day-to-day environment. Beyond the occasional Rename or Extract Method I didn't really do any refactoring; like design patterns it seemed to often be extra work that didn't actually do anything. Reading Working Effectively With Legacy Code changed that. I had an entire new arsenal of techniques to break dependencies, shrink giant classes, increase test coverage, clarify what the system actually does, and make the code just a little more pleasant to work with. Working Effectively With Legacy Code, and refactoring in general, is great enabler that allows you to bridge the gap between what happened to be and what could be.

Events and messages for decoupled systems. Until I really started using domain events, it seemed like creating a decoupled system was just a lofty goal that you could possibly approach but never get close to. I was wrong. Dependency injection had taught me about about dependencies and how to make them clear but I wasn't sure how to really get rid of them. This is how. With an event system you can remove dependancies between collaborating classes and add functionality without modifying existing code. Not only that, but all the public methods and properties that managed collaboration disappear and your classes expose just their own domain behavior. I still run into issues with sequencing or scenarios where I'm not sure how to do something with events from time to time but simple events and simple pub/sub drastically simplifies and decouples the domain objects and overall architecture.


I could write a post, or probably a small series, on each of these (or link to a hundred other sites). There have been other things that have helped me become a better developer (TDD, DRY, SOLID, debugging tricks, SICP, communicating with others, really listening to users, etc) but these are the ones that really shook things up and moved me in a new direction. What has changed how you program? What are you currently looking into? What do think your next big change will be?


Wednesday, May 2, 2012

Review of a review of iryrwarosh

I recently watched the awesome review of my 7DRL iryrwaroshr by the awesome TheUberHunter. Here's my thoughts (or, Review of a Review of a 7DRL).

He started by pronouncing my name right (which is an achievement in and of itself), then wrong (or at least not how I pronounce it).

@1:04 "Oh Wow! That's kind of cool. (hums zelda theme)" Yes! Total victory for me. If someone starts out thinking it's cool and get's what the overall theme is, then I'm off to a good start.

@1:40 "hiding on the text". Yeah, my bad. The text should move so that it doesn't obscure your view. The "Fame" leaderboard does it so the messages should too. Again: my bad.

@1:55 "serious damage.... more than meets the eye" combat messages need to explain the weapons better. And it needs to be more obvious that goblins use weapons.

@2:40 "I have to really point that thing when I use it" Welcome to Old-School Hyrule! That's one of the things from the original Zelda. It kind of sucks.

@4:20 evasion is mostly based on your immediate surroundings: the more places you can move in to the higher your evasion is. When you evade an attack you not only avoid all damage but you actually move into an adjacent space at random. Other creatures have an evasion percent and certain items affect it. Not at all obvious and rarely important - It's confusing and probably should have been dropped.

@4:40 treasure and fame? Fame is important - It's how you win!

@5:14 "twilight zone time" One of my favorite little details. When you start a new game the screen sort of fades in but you are visible the entire time so you can clearly see where you are. I tend to cram a lot onto the screen so this helps focus on your stating location. Games that have a field of view don't have this problem since you are at the center of what's visible on the screen.

@6:12 evasion and auto-attack. Open space is good for some weapons and a closed space is better for others.

@6:30 "I don't know how first aid kits work" You need 5 rupees - that's too much. Or there's not enough rupees in the game.

@7:19 The exclamation point is an evasion potion. It should be more clear what it does.

@7:20 It took far too long to check the help. Maybe explain immediately? Help should also say what each of the items are.

@7:40 Press space to examine. Unfortunately the examine square is in the center of the screen and not where you are. This is because of some architectural constraints so that's pretty lame. Good design helps make a good user experience - it doesn't hinder it.

@8:40 Yes! TheUberHunter lost because someone else got 100% fame before he did. Victory for me! I'm glad the AI was able to win a game.

@10:05 "whatever you say dude". Many of the auto attacks like impaling on spikes aren't very clear. Part of it is because of the message/event architecture I tried using made it difficult to do some things in a specific order. It's also unclear because it affects things nearby and everything is moving so you can die adjacent to a monster that then moves two spaces away (if is has the DOUBLE_MOVE trait).

@10:20 Once again, there's a horrible lack of rupees throughout so the spells are too expensive.

@11:40 poison for 3 turns == totally weak

@12:25 "does the armor do anything? .... no.... Good to know. Good to know.". No active ability, fail on my part since everything should have an active and passive ability.

@12:56 Evasion potions are still unclear....

@13:04 Help doesn't help with items. It really should - especially the evasion potions.

@14:20 "Dork! I will Dork you in the Dork! Dork! Behold Dork!" Lol.

@15:45 The desert does have too many monsters. The reason is that each region starts with the same number of monsters. Since the desert is only 2x2, it ends up very densely populated. An oddand unintended consequence.

@16:28 rupee machine -> "I learned nothing so far!". But it does make rupees over time! You just died so quickly!

@17:05 "I was hoping for auto attack's to be more happenin'... but that doesn't really seem to be the case". Yeah; me too. It turned out to be a bit underwhelming. Maybe 100% chance would have been better.

@18:30 "a pretty good game anyway" Yay! A few things didn't work out very well but I'm glad that overall, it's not a bad experience.

@19:30 "I guess we could play one more" Hahahahahahahaha! I WIN!

@19:54 You only lasted 18 turns. With as much randomness as this game has you can end up in situations where you die quickly. You can always flee but there should be something to make sure you don't start in such a bad spot.

@20:50 "surprising, but doesn't work properly", auto attack and evade are based on chance. It is hard to know when it will happen and that should have been made more apparent.

@20:55 "a lot to learn" Ha! I really went overboard with the items and subtle points of evasion and auto-atacking. Next year will be much clearer - but also much more stuff....

It was really funny and interesting watching someone else play. It was good to see the "wtf?" moments as well as the "aha!" moments. I knew the auto attack and evasion would be unclear and that there are far too few rupees. I also figured that most people would play aggressively the first few times and die quickly. Once you see that you win by fame and not killing goblins and regular monsters, you play much more cautiously. I wonder if he noticed the flowing water, or the lava, or the different colored trees. The graphics are probably the best thing I did but maybe they're one of those things that don't even get noticed when they're done right. I don't think he knew that goblins have a random weapon or that the monsters had random traits that you can see by examining them with the space bar.

Anyway; it's great that TheUberHunter is taking so much time to play these roguelikes and anyone who made a 7DRL or is thinking of making a game should watch him play some.

Friday, April 6, 2012

Interesting Perlin noise caves

I'm not a big fan of using Perlin noise to generate random terrain - mostly because the results are uninteresting and you have so little control over it. However; I came up with a use for using Perlin noise to generate interesting caves that I haven't seen before.

Step 1: Generate a map of solid rock. Use Perlin noise (or whatever) to make it of varying density.
Step 2: Place points of interest in the rock.
Step 3: Use a pathfinding algorithm to connect those points using the rock density as movement cost.

This will create a a map that is guaranteed to connect all the interesting points and the paths between them will wind, curve, connect, and split trying to follow the path of least density between the points. By varying the size of the path finder or removing low-density tiles near the path, the caves can be made to look more interesting.

Here's an example that connects 9 points on a map that is 120 by 40 tiles.




And here is a view that shows the density of the rock, the lighter it is the more dense it is and the less likely a cave will go through it.




There you go, caves that twist and wind and widen and narrow from point A to point B.

Wednesday, March 28, 2012

Common uses for the State pattern

Of all the design patterns, I think the state pattern is one of the simplest and probably the one I use the most. It's easy to understand and easy to use but I still see many places where it could be used but isn't. Here's a few things that indicate when using state objects would be simpler.

If you have a variable that represents what 'mode' or 'state' something is in, or what the current behavior is, then you may want to use the state pattern. A common place for this is if you have a gui and the user can interact with one of many tools. Instead of:

public void onClick(int x, int y){
  if (currentTool == PAINT)
    canvas.paint(x, y);
  else if (currentTool == BLUR)
    canvas.blur(x, y);
  else if (currentTool == ERASE)
    canvas.erase(x, y);
  else if (currentTool == LINE && lineStart == null)
    lineStart = new Point(x, y);
  else if (currentTool == LINE && lineStart != null) {
    canvas.drawLine(lineStart.x, linesStart.y, x, y);
    lineStart = null;
  }
}

you could refactor to the state pattern:

public void onClick(int x, int y){
  currentTool.onClick(x, y);
}

class PaintTool extends GuiTool {
  @Override
  public void onClick(Canvas canvas, int x, int y){
    canvas.paint(x,y);
  }
}

This means that new tools could be added without having to change the gui code. The state pattern would also simplify the gui since it no longer needs to determine what clicking means. This is especially beneficial when multi-click operations are involved since the gui no longer needs extra variables to track that.

class LineTool implements GuiTool {

  private Point startPoint;

  @Override
  public void onClick(Canvas canvas, int x, int y){
    if (startPoint == null)
      startPoint = new Point(x, y);
    else {
      canvas.drawLine(startPoint.x, startPoint.y, x,y);
  }
}

That brings to another common case where the state pattern is useful: If you have variables that are used in some situations and ignored in others, then you may want to use the state pattern instead. For example, if you have a game or simulation where each agent either has a fixed home, another agent it follows, a group it considers "home", then instead of:

public void goHome(){
  if (homeLocation != null)
    goTo(homeLocation.x, homeLocation.y);
  else if (leader != null)
    follow(leader);
  else if (group != null)
    follow(group.getRandomMember());
  else
    wander();
}

you could refactor to the state pattern:

public void goHome(){
  home.goTo();
}

public class StationaryHome implements AgentHome {
  private Agent agent;
  private Point home;

  public StationaryHome(Agent agent, Point home){
    this.agent = agent;
    this.home = home;
  }

  @Override
  public void goTo(){
    agent.goTo(home);
  }
}

Once you have the different states, then the agent no longer needs all of those extra variables and is made much simpler. It also disallows states that don't make sense: what does it mean if an agent has a location it considers home and a group it considers home? If that's not a valid situation then you need to make sure you never end up with both. If it is a valid situation then you can just create a new state object that handles it.

You may have noticed something about these two examples: If you have a bunch of if/if else statements that compare variables to literal values (like enums!), then you may want to use the state pattern instead. Complex objects with complex logic can be greatly simplified by using the state pattern. In fact; it's possible to completely remove all branching and delegate behavior to multiple different state objects instead.

Since these scenarios are all cases where we want different behavior based on some runtime values, they're good candidates for the state pattern. So keep an eye out for chances to use the state pattern.

Monday, March 19, 2012

I rule, you rule, we all rule old-school Hyrule retrospective part 1

So the 2012 7DRLC has come and gone and I've finished my third and best entry. I've looked at some posts and announcements that others have made but have only tried a couple other entries so far. Without getting "official" feedback from this years judges and without comparing my entry to the others, I have to ask myself: what went right? What went wrong? What did I learn? And what can I do differently?

Right. I had a plan and stuck with it when it worked and dropped it when it didn't. I got a zeldalike overworld that was aesthetically pleasing and fairly interesting. I got a bunch of different items to use, most of which have a passive and active use. I also have fairly intelligent rivals that really push you forward and made the game much more fun. The random monsters were sometimes fun and I really liked the camouflage and calling for help. The code - while a bit on the spaghetti side - was mostly decent and did use events. In the end I had a game that was somewhat fun with a clear indication of progress and you could win by cautious exploration, reckless combat, or an opportunistic combination of both. I also had someone playtest and spot so many spelling errors.

Wrong. The overworld sometimes had inaccessible places. It's rare and not game breaking, unless you start on a tiny area and can't escape, but it happens. The evasion thing was pretty uninteresting and some of the items aren't as useful or interesting as others. I tried to make all items equally interesting and useful but that didn't work out as well as I thought. I ditched many of my ideas because they were just not fun. Sometimes the monsters were too overpowering or just uninteresting. The game was often to short to really get into it. I also had a hard time deploying as an applet and eventually just provided a download link. That really sucked since a big part of choosing java was being able to play it in the browser. The biggest problem was that I also spent the middle portion of my week flubbing around and spastically tweaking things left and right without a clear plan. It was chaotic and I moved sideways as much as I moved forward, if that makes any sense.

Learned. Worldgen shouldn't be all or nothing - if I could make one "room" or "screen", check it, and then accept or reject it on its own then I could avoid having inaccessible sections and unintentional dead ends. I don't think I could have done the items much better since I originally had detailed plans that just turned out to be uninteresting. That's not to say they couldn't be done better but I think that's one thing that you just have to get right through iteration and hands on playtesting. My weakness was probably the items and item balancing and I probably should have stuck with the the best parts: worldgen and rivals. Not that it matters that much - the game is so short that I often see only a small portion of it before the game ends. I think that the more randomness a game has and the more content it has to explore, the more chances you need to overcome the randomness and the more time you need to explore. I'll have to make a post on randomness and the number of choices required to rise above being slave to the RNG.

Next time. I tend to go overboard with my ideas; like having a zelda overworld, random monsters, evasion, 2 item max, rivals, and fame percent all in one seven day project. Although it's great having different options to explore, the items were probably my weakness. I should either focus on that and practice making item-based roguelikes or ditch it for the next 7DRL. The events were also a bit of a mixed blessing. When should I use events and when should I code things inline? It was also difficult to control the order of when messages appeared and deal with situations where one action would have similar events published and logged. I'll try dropping the event based thing and rely on explicitly sequenced overrides and callbacks as an alternative. Yeah, it's tightly coupled, but I also have the control I need. I also need to have specific goals for each session: worldgen, rivals, polish, etc and not have generic "content". That's how I end up with a bunch of items most people will never see and even fewer will like. Lastly, java isn't as cross platform and easy to deploy as I thought. I'll have to look more into Flash for my next roguelike.

So, have a plan but ditch it when it doess't work and focus on your strengths since your strong points will make your project a success and your weak points will, at best, be a waste of time, and, at worse, may overshadow your strengths. Also, if you can, have someone else playtest it. Once I get more feedback from the fine people at the roguetemple and other folks who review my game, I'll come up with a retrospective part 2.

Friday, March 16, 2012

I rule, you rule, we all rule old-school Hyrule

Here it is! My 2012 7DRL, I rule, you rule, we all rule old-school Hyrule. I no longer have it running from this page since so many people were having problems with it but you can still download it and run it localy.

Source:
  https://github.com/trystan/iryrwarosh

Download the iryrwarosh.jar:
  https://sites.google.com/site/trystansprojects/iryrwarosh.jar

Once you have the jar file, double click it or type "java -jar iryrwarosh.jar" from the command line.

Good luck!


2012-03-23 update: I made a minor bugfix that was causing an infinite loop when a monster tried to unhide but couldn't find an acceptable place. This doesn't change the gameplay except it's now theoretically possible to kill something that's hiding by blocking the only places it could enter again.

Tuesday, March 13, 2012

I rule, you rule, we all rule old-school Hyrule halfway milestone

So, I'm about halfway through this year's 7DRL and these are my thoughts.

I've made amazing progress on my 7DRL. Neat worldgen, unique items to choose from, limited but interesting inventory choices, challenging and interesting enemies, pleasant aesthetics - all good so far.

I've sort of but not explicitly abandoned the allies/followers idea. It turns out that it's not very fun to implement or play. If it was a city simulation or tactics game then it may be interesting, but it doesn't add much to the lone hero vs the world storyline we're all so familiar with. These are common game tropes but I'd say there's three reasons why that works so well: clear playability, clear progress, and clear obstacles.
  • Clear playability. You know what to do. Going down stairs is good. Getting new stuff is good. +5 is better than +3. A Black Dragon is scary, a Newt is not. The conventions and standards from high fantasy, AD&D, previous roguelikes, and numerous hero stories means that you have a general idea of what to do (go down the stairs) how to do it (find [>] and press [>]) and the common supporting ideas ([q]uaff, AC, DEX, [e]at, Potion of Stone Skin, etc).
  • Clear progress. You know how close you are to winning. You're on dungeon level 4 of 20. Or the sewer branch. Or you're at character level 8 and 11 is the highest you've been at before. Or you've got 1000 gold coins. Or you just got the Master Sword. Roguelikes, and possibly games in general, tend to have a clear way of seeing how close you are to the end - by a numeric success vs total (Mario Bros. world number) or success vs failure (chip pile during poker tournament).
  • Clear obstacles. You know how close you are to losing. You are low on hp. Or poisoned and starving. Or paralyzed and surrounded by ants. Whatever the situation is, you can clearly see that you are closer and closer to failing.
This means that in the best games you know what to do, and how close you are to winning, and how close you are to losing. Like knowing that you should be able to handle petrification as you turn to stone on level 18 of 20 while surrounded by demons. So close to winning (level 18/20), but you know you're going to fail (petrified and surrounded), but you know how to play it better next time (resist petrification). Possibly the roguelike ideal.

So, what other game mechanics contribute to showing what to do, how close you are to winning, and how close you are to losing? Do you know of any clear examples that support these ideas? Any that contradict?

Monday, March 5, 2012

My plan for the 2012 7DRL

I've been thinking a lot about what I want to do with this year's 7DRL. For 2011 I wanted to see what it was like to not be the hero but have to cooperate with other heroes and to try a survival goal rather than the tried-and-true "descend and return". Even though it wan't very fun, I'm happy that I did that and I consider it a success. I've posted some of my ideas before, but as March approaches, I've been narrowing down what I want to focus on.


Event based architecture. I've had a lot of fun and learned much while delving into simple event based programming and I think this will be a good test of how to apply it to an interesting application. Roguelikes tend to have very messy dependancies and have an unholy number of exceptions to the rules and complex interactions so this will be a good test of how well I can make events, commands, and sagas work.

Interesting overworld. I've gotten tired of playing games that have too much uninteresting space. Long corridors, huge outdoor fields, empty room after empty room after empty room. I want small and unique spaces. Moving is so boring that some roguelikes have it automated for you. Despite all the hours I played the original Zelda as a kid I never got tired of it. Each screen had its own unique charm and character, each fit within its own little neighborhood, and each area had it's own secrets to reveal. I want that.

Random monsters. Other than the Forgotten Beasts of Dwarf Fortress, I haven't seen this implemented. I don't think I'll have DF's giant vomit monsters, just a few species with three or four random advantages each game. This should add variety like identifying potions does, except perhaps with deadlier consequences.

Dynamic quests. The more I think about it the less intimidating this seems - but that may just be my own hubris. Since it's a 7DRL I will probably only have a few quests. Getting other people to follow commands and attempt the same quests would be interesting - and it should be possible if I'm right about the connection between commands and quests.


Focusing on these means I would de-emphasize other things. There will probably be just a few simple armors, weapons, and other items. I will most likely skip magic alltogether. The game itself may not even be fun or difficult. I'm not sure what the story will be either but it should involve quests and followers. I should probably think of something soon otherwise I'll end up with just a proof of concept: a bunch of neat ideas with no theme to tie them together.

My 7 day plan:

Day 1. Hyrulian Overworld: worldgen, player controlled @
Day 2. Basic gameplay: basic creatures, basic combat, basic stats, basic items
Day 3. Monsters: randomized monsters, better creature AI, a few status effects
Day 4. Society: people, victory, basic commands
Day 5. Dynamic quests
Day 6. More content and polish....
Day 7. More content and polish....

Tuesday, February 28, 2012

Followers, spoken commands, and quests


I think I've found something that hasn't been done that could add a lot to roguelikes: spoken commands. You type what you want your followers to do and they do it. Instead of having a complex AI that handles the entire english language, you could focus on a few things that could be combined in different ways. If you have many people following these commands then you and your rag-tag team of adventurers could really change the world.

Here's a simple command syntax that I have in mind:
  <target> <verb> [<objects>] [<preposition clauses>]

target is an optional person or group you are talking to: healer, fighters, Bob, Joe, etc.
verb is one of a dozen or so supported verbs: attack, defend, go, pickup, drop, help, etc.
objects are the people, places, or things directly involved with the verb: a sword, goblins, me, the desert, home, etc.
preposition clauses are optional clauses that constrain the verb: in <location>, with <item>, etc.

The prepositions are where the real flexibility and power come from since you can specify where something should happen, what should be used, or whatever else makes sense. The verbs, people, places, things, and prepositions would be whatever is appropriate to the game; resource gathering, squad maneuvers, mixing potions, social intrigue, whatever you can think of.

Turning the spoken words into commands would be three steps:
  1. Normalize the sentence, removing fluff words and changing synonyms (protect -> defend)
  2. Parse the sentence
  3. Correct the prepositions and objects if necessary

As an example, Miners, give the blacksmith ore from the mines would be normalized into
 miners give blacksmith ore from mines which would be parsed into this:
 target = miners
 verb = give
 objects = blacksmith, ore
 prepositions = from mines

The correction phase would be necessary in this example since the "give" verb requires the verb's object to be a thing and requires a "to <person>" prepositional clause. "blacksmith" is a person and "ore" is a thing so "blacksmith" should be the "to" prepositional clause and "ore" should remain as the verb's object. The corrected interpretation is:
 target = miners
 verb = give
 objects = ore
 prepositions = from mines, to blacksmith
or miners give ore from mines to blacksmith

So the miners who hear this would get ore from the mines and give it to the blacksmith.

Some other example commands:
 healer, help the villagers at home
 kill the goblins in the dark forest with spears
 Urist, craft a sword with steel at the master's forge
 guards, escort the prince from the castle to the fort


There seems to be a deep similarity between commands and quests. Even my example Lost Heirloom Quest could be seen as a command: player, give the McUrist family watch from the dark forest to Urist McUrist. Since the NPCs can follow commands, and commands and quests are the same, then they should be able to follow quests. Also; since the player can give commands, the player is also giving quests. Imagine a world with a few hundred NPCs running around trying to fulfill quests and giving quests to others when appropriate.

Wednesday, February 22, 2012

Procedural quests for a dynamic world

Interesting and procedurally generated quests are something of a holy grail for many roguelike developers. I've also given it some thought and here's a simple idea I came up with.

Basically, if you have a catalogue of possible quests and you have an event based architecture, then each quest type would have it's own saga. That saga would listen to domain events and when the preconditions were right, it would add the quest to a quest giver. By talking to a quest giver the player, or any other actor, could accept the quest. When the saga receives the right domain event, the quest is over and everyone undertaking the event is rewarded or notified as appropriate.

Here's a concrete example I'll call a Lost Heirloom quest.
  1. A LostHeirloomSaga subscribes to certain events like PersonMoved (while fleeing or confused) or ItemStolenFromPerson. As a response to those events, it may create a LoseItem command with a reference to the person and item.
  2. Some command handler causes the target of the LoseItem command to drop the item (if it wasn't already stolen) and create an ItemLost event with references to the person, the location, the time, the item, and the reason why.
  3. The LostHeirloomSaga listens to ItemLost events and when it handles the event, the person who dropped the item is given a LostHeirloomQuest and can ask others to accept it.
  4. When the player talks to that person they can accept that quest. The details from the LostItem event can be used to create the quest specific rewards and text. Imagine talking to URIST McURIST the WOODCUTTER when he says "TWO WEEKS ago I was CUTTING WOOD in the DARK FOREST and was attacked by a GIANT BEETLE. While fleeing for my life, I dropped my McURIST FAMLIY WATCH. If you find it and return it, I'll give you my spare WOODCUTTER'S AXE and a PASS TO THE WOODCUTTER'S GUILD."
  5. The LostHeirloomSaga also listens to ItemGiven events. When the item that was given matches a lost item and the person it was given to matches the person who lost it, the associated quest is completed and the person who gave the item is rewarded.
  6. If a CreatureDied event for the quest giver happened, an ItemDestroyed event for the lost item, or some other quest-canceling event happens, then the LostHeirloomSaga cancels that creature's quest and everything else is cleaned up appropriately.
  7. For extra awesomeness, when the saga notices other events related to the item (like ItemSold or ItemPickedUp), it could somehow add details to the world about it. Maybe the town's gossipmonger would tell you rumors about how the local blacksmith found a family watch in the dark forest. You could then talk to the blacksmith to find out what happened to it or you could sneak through his stuff when he's not looking.
Implementing this quest means adding a few classes: a LoseItem command, a method to handle that command, a ItemLost event, a LostHeirloomQuest, and a LostHeirloomSaga. The neat thing is that no existing classes need to be updated except for making sure the quest saga subscribes to the right events - all the logic is contained in the command handler and LostHeirloomSaga. The LostHeirloomSaga can use details of the quest giver to create dynamic and relevant details about what was lost, how it was lost, and when and where it was lost as well as a reward appropriate for the quest giver and the location and value of the lost item.


The real emergent behavior comes from quests that play off of events generated by other quests. If each quest can be ended two or three different ways, each quest directly or indirectly involves affecting the world, and there are multiple actors giving or accepting quests, then a complex chain of events could cause gathering firewood to lead to the downfall of a civilization.
  • Perhaps LostHeirloomQuestCompleted events please the god of compassion who may give the quest completer a Help The Townfolk quest.
  • Perhaps when a Rescue Princess quest is ended by the princess dying, her family creates a Kill Person quest targeting the killer and a Revenge quest against every group the killer was a member of. When a Rescue Princess quest is ended by the princess returning home, her family rewards whoever escorted her and every group the escort is a member of.
  • Perhaps 10 Expand Influence quests must be completed before a size 3 town can become size 4. Whenever an Expand Influence quest is completed, nearby paranoid town mayors become nervous and may create an Attack Town quest or Assassinate Ruler quest targeting their rival neighbors. When an Attack Town quest is completed, the targeted town's mayor can give Strengthen Defenses and retaliatory Attack Town quests. Undertaking either requires buying resources from the market and if a market trader's goods are running low then he could create Gather Resource quests. Of course gathering resources in your neighbor's territory will cause them to hand out quests to get you to stop; by bribery, trade, or sword and shield.
This, right now, is just idle speculation but I think this could be done. By relying on domain events and sagas, new quests can be implemented without muddying up the existing code since it doesn't even need to be touched. By relying on specific details of the people and places creating the events, compelling and believable quests can be generated. And by relying on quests that build on domain events raised as part of attempting other quests, an interdependent and dynamic history following simple laws of cause and effect can be created. I'll have to create a proof of concept some time.