Giter Club home page Giter Club logo

godot-game-template's People

Contributors

maaack avatar ngwenyang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

godot-game-template's Issues

[Suggestion] Separate Menu Templates

Hey there, I thought about some things and realized some people might not want all of the Menus Template, but it may be difficult to separate, so maybe separating the menus into their individual scenes like "Main Menu Template", "Settings Menu Template", "Pause Menu Template", and so on could be beneficial to those users, and make it more accessible and modular.

Plugin doesn't include keybindings for gamepads present in full template

The full template has added some gamepad inputs to the default UI actions. Specifically, ui_accept, ui_cancel, ui_page_up, and ui_page_down.

image

These are currently not present in the plugin version, and result in a different experience for users of the plugin. One solution suggested in the Discord was to use an autoload to add the input events when the app starts. However, according to the documentation, project settings can be overridden by including a override.cfg in the project's root directory.

https://docs.godotengine.org/en/stable/classes/class_projectsettings.html

Editor error: RuntimeLogger.gd does not inherit from Node.

Editor throws errors:
Failed to create an autoload, script 'res://addons/maaacks_game_template/extras/scripts/RuntimeLogger.gd' does not inherit from 'Node'.
editor/editor_autoload_settings.cpp:550 - Condition "!info->node" is true. Continuing.

Menu navigation is possible via directional input during title/sub-title fade animation, causing other buttons than Play to be focused when buttons appear

Setting Game Scene Path allows to show Play button, but sometimes the Options button is still the one focused on start, instead of the expected Play button at the top.

EDIT: found cause: ghost navigation, see comment below

Btw nice addon, it goes farther than EasyMenus and already has Credits and above all, remappable controls! I'll use it from now on for my jams, and maybe even my other games!

Fixes to ProjectMusicController

Music controller is supposed to check AudioStreamPlayers that match the audio_bus variable, but it does not.

Also, sometimes an AudioStreamPlayers can get added before the _ready() on the ProjectMusicController gets called. Should use _enter_tree() instead.

Options: Controls: Cannot customize built-in actions (starting with "ui_")

All built-in actions, namely starting with ui_ are filtered out from the remappable Controls options:

AppSettings.gd

static func get_filtered_action_names() -> Array[StringName]:
	var return_list : Array[StringName] = []
	var action_list : Array[StringName] = InputMap.get_actions()
	for action_name in action_list:
		if not action_name.begins_with("ui_"):
			return_list.append(action_name)
	return return_list

which prevents us from displaying and customizing actions like "ui_cancel", which is used to go Back in the menu, and therefore useful to customize when using gamepad.

In practice I don't think it's a big issue, because it's more rare to customize such actions, and I can always customize my scripts to use another action name to go back.

However, since the template itself uses it, I thought it would be nice if we could add a list of whitelisted actions so we can force show a few actions even if they start with "ui_", but not all of them (which would be annoying).

Even when not modifying some inputs, it's nice to be able to display the mappings for such inputs (however, display only would require a "read-only" mode showing inputs without the +/- buttons, a bit more work and maybe less intuitive for the player).

For now I'll manually tweak get_filtered_action_names to get the mappings I need.

SceneLoader fails to load a cached scene (ResourceLoader.has_cached(scene_path) returns true, e.g. due to PackedScene being assigned to some node)

After adding a custom script that was referencing some scene A in order to load it manually, I noticed that the main menu Play button stopped loading scene A as the initial scene.

Debugging SceneLoader.load_scene shows that the block checking if ResourceLoader.has_cached(scene_path): only sends a signal, then returns:

	if ResourceLoader.has_cached(scene_path):
		call_deferred("emit_signal", "scene_loaded")
		return

and in general you don't have custom code plugged to scene_loaded, so nothing more happens.

To fix this, I defined the following function:

func change_scene_to_path(scene_path: String) -> void:
	# Load scene from path
	# This should only be called for cached or very lightweight scenes
	# Otherwise, use load_scene to benefit from async loading
	var scene = ResourceLoader.load(scene_path, "PackedScene")
	var err = get_tree().change_scene_to_packed(scene)
	if err:
		push_error("failed to change scene to passed scene: %d" % err)
		get_tree().quit()

and added the following line before return:

change_scene_to_path.call_deferred(scene_path)

I added call_deferred to follow the logic of the existing line call_deferred("emit_signal", "scene_loaded") although it didn't seem necessary in this case, but always safer to change scene on deferred call anyway.

I suspect that the dev's intention was to mimic background loading, where we would emit a signal and let the user plug some custom behavior there. However, it seems unnecessary when the scene is already cached since it wouldn't take more than 1 frame.

So I should probably remove the scene_loaded signal which would be irrelevant when directly changing to new scene.

Suggestion: Generic GameState that saves into JSON (or similar)

Currently, the GameLevelLog tracks progress in the config file. This does not follow convention on where that data would typically be stored, as it mixes application configuration settings with game state.

Instead, we could try creating a generic GameState (or even more generic AppState) that stores a dictionary of data and manages the saving/loading behind the scenes. There's a lot of documentation available on how to save and load game state to and from files.

https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html

Eventually, it could have multiple levels, like UserGameState, PCGameState, WorldGameState depending on the level of persistence desired.

GameLevelLog, GameLog, AppLog could then be updated to read from the GameState instead of Config.

Unwanted process: Credits are auto-scrolling while invisible

Currently Credits._process just runs in the wild, even when Credits are not visible (e.g. when touching nothing on the main menu).

I noticed this when logging scrolling value (I'm working on a version that stores float scrolling to support slower scrolling, esp. important on lores pixel art games where 1px/s is very fast).

Credits should either manually return from _process when not visible, or we set its process mode to DISABLED entirely when not visible.

Ex of code hotfix:

func _process(_delta):
	if Engine.is_editor_hint():
		return
	# LOCAL FIX by hsandt to avoid scrolling Credits while invisible,
	# in the background
	if not visible:
		return
	# do stuff...

UISoundController misc issues: unwanted initial button press sound, overlapping focus/press sounds, missing sounds

This is a meta issue for various UISoundController-related issues that prevent me from getting the UI SFX I really want.

  • Unwanted initial button focus sound
  • Overlapping focus/press sound when clicking with mouse
  • No SFX to move slider via directional input
  • Inconsistent tab control focus

Unwanted initial button focus sound

button_focused SFX plays when the main menu appears, as the first button is focused. This is generally not wanted.

In addition, it plays even when the main menu gradually appears with transitions (title fade in), which makes it even weirder.

I have already coded a custom UI SFX manager for Unity and despite the differences with Godot, I remember I had the same issue, so I had to check manually if this was the initial selection or not (by checking some custom flag or current selectable reference). I think it's possible to do the same in Godot.

Overlapping focus/press sound when clicking with mouse

When clicking a button with the mouse, it focuses the button then presses it, causing double sound. I'm not sure how to fix this. The user may hold the button for a while before releasing, in which case playing two sounds makes sense, and there is no way to predict it.

In general I'm interested in a sound to select a button while navigating with directional arrows / D-pad, rather than actually focusing the button, but there doesn't seem to be a way to distinguish here. I don't remember I did any particular fix in Unity, so I probably have the same issue there, but I think I used a single Audio Source for all my UI SFX, which means that if user quickly presses and releases mouse button, the Press button SFX will take over the Focus/Select SFX.

No SFX to move slider via directional input

There is a sound to drag slider with the mouse (drag start and end) but not via keyboard/gamepad. I suppose this could be done via value change detection. However that means that dragging with mouse would also spam value change SFX (I reduced this effect by using sound throttling in Unity, so this could be done, but still ugly to play value change button when dragging with mouse...). Probably a lower level detection of directional input to change slider by step values may be better.

Inconsistent tab control focus

Controls tab doesn't autofocus the first element and even if it did, the big controls box doesn't have any focus SFX associated.

Audio and Video tabs autofocus the first element which could be a slider or toggle with their own focus sound.

This means that if I set Focus SFX for Tab Changed and slider/toggle, I will hear twice the SFX (I tested, the SFX seems played at louder volume).

Again, reusing the same source would in this case force SFX overwrite and thus play it only once.


I'll add more issues when I think about them.

A few minutes later: added Inconsistent tab control focus

Suggestion: Support animating background music players in starting scenes

I get these errors if I try to animate the background music player.
image

I think it would be ideal if developers are still able to control the background music player from the scene it starts in.

Maybe the re-parenting of the player node could instead happen when the scene is about to be unloaded.

Easier process to switch between Menus Template and Game Template

I found the Menus Template, installed it, then later found about the Game Template which adds a Pause menu.

So I removed the Menus Template addon, installed the Game Template and most references worked at first, and replacing the manual extends path from maaacks_menus_template to maaacks_game_template was easy.

Fixing all the menu prefabs, not so. I had to replace the OptionsControl script with the new one, but even then I'd get a bunch of broken dependencies. At some point errors stopped, I ran the game from the main menu, but it immediately closed.

I realized I was still using the old Autoload singletons so I removed them, and unchecked Project Settings maaacks_menus_template/disable_plugin_dialogues so the addon prompts me to recopy all prefab examples once more. It offered me to update the main scene to the new opening with logo, and the new autoload singletons were properly re-added.

Now the new main menu does work but I lost, as expected, all my prefab overrides, and I don't think I can easily revert my changes without breaking dependencies again. To be honest, I just tried and it's not that bad, I managed to bring back my local options sub-menu changes, but for some reason I can't retrieve the MainMenu changes themselves.

Well, I suppose the easiest will be to just copy paste the PauseMenu.gd, .tscn PauseMenuController.gd and InGameMenuController.gd and replace _game_ with _menus_ in references, rather than the other way round. Is this what you'd recommend?

For next project I'll think ahead which addon suits my project best. I may end up with my own Pause Menu for bigger projects too.

Since it's pretty edge case, I don't expect you to code a super tool to automate that, but if you have some tips on how to make the process easier (after I started working customizing the main menu), you can tell me.

I haven't modified that much of the main menu and I saved the theme as a separate resource, so I suppose installing a brand new Game Template and reapplying my changes manually could also be a solution.

Options: Controls: keys seem to always register and display international US keyboard

I'm using an international US keyboard myself I didn't notice this at first, but when I tried to switch to Azerty to register the Q key, it was still displayed as Q, in both the prompt and registered key. I verified that it was also bound to physical Q = A on Azerty indeed.

2024-06-02_16-44-27 Bug Azerty A is shown as Q

While this allows stable display, it's confusing when using an actual Azerty keyboard, or other.

I see the complexity of displaying the right key at all times though: you'd have to detect system layout change at runtime, and I'm not sure there is a signal for that.

However, it should at least work when the layout doesn't change mid-game.

I found the culprit line:

InputHelper.gd

static func get_text(event : InputEvent) -> String:
	elif event is InputEventKey:
		return OS.get_keycode_string(event.get_physical_keycode_with_modifiers())

Maybe it could use get_keycode_with_modifiers instead. In fact, I just tried it and it works. Can you think of any side effect of doing this?

Ideally it would allow the user to choose a physical mapping like Godot editor itself, but I understand it would be extra work and few people would need to do that.

I also found this function:

InputOptionsMenu.gd

func _get_action_keycode(action_event : InputEvent):
	if action_event is InputEventMouse:
		return 0
	if action_event.keycode != 0:
		return action_event.get_keycode_with_modifiers()
	else:
		return action_event.get_physical_keycode_with_modifiers()

But it's never called.

Suggestion: option after install to copy UI prefabs/scenes even deeper

I really like the prefab copy (or rather, inheritance) system on start, but I still need to customize the option widgets further (there are too big on my lores pixel art game, I need to change some HBox to VBox, etc.).

Maybe we could have an option to create copies (or rather, inheriting scenes, since I see the copy inherit from the addon scenes, which is great) of low-level widgets as well?

Right now I must do it manually and remember to reassign references everywhere accordingly.

Suggestion: Automating the process of propagating changes to the other repos

These are the other repos that this repo shares code with:

It would be a huge time-saver if some of the process of porting the code could be automated. It could be done from either end, going up the chain, or down, and still save time. The major differences between repos are the plugin directory name and the scope of their contents.

Suggestion: option to use version from Project settings

I already wrote my own main menu scripts for other games, and I just use the Project settings version to fill the version label

I found it less error-prone as I don't have to manually update the version each time.

An option to do so, or alternatively fallback to the project settings version when version name is empty of "0.0.0", would be helpful.

Here is my current custom patch:

func _setup_version_name():
	# CUSTOM CHANGE by hsandt
	# If not setting a custom version name, use the one from project settings
	# This avoids having to manually update it every time
	if version_name == '0.0.0':
		version_name = ProjectSettings.get_setting("application/config/version", "0.0.0")
	AppLog.version_opened(version_name)
	$"%VersionNameLabel".text = "v%s" % version_name

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.