underminersteam / undertalemodtool Goto Github PK
View Code? Open in Web Editor NEWThe most complete tool for modding, decompiling and unpacking Undertale (and other GameMaker games!)
License: GNU General Public License v3.0
The most complete tool for modding, decompiling and unpacking Undertale (and other GameMaker games!)
License: GNU General Public License v3.0
Toby has said before he's not a programmer, and when you look at the code you realize that quickly. The most notorious issue (that he's actually commented on) is SCR_Text being one giant switch statement.
Previous tools which supported decompiling (such as GMDSam) would decompile the main text script and other similar scripts into large switch statements.
The decompiler here outputs an if-else block so long it hangs if you scroll down on SCR_TEXT.
GMDSam could determine if-else blocks and switch statements apart so there has to be some form of identifier in the code.
I hate I18N so much. In Polish locale (which is my locale, by the way) decimal numbers are usually written down as 123,4
instead of 123.4
and the default locale of most programs follows that. But this means that things like file parsers break all the time because the programmer didn't expect the system input/output functions to use different number formats than usual. And this... actually happens in my decompiler too. I did't get around to fixing it yet because I know it's not a problem for most people, but it prevented me from noticing #15.
What I mean: In Polish locale, instead of:
self.somevar = 13.5
function(12.5, 3.1337, "something")
I get:
self.somevar = 13,5
function(12,5, 3,1337, "something")
some sprite's edges (usualy the ones farthest in the 4 cardnal directions) will be... extended, I guess? this can result in a lot of black boxes surrounding the sprites.
Not sure there is much that can be done about it, but I'll mention this here anyway since the goal of this project was to never do unintended modifications on the bytecode level
This instruction (from Deltarune, if you want to check yourself):
003C9904 00048: push.d 31.4159265358979
Originally is encoded as:
00 00 00 C0 5E 38 55 29 7A 6A 3F 40
but after disassembling and reassembling turns into:
00 00 00 C0 55 38 55 29 7A 6A 3F 40
Full stack
> UndertaleModLib.dll!UndertaleModLib.Models.AssetListItem1.Unserialize(UndertaleModLib.UndertaleReader reader) Line 498 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleObject<UndertaleModLib.Models.AssetListItem1>() Line 166 C#
UndertaleModLib.dll!UndertaleModLib.UndertalePointerList<UndertaleModLib.Models.AssetListItem1>.Unserialize(UndertaleModLib.UndertaleReader reader) Line 112 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleObject<UndertaleModLib.UndertalePointerList<UndertaleModLib.Models.AssetListItem1>>() Line 166 C#
UndertaleModLib.dll!UndertaleModLib.Models.UndertaleRoom.Layer.Unserialize(UndertaleModLib.UndertaleReader reader) Line 478 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleObject<UndertaleModLib.Models.UndertaleRoom.Layer>() Line 166 C#
UndertaleModLib.dll!UndertaleModLib.UndertalePointerList<UndertaleModLib.Models.UndertaleRoom.Layer>.Unserialize(UndertaleModLib.UndertaleReader reader) Line 112 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleObject<UndertaleModLib.UndertalePointerList<UndertaleModLib.Models.UndertaleRoom.Layer>>() Line 166 C#
UndertaleModLib.dll!UndertaleModLib.Models.UndertaleRoom.Unserialize(UndertaleModLib.UndertaleReader reader) Line 146 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleObject<UndertaleModLib.Models.UndertaleRoom>() Line 166 C#
UndertaleModLib.dll!UndertaleModLib.UndertalePointerList<UndertaleModLib.Models.UndertaleRoom>.Unserialize(UndertaleModLib.UndertaleReader reader) Line 112 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleListChunk<UndertaleModLib.Models.UndertaleRoom>.UnserializeChunk(UndertaleModLib.UndertaleReader reader) Line 113 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleChunk.Unserialize(UndertaleModLib.UndertaleReader reader) Line 66 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleChunk() Line 90 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleChunkFORM.UnserializeChunk(UndertaleModLib.UndertaleReader reader) Line 58 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleData() Line 112 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleIO.Read(System.IO.Stream stream) Line 392 C#
UndertaleModTool.exe!UndertaleModTool.MainWindow.LoadFile.AnonymousMethod__0() Line 130 C#
Output
Reading chunk GEN8
WARNING: File specified length 1552, but read only 1488 (64 padding?)
Reading chunk OPTN
WARNING: File specified length 88, but read only 80 (8 padding?)
Reading chunk LANG
WARNING: File specified length 24, but read only 12 (12 padding?)
Reading chunk EXTN
WARNING: File specified length 8, but read only 4 (4 padding?)
Reading chunk SOND
WARNING: File specified length 17816, but read only 17804 (12 padding?)
Reading chunk AGRP
WARNING: File specified length 24, but read only 12 (12 padding?)
Reading chunk SPRT
Reading chunk BGND
WARNING: File specified length 20568, but read only 20560 (8 padding?)
Reading chunk PATH
WARNING: File specified length 3608, but read only 3604 (4 padding?)
Reading chunk SCPT
WARNING: File specified length 3640, but read only 3628 (12 padding?)
Reading chunk GLOB
Ignoring the GLOB chunk in GMS2 for now as apparently Undertale started using it
WARNING: File specified length 24, but read only 0 (24 padding?)
Reading chunk SHDR
WARNING: File specified length 8, but read only 4 (4 padding?)
Reading chunk FONT
WARNING: File specified length 149304, but read only 149296 (8 padding?)
Reading chunk TMLN
WARNING: File specified length 8, but read only 4 (4 padding?)
Reading chunk OBJT
WARNING: File specified length 904488, but read only 904476 (12 padding?)
Reading chunk ROOM
Exception thrown: 'System.NotImplementedException' in UndertaleModLib.dll
The method or operation is not implemented.
If you need anything else (like a small portion of the data just to see the structure), just let me know. I know you don't have access to the data at the moment.
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L216
uint MinValue; // 2147483648 (Constant)
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L217
uint UnknownTwo; // 2 (Constant)
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L218
int64 OptionsFlag (8bytes)
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L227
SplashBackImage
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L228
SplashFrontImage
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L229
SplashLoadImage
Right now, if you decompile something that contains the " character, everything breaks. Same goes for \n.
An error occured while trying to load:
Only bytecode version 16 is supported for now, you are trying to
load 14
at 000005D0 while reading object
UndertaleModLib.Models.UndertaleGeneralInfo in chunk GEN8
I mean, I can retexture and move stuff around, but how do you add/remove objects in a single room?
(Sorry for the constant questons, just REALLY eager to use this on Undertale)
The not-yet-released export button for sprites adds a bit of blur, because of how the image is rendered to deal with the empty space and scaling.
https://www.reddit.com/r/Underminers/comments/9m4riq/new_mew_mew_sprites_from_undertale_nintendo/e7c73rh/
Another QOL improvement request for the decompiler. Currently, if you have a conditional check with multiple parameters such as
if(foo = bar && dog == cat)
DoStuff();
it gets treated as
if(foo == bar)
_temp_local_var_1 = (dog == cat)
else
_temp_local_var_1 = 0
if(temp_local_var_1)
DoStuff()
Just for reference at how much more readable this is, here's a comparison between the UndertaleModTool output and the GMDSam output (doesn't work with Bytecode 16).
UndertaleModTool Output
if (self.con == 12)
{
1584.cutscene = 1 // 1584 = obj_mainchara (UndertaleGameObject)
__view_set(9, 0, -4)
self.siner = (self.siner + 1)
if (self.alarm[4] > 20)
_temp_local_var_766 = (self.intense < 1.5) // 1 = obj_musicobjectparent (UndertaleGameObject)
else
_temp_local_var_766 = 0
if _temp_local_var_766
self.intense = (self.intense + 0.02) // 0 = obj_backgrounder_parent (UndertaleGameObject)
if (self.alarm[8] > 1)
_temp_local_var_767 = (self.intense < 0.6) // 0 = obj_backgrounder_parent (UndertaleGameObject)
else
_temp_local_var_767 = 0
if _temp_local_var_767
self.intense = (self.intense + 0.01) // 0 = obj_backgrounder_parent (UndertaleGameObject)
else
{
if (self.intense > 0)
self.intense = (self.intense - 0.1) // 0 = obj_backgrounder_parent (UndertaleGameObject)
}
__view_set(0, 0, (self.xx + (sin((self.siner / 1.3)) * self.intense))) // 1 = obj_musicobjectparent (UndertaleGameObject)
__view_set(1, 0, (self.yy + (sin((self.siner / 0.9)) * self.intense))) // 0 = obj_backgrounder_parent (UndertaleGameObject)
}
GMDSam output
if(self.con == 12) {
obj_mainchara.cutscene= 1;
self.view_object[0]= -4;
self.siner++;
if(self.alarm[4] > 20 && self.intense < 1.5)
self.intense+= 0.02;
if(self.alarm[8] > 1 && self.intense < 0.6)
self.intense+= 0.01;
else {
if(self.intense > 0) self.intense-= 0.1;
}
self.view_xview[0]= self.xx + sin(self.siner / 1.3) * self.intense;
self.view_yview[0]= self.yy + sin(self.siner / 0.9) * self.intense;
}
Would be great if this could be unraveled as single checks using && or || rather than multiple checks.
This isn't a major concern right now, but this can be fixed eventually.
What I'm referring to is something like this:
abc = [1, 2, 3, 4, 5];
This is a new syntactical sugar introduced in GMS2 I believe, though it may have been added to older versions like gml_pragma was.
What this converts to is a strange function call to @@NewGMLArray@@
. It's some internal function that does what its name says. Specifically, it creates an array given its arguments as values. The bytecode for that example would be this:
00000: pushi.e 5
00001: conv.i.v
00002: pushi.e 4
00003: conv.i.v
00004: pushi.e 3
00005: conv.i.v
00006: pushi.e 2
00007: conv.i.v
00008: pushi.e 1
00009: conv.i.v
00010: call.i @@NewGMLArray@@(argc=5)
00012: pop.v.v self.abc
The decompiler currently thinks that it is
self.abc = (1, 2, 3, 4, 5)
...which is pretty close, just with parentheses instead of brackets. However, the editor allows you to click on the space before the "array literal" and that crashes it.
I try to load data.win,it showed"Something got misaligned"
Used pushvar.v instead of push.v on a standard member variable and got
############################################################################################
FATAL ERROR in
action number 1
of Draw Event
for object obj_time:
DoPushBuiltin :: variable index is out of range 103910 max is 212
at gml_Object_obj_time_Draw_77
############################################################################################
Because not everyone can use WPF (Mono users running Linux exist, too!), could you please add a CLI simple version of the tool, so I can try it out?
Thanks
With some analysis of the latest GameMaker compiler and some testing of my own, I managed to figure out exactly how the EXTN chunk is formatted. It's actually pretty simple. I may do some more of this for another chunk later on.
Here are the notes I took down, sorry if it's a little messy (indentation should be pretty obvious?):
EXTN: ListChunk
---
<normal FourCC and chunk length in every chunk>
Int32 - Count of (used) extensions
<normal list of 32-bit int pointers to item data, like other ListChunks, using count of used extensions>
Each item:
32-bit string pointer to empty string: literally "" (just a null terminator), always (hardcoded seemingly)
32-bit string pointer to extension name (Name)
32-bit string pointer to class name (ClassName)
List of "extension includes" (files), takes format of List<T>:
Int32 - Count
<list of 32-bit pointers to each item, as in List<T> format>
Each item:
32-bit string pointer to filename (Filename)
32-bit string pointer to name of function called when game ends, as stored in the extension file, not as referenced in GameMaker, unless they are the same (Final)
32-bit string pointer to name of function called when extension initializes, as stored in the extension file, not as referenced in GameMaker, unless they are the same (Init)
Int32 - extension type/kind, value taken directly from project file (Kind)
0 -> unknown; likely unused
1 -> DLL
2 -> GML "placeholder"
3 -> unknown, but potentially used before GM:S
4 -> either an included data file, or a "generic placeholder" file
5 -> JS "placeholder"
List of functions in the include file (if Kind is 2 [which is "GML placeholder"], then this is always empty):
Int32 - Count
<list of 32-bit pointers to each item, as in List<T> format>
Each item:
32-bit string pointer to function name, as referenced in GameMaker (Name)
Int32 - function ID (Id) - just a unique ID of some kind (very likely based on code analysis, incrementing)
Int32 - function type/kind (Kind)
Int32 - function return type (ReturnType). Value taken directly from project file:
1 -> string
2 -> double
32-bit string pointer to external function name (in the external file); not as it is referenced in GameMaker code, unless they are identical (ExtName)
Int32 - Count of arguments
Array (NOT a List-type thing) of Int32, count of items is the "Count of arguments" just stated - represents each argument's type. Value taken directly from project file:
1 -> string
2 -> double
So, anyway, I guess this issue could be used to track the implementation of the EXTN chunk in the tool/lib, unless this isn't meant to be where this is done.
This chunk is pretty complex compared to the last one I documented, and many others... I'm not sure how much of this will make sense, but I guess this issue can track the implementation of the SHDR chunk to this library/tool.
Here's what I got, from the latest GMS2 compiler. I haven't tested too much because it gets complicated very fast.
SHDR: ListChunk
This chunk seems pretty strange and complex in some places, and I tried my best to document it (somewhat) clearly.
---
<normal FourCC and chunk length>
List<T> format beginning:
Int32 - count
<list of 32-bit pointers to each item>
For each item:
32-bit string pointer to shader name
Int32 - shader type with a bitwise OR against -0x80000000 (in big endian here, also it's signed and negative), as a number it is -2147483648
Basically, in this case, this just changes the last byte of the little-endian Int32 to 0x80. For what reason is unknown?
Little-endian-formatted types that are known, total of seven:
0x01000080 (1) -> GLSL ES
0x01000080 (2) -> GLSL
0x03000080 (3) -> Unknown
0x04000080 (4) -> HLSL
0x05000080 to 0x07000080 (5 to 7) -> Unknown
Missing from this list (the "unknown" types) are PSSL (PlayStation Shader Language), Cg, and Cg_PS3 (for PS3 seemingly)
Also potentially a difference between HLSL9 and HLSL11
I was unable to test these
<note: many of the strings and pointers in this chunk will be null>
32-bit string pointer to GLSL ES vertex shader code
32-bit string pointer to GLSL ES fragment shader code
32-bit string pointer to GLSL vertex shader code
32-bit string pointer to GLSL fragment shader code
32-bit string pointer to HLSL9 vertex shader code
32-bit string pointer to HLSL9 fragment shader code
<note: I'm going to give some pointers ID numbers so it's easy to tell where they go in the chunk>
32-bit pointer to HLSL11 vertex shader string/bytes (ID #1)
32-bit pointer to HLSL11 pixel shader string/bytes (ID #2)
Int32 - count of vertex shader attributes
Array (NOT a List<T>) of 32-bit string pointers, using the count specified on the last line, each representing a vertex shader attribute
Int32 - literally just the number 2
32-bit pointer to PSSL vertex shader string/bytes (ID #3)
Int32 - length of PSSL vertex shader string/bytes
32-bit pointer to PSSL pixel shader string/bytes (ID #4)
Int32 - length of PSSL pixel shader string/bytes
32-bit pointer to Cg vertex shader string/bytes (ID #5)
Int32 - length of Cg vertex shader string/bytes
32-bit pointer to Cg pixel shader string/bytes (ID #6)
Int32 - length of Cg pixel shader string/bytes
32-bit pointer to Cg_PS3 vertex shader string/bytes (ID #7)
Int32 - length of Cg_PS3 vertex shader string/bytes
32-bit pointer to Cg_PS3 pixel shader string/bytes (ID #8)
Int32 - length of Cg_PS3 pixel shader string/bytes
<note: Here's where everything starts to get complicated. I will do my best to represent if statements and loops used>
<note2: This part contains a lot of actual shader data, but not all of it>
<note3: There is a lot of strange padding involved, but it's probably unnecessary when re-compiling because of pointers?>
If there is HLSL11 vertex shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 7) is not 0:
Byte - number 0
<pointer ID #1 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
Or it's a possibility that you read until you hit the necessary zero padding before the location the next pointer points to (for the next shader data)?
Or you just continually read through the zeros until you hit the next shader data (using the pointers)?
If there is HLSL11 pixel shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 7) is not 0:
Byte - number 0
<pointer ID #2 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
If there is PSSL vertex shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 7) is not 0:
Byte - number 0
<pointer ID #3 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
If there is PSSL pixel shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 7) is not 0:
Byte - number 0
<pointer ID #4 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
If there is Cg vertex shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 7) is not 0:
Byte - number 0
<pointer ID #5 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
If there is Cg pixel shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 7) is not 0:
Byte - number 0
<pointer ID #6 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
<note: Take care of the next two: it uses the number 15 for its bitwise AND operation instead of 7)
If there is Cg_PS3 vertex shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 15) is not 0:
Byte - number 0
<pointer ID #7 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
If there is Cg_PS3 pixel shader data:
While (Int64 stream position/position in file) bitwise AND (Int32 number 15) is not 0:
Byte - number 0
<pointer ID #8 leads here>
The buffer/bytes/string for the shader data - the length is found nowhere else, maybe?
(same thoughts as above)
According to GitHub, this repo is 100% C#. That means that it'll only really work for Windows, and not for Mac or Linux. I know systems like MonoDevelop let you use C# multi-platform, but it'd still have trouble finding the files to decompile a GameMaker game from, yeah? Is it at all feasible to have UMT versions for other OSes or not?
While I'm aware it's not completely implemented, the commits imply you've at least partially implemented GMS2 support.
While loading the game.win from the Switch version, a generic exception is thrown during the GLOB chunk.
Pulling it up in VS and it's actually a NotImplementedException.
Looking at the wiki page for GMS2 changes, there's no mentions of this chunk which is why I'm opening this issue.
Full callstack
UndertaleModLib.dll!UndertaleModLib.Models.UndertaleGlobal.UndertaleGlobal() Line 13 C#
[External Code]
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.GetUndertaleObjectAtAddress<UndertaleModLib.Models.UndertaleGlobal>(uint address) Line 147 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleObjectPointer<UndertaleModLib.Models.UndertaleGlobal>() Line 170 C#
UndertaleModLib.dll!UndertaleModLib.UndertalePointerList<UndertaleModLib.Models.UndertaleGlobal>.Unserialize(UndertaleModLib.UndertaleReader reader) Line 53 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleListChunk<UndertaleModLib.Models.UndertaleGlobal>.UnserializeChunk(UndertaleModLib.UndertaleReader reader) Line 90 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleChunk.Unserialize(UndertaleModLib.UndertaleReader reader) Line 52 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleChunk() Line 90 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleChunkFORM.UnserializeChunk(UndertaleModLib.UndertaleReader reader) Line 58 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleReader.ReadUndertaleData() Line 112 C#
UndertaleModLib.dll!UndertaleModLib.UndertaleIO.Read(System.IO.Stream stream) Line 379 C#
UndertaleModTool.exe!UndertaleModTool.MainWindow.LoadFile.AnonymousMethod__0() Line 130 C#
It crashes specifically once it reaches gml_Object_obj_kingcutscene_Step_0
I imported a sprite sheet and upon seeing it in game it was all blurry due to anti-aliasing. How do I disable this?
Currently, the assembler requires that you explicitly specify variable by index as I was not sure how to handle duplicate names, but I think I get it now:
please, it would be great if you added support to the nintendo switch version
it would be great if you would make some string editor as if it were a text editor instead of changing the lines of dialogue one by one, you could use for example as the testing scritp.
You do not know how hard it is to put each line of the characters one by one, I just ask you some option that allows me to copy and paste as if it were the notepad or some way to export and import dialogs
I'm very slow when it comes to adding the dialogues translated to the game by this, if you could make some editor or some way to import it would be very helpful
gml_Object_obj_kingcutscene_Step_0
Process is terminated due to StackOverflowException.
An unhandled exception of type 'System.StackOverflowException' occurred in UndertaleModLib.dll
I am trying to do a translation to the spanish, so I need to add some characters like: "´", "¡" and "¿". So I modify a bit the TTFFonts to make it work good with Deltarune, but I don't know how to add the DotumChe font.
I already checked and yes, I have the DotumChe.ttf file in my SURVEY_PROGRAM folder, but it just doesn't works, it is the only font that is not working for me for DeltaRune.
At the moment, the decompiler doesn't resolve the object that is being called in instance_exist() and instance_create(). Understandably, there's more than one item which holds the same numeric reference, but those methods always expect an object and nothing else as far as I can tell from the documentation.
Now, when in the tool you can click it to see the object it resolves to, but those are extremely common methods that should probably resolve as a comment similar to string resolution.
Another method which should be resolved is script_execute. The first parameter will always be a script, despite being a generic numeric reference.
Whenever I try to load into the editor on a long script, the program hangs like mad.
(this assumes that timelines are implemented [internally] in this main repository, presumably once the pull request gets brought in)
Currently there is no timeline editor implemented, and that could be a nice thing to have. This is just here to track its implementation, eventually.
Something just smells wrong, there is too much code repetition between the debugmode and non-debugmode path...
The heuristics are goofing up a bit and treating numeric values as if they're references.
Some examples
if _temp_local_var_236
{
1180.sprite_index = 1764 // 1180 = obj_alphys_npc (UndertaleGameObject)
self.follow = 0
self.al.image_speed = 0.2 // 0 = obj_backgrounder_parent (UndertaleGameObject)
self.al.hspeed = -1
self.con = 67
self.alarm[4] = 40
}
if (self.con == 68)
{
self.al.image_speed = 0
self.al.speed = 0
self.con = 68.1 // 68 = obj_coremusic (UndertaleGameObject)
self.alarm[4] = 60
}
if (self.con == 69.1) // 69 = obj_sansmusic (UndertaleGameObject)
self.con = 69
The first comment is correct, but it picked up the normal condition checks as if they were objects.
self.al.image_speed = 0.3334 // 0 = obj_backgrounder_parent (UndertaleGameObject)
The count exactly matches the amount of rooms. If this list is not updated after adding new rooms, then room_prev
and room_next
functions in GML start to misbehave.
In context menu that appears when clicking on a number/resource in the code editor, it seems that the MenuItems interpret the resource names put into the Header field as formatted. This is a problem because then the names can lose characters/underscores and change appearance for no apparent reason.
The problem seems to occur at https://github.com/krzys-h/UndertaleModTool/blob/master/UndertaleModTool/Editors/UndertaleCodeEditor.xaml.cs#L382. Perhaps something could be done to format the string (like escaping all underscores?).
While this is specific to UT and DR, mapping strings to their respective localization is a bit of a pain. It'd be great if it was possible for the decompiler to have the ability to have the strings rather than the reference to the localization file.
There's two real approaches I can see to this.
Make it so the decompiler adds comments with the actual value
Make scripts to swap out the reference with the actual value
Time to dig. https://www.deltarune.com/
Hello again, I'm here to ask you a question, we need to add some scripts in .gml format to the game (deltarune) right now we are adding it manually but it is very heavy, if you could give us An example of scripts to add it would be appreciated
It'd be great if we could actually see the numerical ID of assets (rooms, objects, etc.) when we have them selected to make it easier to search through the game's ridiculous object check scripts and such.
As far as I can tell the only way right now is manually counting which obviously not ideal.
BorderEnabler will need to be updated whenever the next PC update happens.
The checks have changed from
if (self.os_type == 14)
scr_draw_background_ps4(some_other_number_im_too_lazy_to_check, 0, 0)
to
if (self.os_type == 14)
_temp_local_var_1 = 1
else
_temp_local_var_1 = (self.os_type == 20)
if _temp_local_var_1
scr_draw_background_ps4(2814, 0, 0)
which broke the pattern detection
Well, I am still trying to do a translation so I need some characters that aren't in the game, so I am modifying every font to ascii from game maker and then trying to replace every old font to the ascii ones, but add every glyph manually is a lot of work, and I see you can see the actually glyphs from the raw code of the .font.gmx file, and it would be good to have an option to do that automatically.
This is some magic optimization that abuses the way the GMS runner stores the stack, it duplicates one 64-bit value instead of two 32-bit ones. This causes decompilation problems because we use the C# Stack<> which is obviously implemented differently.
Doesn't seem to happen in neither Undertale or Deltarune, discovered by @colinator27 in some other game, see #27 (comment)
I think the circular references in the Block structure are preventing them from being GCed correctly, trying to decompile SCR_TEXT a few times results in OutOfMemoryError
1.I would love to edit Kris' sprite to look like me,but I've only gotten as far as to export the sprite. Every time I edit the sprite,it doesn't allow me to save it. I've tried Paint and Paint 3D.
2.In order to truly put myself in the game,I would have to Kris' name to my name. I've tried looking through the "scripts" section,but I can't seem to find what I'm looking for.(I also kinda wanna make Ralsei a girl,lol.)
Any help on either of these questions would be great. Thanks :)
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L45
Scale = 0x0010, // Scaling: Keep aspect
and new flags: DefaultCodeKind = 0x8000, LicenseExclusions = 0x10000
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L81-L82
time64_t DateTime (8 bytes)
Example:
hex: AA 3B E4 5B 00 00 00 00
string: 11/08/2018 13:35:38
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L84
uint ActiveTargets1
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L85
uint ActiveTargets2
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L86
uint FunctionClassifications1
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L87
uint FunctionClassifications2
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L88
int SteamAppId; // negative value
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L93
float GameSpeed
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L94
uint AllowStatistics; // Allow anonymouse statistics
https://github.com/krzys-h/UndertaleModTool/blob/aa97bb3be3b6e3a47e475a28a7ab2fcb6f52392d/UndertaleModLib/Models/UndertaleGeneralInfo.cs#L95
byte GameGUID // 16bytes
Example:
HEX: 67 45 34 12 90 78 22 11 33 44 55 66 77 88 99 00
String: 12344567-7890-1122-3344-556677889900
Not 100% sure what I did to cause it, but I just found dot.exe running utilizing a full thread minutes after I quit the tool (and at least an hour after I last used the graph). Should probably spawn it as a child so if the main tool dies it comes along with it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.