I'm making a text-based RPG in JavaScript. I made a skill leveling system that works, but I feel like the function arguments get passed around a lot and, the code is not very scalable. Do you have any suggestions on how I can improve this code? Ideally, I want to call only one function like:
addExperience(25, charisma);
What my code does:
The properties
object gives each skill level a title. Currently, all skills have the same title. In the future, these will have different titles and number of titles.
The player
object has a skill level
and experience
key for each skill, so the skills can level independently.
I've also posted the HTML and CSS code for completion. However, this is not important because I only wrote it to test the JavaScript code, and it is not part of the game.
// Skill variable
const properties = {
strength: [
"Dabbler",
"Skilled",
"Untrained",
"Proficient",
"Amateur",
"Superb",
"Master",
],
endurance: [
"Dabbler",
"Skilled",
"Untrained",
"Proficient",
"Amateur",
"Superb",
"Master",
],
charisma: [
"Dabbler",
"Skilled",
"Untrained",
"Proficient",
"Amateur",
"Superb",
"Master",
],
};
// Player variables
const player = {
stats: {
strength: {
level: 0,
experience: 0,
},
endurance: {
level: 0,
experience: 0,
},
charisma: {
level: 0,
experience: 0,
},
},
};
function getExperienceToNextLevel(level, skill) {
if (level < skill.length) {
return ((level * (level + 1)) / 2) * 1000;
}
}
function addExperience(amount, stat, skill) {
if (stat.level !== skill.length - 1) {
stat.experience += amount;
while (stat.experience >= getExperienceToNextLevel(stat.level, skill)) {
stat.experience -= getExperienceToNextLevel(stat.level, skill);
++stat.level;
}
}
display(stat, skill);
}
function display(stat, skill) {
document.getElementById("level-display").innerHTML = `${stat.level} ${
skill[stat.level]
}`;
document.getElementById("xp-display").innerHTML = `${stat.experience}`;
}
body {
background: #ff930f;
background: linear-gradient(
90deg,
rgba(255, 147, 15, 1) 0%,
rgba(255, 249, 91, 1) 100%
);
box-sizing: border-box;
font-family: sans-serif;
margin: 0;
padding: 0;
}
.title {
background-color: rgb(0, 0, 0, 0.1);
color: #fff;
margin: 5% auto;
padding: 25px;
text-align: center;
text-shadow: 2px 2px rgb(0, 0, 0, 0.5);
}
.display {
background-color: rgb(0, 0, 0, 0.1);
color: #fff;
margin: 5%;
padding: 25px;
text-align: center;
text-shadow: 2px 2px rgb(0, 0, 0, 0.5);
}
.xp-buttons {
text-align: center;
}
.xp-buttons button {
background-color: #333;
border: none;
border-radius: 999rem;
color: #fff;
font-weight: 700;
height: 2.5rem;
max-width: auto;
min-width: 5rem;
transition-duration: 0.2s;
margin: 0 auto;
}
.xp-buttons button:hover {
background-color: #444;
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="JavaScript - Debugger" />
<title>JavaScript - Debugger</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<main>
<h1 class="title">JavaScript - Debugger</h1>
<div class="display">
<h2>Level: <span id="level-display"></span></h2>
<h2>XP: <span id="xp-display"></span></h2>
</div>
<div class="xp-buttons">
<button
onclick="addExperience(50, player.stats.charisma, properties.charisma)"
>
50 XP
</button>
<button
onclick="addExperience(1000, player.stats.charisma,properties.charisma)"
>
1000 XP
</button>
<button
onclick="addExperience(0, player.stats.charisma,properties.charisma)"
>
Update
</button>
</div>
</main>
<script src="app.js"></script>
</body>
</html>