Implementing Events 2 – Expanding and Frequency

There is still more to be said about Events so here is part 2!

Expanding the Events Feature

If all the game did was pick a random event from a pool of every event, the world wouldn’t seem very… alive…duuude. So, some events should only happen in particular climates (I call them Biomes). For example coming across a pool of water might be something that can happen in any biome but an event like “Falling Tree” might only happen in a Forest biome and not in a Plains biome.

To allow for this Events have a Biome, Terrain and hasPriority property. When the game’s engine creates the pool of available events to choose from it grabs all events that can happen in any biome as well as the events that can only happen in the biome the character is currently in. So a character in a forest biome, Big Tree terrain would have an event pool that contains events that can happen in Any biome, in the Forest biome specifically and events that can only happen in the Big Tree terrain tile.

The hasPriority property is only used if a certain event should always be used in a given terrain tile. Such as a Throne Room terrain tile in a dungeon should always have a boss encounter. That event would then have it’s Terrain property set to ‘Throne Room’ and hasPriority set to True (as that variable is a bool).

Event Frequency

There is also a Frequency property to each event and event reward. This number give some measure of control over which events are more common over others. Not too much to say about that one really. While the concept is fairly straightforward, implementing it was not so simple. So here is what I did:

After creating the initial Event Pool, I had a list of possible events. I then added together all the event’s Frequency properties. I used this number as my MaxRandom number, the maximum number the game could roll when picking an event from the pool. I also made a second list called the Event Pick List which only had 2 properties: Event and SlotID. This list was then populated with a number of entries for each event equal to the event’s Frequency. So, an event with a frequency of 10 would have 10 entries in the Pick List. The engine also applied SlotID numbers in sequence.

For Example:
An event pool with 3 events:
A Pool of Water (Freq. 10)
A Falling Tree (Freq. 5)
Strange Mushrooms (Freq. 5)

MaxRandom = 20 (10+5+5)

Pick List:
A Pool of Water (slotID = 1)
A Pool of Water (slotID = 2)
A Pool of Water (slotID = 3)
A Pool of Water (slotID = 4)
A Pool of Water (slotID = …)
A Falling Tree (slodID = 11)
A Falling Tree (slodID = 12)
A Falling Tree (slodID = 13)
A Falling Tree (slodID = …)
Strange Mushrooms (slotID = 16)
Strange Mushrooms (slotID = 16)
Strange Mushrooms (slotID = 18)
Strange Mushrooms (slotID = …)

Then the random number is picked between 1 and MaxRandom. The number picked corresponds to the Pick List’s slotID and that is the event assigned to the character.

With some form of filtering being applied to the possible events and then frequency being taken into account to allow for common/rare events, when a character encounters an event it will hopefully feel more meaningful.

Implementing Events Part 1 – Being Stateless

I’ve started implementing the Events feature into Nano. So far my posts haven’t been too technical or in depth, so this one might be a bit heavy for some. First, allow me to describe the overarching idea behind Events in Nano.

The Idea

As a player navigates the world they occasionally encounter an Event upon entering a new location. An Event is basically a description of something that is happening and a list of choices about how to react being made available to the player. Once the player has made a choice they are given some type of result, such as stat alterations, finding treasure, or getting into combat with an enemy.

Example Event

A player enters a new location called ‘The Open Plain’. Upon entering this location they are shown an Event screen, for the event ‘A Pool of Water’. This event has a description; “You see a pool of water. It looks clean enough to drink.” and a couple of choices:
Choice 1: “Drink the water.”
Choice 2: “Ignore the pool of water, bugs have probably pooped in it.”

The player selects Choice 1, “Drink the water.” (Ignoring the possibility of bug poop!). This choice results in the character’s Thirst being reduced by 100. Had the player ignored the water, they would not have received that reward. A second screen is displayed given both a description and a breakdown of the results.

“You drink the bug poop free water. Ahh, refreshing!”
Thirst: -100

How to Organize the Data?

So now that we know the overall idea of what we’re trying to do. How do we execute that in code? It’s never as straightforward as you think and even when you’re prepared for it to become complex, it’ll go and get even more complex than that. This is because at this stage of development I’m really building a system, not just a ‘if this, then that’ scenario.

How does the database look?

First I had to figure out how to organize the information in the database. Will the events, choices and rewards all be in one table or would it be better to have a separate table for each event element?

After a lot of thought, I decided on having separate tables for Events, Event Choices and Choice Rewards. The reason is that each of these has a One-to-Many relationship with the next. For example an Event has many Choices and each Choice can have many Rewards. This would suggest that using a separate table for each piece would be the best way to manage them.

Being Stateless

One major pain that I’m always dealing with in this project is that as a web game using MVC4 and standard postbacks (ie. I’m not using Flash) is that this game is Stateless. Most games can save information about the player’s current location, stat values, and what screen their looking at in your computer’s memory, but not Nano. Nano needs to save all these variables in a database and access that database after every player choice.

Being Stateless Allows Cheating

So given the Stateless limitation, how does the player’s choice get sent back to the server? Another problem with being Stateless is that user input cannot be trusted, they could send any value they want back to the server and the server just accepts that value, never thinking that the user might be a big fat cheater! For example, if a player is in combat and clicks the Use Kick button, the link they click actually forms a URL that ends in /UseCard#CardID=3 which calls the UseCard method with CardID=3 (3 being the ID # for the Kick card).

So there you go, that’s how you can try to exploit Nano. During a combat just change the url to have the CardID equal a number of an amazing card like ‘Sword of a Thousand Truths Stab’ and you can use that card even if it’s not in your hand or even in your deck!

Just kidding, you can’t do any of that because I had to take special measures to stop that form of abuse. Again, because the game is stateless, when the user sends a request to use a card with a particular ID I first check to see if that card is in the user’s hand. If not the user will get a message saying it’s an invalid card and then it will taunt them for trying to cheat. But the point is, this is something many games don’t have to be concerned about since they can store information in memory.

Record the Character’s Current Event

Something that is nice about working in this Stateless environment is that it allows the player to leave the game at any moment and when they return they will be right back where the left off. Whether that is standing in the middle of a forest, at a crucial choice for an event, or right in the middle of combat.

But this also means that the game must record everything to allow for this seamless return. For Events, I decided to add a property to my Character records called ActiveEvent this field stores the ID# of the event that the character is currently involved in. Upon page load the game says “Is the character in an event?” If no, then the ActiveEvent field is null and the game displays the location the character is in. If yes, then the game looks up which event it should display based on this ActiveEvent field.

Sum it up

So that’s how working in a stateless environment for a game adds a layer of complexity to the design of the game. I have to think about everything in steps and each step has to end in a single output of information for the player to react to. In the next post I’ll get into making events more interesting by limiting their frequency and availability.

Inventory got all AJAX’d up

Over the weekend I enlisted the help of my old pal Zach Lysobey to give me some tips on adding Ajax functionality to Nano. Zach and I have been working together as a web design and development duo for years now as Rough Giraffed. He’s no stranger to javascript, AJAX and programming in general so he was able to hook me up with the basics real quick.

Ajax is a technology that does lots of stuff for websites/applications, but for Nano the primary benefit is avoiding full page refreshing. This is another step into making Nano feel less like a browser game and more like a standard video game. Avoiding the flicker of a full page refresh will hopefully make the player feel like they haven’t left the game world to enter an Inventory screen. Instead the Inventory screen opens right there, as an overlay to the standard World screen.

The screenshot above can’t show the Ajax functionality in action, that’ll have to wait for the video demo. But what you do see is how the current, basic Inventory screen looks. On the left is the character’s inventory with a list of Cards, and Items gathered from the world or winning events. You see a bunch of Kick cards because, while testing, I had my ol’ Test Dummy only dropping Kick.

On the right is the character’s Deck list. These are cards that the player can use while in combat. Currently, there are only about 15 cards in the deck, but later there will be a minimum deck size that will, most likely, be greater than 15.But, I’ll get more into Deck editing, and Items in another post.

For now, just know that there will be a lot of this kind of effort put into making this browser game not feel like a traditional frame-based browser game.

Basic Survival and Character Score Added

Survival

You’re wandering around a forest. You’re don’t know where you are, but you aren’t lost. Where you are isn’t something you are concerned about, but where you are going to get your next drink of water, or bite of food is.

I’ve added some basic ‘Survival’ mechanics to Nano. As you move from location to location you gradually build up Hunger and Thirst. Meat and Water Jug consumable items have been added to sustain your character. If a character reaches a certain hunger or thirst threshold they will begin taking damage whenever they move to a new location as they slowly dehydrate or starve to death.

Currently the only way to get your hands on Meat or a Water Jug is to win a random encounter with an enemy, and then hope that enemy drops the consumables. This is causing a bit of an issue because there is currently only a 10% chance a character will get into a random encounter, and on top of that there is an 20% chance the enemy will NOT drop a consumable. Meaning, consumables are fairly rare, while starvation is common. It’s like a virtual 3rd world country.

So next up is adding more sources of food and water. One thing I plan on adding is environmental sources of sustenance. Rivers, streams and lakes that provide water, and edible plants to reduce hunger. I hope this will keep vegans off my back as well.

Score

I also added some simple Scoring mechanics. Currently, a player is awarded points for every combat encounter that they win. The value of the combat is determined by the type of enemy encountered. Soon I’ll be adding more ways to up one’s score, such as points for discovering new locations, or perhaps acquiring hard to get items.

The idea of having character’s maintain a score is that eventually there will be a leaderboard. Where players can compete to be top dog. Aside from that I’d like to have a character history page. A page where a player can go and see all of his/her old, deceased characters, along with the character’s score upon death. This will allow players to try to beat their personal best score as well as compete against other players.

Weekend Update 05-12-13

Some updates from this weekend:

  • UI improvements for the World screen. It still have a ways to go, but it’s a start.
  • Random Monster Encounters! Characters are now hurled into combat randomly when they enter a new location.

Probably going to need to reconjigger Cards and combat again to make room for more complex card interactions. I’d like to avoid making a separate method for each card, but I think some cards will require it.

Thinking about making more complex card interactions means I might have to step my AI’s game up. Perhaps that is where I can begin implementing the learning AI I’ve been wanting to experiment with.

I need to add a lot more content, more Cards, Enemies, Terrains, Items, etc. I’ll make a form that I can use to easily add those things to the database.

I hope to have a veeeeery early build “playable” in a few weeks, if anyone is interested in trying out what I have so far.

Pre-Alpha: World Screen

Here is a preview image of the “World” screen. As a player navigates the world they will be shown artwork for the terrain type they have come upon, as well as a text description.

You can also see the current implementation of the navigation buttons. Which are simply text links for now. As I begin working on the actual user interface these text links will change into buttons with graphics, just like a big boy game!

Codename: Nano

Here is a brief description of the game that I’m developing. Pretty much nothing is set in stone but these are some of the ideas I’m working on and/or implemented already.

Nano is the temporary name of my browser-based, multiplayer  survival game. Nano puts the player in control of a character who explores the world, fighting enemies, getting loot and just trying to survive in the distant future.

Setting

“The distant future you say? Well I’m sure survival is easy in the future! It’s already so easy to live now!” – Some Nerd

“No.” – Me to some nerd

Nano’s set on Earth in the distant future centuries after an apocalyptic event that left very few humans alive. Those that did survive have had to start over, living in small nomadic tribes, living off the land, no longer having access to technology.

Centuries have passed since the apocalyptic event took place and nature has done its thing and reclaimed the land and sea. The Earth is starting to look a lot like it had in the time before humanity ever came around and mucked everything up.

So you’ll be able to piece together more about the world as you roam around. Neat.

Features

  • The world uses procedural generation to build the world as players explore new locations.
  • Survival! Starvation, Dehydration, Disease! All fun ways to die! 
  • Card based combat! As you explore the world you’ll find cards and edit your deck, effectively ‘customizing’ your character. No classes, no levels, that crap is played out.
  • ScoreBoard: Explore, win fights and find stuff to gain points and get ranked against other players.
  • Death is fun! Permanent death! (As see in the hit classic, Real Life!)
  • Multiplayer! I don’t know how exactly yet, but it’s possible… and characters all exist in the same persistent world so it’s just a matter of adding ways for them to interact. Shouldn’t be hard to do, right?
  • Arts! Nice world and character art to look at, so you’ll have something nice to look at while you die of dysentery.
  • And probably more!

Tech Stuff

I’m using C#, asp.net MVC4, and SQL server.

Why these things?

I dunno really. I don’t know enough about all the different options out there to make an informed decision. I just saw what MVC4 could do and was like “Hey! I could make a game with that, I think!” and here we are.

So… what is it, again?

I’m taking inspiration from a few other games:

  • FTL
  • Kingdom of Loathing
  • Magic: The Gathering
  • DayZ
  • Your standard RPGs

Combining aspects of those games and others to make some concoction that I haven’t seen before, but probably already kinda exists because that’s how the world is.

So, those are the basics. I’ve got a long way to go, so let’s see what happens.