Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

De-couple the "core" functionality from the "Dimensionfall" mod #506

Open
snipercup opened this issue Dec 1, 2024 · 4 comments · May be fixed by #571
Open

De-couple the "core" functionality from the "Dimensionfall" mod #506

snipercup opened this issue Dec 1, 2024 · 4 comments · May be fixed by #571
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@snipercup
Copy link
Collaborator

snipercup commented Dec 1, 2024

In order to facilitate overhaul mods, we should provide a bare-minimum of functionality that we can then extend using mods.
This requires the implementation of mod functionality and is going to take a while.

To resolve this issue:

  • Make a list of entities that are hard coded
  • Move everything but these entities from the "Core" mod to a new mod called "Dimensionfall". Only the essentials remain in the "Core" mod

Here is the start of the list, please add on to it if you know any:
Skills:

  • athletics
  • ranged

Maps:

  • Any "field" and "forest" maps

The starting inventory items are listed in the ItemManager and are part of the Core mod

@snipercup
Copy link
Collaborator Author

Here's the details on "athletics":

The "athletics" skill in this script primarily influences movement and stamina-related functionalities. Its level affects the player's ability to run faster, lose less stamina while running, and regenerate stamina more efficiently when stationary. Here's a breakdown of its functions within the script:

1. Stamina Management

  • Stamina Loss While Running: The athletics level reduces the rate of stamina loss when the player is running. Higher levels make running more efficient.
    stamina_lost_while_running_per_sec = 15 - (athletics_level / 100.0) * (15 - 5)
  • Stamina Regeneration: When the player is stationary, higher athletics levels increase the stamina regeneration rate.
    stamina_regen_while_standing_still = 3 + (athletics_level / 100.0) * (8 - 3)

2. Run Speed

  • The skill level increases the run multiplier, making the player faster when running. This is scaled by the level of the "athletics" skill.
    run_multiplier = 1.1 + (athletics_level / 100.0) * (2.0 - 1.1)

3. XP Gain

  • Each time the player runs and consumes stamina, a small amount of XP is added to the "athletics" skill.
    if is_running and current_stamina > 0:
        current_stamina -= delta * stamina_lost_while_running_per_sec
        add_skill_xp("athletics", 0.01)

4. Skill Level Integration

  • The get_skill_level("athletics") function retrieves the current level of the athletics skill. This level determines the effectiveness of the above benefits.

Summary of Role in the Script

The "athletics" skill dynamically enhances the player's performance by:

  • Increasing running efficiency through reduced stamina loss.
  • Improving stamina regeneration when idle.
  • Allowing faster running speeds.
  • Gaining XP while running, enabling progression in the skill and further improvements.

This functionality makes "athletics" a critical skill for gameplay elements involving movement, stamina management, and player endurance during exploration or combat.

@snipercup
Copy link
Collaborator Author

I'd like to separate the functionality from the skill. If we have:

  • run speed modifier
  • stamina regeneration modifier
  • stamina loss modifier

If we had these variables, we could then allow a modder to tie those to a skill called "athletics" or any other skill, even items maybe.

However, then there's still the "stamina" component. If possible, I'd like to break it down even further.

@snipercup
Copy link
Collaborator Author

The suggestion from Chatgpt:

To achieve a modular and extensible system that separates functionality from the "athletics" skill, we can introduce a framework for modifiers and attributes that can be dynamically tied to skills, items, or other gameplay elements. Here's a breakdown of how this could be implemented:


Proposed Breakdown

  1. Modifiers

    • Create general-purpose variables for:
      • run_speed_modifier
      • stamina_regeneration_modifier
      • stamina_loss_modifier
    • These modifiers can be tied to any source (skills, items, buffs, etc.) and their effects can stack or override.
  2. Stamina Management

    • Stamina should be encapsulated in a separate system (e.g., a StaminaManager) to handle:
      • Current stamina
      • Maximum stamina
      • Regeneration and depletion rates
      • Triggering related effects (e.g., player exhaustion).
  3. Attributes and Sources

    • Attributes (like stamina) are influenced by one or more sources, which include:
      • Skills (e.g., "athletics").
      • Items (e.g., "Running Shoes").
      • Buffs/Debuffs (e.g., "Tired" or "Energized").
    • Each source can contribute to modifiers like speed or stamina regeneration.

Implementation Steps

1. Define Modifiers

Add new variables to manage the modifiers independently:

var run_speed_modifier = 1.0
var stamina_regeneration_modifier = 1.0
var stamina_loss_modifier = 1.0

2. Create StaminaManager

Encapsulate stamina logic in a separate class. This class will handle all stamina-related calculations and apply the modifiers:

class_name StaminaManager
extends Object

signal stamina_changed(new_stamina)

var max_stamina = 100
var current_stamina = max_stamina
var regeneration_rate = 3.0  # Base regeneration rate
var loss_rate = 15.0  # Base loss rate

func modify_stamina(amount: float) -> void:
    current_stamina = clamp(current_stamina + amount, 0, max_stamina)
    emit_signal("stamina_changed", current_stamina)

func regenerate_stamina(delta: float, modifier: float) -> void:
    modify_stamina(delta * regeneration_rate * modifier)

func deplete_stamina(delta: float, modifier: float) -> void:
    modify_stamina(-delta * loss_rate * modifier)

3. Integrate Modifiers into Movement

Update _physics_process to incorporate modifiers:

func _physics_process(delta):
    # Movement direction
    var input_dir = Input.get_vector("left", "right", "up", "down")
    var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

    if is_running and stamina_manager.current_stamina > 0:
        velocity = direction * speed * run_speed_modifier
        stamina_manager.deplete_stamina(delta, stamina_loss_modifier)
    else:
        velocity = direction * speed
        if velocity.length() < 0.1:
            stamina_manager.regenerate_stamina(delta, stamina_regeneration_modifier)

    move_and_slide()

4. Dynamic Modifier Sources

Introduce a generic modifier system that can dynamically adjust the modifiers:

var modifiers = {
    "run_speed": [],
    "stamina_regeneration": [],
    "stamina_loss": []
}

# Add a new modifier
func add_modifier(modifier_type: String, value: float) -> void:
    if modifiers.has(modifier_type):
        modifiers[modifier_type].append(value)
        _recalculate_modifier(modifier_type)

# Remove a modifier
func remove_modifier(modifier_type: String, value: float) -> void:
    if modifiers.has(modifier_type) and value in modifiers[modifier_type]:
        modifiers[modifier_type].erase(value)
        _recalculate_modifier(modifier_type)

# Recalculate a modifier
func _recalculate_modifier(modifier_type: String) -> void:
    match modifier_type:
        "run_speed":
            run_speed_modifier = 1.0 + sum(modifiers["run_speed"])
        "stamina_regeneration":
            stamina_regeneration_modifier = 1.0 + sum(modifiers["stamina_regeneration"])
        "stamina_loss":
            stamina_loss_modifier = 1.0 + sum(modifiers["stamina_loss"])

5. Tie Modifiers to Skills or Items

Link modifiers to the skill system (e.g., "athletics") or items:

func update_skill_modifiers(skill_id: String, level: int) -> void:
    if skill_id == "athletics":
        remove_modifier("run_speed", run_speed_modifier - 1.0)
        remove_modifier("stamina_regeneration", stamina_regeneration_modifier - 1.0)
        remove_modifier("stamina_loss", stamina_loss_modifier - 1.0)
        
        # Apply new modifiers based on skill level
        add_modifier("run_speed", level * 0.01)
        add_modifier("stamina_regeneration", level * 0.05)
        add_modifier("stamina_loss", -level * 0.05)  # Reduces stamina loss

6. HUD Updates

Emit signals from the StaminaManager to update the HUD:

stamina_manager.connect("stamina_changed", self, "_on_stamina_changed")

func _on_stamina_changed(new_stamina: float):
    update_stamina_HUD.emit(new_stamina)

Benefits of This System

  1. Flexibility: Modders can tie attributes to skills, items, buffs, or events.
  2. Encapsulation: Stamina logic is cleanly handled by the StaminaManager.
  3. Extendibility: Adding new modifiers (e.g., "jump height" or "attack speed") requires minimal effort.
  4. Scalability: Easily supports multiple sources affecting the same modifier (e.g., skill + item).
  5. Customization: "Athletics" can be swapped with another skill, or items can directly modify stamina attributes.

Would you like examples of tying items or events to this system?

@snipercup
Copy link
Collaborator Author

But then what if the stamina manager was a playerattribute called "stamina" instead? We'd need some kind of pool to drain from and some mechanic to determine what amount. If no pool called stamina is available, then the player will be unable to sprint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
1 participant