Creating an Inventory System for a Roguelite game. Having some issues

Godot Version

Godot 4

Question

Hi forum people!
I’m working on a Roguelite game where you get various weapons throughout each run, I have a general idea on how to do an inventory system.
But I have to make an Inventory system where every item obtained executes its code for attack or boost (hopefully without having to do a long series of ifs on each character)

To make you understand, here’s respectively

The code used on my character (which at the moment includes a snippet of the code used for the “starter_attack” weapon (weapon 1))

extends CharacterBody2D


const SPEED = 200.0
const JUMP_VELOCITY = -400.0
@export var weapon1: PackedScene 
var new_weapon


func _physics_process(delta: float) -> void:
	# Add the gravity.

	# Handle jump.

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction_horizontal := Input.get_axis("ui_left", "ui_right")
	if direction_horizontal:
		velocity.x = direction_horizontal * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)

	var direction_vertical := Input.get_axis("ui_up", "ui_down")
	if direction_vertical:
		velocity.y = direction_vertical * SPEED
	else:
		velocity.y = move_toward(velocity.y, 0, SPEED)

	move_and_slide()


func _on_timer_timeout() -> void:
	var weapon_pos = global_position + Vector2(30, 0) 
	new_weapon = weapon1.instantiate()
	add_child(new_weapon)
	new_weapon.global_position = weapon_pos

The code I have on the “starter_attack” scene:

extends Node2D
@export var attack_resource: Resource

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	pass


func _on_area_2d_body_entered(body: Node2D) -> void:
	if body.is_in_group("enemies"):
		body.health -= attack_resource.damage

The “attack_resource” is just:

extends Resource
class_name weapon_resource

@export var damage: int = 5
@export var weapon_level: int = 1

So I wanted to base myself on this video:

Basically transforming each item into a resource and then having an array resource for the inventory.
But I would still have no idea how I would run the resource’s code (attacks (timer for spawn and despawn included), boosts etc.) once they are attached to the inventory array.

Do I like make it so that the array loads them as child of my character somehow? that would be a bit unfunctional for items that have to spawn and then despawn though (Example: I have a double-headed spear and I’m making it appear one second and then disappear the one later (as you can see in the codes for the character and the starter_attack)) Edit: About that, maybe I could add code for generating the timers itself in the resource?b(I really have no idea.)

Thanks in advice for the help. This forum is always so useful and welcoming.

Hey! I’m not sure if I understood correctly, but I’ll give it a try

  • You want to execute a piece of code (the attack logic) for every item in the user inventory
  • Every item is a resource
  • I assume every weapon can be wildly different

If that’s the case, I think I ran into a similar situation in my game. What you could do is to add a new PackedScene property (let’s call it LogicScene for this example) in your weapon_resource, which points to a Scene with the actual logic for the attack. I use C#, so my nomenclature could be a little off, sorry!

This LogicScene would have, at least, a reference to the original resource (so you can get the damage and weapon level), and a method to execute the attack logic. If you wanna attach a sprite to it, you could add a Sprite2D to the LogicScene, which gets its texture from the original resource.

Then whenever your character acquires a weapon, you instantiate a LogicScene and add it to an array of acquired weapons.

Hope it helps!

1 Like

That’s literally what I needed to do! Or at least, I think so, I’ll try.
Thanks.

1 Like