January 3, 2017

Building a Stat System in Monogatari

Monogatari while having several features right out the box, it still lacks an implementation of a Stat system, which you could use to create Dating Sims and RPG games, however it does have something, Monogatari is extremly extensible and adding a Stat System is fairly easy.

Step 1: Add the stat Object

Monogatari ships with a variable reserved for custom storage, the storage variable will be found in the options.js file. Inside the storage object, we can put anything we want to save every time a player saves the game. By default it will look like this:

// Persistent Storage Variablevar storage = {	player: {		Name: ""	}}
As we can see, there's already a property called player there, we'll use that property to save our stats. Since it's a date sim, we might want to store stats like intelligence, love, attractiveness etc. To do so, let's create a property inside the player object for the stats and let's start them all in cero:

var storage = {	player: {		Name: "",        Stats: {            "intelligence": 0,        	"love": 0,            "atractiveness": 0        }	}}

Now we can access this from JavaScript and the stats will be saved with every saved game. What we need now is to be able to add or substract points to those stats. To keep this simple, doing it by using functions might be the best option.

Step 2: Make our stats usefull

When you first create a new Monogatari Project, there's already a custom Script, in it you can actually see the storage.player.Name property being used to store the name of the player:

var script = {	// The game starts here.	"Start": [		"notify Welcome",		{"Input": {				"Text": "What is your name?",				"Validation": function(input) {					return input.trim().length > 0;				},				"Save": function(input) {					storage.player.Name = input;				},				"Warning": "You must enter a name!"			}		},
"h Hi {{player.Name}} Welcome to Monogatari!", "h Have you already read some documentation?",
{"Choice": { "Yes": { "Text": "Yes", "Do": "jump Yes" }, "No": { "Text": "No", "Do": "jump No" } } } ],
"Yes": [
"h That's awesome!", "h Then you are ready to go ahead and create an amazing Game!", "h I can't wait to see what story you'll tell!", "end" ],
"No": [
"h You can do it now.",
"display message Help",
"h Go ahead and create an amazing Game!", "h I can't wait to see what story you'll tell!", "end" ]}

Let's modify the script to make use of our new stats:

var script = {	// The game starts here.	"Start": [		"notify Welcome",		{"Input": {				"Text": "What is your name?",				"Validation": function(input) {					return input.trim().length > 0;				},				"Save": function(input) {					storage.player.Name = input;				},				"Warning": "You must enter a name!"			}		},
"h Hi {{player.Name}}, this demo is to demonstrate how to create a simple stat system", "h Currently you have " + storage.player.Stats.intelligence + " points of Intelligence but you seem far more intelligent, how about we add five points?", function(){ storage.player.Stats.intelligence += 5; next(); }, "h There you have it, you now have 5 more points of Intelligence", "end" ]}

Now the script will ask for your name, show you the initial quantity of intelligence points you have and then add 5 points to it. The same can be done with all the other stats.

Step 3: Show the Stats

We now have modified the stats but currently there's no way the player can see how he's doing so let's add a screen for that. In order to do that, we need to add 3 things:

  1. The HTML code of our new screen
  2. A button to show and hide the stats
  3. The javascript code to make that button work

For the HTML part, we'll create a modal window but it really is up to you how you want your players to view the stats. Add the following code right above the data-ui='message' element:

<div data-component="modal" data-ui="stats" class="middle vertical align-center">	<b>Stats</b>	<span>Intelligence:</span>	<meter value='0' max='10' data-stat='intelligence'></meter>	<span>Love:</span>	<meter value='0' max='10' data-stat='love'></meter>	<span>Attractiveness:</span>	<meter value='0' max='10' data-stat='attractiveness'></meter></div>

As you can see, by using meters the players will actually see a bar for each of their stats. Now let's add the button to the data-ui='quick-menu' element:

<span class="fa fa-tasks" data-action="stats"></span>

And finally inside the main.js file, we'll add a handler so that when the button is clicked, the modal is shown or hidden:

$_ready(function(){	$_('[data-action="stats"]').click(function(){		if($_('[data-ui="stats"]').isVisible()){			$_('[data-ui="stats"]').removeClass('active');		}else{			$_('[data-ui="stats"]').addClass('active');		}	});});

Once you've done all this, you should be able to see the button, click it and the stats will be shown. However, after some playing will it, you'll notice something, the stat bars are not changing even when the stat is modified. The reason is simple, we are changing it's value in JavaScript but not in the HTML document however doing it with our current code that would involve repeating many innecessary code. How about we create a function to modify the stats instead of doing it manually as we previously did? To do it, right above the declaration of the script variable in the script.js file place the following function:

function stat(stat, value){	storage.player.Stats[stat] += value;	$_("[data-stat='" + stat + "']").value(storage.player.Stats[stat]);}

The function will take 2 parameters, the stat name and the quantity you want to add, once added we can modify our previous script code:

var script = {	// The game starts here.	"Start": [		"notify Welcome",		{"Input": {				"Text": "What is your name?",				"Validation": function(input) {					return input.trim().length > 0;				},				"Save": function(input) {					storage.player.Name = input;				},				"Warning": "You must enter a name!"			}		},
"h Hi {{player.Name}}, this demo is to demonstrate how to create a simple stat system", "h Currently you have " + storage.player.Stats.intelligence + " points of Intelligence but you seem far more intelligent, how about we add five points?", function(){ stat("intelligence", 5); }, "h There you have it, you now have " + storage.player.Stats.intelligence + " points of Intelligence", "end" ]}

This way we'll be able to easily change the stats value both in JavaScript and the HTML bars.

Step 4: Changing choices

We've got now a fully functional stat system, the question now is how will we use it? Here are some options:

Step 5: Styling

Naturally, you'll need to style your meter bars and modal window in order to look pretty and match your game's style, just add some CSS and your game will be ready to amaze people!