Sunday, August 10, 2014

Hero Worship - Deep Thoughts

So far everything functions fine, but there's no game.  No goal, no challenge, no progression.  No meaningful choice.  In fact, it's all rather pedestrian, with me relying on tried and true concepts from other titles.  But I don't just want to make a complete knock-off of some generic strategy game. But I want to use the great Actraiser as inspiration.  And I really need to look more closely at what makes that game tick.

What the hell is an "Actraiser" anyway?

If you're not at all familiar with the game, Actraiser was a mix of god-sim and side scrolling action.  The game progression goes something like this:



It was a fairly linear game.  From what I remember, access to more difficult territories was based on your level, so your progression from one place to the next was fairly fixed.  For Hero Worship I think I'll be tossing out the progression from one land to the next in favor on a single, one map / one fight experience.  The game will begin in the town building phase and eventually end with an action phase once all requirements are met. Let's ignore the action phase for now and focus on the town.

Despite its simplicity, the sim phase in Actraiser was really pretty interesting. Let's look at what you did as a player and how I think I'm going to approach it in Hero Worship.

Here's the first map of the game.  The town starts in the center and is represented by a temple surrounded by a road.  On the outer edges of the map are monster spawn points.  As you are building your town, monsters will constantly emerge from these locations to wreak havoc.

Although the game runs in real-time, your villagers can only build once at the beginning of the day.  You can direct where they should be building. One of the goals for each map was to direct your villagers to build up their town right on a monster spawner.  Once they were close enough, they would destroy it, making the land a little safer.


As your villagers made their way around the map, they would discover special technologies (such as bridge building) that they could use to further progress.  They would also find "spells" that they would offer to you so that you could help them out as well.  With these spells you could summon rain to help crops grow or put out fires, or lighten bolts to kill enemies or clear away rock.  There was a very light puzzle-solving element involving locating these technologies and spells in each map, and using them correctly.  It important to note that the whole thing was very simple and very linear in terms of progression.

The other thing the player would do is direct the little cherub guy in the center of the screen around the map and use his (her? its?) arrows to destroy any monsters wandering around.  The villagers are completely defenseless are were prone to being kidnapped or having their houses destroyed.

Here's a quite decent let's play I found on the You Tubes.  The sim stuff comes in at around the 5 minute mark.

Once all of the spawn points were destroyed, the villagers would pinpoint the "ultimate source of EVIL" on the map and request that you come down and squash it (which is something you're all too happy to do during the action phase).

So how do I plan on keeping the spirit of Actraiser while making this game its own thing?  Here are some thoughts:


  • Direct control of town building.  This is a pretty major departure from Actraiser.  But I think there's more moment-to-moment engagement to be had from the player choosing which buildings to place when and where.
  • No direct villager control.  This is not a game about amassing a huge army and steamrolling over the enemy.  The villagers will react and defend.  There may be offensive units, but they will mostly act on their own.
  • God powers to assist and influence.  Like Actraiser, the god spells will assist the villagers in achieving their goals. It can be direct like a lightning bolt to take out enemies or it can be a subtle suggestion to investigate an area.  I'll need an additional resource (mana, belief, etc) to cover this.
  • Minion for direct control. Right now I'm thinking no.  The cherub in Actraiser worked in part because there wasn't much else for the player to do.  
  • Encroaching doom.  I had been playing a lot of the excellent Creeper World 3 and I just love love love the idea of fighting against this overwhelming wave of... stuff.   My initial thought is that the spawners, in addition to creating monsters, will spread corruption around the map.  This would slow units, destroy buildings, and render resources unclaimable. God powers and perhaps a special building would be able to counter the effect.
  • Destroying the monster spawners.  Same basic idea. However, in Hero Worship they will have to be discovered.   I've implemented something I call the "Poor Mans Fog of War" which I'll discuss in a later post.  Basically, these spots will remain hidden until a villager gets close to it.  Once discovered, it will be permanently visible on the map.  A discovered spawner will cause a specific building in the town to create a raiding party to travel over to the location and destroy it.
  • Summoning of the Hero.  This is what will end the "sim" part of the game and begin the action phase. In Actraiser, the action phase was triggered once the location of the "Ultimate Source of EVIL" was discovered.  In Hero Worship a shrine will need to be erected at a special location on the map.  The location will be revealed by destroying the monster spawners.  The shrine itself will require massive amounts of resources to be ferried to the location. Once built, the hero (the embodiment of god) will be summoned and the action phase will begin.
  • Additional villager types. A generic warrior/scout will take care of exploring and patrolling the map.  A druid will "seal" the monster spawners and build the shrine.
Obviously there are many more details to consider, but this should keep me busy.







Thursday, August 7, 2014

Hero Worship - Tower Defense

With villagers running around properly and monsters happily eating them, it was time to get some kind of defensing structure working.  The answer of course was that tried and true RTS mainstay, the tower.  Really nothing fancy here.  It's a building that requires resources to construct.  It has a range and a fire rate.  Once an enemy comes into range, the tower "locks on" to it and will fire exclusively at that enemy until it's either destroyed and it moves out of range.

The bullets generated by the tower move towards the x/y coordinates passed by the tower.  They do damage on contact so depending on the speed of the bullets and/or the enemy, you can make the towers more or less accurate.

That's one way to do it.  You could also have the tower insta-hit any enemy that's been locked on so you wouldn't even need to bother with collision detection at all.  Or you could base your hit on a percent chance modified by things that "accuracy", "distance", or "armor".  All pretty easy to implement, but I wanted to see the bullets fly and it's kind of neat to see them miss every once in a while.  Just remember to kill the bullets if they don't hit anything.


curDist = distance_to_point(originX, originY);

if(curDist > 150)
    {
    with(self)
        {
        instance_destroy();
        }
    }

The biggest takeaway from getting the towers in and working was not just how easy it was.  It was how simple it was to slip it into the existing game.  I have building selection and placement set up so once I have all the sprites and objects build, I just add the new one to my "buildings array" and it just works (with minor tweaking).

Right now my buttons appear just above my town center in a straight line.  I'd like them to appear in a circle.  I'm sure there's some simple math here but I haven't stumbled upon an answer in my journeys.  It's super low priority as I think the whole selection process will be changing when I move to controller input.

With the basics in place, it's time to make it work more like a game...


Sunday, August 3, 2014

Hero Worship - Here There Be Monsters (Part 2)

When we last met, our intrepid monster could successfully wander around aimlessly and eventually head towards civilization. The next bit was to get them to attack buildings and people.  It started simply, but then I quickly got lost in numerous "What if?" scenarios.

To shake the monsters out of their funk, I needed to add an instanace_nearest check for either a building or a person of any kind.  Game Maker allows you to parent objects, so I created generic "obj_building" and "obj_person" objects and childed my buildings and villages.  If there's one within a certain distance, the monster will cease wandering and start moving to attack.

The monster stuff was easy.  Once it collided with a villager or building, it would enter an attack mode, slowly depleting the hp of the collided object.  Once the hp reached 0, the object would be destroyed and the monster would seek a new target or go back to wandering. In order to achieve this, the monster has three states:


  • Moving - I'm wandering around looking for stuff.
  • Aggro - I've found something I don't like and I'm heading towards it.
  • Attacking - I'm in combat mode.

Under a simple test with a building, it all worked perfectly.  I added a health bar to the building with the Draw event so I could track hp depletion.  Here's the code.  The numbers are placeholder until I get them all stored somewhere else:

draw_self(); // you need this so it will still draw the sprite

if(hp < MaxHp) // only show health bar if damaged
    {
    draw_set_color(c_gray);
    draw_rectangle(x-32,y-27,x+32,y-16,false); //healthbar background

    draw_set_color(c_red);
    draw_rectangle(x-30,y-25, x+(hp*6)-30, y-18,false); //healthbar: this gets smaller with less hp.
    }

Here's where it got tricky.  Villages don't stand still.  They are off doing things, so they also need to know they are being attacked (or they are in danger) under different circumstances.  At first, the villages were completely stupid.  They did not react to a monster nearby.  This lead to villagers running right into a monster already occupied.



They needed a panic mode.  The initial implementation was actually pretty simple.  If there's a monster nearby, run in the opposite direction until you are far away, then resume what you're doing. Again, instance_nearest comes to our aid.  Here's the basic script:

monster = instance_nearest(x,y,obj_monster);
monsterDist = distance_to_object(monster);

if(monsterDist < 50 && !panic)
    {
    //panic mode
    path_end(); //stop following current path
    path_delete(myPath); //delete path: you need to do this to prevent memory leaks
    myPath = path_add(); //prepare for new path.
    speed = 0; //stop moving for a moment.
    panic = true; //you are now in a state of panic

//get point to run to
    dir = point_direction(monster.x, monster.y, x, y);  // gets a vector pointing from monster to villager
    radius = random_range(dir+45, dir-45); // this helps randomize the final direction to run in.
    
    targetX = x + lengthdir_x(200,radius);
    targetY = y + lengthdir_y(200,radius);
    targetX = floor(targetX);
    targetY = floor(targetY);
    
    //check to see if it's a valid destination and then go there
    r = mp_grid_path(grid, myPath, x, y, targetX, targetY,1);

        if(r)
        {
        path_start(myPath, GameControl.villagerSpeed,0,0);
        alarm[2] = 90;
        }
        else
        {
        panic = false;  // if not valid path, setting panic to false resets this condition and it starts over again
        }
    }
 


That worked ok.  But what if the villager was heading to a resource?  What if the villager was heading back to his building?  What if the villager was actively gathering resources?  All of these things need to be accounted for.  I already had variables I was tracking to cover these possibilities.  Here are the ones for the lumberjack:

  • onTree - I'm busy chopping down a tree.  At first I just made it so the villager would not run away.  But what if the villager finished chopping before the monster is done killing him?  He starts walking away, but the monster remains frozen in place because he hasn't completed his task.  So I also made the villager stop gathering.
  • myTree - The holds the instance_id of the tree to be chopped.  Zero means it's not an instance_id and any other number means it's an instance_id.  Now I know which path I need to create if the lumberjack leaves panic mode.  If it's zero, create a path back to the sawmill.  If it's any other number, create a path to that instance.
But what if the sawmill is destroyed by a monster?  What do the lumberjacks do?  It depends. Are there other sawmills?  Was the lumberjack already headed to that destination?  My solution was this:

The lumberjack does an initial check for the existence of any sawmill (and then the nearest one) and then goes there.  If no sawmill exists, the town center becomes the destination.  When the lumberjack reaches the town center, the wood is deposited, and the lumberjack disappears.

If the lumberjack is already heading back to a sawmill, there is a check that happens every couple of seconds to see if it's still there.  If it's not, recalculate a path based nearest sawmill or town center.

All of this took a lot more time than I expected, but at this point it all works.  Monsters and villagers swarm around doing what they should all on their own.


Friday, August 1, 2014

Hero Worship - Here There Be Monsters (Part 1)


What if?

What if? What if? What if? What if? What if?

That quickly became my mantra.

When implementing any kind of enemy behavior, simple or no, you wind up asking yourself "What if?" a lot.

And not just "What if?".  You have to think about a lot of things.  I'm always reminded of Liz England's excellent The Door Problem on what game designers actually do all day. There's just a lot of stuff to consider.  And when one small part of it doesn't work, it all comes crashing down.

In coming up with behavior for my generic monster type I had two basic states in mind:


  1. The monster had to wander around the map in a seemingly aimless manner, yet also slowly make his way towards the village.
  2. When close to a villager or building, go destroy it.

Wandering Monsters

For the first state, I already had some experience with this very behavior from my game Truffle Shuffle. (WARNING: doesn't work in Win8 for some reason...)   In it, the trippy shroom clouds float around the level and eventually make their way to your base to damage it.  The logic is pretty simple.  For 80 percent of the time, the cloud will choose a random direction to move.  The other 20 percent has the cloud moving towards the base.

With that as my starting place I created a case statement to fire off every 2 seconds or so.  It has three states:  wander aimlessly, head to the town center, and go idle.  The idea here is to give a sense that the monsters are just doing their thing, and yet they will eventually force a confrontation with the player.  I can tweak the percentages to get more or less aggressive monster types.  Right not the idle state doesn't appear to do much, but when animations are in, they could growl, look about, scratch an itch, etc.

The resulting behavior is pretty good.  I set the time interval  between changing states to be based on distance traveled (which is assigned through a random_range).  This way the monster doesn't walk the same distance each time.

Random distance and direction is accomplished by picking a point on a circle of a random size around the monster.  Here's the script:


//move in a random direction.

point = irandom(360);

radius = random_range(50,100);
radius = floor(radius);

targetX = x + lengthdir_x(radius,point);
targetY = y + lengthdir_y(radius,point);

targetX = floor(targetX);
targetY = floor(targetY);

//check to make sure destination is within the room boundaries.
if(targetX>0 && targetX<room_width && targetY>0 && targetY<room_height)
    {
    moving = true;
    move_towards_point(targetX, targetY, GameControl.monsterSpeed);
    }
    else
    {
    event_user(0); //not a valid destination.  Try again!
    }

There's a conditional in the step event (AKA the update function for your non Game Maker people) that checks to see of you've reached the destination and re-fires the case statement to give the monster new orders:

if(moving)
    {
    dist = point_distance(x,y,targetX,targetY); 
    if(dist < 5)
        {
        moving = false;
        speed = 0;
        event_user(0);
        }
    }

This all came together pretty fast.  I should have known the other part would be far more complicated.

What if? What if? What if? ...

Wednesday, July 30, 2014

Hero Worship - Village People

What's a village without people?  Unlike Actraiser I want the villagers to actually walk around and do stuff. In Actraiser, you would occasionally see people walking around and tending to things, but it was all window dressing.  There was no simulation beyond the how upgraded your houses were (and even that happened automatically).

So in borrowing a huge chunk from Real-Time strategy games like Age of Empires I present to you, the humble lumberjack and his buddy the stonemason.



These guys emerge from their buildings, find resources, gather them, and return.  It's pretty simple behavior, but presented a couple of interesting puzzles to solve.  Both of these guys work the same way, so for the purposes of examples, lets just talk about the lumberjack.

The obvious thing to do here would be to make the lumberjack find and go to the nearest tree.  That's all well and good, and thanks to "instance_nearest" in Game Maker, it's a piece of cake to implement.  But what if you have several lumberjacks.  They will all go after the same tree.  The game would still function correctly, but it would look silly.  I want them to spread out, with each lumberjack finding his own tree to chop down.


There are several ways to possibly do this.  I had been reading up on a couple of features in Game Maker. Specifically Instance Ids which are unique identifiers for each instance in your game, and the funky way Game Maker handles functions.  Basically what I did was have the lumberjack find the nearest tree and find the instance id of the tree.  When the lumberjack and the tree collide, it checks against the instance id and if it's the right tree, it starts gathering the resource.  Almost all of this information is packaged up and sent to an external script to be implement with the results being returned to the lumberjack object, or stonemason object, or any other villager that needs to collect something. Super re-usable.  When the lumberjack is full, it heads back to the building and conveniently forgets the tree. More on why in a later post.

This still didn't solve the problem of all the lumberjacks going to the same nearby tree.  I could have created a Boolean variable in the tree object and flip it when it was "taken" by a lumberjack.  But then in order to get the NEXT nearest tree, I'd have to loop through all the trees in the room and check each one.  I'm lazy and didn't want to write that much code so I had a tree object (obj_tree) that was tagged by an incoming lumberjack swapped out for an different, but identical looking tree object (obj_treeC).  That way, the next time a lumberjack looks for the nearest tree, it finds a different one.  This also fixed some weird collision issues I was having because the lumberjacks now only check to see if they are colliding with obj_treeC objects.

The final bit was to implement some kind of pathfinding so the villagers wouldn't get stuck on impassable objects like buildings, mountains, and whatever else ends up in the game.  Game Maker has several solutions.  I first attempted to use the "dumb" pathing which just redirects a moving object if it bumps into something (kind of like a Roomba vacuum).  That mostly worked but they would still get stuck on occasion. That's when I discovered that Game Maker has the A* pathfinding algorithm build right in.

I thought it would be difficult to implement, but the documentation is excellent.  The pathing grid is set up at the beginning of the game.  Before any village moves it checks and creates a path to the goal and then goes on its merry way.  All of this is done in a script that's called from any villager objects in the game whenever they need a new path.  When a new building is plopped down, it's location is added as "impassable" to the pathing grid.  Then a message is sent out to all the villages to recalculate their path based on this new information.  The result is villagers dynamically altering their paths when necessary.

I felt pretty pleased with my progress and with myself.

Then I added monsters...

Sunday, July 27, 2014

Hero Worship - It takes a village

I've been knocking around a game idea for a while and finally started messing around with it in prototype form.  It's a love letter to one of my favorite games from the 90s.  The genre-busting SNES classic, Actraiser.  God what a weird and wonderful game.  It took elements of city building and mixed it up with side scrolling action.













See??   City Building AND Side Scrolling action!!




In reality, the city building part, while fun was quite anemic.  All you really needed to do was hold the enemies at bay while your villagers slowly built up their town until they reached a point where you could move onto the next part of the game.  You could help them with magic spells and by loosely directing their build efforts, but it never really required much thought.

So I figured it would be fun to make the city building part a little more deep while still retaining some of the things that made the original so interesting.  More on that in a later post. For now I wanted to get some basic city building concepts up and running.  And that starts with the humble village.  I'm using Game Maker Studio because it's quick, easy, and I really like it.

I already knew this was going to be more complicated than I originally thought, but having no preconceived notions about what I would be able to accomplish has been strangely liberating.  I love city building games and have played tons of them, so I just started taking bits and pieces of different ones just to see if I could get them to work right.  Honestly?  So far, so good.

The story so far

Disclaimer.  This is all programmer art. blah blah blah.

It all begins with a Town Center.  In Actraiser there was a temple where each "sim" level in the game began.  I don't remember if you could lose it (because I don't think I even lost those levels) but in Hero Worship, losing your Town Center will mark the end of the game.  From the Town Center you can build your basic buildings, currently: houses, sawmills, and stonewerks.   Already this is a major departure from Actraiser.  You never actually built anything in your game.  You only controlled the direction of development on the map.
The blue squares are to check collision.
I was able to quickly rough up a working selection and placement system and well as push scrolling for the game map which is several times larger than the screen. I really think I want this whole thing to be playable with a game pad (even though right now it's mouse only).  I have some ideas on how it's going to work, but for now, I plan on avoiding using common control paradigms like "right-click to cancel".  This immediately presented me with a problem.  What if the player selects something accidentally and needs to back out?  For the Town Center I implemented a proximity check.  If you selected the town center by accident, once you move your cursor far enough away, it automatically deselects.  This is in line with how people generally behave when they do something wrong.  They try to move away from the problem.



So at this point I've got four buildings, a way to place them in the world, and the basic checks to make sure where you are attempting to place them is valid.  My first pass at resources goes something like this:

Currently there is population, wood, and stone.

Town Center:

  • Placed automatically at the beginning of the game.
  • Give a maximum population of 5.
  • Population will increment slowly up to max.
  • Allows building of Houses, Sawmill, and Stonewerks.
House:
  • Cost 5 population.
  • Increases max population by 5.
  • Slight increase in population increment rate.
Sawmill:
  • Cost 10 population.
  • Generates 5 lumberjacks over time.
Stonewerks:
  • Cost 10 population.
  • Generates 5 masons over time.



Wednesday, March 26, 2014

The problem with Interactive Hyper Narrative

What's the problem with Hyper Narrative in an interactive space?  I'll tell you what he problem is.  It's a great big pain in the ass. That's what the problem is.  I also chose to explore this for my Thesis in Emergent Media. This is what I've been spending the last number of months working on.  I knew it was going to be difficult and I think I'm raising more questions than answering them. Here's a little background for the uninitiated.

I'm currently building a short story that's meant to be read multiple times.  You can read all the way to the end of the story, making choices along the way and come to a (hopefully) satisfying conclusion. If you re-read the story and make different choices you will come away with a more complete picture of the events that transpired.  Nothing earth shattering here.

Where I'm trying to push things is through the notion that the choices you make as you are reading will unknowingly shift the story from one track to another, and that the protagonist appears to be the same person in the same world experiencing a different reality of events.  Where on one track the protagonist is a high-functioning success, another version is struggling. To further complicate matters, it's possible to meet your other selves and through that discover that you all have the same agenda. Ok, it's a little weird, but I'm hoping it at least comes together as an interesting experiment.

I'm a little over half-way done and what I've learned so far should have been obvious to me.  Academically, I knew this was going to be difficult.  Writing one decent story is hard enough.  Writing three at once is clearly more complicated.  Weaving them together so the reader can jump around and still follow what's going on leads to vomit inducing headaches.

To that end, I've come up with a few rules for myself to keep the project on track and in scope:

  1. No Dead Ends - The story continues to move forward.  There are no choices that lead to a premature and unsatisfactory ending to the story.
  2. As an extension to rule #1, time must continue to move forward. This is a departure from more traditional forms of Interactive Fiction where the player could move back and forth between areas as much as he or she wants.  In this format the story would only progress when the player did the right combination of actions (like finding the key that unlocks a door). This has led to some trouble making sure the choices presented are interesting.
  3. If the reader jumps to a different track, the story can and should reference what the reader (and the protagonist) knows from the other track. This is extremely hard to do and difficult to keep track of, but I think it has added a lot of flavor to the story.  In Inklewriter, the tool I'm using to build this, tracking variables is fairly simple and highlights a major difference between Hyper Narrative and something you would experience in a Choose Your Own Adventure book.
  4. Keep It Short - The interactive nature suggests that choices need to come quickly and regularly.  Too much time reading the prose tends to encourage the reader to skip ahead to the choice.
I don't yet know how all of this is going to pan out.  And now that I'm in the thick of it, it has become very hard to show my progress as anyone reading through it will see less than 1/3 of what I've actually produced and won't have a full picture.  I can only hope that once it's done it will make sense.  I think it will.