Skip to content

Conversation

@GabCoolDude
Copy link
Contributor

@GabCoolDude GabCoolDude commented Nov 8, 2025

Overview

This allows for [Export] to change a property's usage without having to use _GetPropertyList or _ValidateProperty. It also brings [Export] back up to speed with GDScript's @export_custom, which also allows for this.

// Before:
[Export] public int Health;

public override void _ValidateProperty(Godot.Collections.Dictionary property)
{
    if (property["name"].AsStringName() == PropertyName.Health)
    {
        var usage = property["usage"].As<PropertyUsageFlags>() | PropertyUsageFlags.ReadOnly;
        property["usage"] = (int)usage;
    }
}

// After:
[Export(usageFlags: PropertyUsageFlags.ReadOnly | PropertyUsageFlags.Default)]
public int Health;

It works by adding an additional optional constructor argument to ExportAttribute and assigning it to a UsageFlags property. Then in ScriptPropertiesGenerator, we just simply grab the constructor argument's value, similar to how it's done for PropertyHint

How to test

  • Setup a .NET build of Godot based on this PR
  • Use this project to test easily and compare behavior between GDScript and C# (should be the same, but just in-case).
  • Mess around

Notes

I consider this PR to be ready, however there is the possibility that tests might be needed. Currently, only base [Export] is tested in Godot.SourceGenerators.Tests, if I were to add tests for PropertyUsageFlags, how would I go about it, and would I need to add tests for PropertyHint and HintString ? We could also leave tests to do in a follow-up PR.

There should also be some changes made to this documentation page about C# exported properties. I will handle it as soon as this is merged.

Closes godotengine/godot-proposals#2957

@GabCoolDude GabCoolDude requested a review from a team as a code owner November 8, 2025 18:26
This allows for `[Export]` to change a property's `usage` without having to use `_GetPropertyList` or `_ValidateProperty`. It also brings `[Export]` back up to speed with GDScript's `@export_custom`, which also allows for this.
@GabCoolDude GabCoolDude force-pushed the dotnet-propertyusageflags-export branch from fd289c3 to ee16575 Compare November 8, 2025 18:34
@paulloz paulloz added this to the 4.x milestone Nov 8, 2025
@paulloz
Copy link
Member

paulloz commented Nov 9, 2025

Hello, and thank you for the contribution!

Linking #105123, which is fairly similar, and opening the discussion for both here.

Our main concern about this is how it interacts with the flags automatically set by the current source generators. Should the flags provided by the user add to those, or override them? Implementation in both PRs go for an in-between, dropping Default, and keeping ScriptVariable (I don't think @export_custom does the same, but I haven't checked). It's debatable which option is "more correct".

If the goal is to provide access to a specific set of functionality (e.g. defining exported properties as read-only), we think doing so through additional attributes would be better. Syntax would look like:

[Export, ReadOnly]
public int Health;

IMHO, that is what most users who want access to usage flags actually want to be able to do. Thoughts?

@GabCoolDude GabCoolDude changed the title Expose PropertyUsageFlags in ExportAttribute [.NET] Expose PropertyUsageFlags in ExportAttribute Nov 9, 2025
@GabCoolDude
Copy link
Contributor Author

GabCoolDude commented Nov 9, 2025

Oh, I didn't notice that there already was a PR for this, sorry about that.

I remember seeing something about @export_custom adding ScriptVariable no matter what, but now I can't seem to find it It's mentioned here. [Export] used to always add Default and ScriptVariable, and this is for a good reason, [Export] always comes from a script so it should always have ScriptVariable no matter what. I guess you could make an argument that a user might want to remove ScriptVariable from a property's usage, but I don't see a good usecase for that. Dropping Default matches the behavior of @export_custom and is useful, for example, when using Storage.

If the goal is to provide access to a specific set of functionality (e.g. defining exported properties as read-only), we think doing so through additional attributes would be better

Additional attributes would work fine, but has a much more complex solution compared to this, as there would need to be one for every value of the PropertyUsageFlags enum. Users are already familiar with [Export], and this wouldn't match with @export_custom.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose property info 'usage' in C# Export Attribute

2 participants