Last post, I teased a bit about the Tier input on the form shown here. Between that post and now I added the Variance option… so let’s talk about these two things!
Weapons Don’t Have Power
While tweaking the randomness generator for adding attributes works for generating weapons with relatively higher capabilities, this doesn’t scale to the base weapon. At this point, the code for selecting our weapon looks like this.
// weapon $sql = $pdo->query("SELECT * FROM weapon_type WHERE active = 1 ORDER BY RAND() LIMIT 1"); $weapon_type = $sql->fetchAll(PDO::FETCH_ASSOC); $weapon = sumWeaponAttributes($weapon, $weapon_type[0]);
We always get a weapon, and it’s always randomly selected from the weapon_type table in our database. Setting our randomness modifier low… say .6% for the first level of our dungeon … means that it is not very likely our character will find a Shocking and Flaming Rapier of Immense Destruction, but they are just as likely to find a knife as they are a greatsword. This might not be a problem at all, but I want to code in the flexibility to be a bit more granular in our selection process. I added a tier
column to the weapon_type
table and ranked the weapons roughly according to their damage (plus or minus a step or two for other attributes).
Now you know what the Tier selection does on the page. We simply select a weapon from the tier you chose. If you select ALL on the form, we treat that as a zero. We check to see if you entered a value other than zero, and select only from those weapons in the database.
// weapon if ($args['tier'] == 0) { $sql = $pdo->query("SELECT * FROM weapon_type WHERE active = 1 ORDER BY RAND() LIMIT 1"); $weapon_type = $sql->fetchAll(PDO::FETCH_ASSOC); } else { $sql = $pdo->prepare("SELECT * FROM weapon_type WHERE active = 1 AND tier = ? ORDER BY RAND() LIMIT 1"); $sql->execute([$args['tier']]); $weapon_type = $sql->fetchAll(PDO::FETCH_ASSOC); } $weapon = sumWeaponAttributes($weapon, $weapon_type[0]);
If you’ve never seen PDO before, you should learn it immediately and use it for everything that touches your database. I suggest this amazing guide:
(The only proper) PDO Tutorial from phpdelusions.net. The short of it is that if you entered a value, we modify our SELECT
to include AND tier = ##
which means we only select from the weapons with that tier value. This works, but it’s not very fun. So for my game, I made it a bit more interesting.
Variability
Choosing weapons from a specific tier is great. I can set it to 1 for the first level, then move up to 2 and so on. While this works to help me control the scaling of levels, it’s also not very fun. Maybe I use this for a boss where I can generate a slightly higher grade of weapon, but for general drops, I’d like it to fluctuate some. So, I changed the function a bit to accept another input $tier-variance
and wrote some new code.
// weapon if ($tier-variance == 0) { // select from a specific tier or range of tiers $sql = $pdo->query("SELECT * FROM weapon_type WHERE active = 1 ORDER BY RAND() LIMIT 1"); $weapon_type = $sql->fetchAll(PDO::FETCH_ASSOC); } else { if($tier-variance > 0) { // tier may be higher or lower $swing = rand(0,100); switch (true) { // determine how much variance case ($swing >= 80): $variance = 2; // occasionally, teir will be adjusted by 2 levels break; case ($swing >= 50): $variance = 1; break; default: $variance = 0; } $min_tier = $args['tier'] - $variance; $max_tier = $args['tier'] + $variance; $sql = $pdo->prepare("SELECT * FROM weapon_type WHERE active = 1 AND tier >= ? AND tier <= ? ORDER BY RAND() LIMIT 1"); $sql->execute([$min_tier, $max_tier]); } else { $sql = $pdo->prepare("SELECT * FROM weapon_type WHERE active = 1 AND tier = ? ORDER BY RAND() LIMIT 1"); $sql->execute([$args['tier']]); } $weapon_type = $sql->fetchAll(PDO::FETCH_ASSOC); } $weapon = sumWeaponAttributes($weapon, $weapon_type[0]);
Now, if we want to be a bit more variable, we can let the RNG decide just how variable it is. Breaking this down, if you select the Variance option on the form, we use rand(0,100)
to generate a percentage. If our results are less than 50%, we just use the entered tier number. Between 50% and 79% and we allow for weapons 1 tear above and below the selected value. Over 80% and we can get a weapon 2 tiers above or below. That’s more fun!
Where Next?
For now, I’m going to leave this alone. I’ll test it some and see how the numbers work out. I may turn this into a more functional code block later so that I can pass in the level of variability that I want. Or I may make it scale based on the tier value entered. That way, even if you ask for a tier 6, you might get a tier 1 anyways… or the other way around!
Like I mentioned last post, I’m just sketching here. I want to get through this part and on to the game itself. While individually these parts are fun to tinker with, I’ll never find out if the game is worth playing until I’ve moved past this. So, I’ll get some functions working and test it out. There’s one more thing I want to add to weapon generation, then I can start using what I’ve learned here to build the other item generators (armor, shields, trinkets).
The next thing will be picking specific a specific weapon or attribute. I want to be able to tell the item generator to give me a freezing weapon or whatever. This ties into a completely tangent distraction that I hope to implement once I get all the generators done. That’s all for now!
Pingback: Requesting Attributes – Roguelike Design part 6 – Chevee Dodd