Dark-Peace / BulletUpHell

Most feature-packed Bullethell Engine. All in 1 plugin for Godot 3 & 4.
https://bottled-up-studio.itch.io/godot-bullethell-plugin
MIT License
271 stars 12 forks source link

A couple minor homing fixes #3

Open russmatney opened 1 year ago

russmatney commented 1 year ago

Hey there! Very cool library, thanks for putting it together and open-sourcing it!

I ran into a few crashes integrating it yesterday/this morning, I thought I'd share the commit in my repo: https://github.com/russmatney/dino/commit/56fbfc2b7f95b1da8ae31737cf6085fa2151ef63.

I can create a proper PR if you want, this was just a lower-lift share, and maybe you prefer a different solution and/or can get to it sooner.

I prefer to do more things from code in general, which might explain why I hit some of these. For now I'm creating bullet and spawn patterns in an autoloaded scene, then updating and firing bullets from enemy instances this:

func fire(target):
    Spawning.change_property("bullet", "bulletPattern1", "homing_target", target.get_path())
    Spawning.change_property("bullet", "bulletPattern1", "homing_steer", 100)
    Spawning.change_property("bullet", "bulletPattern1", "homing_duration", 3)
    Spawning.spawn(self, "spawnPattern1")

This usage seems reasonable to me. It feels like the lib may expect some homing setup is expected to happen in _ready(), but it's too late if we decide afterwards that a bullet should be homing. Maybe I should just create the bullet and spawn pattern in the code as well, to resolve that?

--

I also spent a bit trying to figure out why some spawns never fired, and eventually figured out that nothing fires unless a spawner is in a positive x and y position. Moving a spawner left of the y axis or above the x axis results in no bullets at all. Maybe this is just a bug on my end? I dug into it briefly, but wasn't able to find a clear reason/solution for this yet.

Let me know what you think and if you'd like an actual PR!

Dark-Peace commented 1 year ago

Hi, thank you for the bug report. I see, it's true that change_property might cause some issues. When I added it, I didn't think there would be much use for it. Can you detail me your use case ? Just so I know why you need it and if I can't make a better solution.

I will look into what would be the best fix. I was just planning an update with a change to the homing so it will be a part of the next release.

russmatney commented 1 year ago

Happy to share more! Sorry if this is too long-winded! If you want to chat more I can jump in a Discord or something.

I'm working on my first ever Bullet Hell, so I'm happy to be told my use-case is not typical. I'm still exploring, not sure what exactly the game is yet. I'm doing a quick game jam, and hope to have something done in the next couple days.

My first goal was to spawn bullets from my enemy instances, and have them hone in on a target that they had detected, which could be the player, or a little 'sheep' that follows the player. In general this is the approach I want to use - defining some kind of attack pattern than an enemy instance owns, and being able to drop a bunch of these enemies anywhere in a level.

At first I added the bulletPattern/spawnPattern/spawnPoint to the enemy scene itself, which worked fine for a single enemy - but adding multiple enemies to one scene runs into trouble b/c the bullet/spawnPatterns were being created with the same ID multiple times.

After some thinking, I realized I could create the patterns once in an autoload, and reference them from a spawnPoint on the enemy instance. This seems to be working fine, and probably works for my purposes with just the changes I linked.

The tricky part I hit was dynamically assigning the homing_target to the bulletPattern. I was happy to find change_property, as it seems to do what I need. Though in writing this out, I realized I'm not sure if I can use the same bulletPattern to home-in on two different targets - maybe the bullets copy the bulletPattern's data when they're created/reawakened, in which case it should be fine.

I also ended up adding a new 'sharedArea' to the Spawning autoload so that I could get the bullets on my enemy-projectiles collision layer. Maybe there's a better way to do this?

I'd like to be able to define patterns on an instance, and have them be unique for that instance, rather than shared. This can probably be done completely in the code - instead of working with the nodes in the editor, I could create a bullet/spawnPattern in each instance's _ready, and connect them with unique, per-instance ids and bulletPattern targets that way.

I have a few other ideas I'll try this morning - for example, I think it might be possible to include the patterns as nodes in the enemy scene, and perhaps update the IDs before their ready functions are called - this could let us overwrite the IDs per instance. I'm not sure how simple/possible that is.

russmatney commented 1 year ago

Turns out you can update the ids in _enter_tree()!

So now I have per-instance bulletPatterns/spawnPatterns the way I hoped.

var spawn_pattern_id
var bullet_pattern_id

func _enter_tree():
    bullet_pattern_id = str("bulletPatternID", self.name)
    spawn_pattern_id = str("spawnPatternID", self.name)
    $BulletPattern.id = bullet_pattern_id
    $SpawnPattern.id = spawn_pattern_id
    $SpawnPattern.pattern.bullet = bullet_pattern_id

# ...later in my instance
func fire():
    if not target:
        return

    Spawning.change_property("bullet", bullet_pattern_id, "homing_target", target.get_path())
    Spawning.change_property("bullet", bullet_pattern_id, "homing_steer", 100)
    Spawning.change_property("bullet", bullet_pattern_id, "homing_duration", 3)
    Spawning.spawn(self, spawn_pattern_id)

For some reason the homing doesn't work on the first few bullets tho - I'm not sure why, still debugging to learn more.

I also just found the alternative homing options for groups, not just node_paths - that might solve my use-case much better than change_property, I'll toy with those a bit.

russmatney commented 1 year ago

Confirming that switching to homing in on groups works great for my use-case! So now that I'm getting unique patterns per instance (with the above _enter_tree id updates) and honing on groups, I don't need change_property - though it may come in handy at some point.

Dark-Peace commented 1 year ago

create the patterns once in an autoload

Indeed, but be sure to call Spawning.reset(true) if you have resources loaded globally and those resources' ID must start with @ or else they will be destroyed when changing scene. If you want to avoid doing that, it's better to keep your resources in your level's scene and not globally.

I was happy to find change_property, as it seems to do what I need.

Be warned that using change_property will affect every bullet linked to the resource and not a single bullet.

I also ended up adding a new 'sharedArea' to the Spawning autoload so that I could get the bullets on my enemy-projectiles collision layer.

That's what it's for 👍

Dark-Peace commented 1 year ago

Turns out you can update the ids in _enter_tree()!

That's actually really interesting ! I'll write it in the documentation.

russmatney commented 1 year ago

be sure to call Spawning.reset(true)... change_property will affect every bullet linked to the resource and not a single bullet

Good to know, I'll keep this in mind going forward.

Thanks for the info and for all the effort on this library! I'm excited to make some games!

Dark-Peace commented 1 year ago

Thank you :) If you need help, I'm more reactive on discord so you can post in #plugin-help-chat