Target selection
Asked Answered
S

6

0

Hello there o/

I want to make the premise that I am a very first time Godot (or any other game engine) user ^^" and last time I coded anything was 20 years ago so I have a lot to catch up with, so I thank you in advance for the patience.

I am trying to replicate a turn based system and so far I managed to get everything working where I want it to be.. except I can't seem to be able to make a target selection routine that works

So far what seemed the applicable answer was to "await" for a user defined signal that contains the target object itself (or the object_id) so the function that is supposed to apply damage/effects knows who needs to get stuff done.

The main function that execute the ability and that should be waiting on the signal is on the main loop, and the signal would be emitted from an _input_event function (for left mouse button click) on the Area2D node of the individual enemy scene that are instantiated at run time, in a random number between 1 and 4.

this however does not seem to be possible (or I can't figure out how to do it) because await seems to want specified very clearly where the signal is coming and what it is; I can't find a way to have it listen for a free floating signal of some kind, it may just not be possible.

I thought of moving the _input_event straight into the main but that seems to have its own share of headaches (I still not have a very good hang of the whole handling input thing 🥹 )

Sadly google has not been very useful on this subject.

Thanks to anyone that can give me at least some useful nudges in the right direction.

Schulze answered 21/12, 2023 at 8:36 Comment(0)
S
0

Schulze Seems like you have some misconceptions about how things work. If you don't want to execute some code, simply don't invoke it. No need to wait in idle loops or anything like that. The engine handles that under the hood.

If everything in your game happens after some user action then there's no need for _process() to exist at all. Implementing _process() for a node is totally optional. Simply maintain a state variable that determines whose turn is currently active and early exit any event handlers that don't need to be executed in current state. This can also include _process() which is strictly speaking also an event handler. Its event is frame redraw that (by default) happens 60 times per second.

Supertax answered 21/12, 2023 at 9:34 Comment(0)
S
0

Schulze Firstly, you shouldn't use await here at all. In fact it's best to stay away from it completely if you've just started to learn the engine.

Instead, let your unit's Area2D send input_event signal to unit's script and then that script can send a custom clicked signal to anyone who's connected to that signal, which in your case can be main/top script.

Supertax answered 21/12, 2023 at 8:47 Comment(0)
S
0

Hey, thanks for the recommendation!

Second part is already pretty much done, I do have the code for capturing the input event on the Area2D and send the custom signal
I just have trouble in understanding to what I want/need to connect it to.

func _on_area_2d_input_event(_viewport, event, _shape_idx):
	
	if event is InputEventMouseButton:
		if event.pressed() and event.button_index == MOUSE_BUTTON_LEFT:
			target_selected.emit(self)
			get_tree().set_input_as_handled()

I thought that the general logic for a turn based would be that to stop execution of the code on the player turn, waiting to select an ability then once clicked on one, wait for a second input (the user selecting the target), and then resume back once I have all the needed data, so that was why I thought await was what I was looking for to use

But I guess I am thinking too functionally (and linearly) and not enough object-orient-y? 🤔

Schulze answered 21/12, 2023 at 9:0 Comment(0)
S
0

Schulze In general, you shouldn't ever "stop" code execution. Using await creates a coroutine from function that it's used in. If you don't need a coroutine - don't use await. Especially avoid using it in system callbacks like _process() that get called repeatedly frame by frame, because it'll cause stack overflow at some point, among other problems.

Godot is heavily event driven. So best to think inside event driven paradigm. When something happens, an event is generated and event handler function (if provided) is called and executed. Signals are the main mechanism to perpetuate events through code.

In your case target_selected signal should be connected to a function that handles that event. Where that function should be situated is for you to decide depending on your game architecture. If you don't have a better idea, make a script in the top node of your main scene that handles all the game logic, and put the handler function there.

Supertax answered 21/12, 2023 at 9:14 Comment(0)
S
0

Mm ok if I shouldn't stop the code execution then I'll need to find a way to avoid enemies turns to act when it's the player turn

maybe using a while true around the player turn instead and break it free only once that's all done, that would effectively block the code execution in that spot until the player turn is done without all the other consequences of the await you pointed out

not sure how I'll handle capturing the other input events, but I'll try to figure it out 💝 thanks!

Schulze answered 21/12, 2023 at 9:23 Comment(0)
S
0

Schulze Seems like you have some misconceptions about how things work. If you don't want to execute some code, simply don't invoke it. No need to wait in idle loops or anything like that. The engine handles that under the hood.

If everything in your game happens after some user action then there's no need for _process() to exist at all. Implementing _process() for a node is totally optional. Simply maintain a state variable that determines whose turn is currently active and early exit any event handlers that don't need to be executed in current state. This can also include _process() which is strictly speaking also an event handler. Its event is frame redraw that (by default) happens 60 times per second.

Supertax answered 21/12, 2023 at 9:34 Comment(0)
S
0

Mmm I see, feels like I need to pretty much scrap almost everything and start the whole turn handling from scratch 🤔
still having a hard time wrapping my mind around the concept because it's new to me, but I'll get there

I think I have a vague idea for the implementation just need to see if I got it right.

Schulze answered 21/12, 2023 at 9:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.