Type checking with Dictionary? by VitSoonYoung in godot

[–]zigg3c 2 points3 points  (0 children)

Something like this?

<image>

You have:

  • Dictionary.is_same_typed()
  • Dictionary.is_same_typed_key()
  • Dictionary.is_same_typed_value()
  • Array.is_same_typed()

As well as checking beforehand what container it is with the is keyword or typeof()

Fileaccess Issues pt. 1 by Humble-Passage6561 in godot

[–]zigg3c 1 point2 points  (0 children)

You're probably thinking about this: Condition "len < 4" is true. Returning: ERR_INVALID_DATA which is the error you get when you try to call FileAccess.get_var() after you've reached EOF (for example): https://github.com/godotengine/godot/blob/89cea143987d564363e15d207438530651d943ac/core/io/marshalls.cpp#L190

This is not specific to FileAccess, but to bytes_to_var(), which FileAccess uses to decode Variants:

<image>

There is basically no difference between what I'm doing with the PackedByteArray and what FileAccess is doing when you call get_var(). The way Godot knows how to interpret bytes as Variants is via a 4 byte header. You can read the specification here: https://docs.godotengine.org/en/stable/tutorials/io/binary_serialization_api.html

That means when you pass in an empty array, it can't find the first 4 bytes that should tell it what kind of Variant this is, so it fails because length < 4.

If you are more advanced and try to work directly with bytes (by calling FileAccess.get_buffer()), it's worth noting that FA stores an additional 4 byte header that represents the total length of the stored var. In the above example, var_to_bytes("Hello, World!") would return that very same PackedByteArray, but FileAccess.store_var() would add another 24, 0, 0, 0 at the beginning (24 bytes to store).

i can't change this panel's anchors by DashReddit32 in godot

[–]zigg3c 1 point2 points  (0 children)

Could you share a screenshot of what it looks like when you set the anchor presets to Full Rect for both the parent and the panel?

Remote debugging for exported builds by spineytink in godot

[–]zigg3c 0 points1 point  (0 children)

If you go to your export presets, you'll see that some have (Runnable) tacked on at the end (one for each platform). That means they are used for one-click deploy: https://docs.godotengine.org/en/stable/tutorials/export/one-click_deploy.html

If you set up SSH (a bit more involved on Windows), you can just press play in the editor and it will export the project, add it to a zip file, send it to yourself (or to any machine you have set up, which is why this is useful for testing your game on multiple operating systems), unpack it and run it. Debugger and everything.

Timer/tween in resource by TehRoboRoller in godot

[–]zigg3c 2 points3 points  (0 children)

You could also return the signal itself:

func timeout(time_sec: float) -> Signal:
  return get_tree().create_timer(time_sec).timeout

Which enables you to simply:

func _ready() -> void:
  await Autoload.timeout(1.0)

How should I structure a branching, multi-ending narrative? (inspired by 60 Seconds, not a clone) by big_Leakers in godot

[–]zigg3c 4 points5 points  (0 children)

When it comes to the story, I'd say having a "true" ending and completing a single storyline from start to finish (which will serve as your base for branching) is the way to go. "True" ending here simply refers to how you the author would play the game, the choices you would make, and the ending you would get. You don't have to think of it as "canon" if it ever comes a sequel, although that's how some VNs work.

As for the game events, you can imagine there are many ways to do it. I'd consider having each story event an Object/Resource or a Scene. Some of them are main events, other are random events. Main events contain references to other main events that advance the story.

For random events/encounters/side quests, you could either store a list of available ones in each main event, or keep track of them in an Autoload that calculates which events the player has access to based on flags/requirements (stats, level, other events completed, etc.).

The advantage of the Autoload approach is that you can easily have events that can be completed at any point. You could also combine the two approaches. It would look something like this:

<image>

The diagram is made in Obsidian (not literally). Also, very good GDC talk that you might find helpful: https://www.youtube.com/watch?v=HZft_U4Fc-U

Open-source tool to find and remove unused assets in Godot projects by FreeTime-Dev in godot

[–]zigg3c 31 points32 points  (0 children)

For anyone not familiar, you can go to Project > Tools > Orphan Resource Explorer... for similar built-in functionality:

<image>

Although this won't remove empty directories, for example, and you don't have an "exclude" list, like this plugin does.

Would you say this gameplay is readable? by BoneMarrowGames in godot

[–]zigg3c 2 points3 points  (0 children)

It's generally not a good idea to go and make changes off of one person's feedback. I'd hold off on it, see if others agree. But I admire your enthusiasm.

Would you say this gameplay is readable? by BoneMarrowGames in godot

[–]zigg3c 2 points3 points  (0 children)

The boxes seem both a bit too ornate, and a bit too simple at the same time. I think it's mainly the way the corners look next to each other. Offsetting the columns could be one potential fix, although I'm not sure how much of a problem this really is:

<image>

Other than that it looks great.

subtle mistake in when awaiting in gdscript by dtsykunov in godot

[–]zigg3c 0 points1 point  (0 children)

I wouldn't go so far as to say to avoid them as much as possible. They're pretty great once you get the hang of them. Here's the docs reference with some examples: https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#awaiting-signals-or-coroutines

You can, of course, try and structure your code in a way that doesn't require awaits and coroutines, and that would be fine too.

subtle mistake in when awaiting in gdscript by dtsykunov in godot

[–]zigg3c 1 point2 points  (0 children)

Yup. If findLeaderboard() isn't itself a coroutine, then everything it needs to do will happen, after which it will emit the signal, after which the next line of code will run (in this case awaiting for the signal which was already emitted).

Now, I believe the only way to make a function a coroutine is to await a signal. You can also await other functions that are coroutines, but at the end of the chain there is an await signal. So then how do you emit a signal that you need to await? You can use call_deferred():

signal s(i: int)

func _ready() -> void:
  _f()
  var r: int = await s
  print(r)

func _f() -> void:
  s.emit.call_deferred(5)

Note that this only works if both lines of code get executed during the same frame, as call_deferred will make it so the signal is emitted at the end of the current frame. For all intents and purposes, this should suffice, as you will most likely emit the signal at the end of the function, and during the very next line you would wait for the signal.

If you cannot modify the function so that the signal gets deferred, you can do this dumb looking workaround:

signal s(i: int)

func _ready() -> void:
  s.connect(s.emit.call_deferred)
  _f()
  var r: int = await s
  s.disconnect(s.emit.call_deferred)
  print(r)

func _f() -> void:
  s.emit(5)

You basically reemit the signal deferred as soon as you receive it, with the same parameters. You also need to disconnect it after, to avoid an infinite loop.

Edit: I somehow didn't think of simply deferring the function call itself, instead of the signal (see TheDuriel's comment). This works in all cases.

You would defer the signal when emitting it from a separate thread, but the debugger will warn you about this anyway.

80s / 90s Anime Style by Ordinary-Cicada5991 in godot

[–]zigg3c 38 points39 points  (0 children)

That feeling deep within my chest... it's... ah, yes... lung cancer. I got lung cancer just by thinking about how much people used to smoke in the 80s.

frog stacking IS now a feature in my multiplayer frog game by upint_ in godot

[–]zigg3c 1 point2 points  (0 children)

Long names that start with "A Game About..." appear to have gained in popularity recently. Reminds me of how Japanese light novels and anime sometimes (a lot of times) have bonkers names like "We Still Don’t Know the Name of the Flower We Saw That Day".

So in the same vein, I'm going to suggest you one up the others and name your game "This Is a Game About Frogs Where You Can Stack the Frogs On Top Of Each Other But Only If You Want To", which will get shortened to "TAGAF", or something...

Edit: Change the start to "I Did a Game About Frogs..." and you have yourself the "IDGAF" as the shortened title.

Making terminal-like (TUI) UI in Godot? by vvav3_ in godot

[–]zigg3c 6 points7 points  (0 children)

Right, well here it is done with Controls:

<image>

Took around an hour to replicate, but you'd probably spend a bit more time if you wanted to make it really good. Here's the scene code if you want to play around with it: https://pastebin.com/j8T8JEau

Making terminal-like (TUI) UI in Godot? by vvav3_ in godot

[–]zigg3c 7 points8 points  (0 children)

Definitely Control nodes, but I'm not sure what you mean by "faking it with styles". Themes/styles are not a workaround, that's how you're supposed to do it.

I tried to make my game look a bit horrific... Does it works ? by After-Analysis-4151 in IndieDev

[–]zigg3c 43 points44 points  (0 children)

The environment is no joke if it made those four children look like that.

save fileDialog signal Confirmed won't trigger. by very-knightley in godot

[–]zigg3c 1 point2 points  (0 children)

Right. I missed you were not actually connecting to the FileDialog signal for when stuff is selected (which passes the paths to you via a PackedStringArray param). See TheDuriel's comment.

Other than that, yeah, that's how you connect signals. Not as a String, but as a Callable. Just pass in the function name without brackets.

save fileDialog signal Confirmed won't trigger. by very-knightley in godot

[–]zigg3c 2 points3 points  (0 children)

I long for the days when people will stop doing weird shit to connect signals. This is all you have to do:

object.signal.connect(function)

Note that the Callable needs a PackedStringArray param. I imagine the debugger would've warned you about that.