Enabling you to develop the best web. tools and method for you. HTML ,CSS ,CODE ,websigns ,,webdevelopment
Thursday, July 6, 2017
CodeIgniter Form Validation: From Start to Finish
As a web application developer, form validation is a crucial part of your work, and it should not be underrated as it could lead to security flaws in your application. You should consider it a must if you're striving to provide a professional end user experience.
In this article, we'll go through the built-in form validation library in the CodeIgniter framework.
Here are the highlights of today's article:
- Basic form validation
- Cascading and prepping
- Custom error messages
- Custom validation callback
- Validation configuration
Go Through Basic Validation Rules
In this section, we'll go through the basic form validation concepts in CodeIgniter.
As a part of that, we need to create controller and view files. The controller file loads the validation library and runs validation rules against the submitted form data. The view file holds the form XHTML code, and we'll keep it simple for our needs.
Let's go ahead and create these two files.
Create the controller file application/controllers/Validation.php with the following contents.
<?php
// application/controllers/Validation.php
defined('BASEPATH') OR exit('No direct script access allowed');
class Validation extends CI_Controller {
public function __construct()
{
parent::__construct();
// load form and url helpers
$this->load->helper(array('form', 'url'));
// load form_validation library
$this->load->library('form_validation');
}
public function basic()
{
// basic required field
$this->form_validation->set_rules('text_field', 'Text Field One', 'required');
// basic required field with minimum length
$this->form_validation->set_rules('min_text_field', 'Text Field Two', 'required|min_length[8]');
// basic required field with maximum length
$this->form_validation->set_rules('max_text_field', 'Text Field Three', 'required|max_length[20]');
// basic required field with exact length
$this->form_validation->set_rules('exact_text_field', 'Text Field Four', 'required|exact_length[12]');
// basic required field but alphabets only
$this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha');
// basic required field but alphanumeric only
$this->form_validation->set_rules('alphanumeric_text_field', 'Text Field Six', 'required|alpha_numeric');
// basic email field with email validation
$this->form_validation->set_rules('valid_email_field', 'Email Field', 'required|valid_email');
// password field with confirmation field matching
$this->form_validation->set_rules('password_field', 'Password One', 'required');
$this->form_validation->set_rules('password_confirmation_field', 'Password Confirmation Field', 'required|matches[password_field]');
// basic required field with IPv4 validation
$this->form_validation->set_rules('valid_ip_field', 'Valid IP Field', 'required|valid_ip[ipv4]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
public function cascade()
{
// basic required field with cascaded rules
$this->form_validation->set_rules('text_field', 'Text Field One', 'required|alpha|min_length[8]|max_length[20]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
public function prep()
{
// basic required field with trim prepping applied
$this->form_validation->set_rules('min_text_field', 'Text Field Two', 'trim|required|min_length[8]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
public function custom_message()
{
// basic required field with trim prepping applied
$this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha',
array('required'=>'Please enter Text Field Five!','alpha'=>'Only alphabets please!'));
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
public function custom_rule()
{
// basic required field with trim prepping applied
$this->form_validation->set_rules('text_field', 'Text Field Five', 'callback_custom_validation');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
public function custom_validation($field_value)
{
if ($field_value == '' || $field_value == 'demo')
{
$this->form_validation->set_message('custom_validation', "Come on, don't act like spammer!");
return FALSE;
}
else
{
return TRUE;
}
}
public function configuration()
{
// if you pass group id, only elements in that group will be validated
// $this->form_validation->run('group_one')
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
}
Next, create the view file application/views/validate_form.php as shown below.
<html>
<head>
<title>Form Validation Example</title>
<style>
.field_title{font-size: 13px;font-family:Arial;width: 300px;margin-top: 10px}
.form_error{font-size: 13px;font-family:Arial;color:red;font-style:italic}
</style>
</head>
<body>
<div class="form_error">
<?php echo validation_errors(); ?>
</div>
<?php echo form_open(); ?>
<h2>Form Validation Example</h2>
<div>
<div class="field_title">Text Field One (Required)</div>
<input type="text" name="text_field" value="<?php echo set_value('text_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Text Field Two (Minimum length)</div>
<input type="text" name="min_text_field" value="<?php echo set_value('min_text_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Text Field Three (Maximum length)</div>
<input type="text" name="max_text_field" value="<?php echo set_value('max_text_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Text Field Four (Exact length)</div>
<input type="text" name="exact_text_field" value="<?php echo set_value('exact_text_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Text Field Five (Alphabets only)</div>
<input type="text" name="alphabets_text_field" value="<?php echo set_value('alphabets_text_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Text Field Six (Alphanumeric only)</div>
<input type="text" name="alphanumeric_text_field" value="<?php echo set_value('alphanumeric_text_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Email Field</div>
<input type="text" name="valid_email_field" value="<?php echo set_value('valid_email_field'); ?>" size="30" />
</div>
<div>
<div class="field_title">Password Field</div>
<input type="password" name="password_field" value="" size="30" />
</div>
<div>
<div class="field_title">Password Confirmation Field</div>
<input type="password" name="password_confirmation_field" value="" size="30" />
</div>
<div>
<div class="field_title">IP Field</div>
<input type="text" name="valid_ip_field" value="<?php echo set_value('valid_ip_field'); ?>" size="30" />
</div>
<div class="field_title">
<input type="submit" value="Submit" />
</div>
</form>
</body>
</html>
With this setup, you should see a form when you run http://your-codeigniter-site/validation/basic in your browser. Try to submit it without filling any of the form fields, and you'll see the list of error messages! Don't worry if you don't understand how it works altogether as we'll go through every piece of code in detail.
The story starts with the __construct method.
public function __construct()
{
parent::__construct();
// load form and url helpers
$this->load->helper(array('form', 'url'));
// load form_validation library
$this->load->library('form_validation');
}
I always prefer to load common libraries and helpers in the constructor of the controller itself as it's a nice habit to avoid code duplication elsewhere in controller methods. That's exactly what we've done above—we load the form and url helpers so that we can use the utility methods provided by those helpers throughout the rest of the application.
Next, we load the form validation library so that it allows us to bind form validation rules on form elements, as we'll see in the very next section.
Let's go through the code of the basic method. What does this method do? If you call it with the GET method, it'll display the form, and if it was called using the POST method, it applies validation rules on the submitted data and displays error messages, if any, along with the form.
public function basic()
{
// basic required field
$this->form_validation->set_rules('text_field', 'Text Field One', 'required');
// basic required field with minimum length
$this->form_validation->set_rules('min_text_field', 'Text Field Two', 'required|min_length[8]');
// basic required field with maximum length
$this->form_validation->set_rules('max_text_field', 'Text Field Three', 'required|max_length[20]');
// basic required field with exact length
$this->form_validation->set_rules('exact_text_field', 'Text Field Four', 'required|exact_length[12]');
// basic required field but alphabets only
$this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha');
// basic required field but alphanumeric only
$this->form_validation->set_rules('alphanumeric_text_field', 'Text Field Six', 'required|alpha_numeric');
// basic email field with email validation
$this->form_validation->set_rules('valid_email_field', 'Email Field', 'required|valid_email');
// password field with confirmation field matching
$this->form_validation->set_rules('password_field', 'Password One', 'required');
$this->form_validation->set_rules('password_confirmation_field', 'Password Confirmation Field', 'required|matches[password_field]');
// basic required field with IPv4 validation
$this->form_validation->set_rules('valid_ip_field', 'Valid IP Field', 'required|valid_ip[ipv4]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
As we've already loaded the form validation library in the constructor, you can access it using the $this->form_validation convention.
The set_rules method is used to bind a validation rule on a form field. Generally, it takes three arguments:
- The first argument is the name of a form field.
- The second argument is a label that is used to reference a form field while displaying the error message for that field.
- The third argument is the rule that you want to apply on a form field. The form validation library comes with lots of built-in rules that you could use already.
Let's go through some of these rules as we've used them in the basic method.
One of the most frequently used rules is the required rule, which makes a form field compulsory.
// basic required field
$this->form_validation->set_rules('text_field', 'Text Field One', 'required');
Next, if you want to make a form field of a certain length, you can use the min_length and max_length rules.
// basic required field with minimum length
$this->form_validation->set_rules('min_text_field', 'Text Field Two', 'required|min_length[8]');
// basic required field with maximum length
$this->form_validation->set_rules('max_text_field', 'Text Field Three', 'required|max_length[20]');
The first one makes sure that the min_text_field form field is a compulsory field and the user must enter at least eight characters in it. The second one puts a limit on the maximum characters that can be entered in the max_text_field text field, in addition to making it a compulsory field.
You may have noticed that we've used the | operator to apply multiple rules at once. It's called cascading, and we'll get back to it later.
On the other hand, if you want to make a form field of an exact length, you can use the exact_length rule.
// basic required field with exact length
$this->form_validation->set_rules('exact_text_field', 'Text Field Four', 'required|exact_length[12]');
What if you want to validate a form field to alphabets or alphanumeric only?
// basic required field but alphabets only
$this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha');
// basic required field but alphanumeric only
$this->form_validation->set_rules('alphanumeric_text_field', 'Text Field Six', 'required|alpha_numeric');
The next candidate is the email validation.
// basic email field with email validation
$this->form_validation->set_rules('valid_email_field', 'Email Field', 'required|valid_email');
Next, the matches rule allows you to compare the value of a form field with another form field's value. The best example of this is the password field, which must match the password confirmation field when you submit the form.
// password field with confirmation field matching rule
$this->form_validation->set_rules('password_field', 'Password One', 'required');
$this->form_validation->set_rules('password_confirmation_field', 'Password Confirmation Field', 'required|matches[password_field]');
The last example in our basic method is about validating the IP address.
The valid_ip rule validates the IP address against the first argument passed. In the following example, we're only looking for ipv4 type of IP addresses!
// basic required field with IPv4 validation
$this->form_validation->set_rules('valid_ip_field', 'Valid IP Field', 'required|valid_ip[ipv4]');
So that's it as far as basic validation is concerned in CodeIgniter.
How Cascading and Prepping Works
In this section, we'll explore cascading and prepping, which allow you to combine multiple validation rules in a single go.
In fact, I would say that we've thoroughly used cascading in our earlier examples. Recall that pipe operator that was used to combine multiple rules—and yes, the so-called cascading validation rules.
Grab the code of the cascade method.
public function cascade()
{
// basic required field with cascaded rules
$this->form_validation->set_rules('text_field', 'Text Field One', 'required|alpha|min_length[8]|max_length[20]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
As shown in the example above, we've applied four validation rules separated by the | operator to the text_field text box. So it has to go through each and every rule for the form validation to succeed in this case!
Give it a try and see how it works!
Next, there's a prepping that allows you to apply certain operations on the data that's being submitted. More often than not, you want to remove leading and trailing spaces in the user submitted data. Probably the first thing that comes to your mind in this case is to use the trim function, and the good news is that you can use it!
That's exactly what our prep method does.
public function prep()
{
// basic required field with trim prepping applied
$this->form_validation->set_rules('min_text_field', 'Text Field Two', 'trim|required|min_length[8]');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
As you can see, we've used the word trim in addition to validation rules. So the data is trimmed first, and then it'll go through the other validation rules. In fact, you could use any PHP function that takes a single argument as per the CodeIgniter documentation.
Try running our example by adding few trailing spaces, and see how it goes.
Customizing Error Messages
If you've had a chance to run the above examples, you may have noticed that the error messages displayed to the user are pretty systematic and machine generated. Maybe you want to be more creative and change them in certain cases.
Let's see how you could change the error message for any validation rule. Pull in the code of the custom_message method.
public function custom_message()
{
// field with custom error message
$this->form_validation->set_rules('alphabets_text_field', 'Text Field Five', 'required|alpha',
array('required'=>'Please enter Text Field Five!','alpha'=>'Only alphabets please!'));
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
Please note the fourth argument supplied to the set_rules method. It contains an array of custom validation messages for each validation rule, and the key of each array item is the validation rule itself.
array(
'required'=>'Please enter Text Field Five!',
'alpha'=>'Only alphabets please!'
)
Give it a try, and you should see our custom error messages! Pretty cool, huh?
Custom Validation Callbacks
Although the built-in validation library provides a handful of validation rules already, there's always a need to create a custom one in your day-to-day development work. That's exactly what we'll discuss in this section.
To demonstrate that, we'll create a custom validation callback, and later on we'll see how to use it along with the set_rules method.
To start with, let's have a quick look at the custom_rule method.
public function custom_rule()
{
// field with custom validation callback passed
$this->form_validation->set_rules('text_field', 'Text Field Five', 'callback_custom_validation');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
It's no different than the usual set_rules method call except that we've provided the custom validation callback custom_validation instead of any core validation rule. The important thing to note here is that you need to prefix the custom validation callback with callback_ when you pass it as an argument.
Next, let's implement the custom validation callback.
public function custom_validation($field_value)
{
if ($field_value == '' || $field_value == 'demo')
{
$this->form_validation->set_message('custom_validation', "Come on, don't act like spammer!");
return FALSE;
}
else
{
return TRUE;
}
}
When your custom validation callback is called, the value entered by the user will be passed as the first argument. So the $field_value contains a value that's entered by a user, against which you can implement your custom validation logic.
In the example above, you should see the error message if you enter either a blank value or demo in the text field Text Field Five. It's important to note that when you set the error message using the set_message method, the first argument is the name of the custom validation callback method itself.
And that's the story of custom validation callbacks.
Last but not least, it's the validation configuration that deserves some attention as we move towards the conclusion of this article.
Validation Configuration
As a CodeIgniter developer, you should already be familiar with the config directory, which allows you to configure different aspects of your CodeIgniter application.
For example, database.php allows you to define the database-related settings, while autoload.php allows you to define the components that should be auto-loaded during the bootstrapping of an application.
In the same way, you could create the form_validation.php file under the config directory and use that file to define application-level validation rules that can be used globally. If that sounds alien to you, there's no better way to understand it than actually looking at a practical example.
Create the file application/config/form_validation.php with the following contents.
<?php
$config = array(
array(
'field' => 'text_field',
'label' => 'Text Field One',
'rules' => 'required'
),
array(
'field' => 'min_text_field',
'label' => 'Text Field Two',
'rules' => 'required|min_length[8]'
),
array(
'field' => 'max_text_field',
'label' => 'Text Field Three',
'rules' => 'required|max_length[20]'
)
);
Now, let's quickly look at what our configuration method looks like.
public function configuration()
{
// if you pass group id, only elements in that group will be validated
// $this->form_validation->run('group_one')
if ($this->form_validation->run() == FALSE)
{
$this->load->view('validate_form');
}
else
{
// load success template...
echo "It's all Good!";
}
}
Try running http://your-codeigniter-site/validation/configuration and submit an empty form. You'll see error messages for three form fields! But wait, where do they come from, since we haven't set up any validation rules in our configuration method in the first place?
Users with sharp eyes would have noticed that it's automatically picked up from the validation configuration file defined at application/config/form_validation.php. Isn't that amazing? It allows you to centralize the rules in one place and reduces the code duplication in action methods.
In fact, you could group the rules and apply validation to the fields of only a certain group. Let's see how to do that.
Replace the code in application/config/form_validation.php with the following.
<?php
$config = array(
'group_one' => array(
array(
'field' => 'text_field',
'label' => 'Text Field One',
'rules' => 'required'
)
),
'group_two' => array(
array(
'field' => 'min_text_field',
'label' => 'Text Field Two',
'rules' => 'required|min_length[8]'
),
array(
'field' => 'max_text_field',
'label' => 'Text Field Three',
'rules' => 'required|max_length[20]'
)
)
);
In your configuration method, find the following line:
if ($this->form_validation->run() == FALSE)
And replace it with:
if ($this->form_validation->run('group_one') == FALSE)
Now, try to submit an empty form, and you'll see an error for only Text Field One. That's because we've passed group_one as a group id, so only the elements in that group will be validated.
Finally, let's have a look at the type of configuration that allows you to define rules based on the URL.
Replace the code in application/config/form_validation.php with the following code.
$config = array(
'validation/configuration' => array(
array(
'field' => 'max_text_field',
'label' => 'Text Field Three',
'rules' => 'required|max_length[20]'
)
)
);
In this type of configuration, you need to use a combination of the controller name and the method name separated by the / character. In this way, you could define rules for several action methods at once.
Now, you should see the error message for Text Field Three should you try to submit an empty form at http://your-codeigniter-site/validation/configuration.
And that ends the story of validation configuration and this article as well!
Conclusion
In this article, we thoroughly discussed form validation in CodeIgniter.
We started our journey with the basic validation rules, and then we moved to more advanced topics like cascading, prepping, and configuration validation.
I hope you've enjoyed this article, and you can share your valuable views using the feed below!
Wednesday, July 5, 2017
Balancing a Closed Economy in Multiplayer Games
For players, one of the most scrutinized aspects of a video game is its immersion factor. For designers, it’s creating the illusion with seamless finesse. From the first apprehensive steps of level 1 to the final bold strut of level 70, players are deeply woven into an economic system.
How much they notice, however, is the measure of its designers’ success. Especially evident in Massively Multiplayer Online Role Playing Games (MMORPGs), closed-economy structures are magnificent to behold. These games are composed of potentially thousands of tightly controlled interlocking inputs and outputs, and ostensibly appear to be purely about their chosen theme.
Behind the scenes exists a network of intricate maths and economic principles continuing to maintain that immersion. To illustrate, players fresh out of character creation will inevitably begin by doing the following: exploring the environment, conquering enemies, and then purchasing items. This progression will also often occur in that same order. It’s predictable for a reason, and this article will explore why. The concepts explored below will explain how closed economies operate and sustain themselves and the challenges throughout.
Basics of Stability
When conceptualizing an economy, game designers must begin by choosing a currency. Depending on thematic overtures, the name of the currency will vary. For example, many games use the prototypical “gold” moniker. Whether the setting takes place in a fantastical realm or a futuristic timescape will heavily influence the type of currency depicted.
In the case of a closed economy, currency carries a set value. Some designers utilize open economies, however, which operate similarly to real-world money. There are exchange rates, and differential values, which are each relative to one another’s values. Using this model significantly increases the difficulty of creating and maintaining the currency within the game’s world but allows a realistic perspective and some compelling implications. For the purpose of this article, the focus will be on the former.
For example, if an iron sword costs 100 gold, it is expected that it will continue to cost 100 gold. This basic stability allows for the remaining structure to be upheld throughout each play through. While in-game currency, gold, is what your players will be trading, the actual currency that an MMO employs is time. Operating as the game’s independent variable, player progression serves as a substitution for time passing. This commonality between games allows balance for the economy since items can easily have pre-determined time values.
A few basic principles can govern this process nicely. For example, the less progress a player experiences (often expressed as “XP”), the less expensive the product remains. The inverse is also true. So product price and player progression have a directly corresponding relationship.
At level 1, the local tavern sells an iron sword at 100 gold. The difficulty of an event and the reward given share a directly corresponding relationship as well. So a player defeats a worm at level one and receives 5 gold. A player can purchase this sword at any time, but will most likely buy it very early in the game because there is less money available and the item is weaker. It is best suited for the level 1 warrior and will predictably be purchased by the level 1 warrior. Mechanisms like these control the hidden economic fabric of the traditional MMO.
Keeping these principles inextricably connected will continue to provide economic stability to any MMO. Introducing unbalanced items, like downloadable content weaponry that is significantly stronger than currently available weapons, will always disrupt the network. To counterbalance, these items are often not worth much in-game currency or cannot be used until the player reaches a certain level. When these measures are not taken, however, players may feel less engrossed in the game.
Taking this out of theory and into brass tacks, let’s continue.
System Inputs
Developing the specific input modality for item creation and currency allotment is less complicated than it sounds. To begin, there are three interchangeable models for how to complete this feat: utilizing generators, creating event-based inputs, and compiling individually matched inputs.
Generators can be used for anything that regularly adds to the economy without necessary interaction, the only stipulation being some resource-dependency. For example, if you have a player strike oil during renovations, the amount of oil can be determined by the generator, but whether the player uses the pickaxe is his or her prerogative. So when mining for resources, if an unusually specific amount of coal appears on the player’s screen, this is the culprit. After completing the unrelated task the player was engaged in prior to the generator’s activation, he or she may check the inventory and voila! That resource will have manifested itself.
Event-based inputs can be used when given conditions are met. This is most often used in recurring collection quests—quests that require extracting certain herbs from plants to concoct a potion, for example. The formula behind the quest is: “x plant harvested = y herb extracted”. This modality is often tapped for crafting quests and side-missions.
Single inputs are used for circumstantially driven resource acquisition. When certain conditions are met, but they are also not repeatable, these items are offered—for example, when a player conquers a specific opponent and it drops a unique helmet. These are usually reserved for boss battles and story-driven events since they do not require repetition.
System Outputs
Functioning in the opposite way, system outputs remove items and currency from your economy. Similarly to system inputs, there are three major categories: degenerators, event-based outputs, and single outputs.
Degenerators regularly take away resources that do not necessitate interaction. While more sparingly used than their input counterpart, these appear as ongoing costs throughout game play—for example, tax collection that briefly pops up on the Heads Up Display at regular intervals. This oddly specific number will turn up on its own accord without player interference. When checking the inventory, the player will suddenly be missing exactly that amount of currency.
Event-based outputs are used when players complete specific actions that remove resources from their inventories. For instance, a player sells that iron sword to the shopkeep. In doing so, the event-based output activates to remove the sword from the player’s inventory. Depleting resources while crafting, submitting items for quests, and dropping unwanted items all constitute event-based outputs.
Single outputs are utilized when a resource is removed from the economy altogether and cannot be altered again. Many designers use this mechanism when items must be delivered or destroyed based upon story elements—for example, when obtaining a quest item that players cannot use. These items are usually distinguishable from the others by being held in a separate section of the player’s inventory—like “key items”—and can only be removed when certain events unfold.
Artificial Stability in an Unstable World
Utilizing all three techniques enables game designers to create seamless worlds for their players—if they are in harmony. Ideally, the planned economy would be a perpetually operative and well-oiled machine. It would have a set of inputs that exactly equals the number of outputs, which together produce a purely immersive experience.
However, the ideal rarely becomes real. Being human hosts a number of spectacular pros, but one con is that we are not perfect. We are not machines, and thus our creations will usually come to fruition with flaws. To keep these flaws at a minimum, and relatively minuscule, this article will leave you with some machine-ly wisdom from experience.
- Flag Impactful Items: to most efficiently contain simple mistakes in an intricate economy, assign priorities to each resource based on its orb of influence. For example, implementing tighter controls on an epic-level sniper rifle should become a higher priority since it can easily upset the economy. Having an overabundance of iron ore, however, is less likely to have such a significant effect. This way, when entering miles of code in the vast matrix that is the economy, little red flags will tip off any developer that this particular item is a heavy-hitter.
- Don’t Underestimate Bug Checkers: having players test an alpha version of any game is the first line of defense against potentially disastrous economies. Though some issues may not become evident until more time has passed, these players are ready and willing to try. If an enemy is just too powerful or a weapon is just too rare, they will be upfront with their critique. If this prospect seems a little too gut-wrenching, having friends and loved ones look it over is always a gentler option.
- Matrix Double-Glance: daunting, yet unfailingly practical, this technique involves compiling all the game’s items included in the economy and listing them in spreadsheets. Check it against itself forwards, and backwards, and then code it manually. To add another level of security, implementing an automated system and letting it convert the items will drastically improve both accuracy and speed.
- Abandoned Accounts: multiplayer economies have several unique challenges to keep in mind. Suspended, dormant, and otherwise abandoned accounts can create unaccounted-for outputs across a wide variety of resources. This situation can be combated by building slightly different expected-resources-per-player ratios. Do away with generators and de-generators that operate at a fixed rate. Instead, control the flow of resources based on the current amount operating in the economy. This should eliminate any wealth hoarded by abandoned accounts.
Conclusion
Creating a multiplayer economy is an ambitious but rewarding journey. Being able to observe the careful cogs of code manifest themselves as a bustling marketplace is truly spectacular. Even when players gripe about how expensive the rare daggers are, designers know that it is all working according to plan.
This article has only scratched the surface of what makes MMORPG economies thrive. But the first step is always the hardest! Being able to successfully track resources is a fundamental building block that will launch any game developer ahead in his or her project and field. Examples of how the next steps in this journey may look include exploring ideal resource ratios, establishing player-to-player commodity trading, virtual banks for storing currency, and many more.
To continue the discussion, feel free to drop a comment in the box below!