diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 829f7370f7f..3483e385fbe 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2527,7 +2527,7 @@ Sets which physics engine to use for 3D physics. [b]DEFAULT[/b] is currently equivalent to [b]GodotPhysics3D[/b], but may change in future releases. Select an explicit implementation if you want to ensure that your project stays on the same engine. [b]GodotPhysics3D[/b] is Godot's internal 3D physics engine. - [b]Jolt Physics[/b] is an alternative physics engine that is generally faster and more reliable than [b]GodotPhysics3D[/b]. As it was recently implemented, it is currently considered experimental and its behavior may change in future releases. + [b]Jolt Physics[/b] is an alternative physics engine that is generally faster and more reliable than [b]GodotPhysics3D[/b]. As it was recently implemented, it is currently considered experimental and its behavior may change in future releases. Jolt Physics is the default for projects created starting in Godot 4.6. [b]Dummy[/b] is a 3D physics server that does nothing and returns only dummy values, effectively disabling all 3D physics functionality. Third-party extensions and modules can add other physics engines to select with this setting. diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 5e1cb86a6bb..f3f89e48d26 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -907,7 +907,17 @@ void EditorNode::_notification(int p_what) { feature_profile_manager->notify_changed(); // Save the project after opening to mark it as last modified, except in headless mode. + // Also use this opportunity to ensure default settings are applied to new projects created from the command line + // using `touch project.godot`. if (DisplayServer::get_singleton()->window_can_draw()) { + const String project_settings_path = ProjectSettings::get_singleton()->get_resource_path().path_join("project.godot"); + // Check the file's size in bytes as an optimization. If it's under 10 bytes, the file is assumed to be empty. + if (FileAccess::get_size(project_settings_path) < 10) { + const HashMap initial_settings = get_initial_settings(); + for (const KeyValue &initial_setting : initial_settings) { + ProjectSettings::get_singleton()->set_setting(initial_setting.key, initial_setting.value); + } + } ProjectSettings::get_singleton()->save(); } @@ -7528,6 +7538,17 @@ void EditorNode::notify_settings_overrides_changed() { settings_overrides_changed = true; } +// Returns the list of project settings to add to new projects. This is used by the +// project manager creation dialog, but also applies to empty `project.godot` files +// to cover the command line workflow of creating projects using `touch project.godot`. +// +// This is used to set better defaults for new projects without affecting existing projects. +HashMap EditorNode::get_initial_settings() { + HashMap settings; + settings["physics/3d/physics_engine"] = "Jolt Physics"; + return settings; +} + EditorNode::EditorNode() { DEV_ASSERT(!singleton); singleton = this; diff --git a/editor/editor_node.h b/editor/editor_node.h index a44975d417d..ca147a05e0a 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -768,6 +768,9 @@ public: static bool immediate_confirmation_dialog(const String &p_text, const String &p_ok_text = TTR("Ok"), const String &p_cancel_text = TTR("Cancel"), uint32_t p_wrap_width = 0); static bool is_cmdline_mode(); + + static HashMap get_initial_settings(); + static void cleanup(); EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; } diff --git a/editor/project_manager/project_dialog.cpp b/editor/project_manager/project_dialog.cpp index b44f3a53494..031ab7711fe 100644 --- a/editor/project_manager/project_dialog.cpp +++ b/editor/project_manager/project_dialog.cpp @@ -34,6 +34,7 @@ #include "core/io/dir_access.h" #include "core/io/zip_io.h" #include "core/version.h" +#include "editor/editor_node.h" #include "editor/editor_string_names.h" #include "editor/gui/editor_file_dialog.h" #include "editor/settings/editor_settings.h" @@ -545,6 +546,11 @@ void ProjectDialog::ok_pressed() { initial_settings["application/config/features"] = project_features; initial_settings["application/config/name"] = project_name->get_text().strip_edges(); initial_settings["application/config/icon"] = "res://icon.svg"; + ProjectSettings::CustomMap extra_settings = EditorNode::get_initial_settings(); + for (const KeyValue &extra_setting : extra_settings) { + // Merge with other initial settings defined above. + initial_settings[extra_setting.key] = extra_setting.value; + } Error err = ProjectSettings::get_singleton()->save_custom(path.path_join("project.godot"), initial_settings, Vector(), false); if (err != OK) {