Create a Roblox melee system that supports weapon customization and switching from a variety of melee weapons. Each weapon should consist of specific parts and objects within its model, including:

- **Configuration** (a Configuration object)
- **Animations** (Folder) > Contains animation objects like Swing1, Swing2, etc.
- **Parts** (Folder) > Includes parts that make up the weapon model
- **Triggers** (Folder) > Contains **Handle** (a Part holding the model together and housing welds to other parts)



You’ll likely need three scripts: Module, Server, and Client.

All Remotes and scripts are in these locations:
Client: `StarterCharacterScripts`
Server: `ServerScriptService`
Module: `ReplicatedStorage.GameModules`

All Melee Remotes: `ReplicatedStorage.GameRemotes.Melee.Events Here`

When the player presses **E**, a random animation from the weapon’s **Animations** folder should play on the player. The client only sends a signal to the server; all particles, animations, and related events are handled server-side. Upon the **GrabMelee** animation event, the weapon’s handle is welded to a part in the player’s left arm, called **GrabPart**. A **Motor6D** in the left arm (with **Part0** set to the arm and **Part1** set to **GrabPart**) then updates its **C0** to match the **ArmOffset** from the weapon’s **Configuration** object, positioning the weapon correctly in the player's arm.

While the weapon is swung, a hitbox is created in front of the player, pivoting around the root part. The hitbox is generated and destroyed via the **SwingMelee** and **StopSwingMelee** animation events, respectively. The hitbox detects collisions with non-player objects, and if an opponent or NPC enters the hitbox bounds (using **Region3** and **:GetPartBoundsInBox** with overlap parameters), a **BodyVelocity** launches them in a direction relative to the player’s facing direction (left, right, forward). When the **PlaceMelee** animation event triggers, the weapon is re-holstered by welding its handle to a part inside the torso, called **HolsterPart**, with a **Motor6D** adjusting **C0** to the weapon’s **HolsterOffset** in the **Configuration** object. This ensures each weapon can have a unique holster position.


Think of the animation behavior in Roblox's Blade Ball game, where the weapon transitions between being holstered and wielded smoothly.


The **Configuration** object includes several values, such as:

- **Damage** (NumberValue) – Determines how much damage the weapon inflicts.
- **Range** (Vector3Value) – Defines the hitbox size. The hitbox’s back is always aligned with the player’s root part, and its front adjusts based on the weapon’s range.
- **HitboxDirection** (Vector3Value) – Adjusts the hitbox rotation relative to the root part without affecting the root’s orientation. For example, a Y value of 45 degrees would rotate the hitbox to the right.
- **BreakObjects** (BoolValue) – When the hitbox hits an object tagged with **MeleeBreakable**, its parts become unanchored and set to **CanCollide = true**, and a less intense **BodyVelocity** is applied to them. If the object contains a **MeleeBroke** module script, it fires a **Broken** command.
- **HolsterOffset** (CFrameValue)
- **ArmOffset** (CFrameValue)

Each swing animation has a **Direction** (StringValue) that determines where an NPC or player is launched when hit, relative to the swinging player's direction. The valid directions are **Left**, **Right**, **Forward**, **Up**, or **Down**.

Weapons also include visual and sound effects:

- **Lights** (with types like **GrabLight**, **SwingLight**, etc.)
- **Particles** (e.g., **GrabParticle**, **SwingParticle**, etc.)
- **Sounds** (e.g., **GrabSound**, **SwingSound**, etc.)

Lights have an **OnTime** attribute (duration in seconds), particles have **EmitCount** and **EnabledTime**, and sounds play without attributes. After pressing **E**, the player must wait 2 seconds before swinging again.

The system must easily handle player respawns and weapon swapping. A single command should equip a weapon, remove the current one, and attach the new weapon to the player’s holster.

Developers should be able to create weapons without modifying the core scripts—just update the **Configuration** object for the new weapon to work seamlessly.

Weapon hierarchy example:

- **WeaponModel** (Model)
  - **Animations** (Folder)
    - **Swing1** (Animation)
      - **Direction** (StringValue)
    - **Swing2** (Animation)
      - **Direction** (StringValue)
  - **Parts** (Folder)
    - **Part** (Part)
  - **Triggers** (Folder)
    - **GrabPoint** (Part)
    - **SwingSound** (Sound)
    - **GrabLight** (PointLight)
    - **GrabParticle** (ParticleEmitter)
  - **Configuration** (Configuration object)
    - **Damage** (NumberValue)
    - **Range** (Vector3Value)
    - **HitboxDirection** (Vector3Value)
    - **HolsterOffset** (CFrameValue)
    - **ArmOffset** (CFrameValue)


The server must track each player’s owned weapons using **DataStore**. When a player joins, their stored weapons are placed inside a **WeaponsOwned** folder in their player instance, and the available weapons are loaded from **ReplicatedStorage.MeleeWeapons**. If the player has an **EquippedWeapon** saved, it will automatically equip when they join.

Players do not start with a default weapon; they must acquire one later. The **DataStore** key format should be: `playername_Weapons_playeruserID`.

If player's left the previous game they were in with a weapon equipped, then they have a **DataStore** in the same key with a value called "LastEquippedWeapon"

When the player rejoins the game, if the datastore has a "LastEquippedWeapon" then that weapon is automatically equipped to that player.

This system should be highly advanced, setting a new standard for melee systems and impressing even a developer with 15 years of experience.

Take as long as you need to think for this to perfect.