-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve scene serialized format #13041
Comments
Example file(
resources: {},
entities: {
17179869205: (
components: {
"bevy_transform::components::transform::Transform": (
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
rotation: (
x: 0.0,
y: 0.0,
z: 0.0,
w: 1.0,
),
scale: (
x: 1.0,
y: 1.0,
z: 1.0,
),
),
"bevy_transform::components::global_transform::GlobalTransform": ((
matrix3: (
x_axis: (
x: 1.0,
y: 0.0,
z: 0.0,
),
y_axis: (
x: 0.0,
y: 1.0,
z: 0.0,
),
z_axis: (
x: 0.0,
y: 0.0,
z: 1.0,
),
),
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
)),
"bevy_core::name::Name": "rect",
"bevy_render::view::visibility::Visibility": Inherited,
"bevy_render::view::visibility::InheritedVisibility": (true),
"bevy_render::view::visibility::ViewVisibility": (true),
"bevy_hierarchy::components::parent::Parent": (12884901914),
"bevy_ui::ui_node::Node": (
stack_index: 0,
calculated_size: (
x: 0.0,
y: 0.0,
),
outline_width: 0.0,
outline_offset: 0.0,
unrounded_size: (
x: 0.0,
y: 0.0,
),
),
"bevy_ui::focus::FocusPolicy": Pass,
"bevy_ui::ui_node::Style": (
display: Flex,
position_type: Relative,
overflow: (
x: Visible,
y: Visible,
),
direction: Inherit,
left: Px(0.0),
right: Px(0.0),
top: Px(0.0),
bottom: Px(0.0),
width: Auto,
height: Px(30.0),
min_width: Auto,
min_height: Auto,
max_width: Auto,
max_height: Auto,
aspect_ratio: None,
align_items: Default,
justify_items: Default,
align_self: Auto,
justify_self: Auto,
align_content: Default,
justify_content: Default,
margin: (
left: Px(0.0),
right: Px(0.0),
top: Px(0.0),
bottom: Px(0.0),
),
padding: (
left: Px(0.0),
right: Px(0.0),
top: Px(0.0),
bottom: Px(0.0),
),
border: (
left: Px(0.0),
right: Px(0.0),
top: Px(0.0),
bottom: Px(0.0),
),
flex_direction: Row,
flex_wrap: NoWrap,
flex_grow: 0.0,
flex_shrink: 1.0,
flex_basis: Auto,
row_gap: Px(0.0),
column_gap: Px(0.0),
grid_auto_flow: Row,
grid_template_rows: [],
grid_template_columns: [],
grid_auto_rows: [],
grid_auto_columns: [],
grid_row: (
start: None,
span: Some(1),
end: None,
),
grid_column: (
start: None,
span: Some(1),
end: None,
),
),
"bevy_ui::ui_node::BackgroundColor": (Rgba(
red: 1.0,
green: 0.0,
blue: 0.0,
alpha: 1.0,
)),
"bevy_ui::ui_node::ZIndex": Local(0),
"bevy_ui::ui_node::BorderColor": (Rgba(
red: 1.0,
green: 1.0,
blue: 1.0,
alpha: 1.0,
)),
},
),
},
) |
Alright. But I think what's proposed there is quite different; it's "let's rewrite everything from scratch", which takes some time and seems to have a much large scope. Can't we just make the few above fixes, which for most are just a few lines here and there (e.g. adding |
Yeah, I'm generally on board with merging incremental improvements like that. We should have good serialization output regardless: it will continue to be valuable for other users of serialization (like networking). The main challenge will be in migrating scenes between versions: it would be good to chew on automated or semi-automated tools we can use to aid this process. |
Other potential improvements:
|
We can't not serialize defaults since that tells the deserializer what components to insert. We can do a couple things though:
I believe some people specifically set up their |
I think you're saying we have to serialize the component name at least? I'm saying let's not serialize the 20+ fields of |
I believe this is modifying the serializing of |
Yeah that's what I’m saying. And so I’m suggesting ways we might achieve that since you can't just have a value-less key in the component map. I think the cleanest/simplest option would be to include a separate entry that lists all the defaulted components by name. |
Ah, because if we tell serde to not serialize default values, it will also remove the component name, is that it? Can't we mark the content of the component as "do not serialize default" without marking the component itself? Or is the issue that we don't want explicit marking because there's too many components, and you were thinking about a different way than serde attributes to achieve this @MrGVSV? |
However
That would still be kinda bad with Another option would be putting |
Why not use |
How do we determine if a value is the default value? And we don't want to do this at the reflection serializer level as that would require instantiating the default value and comparing it against each item recursively. So to me the best solution (if we want this), would be to check it only at the component level within the
@SkiFire13 what do you mean? Wouldn't serializing just the type name be the same regardless of the size of the component? The only thing that would be bad would be comparing such large structs, but we'd have to do that in any solution that doesn't maintain an |
Sorry I wasn't totally clear on the situation I had in mind. What I meant was that if even one of the fields is changed (which I would expect to happen in practice) then the entire struct will be serialized. Hence the reference to #5511, because if it was splitted then you could include only the splitted components that are set to a non-default value. |
Oh makes sense! Yeah larger components would definitely suffer like that. Another option is reflection diffing. We could diff against the default values of each component and serialize that diff, which would be a lot smaller. That was part of my initial diffing implementation but I haven't worked on it for over a year or so unfortunately. |
I also tried myself at some point to add a |
What problem does this solve or what need does it fill?
The scene serialization (
.scn.ron
) is very verbose.What solution would you like?
#[serde(transparent)]
: e.g.InheritedVisibility
which currently serializes as(true)
but the parentheses are useless.Transform
, and currently in RON that takes 13 lines.GlobalTransform
are overwritten at runtime, there's no value in serializing them, it's not user data.Transform
per file for example, so if we really need the fully qualified type name, add a table in the file mapping short <-> full names, and use the short name everywhere else. This would save a lot of verbosity, and would make the file more readable (it's very unlikely someone will have a component with the same name as a Bevy one, and if they do we can still handle this with a different short name in the mapping table).What alternative(s) have you considered?
Live with it. Not sure there's much I can do as a third party without a Bevy fix.
Additional context
Currently an empty scene with a single entity with a UI rectangle with almost all default values (so not even a useful one) serializes at 150 lines.
The text was updated successfully, but these errors were encountered: