Godot Engine: Conservatory Edition
The Conservatory runs on a custom version of the Godot game engine with modifications ranging from "generally helpful" to "required for proper function". This page outlines the features that have been added or changed.
To view the original contributors and creators, please visit https://godotengine.org/license.
Core Changes
Changes relevant only to The Conservatory.
SimulationDomain
  SimulationDomain is a highly complex type fundamental to the game. It is a mix between SubViewport and Viewport with several unique properties:
- Only one SimulationDomaincan be active at a time; an instance must be made active explicitly.- The active SimulationDomainoverrides the root viewport, effectively becoming that viewport.
- All settings that affect the viewport (like graphics settings) are proxies to that of the root viewport; SimulationDomaininherits the properties but doesn't actually use them since it still piggybacks off of the root viewport.
 
- The active 
- SimulationDomaininstances always have their own 2D and 3D physics spaces and render scenarios, meaning their own- World2Dand- World3Das well. These simulate in the background regardless of if the domain is active, allowing parallel simulation of several worlds at once.
- SimulationDomainis highly protected. You cannot create new instances of it, only the engine can. Even the slightest misuse of it outside of its strict specification will purposely crash the game. It's basically the only class in the game where I growl at you and say don't touch. It's very sensitive!- You can still query its World2DandWorld3D, as well as itsPhysicsSpaceandRenderScenarioproperties to access the respective RIDs.
- Don't you even think about freeing these objects. Unless you like it when the game crashes on you. I'm not your mom.
 
- You can still query its 
  In essence, SimulationDomain does what it says on the tin - it's an entire domain upon which the game is simulated, both physics and rendering. As you may be able to infer, these are used for running several worlds at once, primarily on servers where players may be on different planets at once, and so all of them need to be simulated in their own little isolated box.
ConservatoryDebugBridge
  This class is largely internal, but the short description is that it allows debug versions of the engine to hook into The Conservatory itself, permitting the C# debugger to also debug the engine using its associated .pdb files. This was especially useful when designing SimulationDomain since I could see exactly how the managed and unmanaged parts of the code worked together.
Physics and Space/Vector Improvements
Changes to the physics engine, its API, and types relating to space.
RayCast3DDirect and ShapeCast3DDirect
  These two classes are, unlike their siblings RayCast3D and ShapeCast3D, not based on Node. Instead, these instances provide fast, low level physics engine access to perform raycasts on demand. This is used by several systems in the game, in particular deferred casting, which uses an instance of this type to effectively perform and store a raycast so that it can be done in an async method (see Star3D.Maths.Physics.Raycasting::RaycastAsync()).
The primary benefits of these types include:
- No scene tree access is required to operate them.
- They avoid the slow Godot.Collections.Dictionaryreturn fromPhysicsServer3D.intersect_rayandPhysicsServer3D.intersect_shape.
- They cast only when you tell them to, and can export their results.
Related Improvements
- RayCastResultwas added to contain results from- RayCast3DDirect. It, and- RayCast3D, now include a new enum property- HitObjectType. This will be either- Invalid,- Area,- Body, or- SoftBody, and can be used to appropriately handle raw collider- RIDs since The Conservatory makes extensive use of physics objects without nodes.
- ShapeCastResult(the analogue to this type for- ShapeCast3DDirect) exists as well.
Vector, Rect, and Transform Changes
- All Vectortypes (Vector2,Vector3,Vector4, and their integer counterparts) now implementIComparablewhich will sort them by magnitude extremely quickly.
- All Vectortypes now include two new spatial metrics:
- All Vectortypes now have a micro-optimizedIsExactlyZeromethod which uses bitwise comparison. This is one of those things that saves a few nanoseconds so it's not really worth it.
- Rect2and- Rect2Ihave new API:- FromSizestatic methods now exist which create a new- Rect2(I)at- [0, 0]with the provided size.
- Arithmetic operators +and-are now defined withVector2(I)which translates theRect2(I)without changing its size.
- The &operator is now a proxy forIntersect()
 
- Transform3D * Basisis now a defined operation, identical to- transformLeft * new Transform3D(Vector3.Zero, basisRight).
Other
- PhysicsServer3D::body_get_shape_disabled(and an- areaequivalent) were added.
- Added PhysicsServer3D::BODY_PARAM_INVERSE_INERTIA_TENSORas a new parameter forPhysicsServer3D::body_get_param. Saves having to get a reference to the entire physics state.
Unsorted Changes
- Engine::get_version_infonow returns improved data:- New versionfield which is a stringified Godot version following the display rules, i.e."4.5"
- New commitfield, which is the last 6 digits of the commit hash.
- New modulesfield, an array of features, likemonoanddouble
 
- New 
- Added Mathf.IsOneApproxandMathf.IsExactlyOne.
- Added static properties NodePath.Self(an alias for".") andNodePath.Parent(an alias for"..").
Rendering Improvements
Changes related to rendering, both 2D and 3D
2D Changes
- CharFXTransformnow provides several new properties.- TextLabelis a reference to the current- RichTextLabelthat the effect is rendering for.
- GlyphCodepointis now available which returns the first unicode codepoint of the rendered character. This is primarily useful in English, but some languages may mishandle this and so it is considered unsafe.- Glyph(C# Only!) exposs this as a- System.Text.Rune.
- get_glyph_codepointexists for GDScript and returns an- Int
 
- FontSizerepresents the size of the font as of the currently rendered character, respective of text styling.
 
- New Control.pivot_is_relativeproperty which changesControl.pivotto be expressed as a continuously updating percentage of theControl's size. This allows the pivot to maintain its relative location if the control is resized.
- RichTextLabelnow provides several new API members.- (C# Only!) RichTextLabelnow declarespublic virtual string BBCode { get; }which can be overridden to achieve the same purpose as declaring abbcodefield.- To make this work, the engine now represents a property named BBCodeas well as the legacy, all-lowercasebbcode.
 
- To make this work, the engine now represents a property named 
- (C# Only!) RichTextLabel.InstallEffect<T>()(whereTisRichTextEffect) can be used to automatically instantiate an instance of the effect.
- (C# Only!) RichTextLabel.PushCustomfx<T>()(whereTisRichTextEffect) can be used to push a custom effect onto the effect stack.
- New parsingsignal (Parsingevent in C#) has been added, which fires before and after theTextproperty parses the contained bbcode.
 
- (C# Only!) 
3D Changes
- The Stencil Buffer was added, though this is officially in Godot now.
- #pragma featuresand- #pragma exclusive_variantsare now usable in Godot shaders. These allow static compliation of branches in shaders with configurable options in the inspector.
- Shader::set_include_pathand- Shader::get_include_pathare now provided, allowing procedurally generated shaders without a file/resource path to still reference from an- #includedirectory as if they are in that directory.
- light()in spatial shaders now exposes more internal data, including:- LIGHT_POSITION- The position of the light, in view space.
- LIGHT_VERTEX_POSITION- The position of the geometry that the light is shining on, in view space.
- PHYSICAL_ATTENUATION- The same as- ATTENUATION, without the influence of shadows.
- SHADOW- The same as- ATTENUATION, but this is only the influence of shadows.
 
Other Changes
- MaterialStorage::global_shader_parameter_getis no longer an error, but will still print one to the console. The Conservatory uses this to initialize shader globals in its own data storage from the values set in the engine.