-
Notifications
You must be signed in to change notification settings - Fork 239
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
Add (most) save/load support for GameMaker 2024.6 #1827
Conversation
Note: This does not account for some of the variable changes that came in earlier releases, so games may still fail to load until changes are merged from the upcoming Underanalyzer branch.
Forgot to mention, I tested this on a bunch of pre-2024.6 games to ensure no regressions, and I tested each 2024.6 detection mechanism individually to make sure they work as intended. |
Download the artifacts for this pull request here: GUI:
CLI: |
@@ -2059,6 +2068,10 @@ public void Unserialize(UndertaleReader reader) | |||
NineSlices = reader.ReadUndertaleObjectPointer<UndertalePointerList<SpriteInstance>>(); | |||
if (reader.undertaleData.IsNonLTSVersionAtLeast(2023, 2)) | |||
ParticleSystems = reader.ReadUndertaleObjectPointer<UndertalePointerList<ParticleSystemInstance>>(); | |||
if (firstPointerTarget > reader.AbsPosition && !reader.undertaleData.IsVersionAtLeast(2024, 6)) | |||
reader.undertaleData.SetGMS2Version(2024, 6); // there's more data before legacy tiles, so must be 2024.6+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reader.undertaleData.SetGMS2Version(2024, 6); // there's more data before legacy tiles, so must be 2024.6+ | |
reader.undertaleData.SetGMS2Version(2024, 6); // There's more data before legacy tiles, so must be 2024.6+ |
if (reader.undertaleData.IsVersionAtLeast(2, 3)) | ||
{ | ||
sequencesPtr = reader.ReadUInt32(); | ||
if (!reader.undertaleData.IsVersionAtLeast(2, 3, 2)) | ||
nineSlicesPtr = reader.ReadUInt32(); | ||
if (reader.undertaleData.IsNonLTSVersionAtLeast(2023, 2)) | ||
partSystemsPtr = reader.ReadUInt32(); | ||
if (legacyTilesPtr > reader.AbsPosition && !reader.undertaleData.IsVersionAtLeast(2024, 6)) | ||
reader.undertaleData.SetGMS2Version(2024, 6); // there's more data before legacy tiles, so must be 2024.6+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reader.undertaleData.SetGMS2Version(2024, 6); // there's more data before legacy tiles, so must be 2024.6+ | |
reader.undertaleData.SetGMS2Version(2024, 6); // There's more data before legacy tiles, so must be 2024.6+ |
public UndertaleString Name { get; set; } | ||
public int X { get; set; } | ||
public int Y { get; set; } | ||
public UndertaleFont Font | ||
{ | ||
get => _font.Resource; | ||
set | ||
{ | ||
_font.Resource = value; | ||
OnPropertyChanged(); | ||
} | ||
} | ||
public float ScaleX { get; set; } | ||
public float ScaleY { get; set; } | ||
public float Rotation { get; set; } | ||
public uint Color { get; set; } | ||
public float OriginX { get; set; } | ||
public float OriginY { get; set; } | ||
public UndertaleString Text { get; set; } | ||
public int Alignment { get; set; } | ||
public float CharSpacing { get; set; } | ||
public float LineSpacing { get; set; } | ||
public float FrameWidth { get; set; } | ||
public float FrameHeight { get; set; } | ||
public bool Wrap { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing docstrings. Please add at least a TODO if you're not implementing them in this PR (altho would be prferred if you added them)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ended up just adding a TODO because I don't know all the possible values here yet.
Wrap = reader.ReadBoolean(); | ||
} | ||
|
||
public static UndertaleString GenerateRandomName(UndertaleData data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring
/// <inheritdoc /> | ||
public override string ToString() | ||
{ | ||
return "Text item " + Name?.Content + " with text \"" + (Text?.Content ?? "?") + "\""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use string interpolation please
public (uint Width, uint Height) CalculateMaskDimensions(UndertaleData data) | ||
{ | ||
if (data.IsVersionAtLeast(2024, 6)) | ||
{ | ||
return CalculateBboxMaskDimensions(MarginRight, MarginLeft, MarginBottom, MarginTop); | ||
} | ||
return CalculateFullMaskDimensions(Width, Height); | ||
} | ||
|
||
public static (uint Width, uint Height) CalculateBboxMaskDimensions(int marginRight, int marginLeft, int marginBottom, int marginTop) | ||
{ | ||
return ((uint)(marginRight - marginLeft + 1), (uint)(marginBottom - marginTop + 1)); | ||
} | ||
|
||
public static (uint Width, uint Height) CalculateFullMaskDimensions(uint width, uint height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstrings please :)
UndertaleModLib/UndertaleChunks.cs
Outdated
uint nextSpritePtr = 0; | ||
if ((i + 1) < spriteCount) | ||
nextSpritePtr = reader.ReadUInt32(); | ||
reader.AbsPosition = spritePtr + 4 /* skip name */; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reader.AbsPosition = spritePtr + 4 /* skip name */; | |
reader.AbsPosition = spritePtr + 4; // skip name |
UndertaleModLib/UndertaleChunks.cs
Outdated
|
||
reader.Position += 28; | ||
|
||
if (reader.ReadInt32() == -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
invert this one please. if != 1, throw exception
UndertaleModLib/UndertaleChunks.cs
Outdated
// If the "full" mask data runs past the expected end offset, and the "bbox" mask data does not, then this is 2024.6. | ||
// Otherwise, stop processing and assume this is not 2024.6. | ||
long fullEndPos = (reader.AbsPosition + fullLength); | ||
if (fullEndPos != expectedEndOffset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
invert this one please. if fullEndPos == expectedEndOffset break
UndertaleModLib/UndertaleChunks.cs
Outdated
continue; | ||
} | ||
|
||
reader.Position += 8; // playback speed values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reader.Position += 8; // playback speed values | |
reader.Position += 8; // Playback speed values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything seems good besides what Miepee has commented on. GUI support would be nice but it's not a priority to 0.5.2.0 like successful deserialization.
Do also note that most 2024.6 games still won't load, even with this, due to changes in the reference chains (where |
Description
Adds save/load support for new structures introduced in 2024.6, including text items in rooms, an additional field in sound assets, and collision masks in sprites that now depend on bounding box size instead of width/height.
Caveats
This does not account for some of the variable changes that came in earlier releases, so 2024.6 games may still fail to load until changes are merged from the upcoming Underanalyzer branch.