MOBA Hero Generator documentation

2017-03-17, by Markus V.

The MOBA Hero Generator "generates" MOBA-game style heroes by randomising which content to show on page.
Here I'll go into detail on each element and try to explain how they work.

Here's an example of a generated hero (click to enlarge). The second image shows all the randomised content.

Example generated hero The generated content

Generating hero name

The hero name has two schemes from which to choose from. The first scheme is a simple one part name and returns names such as "Talos", "Aggrott" and "Chimera".
The second scheme combines elements from 2 arrays to form names such as "Dragon Guardian" and "Phantom Emperor".

In the beginning of my .js file I have a simple function which I call multiple times throughout the whole content generation process:

var randInt = function(low,hi) {return low + Math.floor(Math.random() * (hi-low))};

For the hero name generation I have three arrays:

var fantasyNames = [
	'Acidos','Javyn','Tempero', ... ]
var namePart1 = [
	'Abyssal','Phantom','Wyrmtooth', ... ]

var namePart2 = [
	'Assassin','Incarnate','Titan', ...	]

The createHeroName function (below) first rolls a number to decide which naming scheme to use. If the first one is selected a random number is rolled and a name is selected from the array and returned.
The second scheme does exactly the same except it has to combine the two names before it is returned.

After this we can simply select the desired html element and call the function to have the returned final name placed in it. The created name is also stored as a variable for later use.
This is how the name selection looks like:

function createHeroName() {
	var heroName = "";	
	var ranNum = randInt(0, 100);	
		if (ranNum <= 50) { 	
			heroName = fantasyNames[randInt(0, fantasyNames.length)];		
		} else {
			heroName = namePart1[randInt(0, namePart1.length)] + " " + namePart2[randInt(0, namePart2.length)];	
		}
	return heroName;
}
var heroName = createHeroName(); 
$("div.heroName").html(heroName);

Generating hero sub-name

The sub-name is the "title" or so beneath the main name. They are usually something like "The Destroyer of Nations" or "The Abyssal Berserker" and so forth. The hero sub-name generation is very similiar to the main name generation.

There are 2 naming schemes from which to choose from, both with 2 arrays from which to combine the name. It is also decided whether or not the sub-name should have "the" prefix placed before it. The arrays and the whole sub-name generation looks like this:

var subName1A = [
	'Aegis of','Destroyer of','Savior of', ... ]
var subName2A = [
	'Depths','Empires','Steel', ... ]
var subName1B = [
	'Arcane','Crimson','Wild', ...	]
var subName2B = [
	'Annihilator','Juggernaut','Protector', ...	]
			
function subNameThe() {
	var result = "";
	var ranNum = randInt(0 ,100);
		if (ranNum <= 50) { 		
			result = "The "; }
	return result;	}	

function subName(myParam1, myParam2) {	
	var ranNum1 = randInt(0 ,(myParam1).length);
	var part1 = myParam1[ranNum1];
	var ranNum2 = randInt(0 ,myParam2.length);
	var part2 = myParam2[ranNum2];
	var subName = part1 + " " + part2;
	return subName; }			
					
function createSubName() {
	var finalName = "";
	var ranNum = randInt(0 ,100);
		if (ranNum <= 50) { 		
			finalName = subName(subName1A, subName2A);		
		} else {			
			finalName = subName(subName1B, subName2B);
		}		
	var result = subNameThe() + finalName;
	return result; }	

$(".heroSubName").html(createSubName());

The array names are used as parameters. The arrays of the first naming scheme are subName1A and subName2A, while the second's are subName1B and subName2B. Afterwards we can simply select our html element and have the name placed in it by calling the createSubName function, as it returns the final name.


Selecting hero avatar

The displayed hero avatars are ripped from Smite, Warcraft 3, Dawn of War 2 and Heroes of Newerth. The avatar selection is very simple.

My image files are named incrementally. I input the total amount of avatar images into a variable and use it to generate a random number. The number is returned. We select the avatar img element on the page and modify its src attribute based on the random number to form a file path to a random avatar image, eg. pics/main/heroes/254.jpg. This is how it looks like:

function selectAvatar() {
	var totalImgs = 598; /* avatar image total goes here */
	var ranNum = randInt(1 , totalImgs);
	return ranNum; }
	
$('.avatar').attr('src', 'pics/main/heroes/' + selectAvatar() + '.jpg');

Selecting roles

The roles are tags to identify the characters in-game purpose and playstyle. On the generator these are selected randomly from a few arrays so unfortunately they are not consistent or intelligent with each other, or with the skills.
My approach also limits the possible combinations a bit, but some combinations are simply not believable (such as a character having both the "Carry" and "Support" tags).

Here are the arrays from which the roles are selected:

var roles1 = [
	'Melee, ','Ranged, ' ]
var roles2 = [
	'Carry, ','Hard Carry, ','Semi-Carry, ','Support, ','Tank, ','Jungler, ','' ]
var roles3 = [
	'Disabler, ','Pusher, ','Ganker, ','Nuker, ','Initiator, ','' ]
var roles4 =[
	'Durable, ','Escape, ','Roamer, ','Offlaner, ','' ]
var roles5 = [
	'Fighter','Slayer','Mage','Controller','Bully','Stealth','Sustain','' ]					

Note how the elements in the first 4 arrays have a comma and a white space after them. The last array doesn't have these. This setup worked nicely before I added in the empty array elements. I added it for the sake of variety so a hero won't always have all the 5 roles. This however caused problems; if the last array rolled the empty element, the fourth one would end in a comma and a white space. This was unacceptable so I added in a small check to take care of this.

Here's the whole role selection code:

function createRoles(){
	var role1 = roles1[randInt(0 ,roles1.length)];
	var role2 = roles2[randInt(0 ,roles2.length)];
	var role3 = roles3[randInt(0 ,roles3.length)];
	var role4 = roles4[randInt(0 ,roles4.length)];
	var role5 = roles5[randInt(0 ,roles5.length)];
	
	var roles = role1 + role2 + role3 + role4 + role5;	
	if (roles.substring(roles.length-2) == ", ") { 
        roles = roles.substring(0, roles.length-2);
		return roles;	
	}		
    return roles;	
}
$(".roles").text(createRoles);

Selecting stat icons

I have a few different icon sets for the hero statistics. I added them for the sake of variety. All the graphics are ripped.

I have a switch statement which has one case for each icon set. Once again, a number is rolled and the case is selected based on the integer. The iconSetSelector function outputs a string which is used as a parameter in the statIconSet function, which sets the src attribute of the icon image elements in the html.

The files needed to be named in uniform style to make this work. More icon sets could be added easily with this setup by just increasing the range for the random number and adding in more cases.

This is how the icon sets are selected and displayed:

function statIconSet(set) {
		$('.hp').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_hp.png');
		$('.hpRegen').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_hpRegen.png');
		$('.mana').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_mana.png');
		$('.manaRegen').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_manaRegen.png');
		$('.atkDmg').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_attackDamage.png');
		$('.magicDmg').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_magicPower.png');
		$('.armor').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_armor.png');
		$('.magicArmor').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_magicArmor.png');
		$('.moveSpeed').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_movementSpeed.png');
		$('.atkSpd').attr('src', 'pics/main/stats/' + set + '/stats_' + set + '_attackSpeed.png'); }

function iconSetSelector(){
	var selectedSet = "";
	var rand = randInt(1 , 5.999);
	switch(rand) {
		case 1:
		selectedSet = "dow";
		break;
		
		case 2:
		selectedSet = "lol";
		break;
		
		case 3:
		selectedSet = "dota";
		break;
		
		case 4:
		selectedSet = "wht";
		break;
		
		case 5:
		selectedSet = "wc3";
		break;
	}	
	return selectedSet;
}
statIconSet(iconSetSelector());	

Selecting stat names

The different stats have some variation in their names. The setup is simple; each stat has an array from which to choose a name based on random number. This however causes problems in consistency in the displayed content.

For example, if we roll "Magick Force" in the magic power stat slot and "Physical Armor" in the armor stat slot, the magic armor stat name should logically be a combination of the two; "Magick Armor". This is achieved with simple regular expressions. The exact wording across the content is also important so the stat names as stored as variables for later use.

Here we first create the name for the magic power stat by selecting an element from statsMagicPower array based on a random number, store it as a variable and input it into the appropriate html element for display:

function createMagicPowerName() { 
	var name = statsMagicPower[randInt(0 ,statsMagicPower.length)];
	return name;}
	
var magicPowerName = createMagicPowerName();
$(".magic-dmg").text(magicPowerName);	

Then we do the exact same for the armor stat; create a name, store it as a variable and input it into the selected html element:

function createArmorName() { 
	var name = statsArmor[randInt(0 ,statsArmor.length)];
	return name;}
	
var armorName = createArmorName();
$("li.armor").text(armorName);

Now we are ready to create the magic armor stat name based on these two names.

The previously created stat names are given new names and a check is performed on both of them. The strings are tested for white spaces with the RegExp.test(string) method. If the name has two parts (eg. Magick Force) the white space is encountered, and the desired part for removal is matched with a regular expression and removed with string.replace() method.

In these examples the underlined parts are matched and removed:

This way we preserve consistency and the new name is a combination of the magic power and armor stat names.
In the above example we would get "Magick Shield" as the magic armor stat name.
With these checks the previously created names can be anything and the combined name will always be accurate and consistent with them.

This is the magic armor stat name creation script, here the stat is called "Magic Resist":

function createMagicResistName() { 	
	var magix = magicPowerName;
		if (/\s/.test(magix)) {
			var magixRegex = /([\s].+)/ 
			magix = magix.replace(magixRegex, "");		
		}	

	var armorz = armorName;
		if (/\s/.test(armorz)) {
			var armorzRegex = /([^\s]+)./
			armorz = armorz.replace(armorzRegex, "");		
		}

	var result = magix + " " + armorz;
	return result;	
}
var magicResistName = createMagicResistName();
$(".magic-resist").text(magicResistName);

The regular expression for editing the magic power name is also used to extract only the magic name for later use.
The name will be used in skill description texts so before returning the name the capital first letter is lowered with string.toLowerCase() method. At this point nothing is done further with the extracted name.

The magic name only is extracted like this:

function extractMagicName() {
	var magix = magicPowerName;
	if (/\s/.test(magix)) {
		var magixRegex = /([\s].+)/ 
		magix = magix.replace(magixRegex, "");		
	}	
	magix = magix.toLowerCase();	
	return magix;		
}
var magicDamageName = extractMagicName();	

Generating stat numbers

I used the statistics of League of Legends characters for reference when creating the scripts for the stat numbers. The numbers are random but stay in a believable range for a generic MOBA-game context. All the stat number scripts follow the same pattern; simply generate the numbers in the specified range and input them to a selected html element.

Here are some examples:

	$('.baseHP').text( Math.floor(Math.random() * (610 -  490 + 1)) + 490); 
	$('.perLvHP').text( Math.floor(Math.random() * (89 -  68 + 1)) + 68 ); 
	
	var num1 = ((Math.random() * (8 -  5 + 1)) + 5).toFixed(2);
	$('.baseHPregen').text(num1); 	
	var num2 = ((Math.random() * (1 -  0.5 + 0.1)) + 0.5);
	var num3 = (Math.round(num2 * 20 ) / 20).toFixed(2) ;
	$('.perLvHPregen').text( num3 ); 

Below the base mana stat is rounded between tenths. If a decimal is other than 0 it will be shown (such as 365.2). If the number is an integer the decimal won't be shown; 365.0 displays just as 365.

	var num4 = ((Math.random() * (390 -  280 + 1 ) + 280));
	var num5 = (Math.round(num4 / 0.1 ) * 0.1) ;	
	if(num5.toString().indexOf('.') != -1)
		num5 = num5.toFixed(1);
	$('.baseMana').text( num5 ); 

Creating flavor text

The flavor text is a small snippet of "lore" or background story of the hero. The flavor text generation used here is quite crude; a text is inserted into html, and afterwards a few selected words are replaced based on span elements with specific classes. A better way would be to edit the text first and then insert the finished text into the html for display. But the current system works fine so I let it be.

I built the MOBA Hero Generator on one of my earlier projects, d3_random, which generated flavor texts by taking in flavor texts copied from Diablo 3 and replacing specified words with new ones. Later on I added in some other texts.

The generated texts are usually not very intelligent or original (as only a few words are replaced), but I decided to include it as the flavor text generation was already built and in the project. It also fits in the MOBA context.

I wrote a text file on how the d3_random works. The same system is used here.


Skill slots

The skill slots (which include the icons, names and descriptions) were initially the most challenging parts to get right, but also the most interesting ones.

In the html I have 4 identical elements with skill-item class. The elements are iterated over one after another and the contained elements are populated along the way with content.

First we select all the elements with the skill-item class and create an array out of them. Then they are iterated over with array.forEach() method.

var slottiLista = document.getElementsByClassName("skill-item"); 
slottiLista = Array.prototype.slice.call(slottiLista);

slottiLista.forEach( function(element, index) {
	/* do stuff with each element */	
});	

Selecting skill icons

The skill images are ripped from League of Legends, Dawn of War 2, Dota 2, Smite and Heroes of Newerth. There are a lot of images, but a tiny chance remains that the same image will be rolled and displayed twice or more. This is okay.

The skill icon selection is similiar to the hero avatar selection. The difference is that it is done with each iteration so all the skill slots are given icons. I have my skill images named incrementally.

First we get a random number based on the total amount of skill images:

function selectSkillIcon (){
	var imgTotal = 1209 /* skill image total goes here */
	var num = randInt(1 , imgTotal); 
	return num; }

Then, inside the loop we select the current skill-icon element and edit its src arttribute based on the random number. As we do this for each of the skill slots all the skill-icon elements will be populated with images:

$(element).find('img.skill-icon').attr('src', 'pics/main/skills/' + selectSkillIcon() + '.jpg');

Generating skill names

Skill names have 3 different naming schemes from which to choose from:

Each naming scheme has its own arrays from which to choose the words. The arrays are designed in a way that all the possible combinations fit and are relatively intelligent.
Choosing which scheme to use is similiar to when deciding the hero name and hero sub‑name.

This is how the skill names are picked:

function skillNameStyle1(){
	var skillName = skillNameSetA[randInt(0, skillNameSetA.length)];
	return skillName; }

function skillNameStyle2(){
	var part1 = skillNameSetB1[randInt(0, skillNameSetB1.length)];	
	var part2 = skillNameSetB2[randInt(0, skillNameSetB2.length)];
	var skillName = part1 + " " + part2;
	return skillName; }	

function skillNameStyle3(){				
	var part1 = skillNameSetC1[randInt(0, skillNameSetC1.length)];	
	var part2 = skillNameSetC2[randInt(0, skillNameSetC2.length)];
	var skillName = part1 + part2;
	return skillName; }	

function createSkillName (){ 			
	var randomSkillName = "";
		var ranNum = randInt(0 ,100)
			if (ranNum <= 33) { 
			randomSkillName = skillNameStyle1(); }			
			else if (ranNum > 33 && ranNum < 75) { 
			randomSkillName = skillNameStyle2(); }									
			else  { 
			randomSkillName = skillNameStyle3(); }
	return randomSkillName; } 

Each scheme has its own function and returns a viable skill name. The createSkillName function rolls a number to decide which scheme to use and returns the decided name. The third naming scheme (combination name) has a slightly lower chance to occur, as it's a bit more "special".

The createSkillName function is called inside the array.forEach loop and the skill name is placed in the appropriate html element. The name is stored as a variable to be used in the skill's description text.

var skillName = createSkillName(); 
$(element).find(' .skillName ').html(skillName);

Selecting skill descriptions

The skill description is the part with the most things going on. A skill description is chosen from an array and is edited before it is placed into the appropriate html element.

The skill descriptions needed to be consistent with the rest of the content; it had to be possible to use the correct hero name, skill name and stat names in the texts. Also most of the numbers (damages, durations etc.) had to be randomised. Some select words are also randomised.

The skill description texts are stored in an array named textList:

The texts cannot be picked in the same way as almost all the other content on the page is picked, because this would include the chance of one skill text appearing twice (or more) on the page. This would be unacceptable. Four different texts should be picked and displayed. This is achieved by shuffling the array and picking the first 4 elements.

First we need to shuffle the textList array. The shuffle function is defined:

function shuffle(para) {
	for (let i = para.length; i; i--) {
		let j = Math.floor(Math.random() * i);
		[para[i - 1], para[j]] = [para[j], para[i - 1]]; }
}

Then the function is called with the textList array as the parameter. The list is cut with the array.slice() method to include only the first 4 elements. The shuffled list is assigned into a variable; shuffledList. This new array will be used in the array.forEach() loop. As the index of every iteration is used in the loop, we can use it to match and use an element from the shuffledList array.

shuffle(textList); 
var shuffledList = textList.slice(0, 4);		

In the end all the skill slots have a different text and no slot can have the same text. But the texts can't be the same every time!
They need to be modified.


Modifying skill descriptions

Each skill text in the textList array has been edited to include certain parts to be randomised, such as numbers and certain words. Other parts are set to to use the previously generated hero name, skill name or the names of stats. This way some variety is added while preserving consistency across the content.

Before the selected skill description is placed in the html element it is modified in multiple ways. The selected skill text is assigned to a variable and is edited throughout an iteration.

Inserting previously created names

First we use a multitude of global regular expression to replace hero name, skill name and the stat names:

A few of the regular expressions add html tags. These are for the special occasions when colors are needed. Colorless versions are also provided for these names.


Inserting "leveled" number sequences

I used League of Legends as a reference point for the skill texts. This meant that the first three skills would have 5 levels, while the fourth would have only 3 (as it would be the hero's "ultimate" skill).

So for the damages, percents, seconds etc. I needed to create sequences with numbers representing each level, such as 90/120/150/180/210. I took the easy road and created arrays for each "category" and added in a few combinations.
I think generating these numbers would have been too much of a hassle.

var scalingDmg = [
	'90/120/150/180/210','14/23/32/41/68','60/90/120/150/180',
	'80/120/160/200/240','100/140/180/220/260','50/100/150/200/250',
	'60/110/160/210/260','100/130/160/190/220'] 
function createScalingDamage() { 
	var item = scalingDmg[randInt(0 ,scalingDmg.length)];
	return item; }

var scalingPercent = [
	'40/45/50/55/60','10/15/20/30/40','20/25/30/35/40',
	'15/20/25/30/35','10/20/30/40/50','30/35/40/45/50',
	'5/10/15/20/25','5/15/25/35/45','40/50/60/70/80'] 
function createScalingPercent() { 
	var item = scalingPercent[randInt(0 ,scalingPercent.length)];
	return item; }

var scalingSecond = [
	'2/3/4/5/6','1/2/3/4/5','1/2/3/5/6',
	'1.5/2/2.5/3/3.5'] 
function createScalingSecond() { 
	var item = scalingSecond[randInt(0 ,scalingSecond.length)];
	return item; }

So now we could simply call the functions each time we needed to input a scaling number into a skill text. But now the 4th slot would also have 5 "levels" on these sequences.
The first two numbers need to be removed to achieve a sequence of 3 "levels", as if the skill was indeed the hero's "ultimate" skill.

For this purpose a function was created; ultSplitter:

function ultSplitter (myParam){ 
	var myRegex = /(.+?[.*/]){2}/ 
	result = myParam.replace(myRegex, "")
	return result; }

The ultSplitter function takes in a parameter and the lazy regular expression searches for matches with anything ending in a slash. This check is done twice. Then the matched part is removed with str.replace() method.

If the ultSplitter is invoked with one of our scaling damage strings as the parameter, the underlined part would be matched and removed:

90/120/150/180/210,

resulting in just 150/180/210. This is perfect for our needs.
Now we only need to check the index of the current iteration; on indices 0, 1, 2 the strings are selected and inserted into the text normally. On the index 3 we need to invoke the ultSplitter function and then insert the strings.

A function is created to check for the index of the current iteration and perform operations accordingly:

function indexChecker() { 
		if (index == 3) { 
			text = text.replace("SCALINGDAMAGE", ultSplitter(createScalingDamage()));
			text = text.replace("SCALINGDAMAGE", ultSplitter(createScalingDamage()));
			text = text.replace("SCALINGDAMAGE", ultSplitter(createScalingDamage()));
			text = text.replace("SCALINGPERCENT", ultSplitter(createScalingPercent()));
			text = text.replace("SCALINGPERCENT", ultSplitter(createScalingPercent()));
			text = text.replace("SCALINGSECOND", ultSplitter(createScalingSecond()));
		} 
			else {		
				text = text.replace("SCALINGDAMAGE", createScalingDamage());
				text = text.replace("SCALINGDAMAGE", createScalingDamage());
				text = text.replace("SCALINGDAMAGE", createScalingDamage());
				text = text.replace("SCALINGPERCENT", createScalingPercent());
				text = text.replace("SCALINGPERCENT", createScalingPercent());
				text = text.replace("SCALINGSECOND", createScalingSecond());
			}
	}
indexChecker();

The str.replace() method is used multiple times as the match targets are not matched globally. If they were, all the numbers would be the same as the first run of any creating function would replace all the replacable parts with the same string! The multiple replaces are for the skill text with multiple replacables.

If any given skill text has more replacable parts than is replaced here the displayed text would simply show eg. "SCALINGDAMAGE". In that case an appropriate new replacer should be added in. At the moment the above replacers are enough for all the skill texts there are.

Inserting numbers

The skill description texts also need randomised numbers for variety. These are mostly percents and durations in seconds. I created a few different number generation functions for different needs:

				
function createNumber1 (){ /* 5-100, rounds to every 5 */
	var num1 = Math.floor((Math.random() * (100 -  5 + 1 ) + 5));
	var num2 = (Math.round( num1 / 5 ) * 5) ;
	return num2; }

function createNumber2 (){ /* 5-15, integer */
	var num = Math.floor((Math.random() * (15 -  5 + 1 ) + 5));
	return num; }

function createNumberSec1 (){ /* 1-3, rounds to every 0.5, if integer then hide decimal */
	var num1 = ((Math.random() * (3 -  1 + 1 ) + 1));
	var num2 = (Math.round( num1 / 0.5 ) * 0.5) ;	
	if(num2.toString().indexOf('.') != -1)
		num2 = num2.toFixed(1);	
	return num2; }

function createNumberSec2 (){ /* 4-9, integer*/
	var num = Math.floor((Math.random() * (9 -  4 + 1 ) + 4));
	return num;	}

function createNumberSec3 (){ /* 8-18, integer */
	var num = Math.floor((Math.random() * (18 -  8 + 1 ) + 8));
	return num; }				

The above functions are invoked multiple times in the array.forEach() loop and the specified words are replaced with the generated numbers. Again, the replace methods are used multiple times for the texts with multiple replacables. The comments are retained for reference.

var number1 = createNumber1(); /* 5-100, rounds to every 5 */
	text = text.replace("NUMBER1", createNumber1());
	text = text.replace("NUMBER1", createNumber1());
	text = text.replace("NUMBER1", createNumber1());
	text = text.replace("NUMBER1", createNumber1());
	
	var number2 = createNumber2(); /* 5-15, integer */
	text = text.replace(/NUMBER2/g, createNumber2());

	var seconds1 = createNumberSec1(); /*1-3, rounds to every 0.5, if integer then hide decimal*/
	text = text.replace("SECONDS1", createNumberSec1());
	text = text.replace("SECONDS1", createNumberSec1());
	
	var seconds2 = createNumberSec1(); /* 4-9, integer*/
	text = text.replace("SECONDS2", createNumberSec2());

	var seconds3 = createNumberSec3(); /* 8-18, integer */
	text = text.replace("SECONDS3", createNumberSec3());
	text = text.replace("SECONDS3", createNumberSec3());					

Inserting other items

A few other items are also inserted into the texts for the sake of variety.

Here we randomise a substance name to be inserted into a text.

var substanceList =[
	'iron','fire','steel','ice','light','blood','stone','bone','flesh','venom',]

function createSubstance(){
	var result = substanceList[randInt(0, substanceList.length)];
	return result;}

The selected substance is inserted into the text in the array.forEach() loop:

var randomSubstance = createSubstance();
	text = text.replace(/SUBSTANCE/g, randomSubstance);

The exact same method is used to create and insert other words, such as weapons and "Crowd Control" effects. Adjective and noun selection is using the same method used in the flavor text generation.

Here are the rest of the replacers in the array.forEach() loop:

The CcEd, CcIng and CcS replacers all insert "Crowd Control" effect, each in different conjugation. Each has their own array with the words in the appropriate conjugation.

Here are some examples of products of these replacers:

The last replacers with the html tags only add colors to desired elements. By adding the html tags here we can keep the actual texts in the array a bit cleaner. Unfortunately some html tags remain in the texts, as some custom coloring has to be done on special occansions. Many different replacers could easily be added in to increase the variety in the texts.

With the above replacers we could take something like the following:

HERO slams the ground with their ADJECTIVE WEAPON, creating an impassable ridge of SUBSTANCE,

and turn it into:

Onixian Strider slams the ground with their astral mace, creating an impassable ridge of bone.


Inserting finished text to html

When the selected skill description text has finally been fully modified it can be inserted into the html for display:

$(element).find(' .skillDesc ').html(text);

After inserting the final edited text into html, one final edit is performed: words with the capital class are given upper case first letters. This may not be the most elegant way to do this, but it's only used on a few special occasions:

$(".capital").css("text-transform", "capitalize");

The desired words for upper cases are wrapped in a span element with the class capital in the initial textList array.

As we loop through the array.forEach() method all four skill-item slots get populated with content. The fourth slot gets a special treatment with the number sequences. Now the page is done and a new hero is born!

Finally, I wrapped the whole content creation in a function and created a button which executes it on click.
Now we can get a new hero without having to reload the whole page.


Check out the MOBA Hero Generator here!



contact markus.vaananen+mobaherodoc (at) gmail.com


2017