From c4bbf27cb535a5394e301d31bf61a9b8ca2e8558 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 25 Apr 2025 02:24:12 +0200 Subject: [PATCH] Use Jolt Physics by default in newly created projects This also adds infrastructure to make specific settings the default, but only in projects created after this point (so that existing projects are not affected). This can be used for progressive upgrades in the future. This applies to both the project creation dialog and creating projects through the command line using `touch project.godot`. --- doc/classes/ProjectSettings.xml | 2 +- editor/editor_node.cpp | 21 +++++++++++++++++++++ editor/editor_node.h | 3 +++ editor/project_manager/project_dialog.cpp | 6 ++++++ 4 files changed, 31 insertions(+), 1 deletion(-) 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) {