Add 4.4 release page (#1023)

Co-authored-by: Nathalie Galla <murderveggie@gmail.com>
This commit is contained in:
Adam Scott
2025-03-03 17:41:42 +01:00
committed by GitHub
parent 35271d3a81
commit e6bdb5c006
134 changed files with 4438 additions and 27 deletions

View File

@@ -28,6 +28,8 @@ collections:
permalink: /download/3.x/:name/
priorities:
output: true
release_4_4:
output: true
# Build collection items with a future date.
future: true

View File

@@ -1,8 +1,12 @@
- name: "4.4"
flavor: "rc3"
release_date: "28 February 2025"
release_notes: "/article/release-candidate-godot-4-4-rc-3/"
flavor: "stable"
release_date: "3 March 2025"
release_notes: "/article/godot-4-4-a-unified-experience/"
featured: "4"
releases:
- name: "rc3"
release_date: "28 February 2025"
release_notes: "/article/release-candidate-godot-4-4-rc-3/"
- name: "rc2"
release_date: "26 February 2025"
release_notes: "/article/release-candidate-godot-4-4-rc-2/"
@@ -47,7 +51,6 @@
flavor: "stable"
release_date: "15 August 2024"
release_notes: "/article/godot-4-3-a-shared-effort/"
featured: "4"
releases:
- name: "rc3"
release_date: "8 August 2024"

View File

@@ -133,7 +133,7 @@
});
// Open from the main download buttons.
const downloadButtons = document.querySelectorAll('.btn-download');
const downloadButtons = document.querySelectorAll('.btn-download, .download-button');
downloadButtons.forEach((it) => {
it.addEventListener('click', () => {
thankYouWrapper.style.display = '';
@@ -174,4 +174,4 @@
<img src="/assets/icons/cross.svg" width="24" height="24" alt="Close this popup" class="lightbox-ignore">
</div>
</div>
</div>
</div>

View File

@@ -10,4 +10,5 @@ layout: default
{{ content }}
</div>
{% include thankyou.html %}
{% include footer.html %}

View File

@@ -17,34 +17,64 @@
$i: index($sections, $section);
$diff: $i - $base-category-i;
$base-color-top: offset-hue($base-color, $offset, $diff);
$base-color-bottom: adjust-color(offset-hue($base-color, $offset, $diff + 1), $lightness: -10);
$base-color-bottom: adjust-color(
offset-hue($base-color, $offset, $diff + 1),
$lightness: -10
);
$color-top: adjust-color($base-color-top, $saturation: -10);
$color-bottom: adjust-color($base-color-bottom, $saturation: -10);
$color-top-muted: adjust-color($base-color-top, $saturation: -25);
$color-bottom-muted: adjust-color($base-color-bottom, $saturation: -25);
$color-selection: adjust-color($base-color-bottom, $saturation: -30);
$color-invert: adjust-color($base-color-top, $hue: 180, $lightness: 0, $saturation: 30);
$color-highlight: adjust-color($base-color-top, $lightness: 0, $saturation: 30);
$color-highlight--dark: adjust-color($base-color-top, $lightness: 30, $saturation: 30);
$color-invert-highlight: adjust-color($color-invert, $lightness: 20, $saturation: 30);
$return-value: map-merge($return-value, (
#{$section}: (
color-top: $color-top,
color-bottom: $color-bottom,
color-selection: $color-selection,
color-invert: $color-invert,
color-highlight: $color-highlight,
color-highlight--dark: $color-highlight--dark,
color-invert-highlight: $color-invert-highlight
$color-selection--light: adjust-color(
$base-color-bottom,
$lightness: 40,
$saturation: 30
);
$color-invert: adjust-color(
$base-color-top,
$hue: 180,
$lightness: 0,
$saturation: 30
);
$color-highlight: adjust-color(
$base-color-top,
$lightness: 0,
$saturation: 30
);
$color-highlight--dark: adjust-color(
$base-color-top,
$lightness: 30,
$saturation: 30
);
$color-invert-highlight: adjust-color(
$color-invert,
$lightness: 20,
$saturation: 30
);
$return-value: map-merge(
$return-value,
(
#{$section}: (
color-top: $color-top,
color-bottom: $color-bottom,
color-top-muted: $color-top-muted,
color-bottom-muted: $color-bottom-muted,
color-selection: $color-selection,
color-selection--light: $color-selection--light,
color-invert: $color-invert,
color-highlight: $color-highlight,
color-highlight--dark: $color-highlight--dark,
color-invert-highlight: $color-invert-highlight,
)
)
));
);
}
@return $return-value;
}
@function r-desktop-mobile($sizes...) {
@return (
"desktop": nth($sizes, 1),
"mobile": nth($sizes, 2)
);
@return ("desktop": nth($sizes, 1), "mobile": nth($sizes, 2));
}
@function r-get-desktop($value) {

View File

@@ -0,0 +1,6 @@
---
---
.comparison-range {
display: none !important;
}

1708
assets/css/releases/4.4.scss Normal file

File diff suppressed because it is too large Load Diff

384
assets/js/releases/4.4.mjs Normal file
View File

@@ -0,0 +1,384 @@
// GSAP for animations.
import { gsap } from "../modules/gsap@3.12.5.min.mjs";
import { ScrollTrigger } from "../modules/gsap@3.12.5_ScrollTrigger.min.mjs";
import detectPlatform from "../modules/detect-browser.mjs";
gsap.registerPlugin(ScrollTrigger);
// Parallax scrolling.
const releaseHeaderBackground = document.querySelector(
".release-header-background",
);
gsap.to(releaseHeaderBackground, {
scrollTrigger: {
trigger: ".release-header",
start: "top 0%+=64px",
end: "bottom 0%",
onUpdate: (self) => {
const progress = self.progress;
releaseHeaderBackground.style.transform = `
translateY(${progress * releaseHeaderBackground.getBoundingClientRect().height}px)
translateZ(-1px)
scale(2)
`;
releaseHeaderBackground.style.filter = `blur(${easeInCirc(progress) * 5}px)`;
},
},
});
// https://easings.net/#easeInCirc
function easeInCirc(x) {
return 1 - Math.sqrt(1 - Math.pow(x, 2));
}
// Add a scrolling effect to each card and title.
const windowHeight = window.innerHeight;
/**
* @typedef {{
* element: HTMLElement,
* container: HTMLDivElement,
* isLastOfType: boolean
* }} AnimatedElement
*/
/** @type {AnimatedElement[]} */
const elements = [];
/** @type {HTMLDivElement[]} */
const releaseCardContainers = Array.from(
document.querySelectorAll(".release-cards"),
);
for (const releaseCardContainer of releaseCardContainers) {
/** @type {HTMLDivElement[]} */
const releaseCards = Array.from(
releaseCardContainer.querySelectorAll(".release-card"),
);
/** @type {HTMLDivElement | null} */
const lastReleaseCard = releaseCardContainer.querySelector(
".release-card:last-of-type",
);
for (const releaseCard of releaseCards) {
elements.push({
element: releaseCard,
container: releaseCardContainer,
isLastOfType: releaseCard === lastReleaseCard,
});
}
releaseCardContainer.classList.add("overflow-y-hidden");
}
const sectionContainers = Array.from(
document.querySelectorAll(".section-title"),
);
for (const sectionContainer of sectionContainers) {
elements.push({
element: sectionContainer.querySelector("h3"),
container: sectionContainer,
isLastOfType: true,
});
sectionContainer.classList.add("overflow-y-hidden");
}
for (const element of elements) {
if (element.element.getBoundingClientRect().top < windowHeight) {
if (element.isLastOfType) {
element.container.classList.remove("overflow-y-hidden");
}
continue;
}
const timeline = gsap.timeline({
scrollTrigger: {
trigger: element.element,
start: "top bottom",
},
onComplete: () => {
if (element.isLastOfType) {
element.container.classList.remove("overflow-y-hidden");
}
},
});
timeline.from(element.element, {
y: "+=50",
duration: 0.5,
opacity: 0,
});
}
// Hide downloads that aren't for the user's platform.
const platformData = detectPlatform(
navigator.userAgent,
navigator.userAgentData,
);
let platformName = "windows";
switch (platformData.os) {
case "mac":
case "iphone":
case "ipad":
{
platformName = "macos";
}
break;
case "linux":
{
platformName = "linux";
}
break;
case "android":
{
platformName = "android";
}
break;
case "windows":
default:
break;
}
const releasePlatformContainer = document.querySelector(
".release-platform-container",
);
if (releasePlatformContainer != null) {
const releasePlatform = releasePlatformContainer.querySelector(
`.release-platform-${platformName}`,
);
if (releasePlatform != null) {
releasePlatform.classList.add("active");
}
}
// Rename "Export templates and other downloads" to "More downloads"
const downloadOther = document.querySelector(".card-download-other");
if (downloadOther != null) {
downloadOther.textContent = "More downloads";
}
// Add relative weight based on author data
const authors = Array.from(
document.querySelectorAll(
"#special-thanks-release-authors .release-card-authors .release-card-author",
),
);
let max_prs = 0;
for (const author of authors) {
max_prs = Math.max(max_prs, Number(author.dataset.prs));
}
const scales = new Array(5);
for (let i = scales.length - 1; i >= 0; i--) {
if (i + 1 == scales.length) {
scales[i] = Math.floor(max_prs / 2);
} else {
scales[i] = Math.floor(scales[i + 1] / 2);
}
}
for (const author of authors) {
const prs = Number(author.dataset.prs);
for (let i = 0; i < scales.length; i++) {
if (prs >= scales[i]) {
if (i + 1 == scales.length) {
author.classList.add(`size-${i + 1}`);
break;
}
continue;
}
if (i === 0) {
break;
}
author.classList.add(`size-${i + 1}`);
break;
}
}
// Lazy-load videos
const lazyVideoObserver = new IntersectionObserver((entries, observer) => {
for (const entry of entries) {
if (!entry.isIntersecting) {
continue;
}
const video = entry.target;
const source = video.querySelector(":scope > source");
if (source == null) {
continue;
}
video.classList.remove("lazy");
source.src = source.dataset.src;
delete source.dataset.src;
video.load();
observer.unobserve(video);
}
});
const releaseCardVideoContainers = Array.from(
document.querySelectorAll(".release-card-video-container"),
);
for (const releaseCardVideoContainer of releaseCardVideoContainers) {
const noScript = releaseCardVideoContainer.querySelector(":scope > noscript");
if (noScript == null) {
throw new Error("`.release-card-video-container > noscript` is null");
}
// The contents of noScript exist, but as text.
// Let's create a document to store that content.
const doc = document.implementation.createHTMLDocument();
doc.write(noScript.innerHTML);
// The video should exist on the virtual body. If not, let's skip it.
const video = doc.body.querySelector(":scope > .release-card-video");
if (video == null) {
throw new Error(
"`.release-card-video-container > noscript > .release-card-video` is null",
);
}
video.classList.add("lazy");
const source = video.querySelector(":scope > source");
if (source == null) {
throw new Error(
"`.release-card-video-container > noscript > .release-card-video > source` is null",
);
}
source.dataset.src = source.src;
source.src = "";
// Let's swap the noScript for the video itself.
releaseCardVideoContainer.insertBefore(video, noScript);
noScript.remove();
lazyVideoObserver.observe(video);
}
// Show/hide the scroll-to-top button
const linksElement = document.querySelector("#links");
const scrollToTopElement = document.querySelector("#scroll-to-top");
let scrollToTopTween = null;
let scrollState = "";
const showScrollToTop = () => {
if (scrollState === "show") {
return;
}
scrollState = "show";
if (scrollToTopTween != null) {
scrollToTopTween.kill();
}
scrollToTopElement.style.display = "block";
scrollToTopTween = gsap.to(scrollToTopElement, {
opacity: 1,
duration: 0.5,
});
};
const hideScrollToTop = () => {
if (scrollState === "hide") {
return;
}
scrollState = "hide";
if (scrollToTopTween != null) {
scrollToTopTween.kill();
}
scrollToTopTween = gsap.to(scrollToTopElement, {
opacity: 0,
duration: 0.5,
onComplete: () => {
scrollToTopElement.style.display = "none";
},
});
};
const scrollToTopObserver = new IntersectionObserver((entries, observer) => {
// requestAnimationFrame(animationFrameHandler);
const entry = entries[0];
if (entry.isIntersecting) {
hideScrollToTop();
} else {
const rect = linksElement.getBoundingClientRect();
if (rect.y > window.innerHeight) {
hideScrollToTop();
} else {
showScrollToTop();
}
}
});
scrollToTopObserver.observe(linksElement);
// Image comparisons.
/** @type {HTMLDivElement[]} */
const releaseCardMediaElements = Array.from(
document.querySelectorAll(".release-card-media"),
);
for (const releaseCardMedia of releaseCardMediaElements) {
/** @type {HTMLVideoElement[]} */
const videoElements = Array.from(releaseCardMedia.querySelectorAll("video"));
/** @type {HTMLInputElement | null} */
const comparisonRange = releaseCardMedia.querySelector(".comparison-range");
if (comparisonRange == null) {
continue;
}
/** @type {HTMLDivElement | null} */
const comparisonRangeIndicator = releaseCardMedia.querySelector(
".comparison-range-indicator",
);
if (comparisonRangeIndicator == null) {
continue;
}
/** @type {HTMLDivElement | null} */
const comparisonB = releaseCardMedia.querySelector(
".image-comparison-b, .video-comparison-b",
);
if (comparisonB == null) {
continue;
}
const updateMaskWidth = () => {
comparisonB.style = `--mask-width: ${comparisonRange.valueAsNumber}%;`;
};
const updateComparisonRangeIndicator = () => {
comparisonRangeIndicator.style = `left: calc(${comparisonRange.valueAsNumber}% - (0.25em / 2))`;
};
/** @type {(event: MouseEvent) => void} */
const onPointerEvent = (event) => {
const bounds = comparisonRange.getBoundingClientRect();
const x = event.clientX - bounds.left;
const width = bounds.width;
comparisonRange.valueAsNumber = (x / width) * 100;
for (const videoElement of videoElements) {
if (videoElement.paused) {
videoElement.play();
}
}
updateMaskWidth();
updateComparisonRangeIndicator();
};
comparisonRange.addEventListener("pointerdown", onPointerEvent);
comparisonRange.addEventListener("pointermove", onPointerEvent);
updateMaskWidth();
updateComparisonRangeIndicator();
}
// target="_blank"
/** @type {HTMLAnchorElement[]} */
const anchors = Array.from(
document.querySelector("main .release-container").querySelectorAll("a"),
);
for (const anchor of anchors) {
if (anchor.classList.contains("download-button")) {
continue;
}
try {
const anchorUrl = new URL(anchor.href);
const isInternalLink =
anchorUrl.protocol === window.location.protocol &&
anchorUrl.host === window.location.host &&
anchorUrl.port === window.location.port &&
anchorUrl.pathname === window.location.pathname &&
anchorUrl.hash.startsWith("#");
if (!isInternalLink) {
anchor.target = "_blank";
}
} catch (err) {
const newErr = new Error("Error while setting anchor target to blank.");
newErr.cause = err;
console.error(newErr);
}
}

View File

View File

@@ -0,0 +1,31 @@
---
title: Godot 4.4, a unified experience
excerpt: Look forward to plenty of quality of life improvements hidden within this release. Faster load speeds, reduced stutter, streamlined processes — spotting all the optimizations that have been applied in the background will take some time.
categories: ["release"]
author: "Godot contributors"
image: /storage/blog/covers/godot-4-4-a-unified-experience.webp
date: 2025-03-03 15:45:00
redirect_to:
- /releases/4.4/
---
Look forward to plenty of quality of life improvements hidden within this release. Faster load speeds, reduced stutter, streamlined processes — spotting all the optimizations that have been applied in the background will take some time.
On top of that, long-awaited comfort features like embedded game windows and interactive in-game editing will feel more in line with other software on the market, making transitioning between them an even smoother experience. The editor overhaul alone takes up a big chunk of this release, after all.
We invite you to take a look over at the [4.4 release page](/releases/4.4/).
Or grab 4.4 here directly and get started.
{% include articles/download_card.html version="4.4" release="stable" article=page %}
**Standard build** includes support for GDScript and GDExtension.
**.NET build** (marked as `mono`) includes support for C#, as well as GDScript and GDExtension.
- See also [C# platform support](https://docs.godotengine.org/en/latest/tutorials/scripting/c_sharp/index.html#c-platform-support).
## Support
Godot is a non-profit, open-source game engine developed by hundreds of contributors on their free time, as well as a handful of part or full-time developers hired thanks to [generous donations from the Godot community](https://fund.godotengine.org/). A big thank you to everyone who has contributed [their time](https://github.com/godotengine/godot/blob/master/AUTHORS.md) or [their financial support](https://github.com/godotengine/godot/blob/master/DONORS.md) to the project!
If you'd like to support the project financially and help us secure our future hires, you can do so using the [Godot Development Fund](https://fund.godotengine.org/) platform managed by [Godot Foundation](https://godot.foundation/). There are also several [alternative ways to donate](/donate) which you may find more suitable.

View File

@@ -67,7 +67,7 @@ Unfortunately, checksums are the wrong tool for the job to keep track of **uniqu
There could still be value to computing a checksum and storing it in `.uid` files, so that Godot can automatically move the UID file if the source file was moved without its UID file. This is something that should be tackled separately though, as this approach comes with its downsides too.
### Why not use replace `.import` files with `.meta` files and use them for all resources that have an UID?
### Why not use replace `.import` files with `.meta` files and use them for all resources that have a UID?
While Godot must import many resource types before they can be used in a project, not all types actually need to be imported to be used. Resources that don't need to be imported to be used don't have properties that you could set on import, as they are directly loaded by Godot with no remapping system in place. Instead, everything about the file is inferred from the file itself. This approach makes more sense for files that you expect to be able to copy-paste around (or even copy directly from websites), while making sure the file remains functional without needing a separate metadata file. It's a common workflow from users to copy scripts or shaders from websites such as [Godot Shaders](https://godotshaders.com/) after all.

View File

@@ -0,0 +1,21 @@
---
type: entry
section: general
subsection: core
rank: 2
importance: 4
anchor: curve-domains-outside-of-0-1
title: "Curve: domains outside of [0,1]"
blockquote: Ahead of the curve
text: |
By extending the domain of Curve values beyond the normalized [0, 1] range, we aim to give you greater flexibility in how to map functions and data to this ubiquitous resource.
contributors:
- name: ocean
github: anvilfolk
read_more: https://github.com/godotengine/godot/pull/67857
image_src: /storage/releases/4.4/images/godot_curve_outside.webp
image_src_2x: /storage/releases/4.4/images/godot_curve_outside_2x.webp
image_alt: Picture of the editor inspector showing a `Curve` resource with values outside [0,1].
media_position: bottom
position: center-right
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: general
subsection: core
rank: 1
importance: 4
anchor: manifold-library-replaces-CSG-implementation
title: Manifold library replaces CSG implementation
blockquote: Reaping the benefits of open source
text: |
Support for Constructive Solid Geometry (CSG) has been in the engine since Godot 3.1 and is a great tool for rapid prototyping.
Nonetheless, our internal implementation suffered from stability issues and other bugs. This is one of the engine areas that does not have a dedicated maintainer to look after it, so when an open source library with the same functionality was released, we jumped at the opportunity.
Manifold completely replaces the existing implementation, which is a fairly big change in how Godot handles CSG internally, but only minimally impacts the user API. Please check your projects after upgrading and report any negative consequences to us so they can be tackled!
contributors:
- name: K. S. Ernest (iFire) Lee
github: fire
- name: Emmett Lalish
github: elalish
read_more: https://github.com/godotengine/godot/pull/94321
---

View File

@@ -0,0 +1,34 @@
---
type: entry
section: general
subsection: core
rank: 0
importance: 2
anchor: "optimizations"
title: "Optimizations"
blockquote: "Harder, Better, Faster, Stronger"
text: |
Now that the core feature set of Godot 4 feels stable, our contributors have shifted their efforts towards optimizing them across the board.
While many of the linked PRs were finished and tested before the 4.3 release, they did not make the merge deadline, resulting in a big batch for you to enjoy now.
contributors:
- name: Stuart Carnie
github: stuartcarnie
- name: Aaron Pagano
github: aaronp64
- name: A Thousand Ships
github: AThousandShips
- name: Arseny Kapoulkine
github: zeux
- name: lawnjelly
github: lawnjelly
- name: Tomasz Chabora
github: KoBeWi
- name: Clay John
github: clayjohn
- name: Rune
github: rune-scape
- name: Lukas Tenbrink
github: Ivorforce
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2094558%2094353%2092555%20%2092550%20%2092546%2093727%2092734%2095704%2094241%2092213%2092575%2092581%20102132%20101493%20101033%20100294%20100477%20100041%20100015%20
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: general
subsection: core
rank: 5
importance: 2
anchor: scenetree-system-overhaul
title: SceneTree system overhaul
blockquote: A <span class="highlight">performance boost</span> for everyone
text: |
The changes made to how the SceneTree system works, specifically how it processes changes to the nodes, result in an editor performance increase for all projects.
Moving or renaming nodes in complex scenes will be a much faster experience now!
contributors:
- name: HP van Braam
github: hpvb
read_more: https://github.com/godotengine/godot/pull/99700
video_poster: /storage/releases/4.4/video/godot_scene_tree.webp
video_src: /storage/releases/4.4/video/godot_scene_tree.webm
media_position: left
position: top-left
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: general
subsection: core
rank: 3
importance: 4
anchor: temporary-file-and-directory-utilities
title: Temporary file and directory utilities
blockquote: Just a quick sidenote
text: |
With this brand new API you can create and dispose of temporary files and directories. In other words: you can write content on a disc without worrying about polluting user data. By default, any file/directory you create this way automatically disposes of itself after use.
Tool developers in particular should have a look at this new feature!
contributors:
- name: Adam Scott
github: adamscott
read_more: https://github.com/godotengine/godot/pull/98397
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: general
subsection: editor
rank: 1
importance: 2
anchor: "3D-object-snapping"
title: "3D object snapping"
blockquote: <span class="highlight">Snap,</span> you're it
text: |
When placing 3D objects in the editor, they are now able to snap to other surfaces.
This works through a collision detection ray, and makes repositioning objects in a scene easier.
contributors:
- name: Robert Yevdokimov
github: ryevdokimov
read_more: https://github.com/godotengine/godot/pull/96740
video_src: /storage/releases/4.4/video/godot_raycast_position.webm
video_poster: /storage/releases/4.4/video/godot_raycast_position.webp
media_position: left
content_creator: "[@passivestar](https://bsky.app/profile/passivestar.bsky.social)"
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: general
subsection: editor
rank: 11
importance: 4
anchor: autostart-for-all-profilers
title: Autostart for all profilers
blockquote: <span class="highlight">Check</span> this <span class="highlight">box</span>
text: |
If you want to capture profiling data while running your game - without missing the first few seconds of loading a scene - you will appreciate this new checkbox.
It will autostart all profilers when you run a project, rather than forcing you to tab out of the game to do it yourself.
contributors:
- name: Hendrik Brucker
github: Geometror
read_more: https://github.com/godotengine/godot/pull/96759
---

View File

@@ -0,0 +1,19 @@
---
type: entry
section: general
subsection: editor
rank: 3
importance: 2
anchor: "camera3d-preview"
title: "Camera3D preview"
blockquote: "Switch up your perspective"
text: |
Adjusting a Camera3D is now much less of a chore. Enjoy a preview of its capture directly in the inspector, without having to open another viewport or switching back and forth anymore.
contributors:
- name: Haoyu Qiu
github: timothyqiu
read_more: https://github.com/godotengine/godot/pull/90778
video_poster: /storage/releases/4.4/video/godot_editor_camera.webp
video_src: /storage/releases/4.4/video/godot_editor_camera.webm
media_position: right
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: general
subsection: editor
rank: 12
importance: 4
anchor: error-less-first-project-import
title: Error-less first project import
blockquote: Much less intimidating
text: |
No one wants to be met with a wall of errors after freshly importing their project from a version control system.
This used to happen because it is not necessary to push the `.godot` folder into your repositories, since it auto-generates upon opening your project for the first time. After that, you had to restart the editor to get rid of all the errors caused by broken references — not anymore!
contributors:
- name: Hilderin
github: Hilderin
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2092303%2093972%2092667%2093064
---

View File

@@ -0,0 +1,19 @@
---
type: entry
section: general
subsection: editor
rank: 2
anchor: "favorite-editor-items"
title: "Favorite editor items"
blockquote: "You get a star, and you get a star!"
text: |
Pin your most used properties to the top of the inspector for easy access.
contributors:
- name: Michael Alexsander
github: YeldhamDev
read_more: https://github.com/godotengine/godot/pull/97415
image_alt: Picture of the editor inspector showing favorited items.
image_src: /storage/releases/4.4/images/godot_editor_favorites.webp
image_src_2x: /storage/releases/4.4/images/godot_editor_favorites_2x.webp
media_position: top
---

View File

@@ -0,0 +1,21 @@
---
type: entry
section: general
subsection: editor
rank: 4
importance: 2
anchor: "gdscript-tooltips"
title: "GDScript tooltips"
blockquote: "Did you know..."
text: |
Hovering over functions, variables, classes, etc. in the GDScript editor will now greet you with a tooltip pop-up containing further information from the integrated documentation. This includes any notes you have written yourself using the new documentation system.
UIDs will show a human-readable path on hover.
contributors:
- name: Danil Alexeev
github: dalexeev
read_more: https://github.com/godotengine/godot/pull/91060
image_src: /storage/releases/4.4/images/godot_gdscript_tooltips.webp
image_src_2x: /storage/releases/4.4/images/godot_gdscript_tooltips_2x.webp
media_position: left
---

View File

@@ -0,0 +1,26 @@
---
type: entry
section: general
subsection: editor
rank: 4
importance: 3
anchor: new-expression-evaluator
title: New expression evaluator
blockquote: <span class="highlight">REPL</span>ace print statements
text: |
The new expression evaluator has been added as another tab in the bottom panel of the editor. In there, you can evaluate expressions using the local state directly while stopped at a breakpoint.
contributors:
- name: Oğuzhan Eroğlu
github: rohanrhu
- name: Erik Selecký
github: rxlecky
- name: Tomasz Chabora
github: KoBeWi
read_more: https://github.com/godotengine/godot/pull/97647
image_alt: Picture of the new expression evaluator in the editor showing expression results.
image_src: /storage/releases/4.4/images/godot_repl.webp
image_src_2x: /storage/releases/4.4/images/godot_repl_2x.webp
media_position: right
position: bottom-left
inverted: true
---

View File

@@ -0,0 +1,20 @@
---
type: entry
section: general
subsection: editor
rank: 7
importance: 3
anchor: persistent-window-state
title: Persistent window state
blockquote: Continue where you left off
text: |
This is a quality of life improvement for anyone using big monitors or multi-monitor setups.
The Godot editor now keeps track of its window state: whether it is in fullscreen or windowed mode, which screen it is on, as well as its size and position.
These settings are then automatically restored when you open the program again.
contributors:
- name: Samuele Panzeri
github: spanzeri
read_more: https://github.com/godotengine/godot/pull/76085
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: general
subsection: editor
rank: 9
importance: 4
anchor: scene-startup-optimizations
title: Scene startup optimizations
blockquote: Start your engines!
text: |
Editor load speed improves once again. Large projects can expect a speed bump of up to 3x!
This benefits both the project startup and any operations that scan the filesystem.
contributors:
- name: Hilderin
github: Hilderin
read_more: https://github.com/godotengine/godot/pull/95678
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: general
subsection: editor
rank: 5
importance: 2
anchor: shadowmasks-for-lightmapGI
title: Shadowmasks for LightmapGI
blockquote: <span class="highlight">Both.</span> Both is good.
text: |
From now on, you don't have to choose between fully baked or fully dynamic shadows anymore when using LightmapGI.
By enabling shadowmasks while baking your lightmaps, it is now possible to use static shadows in the distance and dynamic shadows up close. The lower resolutions far away will save precious resources, while the level of detail close to the player is not impacted.
Shortening the range of your dynamic shadows like so provides very important optimization, especially for mobile applications.
contributors:
- name: BlueCube3310
github: BlueCube3310
- name: Nathan Dearth
github: DearthDev
read_more: https://github.com/godotengine/godot/pull/85653
---

View File

@@ -0,0 +1,24 @@
---
type: entry
section: general
subsection: editor
rank: 0
importance: 2
anchor: "universal-uid-support"
title: "Universal UID support"
blockquote: "No more broken paths"
text: |
Partial Unique Identifier (UID) support a way to reference resources without relying on human-readable file paths prone to change has been present in the engine since Godot 4.0, but many file types did not benefit from it yet. Now this fully supported workflow makes Godot more resistant to changes in your filesystem organization, and therefore more suitable to larger projects.
To make upgrading your projects from Godot 4.3 easier, this release also includes a UID upgrade tool to automate the not-so-straightforward process for you.
contributors:
- name: Juan Linietsky
github: reduz
read_more: /article/uid-changes-coming-to-godot-4-4/
image_alt: File manager showing project script files with .uid files existing besides them.
image_src: /storage/releases/4.4/images/godot_uid.webp
image_src_2x: /storage/releases/4.4/images/godot_uid_2x.webp
media_position: right
position: top-left
inverted: true
---

View File

@@ -0,0 +1,23 @@
---
type: entry
section: general
subsection: editor
rank: 8
importance: 3
anchor: visual-shader-goodies
title: Visual shader goodies
blockquote: Small but mighty
text: |
In this release, the visual shader editor receives some love:
- material previews and a matching new side dock
- the ability to drag & drop meshes into the visual shader area to automatically create mesh emitters
contributors:
- name: Yuri Rubinsky
github: Chaosus
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2094215%2093017
video_src: /storage/releases/4.4/video/godot_visual_material_editor_goodies.webm
video_poster: /storage/releases/4.4/video/godot_visual_material_editor_goodies.webp
media_position: right
content_creator: "[@heytibo](https://bsky.app/profile/heytibo.bsky.social)"
---

View File

@@ -0,0 +1,29 @@
---
type: entry
section: highlights
rank: 5
importance: 2
anchor: _3D-physics-interpolation
title: 3D physics interpolation
blockquote: Do you get the jitters?
text: |
With Godot 4.3, we introduced physics interpolation for your 2D projects. In this release, the long-awaited 3D counterpart has been merged as well! Make sure to enable it in your project settings.
By decoupling physics ticks and display frame rates, physics interpolation creates additional frames between the last physics position and the current one. This reduces jitter and creates a smoother appearance, especially on displays with a high refresh rate.
Mobile games in particular benefit from this change, since you can now lower the tick rate without compromising on smoothness.
contributors:
- name: Ricardo Buring
github: rburing
- name: lawnjelly
github: lawnjelly
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2092391%2091818
video_poster: /storage/releases/4.4/video/godot_physics_interpolation.webp
video_src: /storage/releases/4.4/video/godot_physics_interpolation_without.webm
video_label: Without <small>(10 ticks/s)</small>
video_comparison_poster: /storage/releases/4.4/video/godot_physics_interpolation.webp
video_comparison_src: /storage/releases/4.4/video/godot_physics_interpolation_with.webm
video_comparison_label: With <small>(10 ticks/s)</small>
media_position: bottom
content_creator: "[@heytibo](https://bsky.app/profile/heytibo.bsky.social)"
---

View File

@@ -0,0 +1,33 @@
---
type: entry
section: highlights
rank: 5
importance: 2
anchor: AgX-tone-mapping
title: AgX tone mapping
blockquote: The cool new kid on the block
text: |
This tone mapping algorithm has gained a lot of popularity lately. Our friends at [Blender](https://blender.org) even replaced their previous "filmic" tone mapper with AgX.
The Godot implementation resembles theirs closely, but is purposely simplified to be more suitable for real time use cases.
AgX gives a movie-esque quality to renders and is capable of handling very bright scenes better than our other available options.
contributors:
- name: Hugo Locurcio
github: Calinou
- name: Allen Pestaluky
github: allenwp
- name: Clay John
github: clayjohn
read_more: https://github.com/godotengine/godot/pull/87260
media_position: top
image_alt: ACES
image_src: /storage/releases/4.4/images/godot_neon_aces.webp
image_src_2x: /storage/releases/4.4/images/godot_neon_aces_2x.webp
image_label: ACES
image_comparison_alt: AgX
image_comparison_src: /storage/releases/4.4/images/godot_neon_agx.webp
image_comparison_src_2x: /storage/releases/4.4/images/godot_neon_agx_2x.webp
image_comparison_label: AgX
content_creator: "[@passivestar](https://bsky.app/profile/passivestar.bsky.social) and [@allenwp](https://github.com/allenwp)"
---

View File

@@ -0,0 +1,25 @@
---
type: entry
section: highlights
rank: 1
importance: 2
anchor: embedded-game-window
title: Embedded game window
blockquote: Window management <span class="highlight">magic</span>
text: |
Godot runs the game as a separate process from the editor for two reasons:
- avoid having to share resources as much as possible
- in case of a game crash, keep the editor running (to avoid data loss)
However, this design choice previously prevented embedding the game window into the editor. Which is something that users with limited screenspace, like on single-monitor setups or laptops, are looking for.
Thanks to some window management tricks, it is now possible to embed the game seamlessly and interact with the rest of the editor, while still keeping the processes separate in the background.
Note that this only works on Linux, Windows, and Android for now. Support for macOS will require a different approach for technical reasons.
contributors:
- name: Hilderin
github: Hilderin
- name: Fredia Huya-Kouadio
github: m4gr3d
read_more: https://github.com/godotengine/godot/pull/99010
---

View File

@@ -0,0 +1,25 @@
---
type: entry
section: highlights
rank: 3
importance: 2
anchor: "android-editor-support-for-XR-devices"
title: "Android editor support for XR devices"
blockquote: Make games <span class="highlight">in VR</span>!
text: |
Because the Godot Editor itself is a project made with the engine like any other, it can be made available in more unconventional places like the web or on mobile.
With this release, the first steps have been taken to use OpenXR to transfer the existing Android editor into the context of XR headsets.
Currently supported on Meta Quest 3, Quest 3S, and Quest Pro.
contributors:
- name: Fredia Huya-Kouadio
github: m4gr3d
- name: Bastiaan Olij
github: BastiaanOlij
read_more: https://github.com/godotengine/godot/pull/96624
video_poster: /storage/releases/4.4/video/godot_xr_editor.webp
video_src: /storage/releases/4.4/video/godot_xr_editor.webm
media_position: top
content_creator: "[@m4gr3d](https://github.com/m4gr3d)"
---

View File

@@ -0,0 +1,19 @@
---
type: entry
section: highlights
rank: 2
importance: 2
anchor: interactive-in-game-editing
title: Interactive in-game editing
blockquote: Step into your projects
text: |
Modifying your game from within the editor while it is running or paused has never been easier. This release lets you click on elements within the scene and move the camera, allowing you to explore your game worlds in ways not possible before.
contributors:
- name: Michael Alexsander
github: YeldhamDev
read_more: https://github.com/godotengine/godot/pull/97257
video_poster: /storage/releases/4.4/video/godot_interactive_editor.webp
video_src: /storage/releases/4.4/video/godot_interactive_editor.webm
media_position: top
position: top-center
---

View File

@@ -0,0 +1,23 @@
---
type: entry
section: highlights
rank: 0
importance: 1
anchor: jolt-physics-module
title: Jolt Physics
blockquote: <span class="highlight">Jolt</span> into action
text: |
The Jolt extension has been used as the _de facto_ physics engine by many Godot developers since its inception in late 2022, so it only made sense to integrate it into the engine directly. [Jolt Physics](https://github.com/jrouwe/JoltPhysics) itself is actually a standalone open source physics engine and its creator helped immensely with the Godot bindings.
While this PR might be one of the most rigorously tested ones, we are eagerly awaiting your feedback (and [GitHub issues](https://github.com/godotengine/godot/issues)) to eventually be able to drop the "experimental" label on this addition. Until then, you have to enable this alternative to Godot Physics in the project settings. Before you do, make sure to check if your interests/use-cases are properly supported [in the documentation](https://docs.godotengine.org/en/4.4/tutorials/physics/using_jolt_physics.html).
contributors:
- name: Mikael Hermansson
github: mihe
- name: Jorrit Rouwe
github: jrouwe
read_more: https://github.com/godotengine/godot/pull/99895
video_src: /storage/releases/4.4/video/godot_jolt.webm
video_poster: /storage/releases/4.4/video/godot_jolt.webp
media_position: right
content_creator: "[@heytibo](https://bsky.app/profile/heytibo.bsky.social)"
---

View File

@@ -0,0 +1,23 @@
---
type: entry
section: highlights
rank: 6
importance: 1
anchor: typed-dictionaries
title: Typed dictionaries
blockquote: Keys required
text: |
Your requests have been heard!
Typed dictionaries are coming to Godot. This impacts the core engine, GDScript, and all other scripting languages when interfacing with Godot's <span class="code-highlight basetype">Dictionary</span> type.
The Inspector UX has been improved accordingly, to let you assign the right keys and values directly in the editor.
contributors:
- name: Thaddeus Crews
github: Repiteo
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2078656%2070096%20
image_alt: "A simple GDScript file showing two typed dictionary declarations: one valid export, and another simple variable declaration that isn't correctly initialized. The parser detects that the dictionary expects `StringName` as keys and `float` as values, but a string was supplied as a value instead."
image_src: /storage/releases/4.4/images/godot_typed_dictionary.webp
image_src_2x: /storage/releases/4.4/images/godot_typed_dictionary_2x.webp
media_position: left
---

View File

@@ -0,0 +1,29 @@
---
type: entry
section: highlights
rank: 4
importance: 2
anchor: ubershaders
title: Ubershaders to reduce stutter
blockquote: <span class="highlight">Uber</span>-exciting!
text: |
Ubershaders are at load time pre-compiled versions of each shader with all their features.
These shaders become the fallback whenever a new object is drawn, so that freezing — as we wait for the more specialized shader pipeline in the background to compile — becomes a thing of the past. This technique therefore completely avoids shader stutter!
The improvement from this change will be noticeable in most games without requiring any content changes. In some cases, the ubershaders won't work however — refer to the workarounds for shader stutter in the official documentation to learn about simple fixes.
We are already in the process of updating our existing shaders to take advantage of this new infrastructure.
contributors:
- name: Darío
github: DarioSamo
read_more: https://github.com/godotengine/godot/pull/90400
video_src: /storage/releases/4.4/video/godot_ubershaders_without.webm
video_poster: /storage/releases/4.4/video/godot_ubershaders.webp
video_label: Without
video_comparison_src: /storage/releases/4.4/video/godot_ubershaders_with.webm
video_comparison_poster: /storage/releases/4.4/video/godot_ubershaders.webp
video_comparison_label: With
media_position: bottom
content_creator: "[@dariosamo](https://github.com/DarioSamo)"
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: platforms
subsection: android
rank: 0
importance: 3
anchor: android-editor-export-support
title: "Android editor: Export support"
blockquote: Stay <span class="highlight">on mobile</span> from start to finish
text: |
The Godot editor has been available on Android devices for a while already, but until now you were forced to switch to a different OS to create the various platform binaries.
No more of that: download export templates onto your Android device and finalize your project right there.
contributors:
- name: Fredia Huya-Kouadio
github: m4gr3d
read_more: https://github.com/godotengine/godot/pull/93526
---

View File

@@ -0,0 +1,16 @@
---
type: entry
section: platforms
subsection: android
rank: 2
importance: 4
anchor: androidfilepicker-support
title: <span class="code-highlight basetype">AndroidFilePicker</span> support
blockquote: New functionality
text: |
You can now utilize Androids native file picker in your games and apps. This creates a more seamless experience on mobile.
contributors:
- name: Anish Mishra
github: syntaxerror247
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2098350%2099385
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: platforms
subsection: android
rank: 1
importance: 4
anchor: javaclasswrapper-fixed
title: <span class="code-highlight basetype">JavaClassWrapper</span> fixed
blockquote: Time for a fresh brew
text: |
You can now map Java classes to Godot objects as an interface. This gives easier access to the Android SDK and lets you avoid creating a plugin for even the most basic things.
contributors:
- name: David Snopek
github: dsnopek
- name: Fredia Huya-Kouadio
github: m4gr3d
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2096182%2097500%2099492%20102494%20102862
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: platforms
subsection: android
rank: 3
importance: 3
anchor: swappy-android-frame-pacing-library
title: Swappy Android Frame Pacing library
blockquote: Pace yourself
text: |
The Android Frame Pacing library also known as Swappy helps games achieve smooth rendering and correct frame pacing on Android. The library handles multiple refresh rates if they are supported by the device, which gives a game more flexibility in presenting a frame.
As a developer, you don't have to do anything to reap these benefits: they are automatic upon upgrading your project.
contributors:
- name: Matias N. Goldberg
github: darksylinc
read_more: https://github.com/godotengine/godot/pull/96439
---

View File

@@ -0,0 +1,19 @@
---
type: entry
section: platforms
subsection: android
rank: 4
importance: 2
anchor: themed-icons
title: Themed icons
blockquote: Matchy-matchy
text: |
To be able to match a user's system theme, you can now provide a monochrome icon for your app on export, which will then automatically be re-colored for them. This is a simple way to enhance your app's native feel.
contributors:
- name: Anish Mishra
github: syntaxerror247
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2097517%2099378
video_poster: /storage/releases/4.4/video/godot_themable_icons.webp
video_src: /storage/releases/4.4/video/godot_themable_icons.webm
media_position: right
---

View File

@@ -0,0 +1,20 @@
---
type: entry
section: platforms
subsection: linux
rank: 0
importance: 2
anchor: linux-camera-support
title: Linux camera support
blockquote: We can see you now!
text: |
Before Godot 4.4, accessing a device's camera was only supported on macOS and iOS devices.
Now Linux support has finally been merged as well.
For other platforms, we still require contributors to pick up the work — could that be you?
contributors:
- name: pkowal1982
github: pkowal1982
read_more: https://github.com/godotengine/godot/pull/53666
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: platforms
subsection: macos-and-ios
rank: 1
importance: 4
anchor: apple-game-controller-improvements
title: Apple game controller improvements
blockquote: Let's get ready to <span class="highlights">rumble</span>!
text: |
We overhauled how game controllers work on macOS and iOS, to unify the code across those two platforms some more. Plenty of bugs were fixed along the way.
You will notice improvements in the reliability of controller discovery and manipulating the rumble motors.
contributors:
- name: Stuart Carnie
github: stuartcarnie
read_more: https://github.com/godotengine/godot/pull/94580
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: platforms
subsection: macos-and-ios
rank: 0
importance: 3
anchor: "metal-rendering-backend"
title: "Metal rendering backend"
blockquote: "Melting the workarounds"
text: |
Metal is a low-level graphics API similar to Vulkan or D3D12, which are both supported by Godot but not available on macOS and iOS. Until now Godot used a library called MoltenVK to run Vulkan over Metal.
This direct implementation is more efficient and allows greater control over features and performance trade-offs in the future. Early results have shown that this backend is at least as fast as Vulkan and in many cases much faster on Apple hardware.
In relation to this new backend, you now have the option to use MetalFX upscaling as an alternative to the existing upscaler.
Note that Metal support is currently limited to Apple Silicon (ARM) devices.
contributors:
- name: Stuart Carnie
github: stuartcarnie
read_more: https://github.com/godotengine/godot/pull/88199
---

View File

@@ -0,0 +1,20 @@
---
type: entry
section: scripting
subsection: dotnet
rank: 0
importance: 3
anchor: "dotnet-8-0"
title: ".NET 8.0"
blockquote: "Time for an upgrade"
text: |
With the release of Godot 4.0, we moved our C# packages from targeting Mono to .NET 6. This version of .NET was released on November 8, 2021 and ended support on November 12, 2024.
Therefore, our next release will implement and raise the minimum required version to .NET 8; existing projects will automatically be upgraded when opened with Godot 4.4 while older releases will keep targeting .NET 6 to avoid breakage.
contributors:
- name: Paul Joannon
github: paulloz
- name: Raul Santos
github: raulsntos
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2092131%20100195%20
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: scripting
subsection: dotnet
rank: 1
importance: 4
anchor: dotnet-support-for-android
title: .NET support for Android
blockquote: Work in progress
text: |
C# projects now support all Android ABIs and [BCL](https://en.wikipedia.org/wiki/Standard_Libraries_(CLI)#Base_Class_Library) APIs (formerly only 64-bit architectures).
contributors:
- name: Raul Santos
github: raulsntos
- name: TCROC
github: TCROC
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%20102627%2098066%2088803
---

View File

@@ -0,0 +1,30 @@
---
type: entry
section: general
subsection: editor
rank: 12
importance: 3
anchor: "export-tool-button-annotation"
title: "<span class='code-highlight gdscript-annotation'>@export_tool_button</span> annotation"
blockquote: On the <span class="highlight">button</span>
text: |
The tool developers amongst you asked and our contributors delivered:
You can now create buttons in the inspector from <span class='code-highlight gdscript-annotation'>@tool</span> scripts.
contributors:
- name: jordi
github: jordi-star
- name: Mack
github: Macksaur
- name: K. S. Ernest (iFire) Lee
github: fire
- name: Danil Alexeev
github: dalexeev
- name: Paul Joannon
github: paulloz
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%2096290%2097894
video_src: /storage/releases/4.4/video/godot_editor_tool_button.webm
video_poster: /storage/releases/4.4/video/godot_editor_tool_button.webp
media_position: top
position: top-left
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: systems
subsection: VFX
rank: 0
importance: 2
anchor: emission-shapes-for-3D-particle-systems
title: Emission shapes for 3D particle systems
blockquote: Removing the guesswork
text: |
From now on, you can rely on a visualization of the 3D particle systems you are placing in your scene, instead of having to guess based on the emission shape's properties alone.
This works for both CPU and GPU particles.
contributors:
- name: Patrick Exner (FlameLizard)
github: paddy-exe
read_more: https://github.com/godotengine/godot/pull/100113
video_src: /storage/releases/4.4/video/godot_particle_emission_shape.webm
video_poster: /storage/releases/4.4/video/godot_particle_emission_shape.webp
media_position: left
content_creator: "[@passivestar](https://bsky.app/profile/passivestar.bsky.social)"
---

View File

@@ -0,0 +1,23 @@
---
type: entry
section: systems
subsection: animation
rank: 2
importance: 2
anchor: "animation-markers"
title: "Animation markers"
blockquote: "Put a pin in it"
text: |
Markers allow you to create subregions of an animation that can be jumped to or looped without playing the entire animation.
These markers are also supported inside the Animation Tree, where you can easily create an <span class="code-highlight basetype">AnimationNode</span>s custom timeline based on the markers.
contributors:
- name: ChocolaMint
github: chocola-mint
read_more: https://github.com/godotengine/godot/pull/91765
image_src: /storage/releases/4.4/images/godot_animation_markers.webp
image_src_2x: /storage/releases/4.4/images/godot_animation_markers_2x.webp
image_alt: Image of the animation editor with markers added.
media_position: right
position: bottom-center
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: systems
subsection: animation
rank: 0
importance: 2
anchor: lookatmodifier3D
title: <span class="code-highlight basetype">LookAtModifier3D</span>
blockquote: Would you look at that
text: |
This new node type is used to handle 3D model procedural animation, partially replacing the deprecated <span class="code-highlight basetype">SkeletonIK3D</span>. It is specialized to make a character model look in the target direction.
Therefore users can now assign angle limitations, forward axis settings, and more directly instead of relying on specific bone structures or arbitrary layouts.
contributors:
- name: Silc Lizard (Tokage) Renew
github: TokageItLab
read_more: https://github.com/godotengine/godot/pull/98446
video_poster: /storage/releases/4.4/video/godot_lookat.webp
video_src: /storage/releases/4.4/video/godot_lookat.webm
media_position: right
content_creator: "[@heytibo](https://bsky.app/profile/heytibo.bsky.social)"
---

View File

@@ -0,0 +1,27 @@
---
type: entry
section: systems
subsection: animation
rank: 1
importance: 2
anchor: springbonesimulator3D
title: <span class="code-highlight basetype">SpringBoneSimulator3D</span>
blockquote: Jiggle physics
text: |
The [VRMSpringBone](https://vrm.dev/en/univrm/springbone/univrm_secondary/) has been available as an add-on on the asset library for a while now, but there were some issues that could only be fixed by a more direct implementation.
The animation team refined the MIT-distributed code based on Godot's <span class="code-highlight basetype">SkeletonModifier3D</span> node, and tied it in with existing core functionality. This helps improve both usability and performance.
contributors:
- name: Silc Lizard (Tokage) Renew
github: TokageItLab
read_more: https://github.com/godotengine/godot/pull/101409
video_poster: /storage/releases/4.4/video/godot_springbone.webp
video_src: /storage/releases/4.4/video/godot_springbone_without.webm
video_label: Without
video_comparison_poster: /storage/releases/4.4/video/godot_springbone.webp
video_comparison_src: /storage/releases/4.4/video/godot_springbone_with.webm
video_comparison_label: With
video_comparison_poster: /storage/releases/4.4/video/godot_springbone.webp
media_position: left
content_creator: "[@heytibo](https://bsky.app/profile/heytibo.bsky.social)"
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: systems
subsection: audio
rank: 0
importance: 2
anchor: runtime-WAV-file-loading
title: Runtime WAV file loading
blockquote: Catch this <span class="highlight">WAV</span>e
text: |
You can now load WAV files at runtime — just like OGG Vorbis audio tracks already allowed.
This feature will come in handy for those looking to load user-generated content at runtime, including non-game audio applications.
contributors:
- name: cherry
github: what-is-a-git
read_more: https://github.com/godotengine/godot/pull/93831
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: systems
subsection: import
rank: 0
importance: 2
anchor: betsy-texture-compressor
title: Betsy texture compressor
blockquote: <span class="highlight">Faster</span> imports
text: |
The [Betsy texture compressor](https://github.com/darksylinc/betsy) is a tool to compress images into various GPU texture formats. It is now being integrated into the Godot Engine.
Betsy runs on the GPU and is able to compress images significantly faster than our current compressors (using the “VRAM Compressed” import setting).
This change reduces import time dramatically.
contributors:
- name: BlueCube3310
github: BlueCube3310
- name: Matias N. Goldberg
github: darksylinc
read_more: https://github.com/godotengine/godot/pull/91535
---

View File

@@ -0,0 +1,20 @@
---
type: entry
section: systems
subsection: import
rank: 1
importance: 2
anchor: new-glTF-extension
title: New glTF extension
blockquote: <span class="highlight">Customizable</span> animation imports
text: |
Previously, glTF imports only allowed you to animate properties from this list: position, rotation, scale, and mesh blend shape weights.
This new extension now enables animations to target custom properties too! Think the color of a light, the FOV of a camera, the albedo color of a material, the UV offset of a material, …
The mappings between Godot properties and [glTF Object Model](https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc) JSON pointers can be defined via GDScript.
contributors:
- name: Aaron Franke
github: aaronfranke
read_more: https://github.com/godotengine/godot/pull/94165
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: systems
subsection: navigation
rank: 0
importance: 2
anchor: async-navigation
title: Async navigation
blockquote: Background checks
text: |
Navigation map synchronization has been moved to an asynchronous background thread.
This avoids slowing down the entire game during navigation updates, especially on lower-end systems. Instead, updates will happen less frequently when resources are limited.
contributors:
- name: smix8
github: smix8
read_more: https://github.com/godotengine/godot/pull/100497
---

View File

@@ -0,0 +1,22 @@
---
type: entry
section: systems
subsection: navigation
rank: 1
importance: 2
anchor: navigation-system-refactor
title: Navigation system refactor
blockquote: Improving the legacy code
text: |
The navigation code may very well be some of the oldest left in the engine's codebase. Therefore the navigation team has taken up the task to clean up thoroughly and add improvements to outdated areas.
This release already contains plenty quality of life changes, from debug indicators to show the direction of navigation links, to supporting the obstactle node's transform, and more. In general, navigation features are going to be faster, in no small part due to the pathfinding queries now using a new internal heap structure.
contributors:
- name: smix8
github: smix8
- name: Steven Le Boëdec
github: ershn
- name: Rie
github: tracefree
read_more: https://github.com/godotengine/godot/issues?q=is%3Apr%20state%3Amerged%20100129%2085965%2096730%20101010
---

View File

@@ -0,0 +1,20 @@
---
type: entry
section: systems
subsection: physics
rank: 0
importance: 2
anchor: custom-colors-for-collision-shapes
title: Custom colors for collision shapes
blockquote: <span class="highlight">Debugging</span> in style
text: |
Collision shapes now have <span class="code-highlight membervariable">debug_color</span> and <span class="code-highlight membervariable">debug_fill</span> properties for you to customize in the editor. If "Visible Collision Shapes" is enabled in the debug menu, you can even change these at runtime.
contributors:
- name: ActualHorse
github: BattyBovine
read_more: https://github.com/godotengine/godot/pull/90644
image_alt: Screenshot of a game running with visible collision shapes showing different colors.
image_src: /storage/releases/4.4/images/godot_collision_shapes.webp
image_src_2x: /storage/releases/4.4/images/godot_collision_shapes_2x.webp
media_position: left
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: systems
subsection: rendering
rank: 2
importance: 3
anchor: 2D-batching
title: 2D Batching
blockquote: <span class="highlight">Call</span> me maybe
text: |
Batching is a performance optimization that drastically reduces the number of draw calls in a scene. The effect will be particularly noticeable in scenes with a lot of text rendering or repeated sprites sharing a texture.
Previously, this optimization was only available in the Compatibility renderer. This release brings batching to the other rendering backends as well, which should make 2D performance comparable amongst all of them.
contributors:
- name: Stuart Carnie
github: startcarnie
read_more: https://github.com/godotengine/godot/pull/92797
---

View File

@@ -0,0 +1,26 @@
---
type: entry
section: systems
subsection: rendering
rank: 5
importance: 3
anchor: 2D-shader-instance-uniforms
title: 2D shader instance uniforms
blockquote: <span class="highlight">Variations</span> made easier
text: |
This release adds support for shader instance uniforms to CanvasItem shaders.
They allow you to assign a different uniform value to each instance of the item, instead of having to compile two separate shaders to achieve this.
This approach is more performant than having to juggle materials, and does not break batching.
contributors:
- name: Patrick Exner (FlameLizard)
github: paddy-exe
- name: Tomasz Chabora
github: KoBeWi
- name: Álex Román Núñez
github: EIREXE
- name: yesfish
github: huwpascoe
read_more: https://github.com/godotengine/godot/pull/99230
---

View File

@@ -0,0 +1,29 @@
---
type: entry
section: systems
subsection: rendering
rank: 0
importance: 2
anchor: lightmaps-bicubic
title: "Lightmaps: bicubic sampling & transparency"
blockquote: Blend into the <span class="highlight">shadows</span>
text: |
Thanks to bicubic sampling (and new antialiasing for direct light samples), your low resolution static shadows will now look better than ever.
This method for reading from lightmaps smoothes out sharp edges, but requires a small run-time performance cost. You can disable it in the project settings if needed.
Additionally, lightmaps now support baking transparent objects and correlatedly: tinted shadows.
contributors:
- name: BlueCube3310
github: BlueCube3310
read_more: https://github.com/godotengine/godot/pull/89919
image_label: "Off"
image_alt: The Sponza scene with bicubic shadows turned off.
image_src: /storage/releases/4.4/images/godot_shadow_bicubic_off.webp
image_src_2x: /storage/releases/4.4/images/godot_shadow_bicubic_off_2x.webp
image_comparison_label: "On"
image_comparison_alt: The Sponza scene with bicubic shadows turned on.
image_comparison_src: /storage/releases/4.4/images/godot_shadow_bicubic_on.webp
image_comparison_src_2x: /storage/releases/4.4/images/godot_shadow_bicubic_on_2x.webp
media_position: left
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: systems
subsection: rendering
rank: 4
importance: 4
anchor: rendering-driver-fallback
title: Rendering driver fallback
blockquote: Godot has got your back
text: |
In case you were trying to run Godot with the Forward+ or Mobile backends on a device that does not not actually support Vulkan, D3D12, or Metal, you used to be met with an OS alert that has proven to confuse users more than it is helpful.
This change instead automatically makes the engine fallback on the Compatibility renderer, which is based on OpenGL. For moments when you do not want this behavior, you can toggle it off in the project settings.
contributors:
- name: 憨憨羊の宇航鸽鸽
github: SheepYhangCN
read_more: https://github.com/godotengine/godot/pull/97142
---

View File

@@ -0,0 +1,18 @@
---
type: entry
section: systems
subsection: rendering
rank: 4
importance: 4
anchor: shadow-caster-mask-property
title: Shadow Caster Mask property
blockquote: A new on/off switch
text: |
Users can now apply a mask on singular Light3D objects to select which rendering layers are considered when casting shadows.
By adding this level of control, dynamic lights can be further optimized and shadows selectively turned on/off.
contributors:
- name: Hannah Crawford
github: EMBYRDEV
read_more: https://github.com/godotengine/godot/pull/85338
---

View File

@@ -0,0 +1,23 @@
---
type: entry
section: systems
subsection: rendering
rank: 1
importance: 2
anchor: "vertex-shading"
title: "Vertex shading"
blockquote: "Retro vibes"
text: |
A new shading option for materials, which can be turned on from within existing material nodes or force enabled on all materials via the project settings.
Vertex shaders reduce GPU workload by checking whether vertices' coordinates are within clip-space (visible to the camera) before processing the data.
This option is most commonly used to achieve PSX-style graphics or to target lower-end devices.
contributors:
- name: ywmaa
github: ywmaa
read_more: https://github.com/godotengine/godot/pull/83360
video_poster: /storage/releases/4.4/video/godot_vertex_lighting.webp
video_src: /storage/releases/4.4/video/godot_vertex_lighting.webm
media_position: right
---

View File

@@ -0,0 +1,19 @@
---
type: section
name: General
anchor: general
rank: 1
subsections:
- name: 2D
anchor: _2D
- name: 3D
anchor: _3D
- name: Core
anchor: core
- name: Editor
anchor: editor
- name: GUI
anchor: GUI
- name: Documentation
anchor: documentation
---

View File

@@ -0,0 +1,7 @@
---
type: section
name: Highlights
anchor: highlights
rank: 0
two_columns: true
---

View File

@@ -0,0 +1,17 @@
---
type: section
name: Platforms
anchor: platforms
rank: 2
subsections:
- name: Android
anchor: android
- name: Linux
anchor: linux
- name: macOS and iOS
anchor: macos-and-ios
- name: Windows
anchor: windows
- name: Web
anchor: web
---

View File

@@ -0,0 +1,13 @@
---
type: section
name: Scripting
anchor: scripting
rank: 3
subsections:
- name: C#/.NET
anchor: dotnet
- name: GDScript
anchor: gdscript
- name: GDExtension
anchor: gdextension
---

View File

@@ -0,0 +1,23 @@
---
type: section
name: Systems
anchor: systems
rank: 4
subsections:
- name: Animation
anchor: animation
- name: Audio
anchor: audio
- name: Import
anchor: import
- name: Navigation
anchor: navigation
- name: Physics
anchor: physics
- name: Rendering
anchor: rendering
- name: VFX
anchor: VFX
- name: XR
anchor: XR
---

385
pages/releases/4.4.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,204 @@
{% assign section_anchor = include.section_anchor %}
{% assign feature = include.feature %}
{% assign importance = feature.importance | default: "4" | plus: 0 %}
{% assign has_media = false %}
{% assign is_video = false %}
{% assign is_image = false %}
{% if feature.video_src == null and feature.image_src == null %}
{% comment %}
{% endcomment %}
{% else %}
{% assign has_media = true %}
{% assign media_position = feature.media_position | default: 'top' %}
{% if feature.video_src != null %}
{% assign is_video = true %}
{% else %}
{% assign is_image = true %}
{% endif %}
{% endif %}
{% assign media_class = "" %}
{% if has_media %}
{% assign media_class = "media-" | append: media_position %}
{% endif %}
{% assign span = "" %}
{% if section_anchor == "highlights" %}
{% if importance == 1 %}
{% assign span = "span-2" %}
{% endif %}
{% elsif importance == 2 %}
{% assign span = "span-3" %}
{% elsif importance == 3 %}
{% assign span = "span-2" %}
{% endif %}
{% assign inverted = "" %}
{% if feature.inverted %}
{% assign inverted = "inverted" %}
{% endif %}
<div id="{{feature.anchor}}" class="release-card {{media_class}} {{span}} {{inverted}}">
<div class="release-card-container">
<div class="release-card-content">
<div class="release-card-content-container">
<!-- .c-title -->
<h4 class="c-title">
<a href="#{{feature.anchor}}">{{feature.title | markdownify}}</a>
</h4>
<!-- .c-blockquote -->
{% if feature.blockquote != null and importance < 4 %}
<div class="c-blockquote">
{{ feature.blockquote | markdownify }}
</div>
{% endif %}
<!-- .c-content -->
<div class="c-content">
{{ feature.text | markdownify }}
</div>
<!-- .c-link -->
{% if feature.contributors == null %}
{% assign contributors = "" | split: "," %}
{% else %}
{% assign contributors = feature.contributors %}
{% endif %}
{% assign contributors_json = "[" %}
{% for contributor in contributors %}
{% assign contributors_json = contributors_json | append: "{" | append: '"name": "' | append: contributor.name | append: '", "github": "' | append: contributor.github | append: '" }' %}
{% if forloop.index != forloop.length %}
{% assign contributors_json = contributors_json | append: "," %}
{% endif %}
{% endfor %}
{% assign contributors_json = contributors_json | append: "]" %}
<div class="c-link"
data-contributors='{{ contributors_json }}'
data-read-more="{{ feature.read_more }}">
<a class="c-link-a" href="{{ feature.read_more }}" target="_blank">Read more</a>
<div class="contributor-area">
{% assign contributors_size = contributors | size %}
<div class="contributor-icon">
<span class="material-symbols-outlined">
{% if contributors_size == 1 %}
person
{% elsif contributors_size == 2 %}
group
{% else %}
groups
{% endif %}
</span>
</div>
<div class="contributor-list">
<span>
Contributed by {% for contributor in contributors %}{% assign is_last = forloop.last %}{% assign penultimate_index = forloop.length | minus: 1 %}<a href="https://github.com/{{contributor.github}}" title="@{{contributor.github}} on GitHub" target="_blank">{{ contributor.name }}</a>{% if forloop.last != true %}{% if contributors_size == 2 %} and {% elsif contributors_size >= 3 %}, {% if forloop.index == penultimate_index %} and {% endif %}{% endif %}{% endif %}{% endfor %}
</span>
</div>
</div>
</div>
</div>
</div>
{% if has_media %}
<div class="release-card-media">
{% assign position_class = "" %}
{% if feature.position != null %}
{% assign position_class = "position-" | append: feature.position %}
{% endif %}
{% if is_video %}
<div class="release-card-video-container">
<noscript>
<video class="release-card-video {{position_class}}"
playsinline="playsinline"
disablepictureinpicture="disablepictureinpicture"
autoplay="autoplay"
loop="loop"
muted="muted"
poster="{{ feature.video_poster }}">
<source src="{{ feature.video_src }}"
type="video/webm" />
</video>
</noscript>
{% if feature.video_label != null %}
<div class="release-card-video-label">{{feature.video_label}}</div>
{% endif %}
</div>
{% if feature.video_comparison_src != null %}
<div class="release-card-video-container video-comparison-b">
<noscript>
<video class="release-card-video {{position_class}}"
playsinline="playsinline"
disablepictureinpicture="disablepictureinpicture"
autoplay="autoplay"
loop="loop"
muted="muted"
poster="{{ feature.video_comparison_poster }}">
<source src="{{ feature.video_comparison_src }}"
type="video/webm" />
</video>
</noscript>
{% if feature.video_comparison_label != null %}
<div class="release-card-video-label">{{feature.video_comparison_label}}</div>
{% endif %}
</div>
<div class="release-card-comparison">
<div class="comparison-range-indicator"></div>
<input type="range"
id="{{feature.anchor}}-comparison-range"
class="comparison-range"
step="0.0001"
min="0"
max="100"
value="50">
</div>
{% endif %}
{% endif %}
{% if is_image %}
<div class="release-card-image-container">
<img class="release-card-image {{position_class}}"
alt="{{ feature.image_alt }}"
src="{{ feature.image_src }}"
srcset="{{ feature.image_src_2x }} 2x"
draggable="false" />
{% if feature.image_label != null %}
<div class="release-card-image-label">{{feature.image_label}}</div>
{% endif %}
</div>
{% if feature.image_comparison_src != null %}
<div class="release-card-image-container image-comparison-b">
<img class="release-card-image {{position_class}}"
alt="{{ feature.image_comparison_alt }}"
src="{{ feature.image_comparison_src }}"
srcset="{{ feature.image_comparison_src_2x }} 2x" />
{% if feature.image_comparison_label != null %}
<div class="release-card-image-label release-card-image-label-comparison">
{{feature.image_comparison_label}}
</div>
{% endif %}
</div>
<div class="release-card-comparison">
<div class="comparison-range-indicator"></div>
<input type="range"
id="{{feature.anchor}}-comparison-range"
class="comparison-range"
step="0.0001"
min="0"
max="100"
value="50">
</div>
{% endif %}
{% endif %}
{% if feature.content_creator != null %}
<div class="release-card-content-creator">
{{ feature.content_creator | markdownify }}
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>

View File

@@ -0,0 +1,105 @@
{% assign section = include.section %}
{% assign data = include.data %}
{% assign is_two_columns = section.two_columns | default: false %}
{% if is_two_columns %}
{% assign two_column_class = "two-columns" %}
{% else %}
{% assign two_column_class = "" %}
{% endif %}
{% if section.subsections == null %}
{% assign section_features = data | where: "section", section.anchor | sort: "rank" %}
{% else %}
{% assign section_features = "" | split: "," %}
{% for subsection in section.subsections %}
{% assign subsection_features = data | where: "section", section.anchor | where: "subsection", subsection.anchor | sort: "rank" %}
{% for subsection_feature in subsection_features %}
{% assign section_features = features | push: subsection_feature %}
{% endfor %}
{% endfor %}
{% endif %}
{% if section_features.size > 0 %}
<div id="{{section.anchor}}" class="section section-{{section.anchor}}">
<div class="section-title">
<div class="container">
<h3>
<a href="#{{section.anchor}}">{{section.name}}</a>
<div class="section-robot godot-icon-godot" aria-disabled="true"></div>
</h3>
</div>
<div class="container section-{{section.anchor}}">
{% if section.subsections != null %}
<div id="{{section.anchor}}-links" class="release-card transparent-card span-3">
<div class="release-card-container">
<div class="release-card-content">
<div class="release-card-content-container">
<div class="c-content">
<ul class="links-container links-container-subsections">
{% for subsection in section.subsections %}
{% assign subsection_features = data | where: "section", section.anchor | where: "subsection", subsection.anchor | sort: "rank" %}
{% if subsection_features.size > 0 %}
<li>
<a
class="link link-{{section.anchor}} link-{{section.anchor}}-{{subsection.anchor}}"
href="#{{section.anchor}}-{{subsection.anchor}}"
>
<span>{{subsection.name}}</span>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
{% if section.subsections == null %}
<div class="container section-{{section.anchor}}">
<div class="release-cards {{two_column_class}}">
{% assign features = data | where: "section", section.anchor | sort: "rank" %}
{% for feature in features %}
{%
include_relative _includes/feature.html
feature=feature
section_anchor=section.anchor
%}
{% endfor %}
</div>
</div>
{% else %}
{% for subsection in section.subsections %}
{% assign features = data | where: "section", section.anchor | where: "subsection", subsection.anchor | sort: "rank" %}
{% if features.size > 0 %}
{% assign is_two_columns = subsection.two_columns | default: false %}
<div id="{{section.anchor}}-{{subsection.anchor}}" class="section subsection section-{{section.anchor}} section-{{section.anchor}}-{{subsection.anchor}}">
<div class="section-title">
<div class="container">
<h3>
<a href="#{{section.anchor}}-{{subsection.anchor}}">{{subsection.name}}</a>
<div class="section-robot godot-icon-godot" aria-disabled="true"></div>
</h3>
</div>
</div>
</div>
<div class="container section-{{section.anchor}}">
<div class="release-cards {{two_column_class}}">
{% for feature in features %}
{%
include_relative _includes/feature.html
feature=feature
section_anchor=section.anchor
%}
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endif %}

View File

@@ -1,5 +1,5 @@
---
permalink: /releases/index.html
redirect_to:
- /releases/4.3/
- /releases/4.4/
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="510" height="823" fill="none"><g fill="#EFF1F5" opacity=".05"><path d="M-38.155-37c-41.615 9.252-82.783 22.134-121.379 41.56.883 34.08 3.086 66.734 7.552 99.903-14.988 9.603-30.741 17.845-44.741 29.087-14.224 10.943-28.754 21.41-41.634 34.209-25.732-17.02-52.963-33.015-81.02-47.133C-349.62 153.174-377.9 188.304-401 227.615c18.154 28.497 37.626 57.138 55.659 79.474v241.265c.441.003.886.018 1.323.059l147.909 14.262a15.926 15.926 0 0 1 14.358 14.75l4.562 65.291 129.021 9.209 8.886-60.264a15.931 15.931 0 0 1 15.76-13.606h156.049c7.899 0 14.603 5.793 15.755 13.606l8.886 60.264 129.026-9.209 4.557-65.291a15.933 15.933 0 0 1 14.358-14.75l147.851-14.262c.437-.041.876-.054 1.317-.059v-19.253l.064-.016V307.089c20.828-26.22 40.549-55.141 55.659-79.474-23.092-39.311-51.385-74.441-81.628-106.989-28.049 14.118-55.294 30.113-81.025 47.133-12.876-12.799-27.379-23.266-41.624-34.209-13.996-11.242-29.771-19.484-44.731-29.087 4.454-33.169 6.66-65.822 7.547-99.903-38.6-19.426-79.764-32.309-121.4-41.56-16.623 27.938-31.824 58.196-45.064 87.773-15.7-2.624-31.472-3.596-47.265-3.784v-.027c-.11 0-.213.027-.307.027-.098 0-.204-.027-.302-.027v.027c-15.822.188-31.583 1.16-47.287 3.784C-6.317 21.196-21.507-9.062-38.155-37Zm-117.018 352.938c49.233 0 89.138 39.874 89.138 89.091 0 49.248-39.905 89.143-89.138 89.143-49.208 0-89.122-39.895-89.122-89.143 0-49.217 39.914-89.091 89.122-89.091Zm419.356 0c49.204 0 89.112 39.874 89.112 89.091 0 49.248-39.908 89.143-89.112 89.143-49.24 0-89.143-39.895-89.143-89.143 0-49.217 39.903-89.091 89.143-89.091Zm-209.69 52.134c15.846 0 28.72 11.692 28.72 26.076v82.057c0 14.396-12.874 26.075-28.72 26.075-15.848 0-28.69-11.679-28.69-26.075v-82.057c0-14.384 12.842-26.076 28.69-26.076Z"/><path d="m321.587 593.09-4.581 65.639c-.552 7.911-6.845 14.208-14.756 14.776l-157.549 11.242a15.3 15.3 0 0 1-1.149.04c-7.829 0-14.584-5.745-15.74-13.607l-9.035-61.271H-9.776l-9.035 61.271c-1.213 8.246-8.585 14.175-16.889 13.567l-157.549-11.242c-7.911-.568-14.204-6.865-14.756-14.776l-4.581-65.639-132.998-12.823c.061 14.294.245 29.953.245 33.071 0 140.464 178.185 207.979 399.568 208.755h.543c221.382-.776 399.507-68.291 399.507-208.755 0-3.176.192-18.769.257-33.071L321.587 593.09ZM-87.484 410.315c0 32.666-26.476 59.141-59.166 59.141-32.675 0-59.167-26.475-59.167-59.141 0-32.667 26.492-59.167 59.167-59.167 32.69 0 59.166 26.5 59.166 59.167ZM196.49 410.315c0 32.666 26.468 59.141 59.134 59.141 32.699 0 59.166-26.475 59.166-59.141 0-32.667-26.467-59.167-59.166-59.167-32.666 0-59.134 26.5-59.134 59.167Z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

Some files were not shown because too many files have changed in this diff Show More