top of page

Weapon Generator

In this small project, I focused on developing a weapon generator system inspired by the Borderlands series. The objective was to create a procedural generation system capable of producing a diverse array of unique weapons, each with randomized stats, attributes, and visual components. This system aimed to simulate endless customization options, enhancing replayability and player engagement. By tackling this project, I gained valuable experience in procedural content generation, balancing randomization with design intent, and ensuring seamless integration of the generated weapons into a game's mechanics.

Role

Coder

Game Engine

Unity

team size 

1 person

development time

3 day

Core Features

Randomization

The Weapon Generator system procedurally creates unique weapons by randomly combining parts from various categories, including the body, barrel, stock, scope, magazine, and grip. Each category is represented as a list of GameObject instances, which are dynamically selected during the weapon generation process. To ensure variability, the system utilizes a random number generator to pick a part from each list:

This approach results in hundreds of possible weapon combinations, as each part can differ in appearance, functionality, and stats. The final weapon is structured around a base body, with additional parts attached at specific socket positions, creating a modular and highly flexible system that enriches gameplay through its unpredictability and variety.

image.png

This approach results in hundreds of possible weapon combinations, as each part can differ in appearance, functionality, and stats. The final weapon is structured around a base body, with additional parts attached at specific socket positions, creating a modular and highly flexible system that enriches gameplay through its unpredictability and variety.

To manage these variables efficiently, the script utilizes a nested class called WeaponStatPair, which holds the stat type, along with its minimum and maximum values. This setup allows each weapon part to have diverse stats while maintaining control over value ranges. Marking the class as [System.Serializable] makes it editable in the Unity Inspector, enhancing flexibility during development. The part stats are stored in a dictionary, allowing for fast lookups and efficient comparisons. When a weapon part is instantiated, the Awake() method runs, iterating through each stat pair and calculating a random value within the given range:

This method ensures that each weapon part has unique and dynamically generated stats upon creation, contributing to the system's dynamic and unpredictable nature.

scope

body

image.png

barrel

stock

magazine

grip

Technical Details

The Weapon Generator system is a dynamic and modular framework designed to procedurally generate a wide variety of weapons in a game environment. By leveraging randomized part selection, statistical calculations, and efficient data structures, the system creates diverse and balanced weapons that enhance gameplay variety. This section outlines the core algorithms, data structures, and performance considerations that make the system both versatile and efficient, while seamlessly integrating with the game's combat mechanics.

Algorithms

1. Random Part Selection:

The system employs a uniform randomization algorithm to select weapon parts, ensuring that each part has an equal probability of being chosen. This is achieved using the Random.Range() method, which selects a random index from the list of available parts

This method is both efficient and straightforward, making it ideal for generating diverse weapon combinations. However, it does not account for part rarity, meaning that common and rare parts have the same chance of being selected. To address this limitation, a weighted random algorithm could be implemented, allowing rarer parts to have a lower selection probability while maintaining the system’s flexibility and variety.

2. Stat Generation:

The algorithm for generating weapon stats utilizes the Random.Range() method to select values within a specified range, allowing for dynamic yet controlled variability.

Each weapon part contains a list of stat pairs, where each pair holds the minimum and maximum values for a given attribute. During initialization, the script iterates through each stat pair and calculates a random value between the specified limits:

This approach ensures that each weapon part has random but controlled stat values upon creation, resulting in a diverse range of weapons while maintaining stat consistency based on the part type.

3. Weapon Initialization and Part Attachment:

The WeaponBody script contains the Initialization algorithm, which is responsible for assembling and configuring a complete weapon from its individual parts.

The algorithm first collects weapon components, including the body, barrel, scope, stock, handle, and magazine, and adds them to a list for easy management. Next, it sets the muzzle position and muzzle FX based on the selected barrel, ensuring that the weapon’s firing visuals are correctly aligned:

Finally, the method initializes the weapon object with the combined stats and assembled parts, allowing the weapon to function as a cohesive unit. This ensures that the generated weapon is immediately ready for combat, with its components correctly positioned and configured.

4. Weapon Stat Calculation:

The Weapon Stat Calculation process is handled by the CalculateStats() method, which aggregates individual part stats to produce the final weapon attributes.

The method loops through each WeaponPart in the list, extracting the stats stored in each part. For each stat, the algorithm checks whether it already exists in the final weapon stats dictionary:

If the stat does not exist, it is added to the dictionary. If it does exist, the value is incremented, allowing for stat stacking. This process combines bonuses from different parts to calculate the final weapon performance, resulting in a dynamic and customizable weapon system.

5. Rarity Calculation:

The Rarity Calculation process is managed by the DetermineRarity() method, which computes the average rarity level of the assembled weapon.

The method first sums the rarity levels of all the weapon parts and then divides the total by the number of parts to calculate the average:

By using Mathf.Clamp(), the calculated rarity value is restricted to a valid range (0 to 4), ensuring that the weapon’s rarity level is consistent and does not exceed the predefined bounds.

The method then applies the calculated rarity color to the weapon’s visual outline, giving players an immediate indication of the weapon's quality and rarity:

This visual cue enhances the player experience by clearly communicating the weapon's value, making loot identification more intuitive.

Data Structures

1. Lists for Weapon Parts:

The system uses List<WeaponPart> to store the various weapon components, allowing for dynamic management of parts:

The List data structure is ideal for situations where the number of parts is relatively small and frequently accessed, as it provides efficient addition and iteration. This makes it well-suited for the weapon generation system, where parts need to be combined dynamically during weapon creation.

Using a list also ensures that the system can easily accommodate new parts without significant changes to the core logic, maintaining scalability and flexibility in weapon generation.

2. Dictionaries for Weapon Stats:

The system uses Dictionary<WeaponStatType, float> to store the aggregated stats of the weapon, allowing for efficient retrieval and updates:

Dictionaries offer O(1) lookup time, making them ideal for quickly accessing critical attributes like damage, fire rate, accuracy, and other weapon stats during gameplay.

The key-value structure also allows for incremental updates, making it easy to add or remove stats when weapon parts are changed. This approach ensures that the system can dynamically update the weapon's performance as parts are swapped or combined, maintaining consistency and efficiency.

  • Facebook
  • Twitter
  • LinkedIn

©2021 by Joseph Merrick. Proudly created with Wix.com

bottom of page