Nesting a bunch of ifs would work, but you could make a minor change and get a bit more bang for your buck. Much of programming is really about structuring data. I'd probably suggest going with a structure more like this (actual names left out for brevity): var names = {
english: {
boy: [],
girl: []
},
german: {
boy: [],
girl: []
},
medieval: {
boy: [],
girl: []
}
}; This makes it easy to do several nice things. Your logic can then operate off of the properties of the names object and its contained objects through introspection. That allows you to validate language choices, provide feedback about what are valid choices, etc. It also makes it pretty easy to add more choices without having to edit the logic. I'd probably restructure your code like this: ;(function(){
"use strict";
var names = {
english: {
boy: ['bob','sam'],
girl: ['nancy','sue']
},
german: {
boy: ['hanz','fritz'],
girl: ['helga','hannah']
},
medieval: {
boy: ['geoffrey','richard'],
girl: ['isabella','joan']
}
};
on('chat:message',function(msg){
if('api' !== msg.type){
return;
}
let cmds = msg.content.split(/\s+/),
who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname');
if( '!namegen' === cmds.shift()){
if(cmds.length) {
let language=(cmds.shift()||'').toLowerCase();
if(_.has(names,language)){
let boygirl = (cmds.shift()||'').toLowerCase();
boygirl = _.has(names[language],boygirl) ? boygirl : _.sample(_.keys(names[language]));
sendChat('',`/w "${who}" Name is ${_.sample(names[language][boygirl])}`);
} else {
sendChat('',`/w "${who}" No language <b>${language}</b>. Available options are: <b>${_.keys(names).join(', ')}</b>`);
}
} else {
sendChat('',`/w "${who}"<div>Usage: <br><code>!namegen [language] [boy|girl]</code><br>Specifying boy or girl is optional. Available language options are: <b>${_.keys(names).join(', ')}</b>`);
}
}
});
}()); I changed the order of your parameters to !namegen [language] [boy|girl], as that makes it easy to leave boy|girl off and randomly choose between the two. I'm making heavy use of Underscore.js, which is a very useful library that's bundled in the API: _.has() -- checks to see if a given key is a property on an object. _.sample() -- randomly chooses one entry from an array. _.keys() -- returns an array of all the properties on an object. Walking the above, I've enclosed it in an anonymous function that is immediately called. This is called an IIFE (Immediately-Invoked Function Expression), which you can read more about on Google. It creates a Closure, basically a container for your functionality which prevents it from being in the global namespace, a pretty good practice. Placing the string "use strict" in a scrope holds your code to higher standards and will warn you about certain coding practices that are out of vogue (for good reason!). Next is the data structure I mentioned at the top. Each of the properties is the name of a language, which lets you pull a list of supported languages with _.keys(names) or check for support for a language with _.has(names, language). Each language property holds an object with boy and girl properties for the names in that language. Adding another language becomes very easy, you just add the additional data to the structure. It registers a single chat event handler which exists for non-api messages. It splits msg.content on any sequence of 1 or more spaces or tabs (/\s+/ is a regular expression, if you want to Google those. \s means whitespace, + means 1 or more). Doing it this way means you don't get strange behavior if someone accidentally hits two spaces between arguments. cmds ends up being an array of each argument, so "!namegen english boy" would result in ['!namegen','english','boy']. The who variable will contain the name of the player running the command, or 'API' if it wasn't a player. Now to the processing. cmds.shift() will remove the first value from the cmds array and return it. It is then compared to '!namegen' to see if this is a command for your program. You should always use === and !== instead of == and != until you understand the difference (and then you'll know there's pretty much never a reason to use == and !=). The nice thing about removing the entry with .shift() instead of just referencing it with cmds[0] is that it simplifies later work. For the example from before, the cmds array will now be ['english','boy']. If they just typed !namegen, it would be [], so checking if there are enough arguments is as simple as checking if there is a positive length with if(cmds.length). If there aren't any more arguments, we drop down to an else case that tells them how to use the script and what the available languages are with _.keys() (introspection for the win!). Next we grab the language argument with cmds.shift() and convert it to lowercase (in case they typed German or GERMAN). Then check it's a language that is supported with _.has(). If it isn't, we tell them we don't have the language they typed (showing what they said allows them to spot misspellings, like 'midevil') and list the available languages with _.keys() again. Now we can grab the boy/girl argument and lowercase it. Next we check if it's one of the keys in the language (this lets you later add things like 'place', or 'emotion' or 'neutral' without changing the logic!). If it isn't one of the specified keys, (or is empty) we use _.sample() to grab one at random. You could split this out and only use sample if they didn't specify one and give an error otherwise. That can be an exercise to the reader. =D Finally, with all the arguments validated and collected, we return the random name with _.sample(names[language][boygirl]). One last note on the sendChat() calls I'm making. Take special note of the type of quotes, the "backtick": ` These are new in Javascript ES2015, they're called template literals. The practical upshot of them is you can embed variables within template literals using the ${ } syntax. You can also embed function calls, as I've done. You can read more about them on Google. They are super handy, but easy to miss when comparing ` to '. Hope that's helpful to you! Happy Rolling!