Compared to modern programming languages, galaxy is lacking a lot of key features. I feel that stuff like making for loops, not worrying about having to put local variable declarations on top, and a bunch of other things are stuff that really should be a part of galaxy. For this reason I designed my own language, called galaxy++, and I built this editor that can convert it to normal galaxy.
I designed it so that regular galaxy is a subset of galaxy++, apart from special galaxy++ keywords. This means that existing galaxy code can be used in the editor with very minor modifications.
The editor
The editor is organized as a list of projects, where each project is a collection of your galaxy++ files and dialogs in various folders. The editor has key features, like useful error messages, the ability to test the map with a click of a button, a suggestion box which shows you suggestions to functions, keywords, variables and types as you type, and a drag and drop dialog designer. For a list of the language features, see the assets page (link at the bottom of this post).
Feedback
I will be happy to get any feed back from you. Both positive and negative.
If you found any bugs, please post about them here, send me a PM, or use the error report feature. If you got some code to replicate the error, I would like that as well (you can choose to include your project in an error report, if you use the error report feature).
Of course, suggestions to improvements or new features are also welcome.
Disclaimer
Use this program at your own risk.
Although I of course try to get rid of them, I can't guarantee that it is completely bug free, so save often and make backups.
If you do run into a bug, please tell me about it, so I can exterminate it.
Technically, this is a new tool.. I wrote most of it from scratch, since I wanted my own text editor and stuff this time around..
Also, I don't plan to remove my other tool, since it still serves to give useful error messages and stuff for pure galaxy.
Added a function to compile and run the script (copy the script to your map, and test it in starcraft)
Added a featuere to collapse blocks in the editor
Changed i++: It now functions as you would expect from other languages
Added ++i
Fixed an error that gave an incorrect result when having multiple assignments to the same variable in the same statement
Bulk copy parameters are now pr default passed value type
Added #ref to specify that a parameter should be passed as refference type
Added #out to specify that a parameter should function as an extra return value
I'm sorry about changing the language in a way that changes the semantics of existing programs. I try to only do it when I feel it is absolutely necessary. Also, somehow I don't think that anyone has written that much code yet :)
I think you added some few Features which are common sources for errors:
You can now have assignments in expressions rather than just statements
This leads to the famous if (x=5) versus if (x==5) error
i++,++i
These statements are nice when used on a line for themselves or inside a for loop. But they can be very confusing when used inside of expressions. It can become very hard to scan your code if you try to figure out wether i can change or not. (reading all the expressions vs reading just the left side of each assignment)
Omitting braces when there is just one statement after an if statement.
This is also dangerous because it is easy to forget the braces if you add a second statement to the if.
It is also easy to misunderstand which block an else belongs to:
Fixed bulk copy, so you can use structs as method return types, parameters and in normal assignments
This might be confusing because many other languages pass structs/objects and arrays per reference and do not create a copy.
Especially it is not possible to write something like p.setX(3.14) if I understand this correctly? Or will it copy the struct to the function and then back to the caller?
1
I strive to make galaxy++ resemble languages like c# or java in terms of features, while still having regular galaxy as a subset. My main reason for implementing assignments in expressions is that this is present in those languages. I agree that it can make the code more difficult to read in some cases, but I think it's up to the individual programmer to decide when/if he wants to use it.
About the if (x=5) error.. I could add a warning if you only have an assignment in an if, then that shouldn't be a problem.
3? - what happened to 2?
Like in java, the else will be connected to the closest if. So if you write
if(...)//Firstif(...)//Second...else...
The else will be connected to the second if statement.
This is not something I'm likely to change - having to add blocks everywhere is one of those things that has annoyed me in pure galaxy. If you really consider it a problem though, I could be persuaded into making an option to give an error if braces are omitted. ;)
4
The struct/array is copied to the called method via the data table. I have to make a copy, since reference passing is not possible in galaxy, and I can not do something which is not possible in galaxy.
------------------------------------------
Edit: On second thought, it would probably be possible using struct arrays and integer pointers to them, but those arrays would sit and take memory all the time, so I like the current approach better - unless someone know about a big performance hit using data tables? ------------------------------------------
You can however mark parameters with #ref (both bulk copy types and normal types). This will make sure to copy the data back into the variable after the method returns. When invoking struct methods, the struct you are calling on is passed to the method in this way, so you can make a p.setX method, and it will work as you would expect - with one exception. When passing a field as #ref the field will not be changed before the method has returned. If it was really reference passing, you would expect the called method to write directly to the field. This behavior can be achieved by marking the parameter with #ref and the function with #inline, but this will cause the code to take up more space if the function is called from many different places (And the function can not be recursive).
If you use getter/setter methods, I would recommend marking them as #inline if they are not too complex - then you skip passing stuff to the data table, and just inline the method where you are calling from.
Hello, I've started using your editor and well it crashed for me when writing this code. Essentially since there's no documentation it's quite hard to know how to code it properly. I think it crashes at the for line.
Ofcourse it shouldn't crash on you, but I have noticed some errors in the code. First of all, you are using non constant variables to define the bounds of an array. At this point, arrays are really just turned into arrays in galaxy, so only constant expressions can be used to define the size of an array. Secondly, you are attempting to define the size with fixed types. Having an array of size 1.25 really doesn't make scense - this should be integer type variables instead.
Also, correct me if Im wrong, but PointFromId(1) returns a point, right? Plus is not defined between point and fixed types.
Another thing, you are trying to invoke the method with Wall.Generation(). You must invoke that method on an actual instance of your Wall struct. So you must first define a variable of type Wall, and then invoke the method on that variable. Otherwise it is searching for a method called Generation in a namespace called Wall.
And lastly, when you want the struct variable DISTANCE, you should not write Wall in front of it. You should just write DISTANCE. In case you had a local variable also called distance you could write #struct.DISTANCE. Same thing apply to Wall.DX and Wall.DY
I just added my map script (about 5k lines) to a new file. You are probably not supposed to do this, I just wanted to see, if everything works out.
And well, it laggs like hell! I cannot even select or scroll at all. Also I get hundreds of warnings about variables and functions which are never used/called/read; some of them are accurate (many dummy boolean parameters for trigger functions for example), but soe are not.
€ At first glance: Functions used by triggers do not count as "used"
€€ Seems to be it, all the dummy parameter stuff (which should) and all trigger functions (which should not) count as unused.
€ Sometimes, error messages are below the bottom of the field, you cannot read them, but you cannot scroll down further, either.
When I'm making a map with the editor, I usually split it into multiple files, so haven't tried 5k lines in one file - I might look for some places to optimize. About unused trigger functions.. I really cant think of any way to distinguish between a trigger function and a normal function that happens to return a bool and take two bools as parameters.. The problem is that triggers need to be handled differently - it is not unused, and it may not be renamed. I made the tag #trigger to specify is a function is actually a trigger.
I admit, writing that in front of each trigger in 5k lines code is tedious.. Thinking about it, I might change it so any global function that has the signature (bool, bool):bool is considered a trigger - as it is now, galaxy is fully a subset of galaxy.
Edit: Realised that I had not added the #trigger line, it seems when you want to add that afterwords it will replace the previous line so for instance if you type out "bool blablabla ()" and then afterwards add the #trigger to the line it will replace the "bool"
I uploaded a new file.. It now checks TriggerCreate for string constants in order to identify triggers, and I also changed the behavior that you pointed out syltman :)
I'm sorry that it took so long - I'm working on a string obfuscation feature that proved more difficult than first anticipated. I wanted to include it in this release, but I feel I have postponed it too long. So it'll wait for another release.
Btw.. I don't think I mentioned it before, but I implemented a feature to search the library or user definitions for functions and stuff in case you don't remember the exact name.. Look under help.
I'm glad i'm finally getting some feedback on this :) Don't hesitate to shout if you feel your favorite feature has been left out for some reason - it's most likely because I haven't needed it in my own projects, and thus haven't thought about it.
I will edit this post for a while with all the stuff I find:
I dislike the automatic alphabetic sorting of folders and files for one project. Maybe I just overlooked it, but I did not find a way to use a custom order here.
An Undo function would be nice.
Oh, and hotkeys for adding new folders and files, C&P support would be nice as well.
And maybe instead of popping up a name window, just name it New Folder/File with the name selected for instant rename like the galaxy editor does - I find this to be more convenient.
I get an unhandled exception when copying a bunch of code. An additional "v" is added to the end of the code (not sure, if I just pressed it again) and the error message pops up
€ happens in like 50% of the times, when i c&p code, I am pretty sure I do not press "v" another time.
I dislike, that compiling multiple script files in multiple folders opens all folders
Maybe display the current line of the cursor somewhere?
I get spammed with warning messages, that the local variable "bulkCopyVar" is never read, but I never declared it anywhere. My guess is, it gets declared automatically for some galaxy+ + features, but is never used?
When I double-click the warning message, I get a "Could not find token" error.
Maybe add an option to not use the galaxy+ + features?
If I have declared 3 variables in one line like this:
inta;intb;intc;
and all 3 are unused, I only get a warning for the first one.
Add an option to deactivate files
Are Gui-Triggers supported? For example the BankPreload - action does not exist in galaxy script, the only way to use it is a Gui-trigger. If you inject the map script using this editor, it gets lost, correct?
the script is compiled again when you test the map, even if you just compiled it.
when testing my own map script, I get several "array out of bounds" errors ingame, which do not show up, when using the original script. Trying to narrow down the problem.
€ My debug window shows exactly 3 variables present. For the original script, there are about 130 of them.
when searching, there should be a possibility to continue searching after the "reached starting point of search" message, or to search backwards.
why do I need to close starcraft for another test? SC2 supports opening maps on-the-fly, if you use multiple copys you should easily be able to start the map without closing SC2. Especially when testing the same map many times in a row, this decreases loading time significantly.
separate the hotkeys for compile and test. I accidentaly hit test quite often, resulting in SC2 to open. Maybe use CTRL + F9 for testing, like the galaxy editor?
"join output to one file" does not seem to work, the output is still multiple files, and on map test I get a "script load failed" error.
Same error for "use short names" (but the output files get the shorter names)
maybe make use of private keywords or name scopes somehow? Anything to make prefixes for functions with the same name obsolete? Maybe something like this is already implemented, though.
Just got back to Sc2, because I got bored of mapping for Warcraft3, I was searching for some good scripting tools. This seems to be exactly what I want and it works great. Good job man :)
The only things I would like to have implemented would be a function list like tesh had for vjass. Also there seem to be no undo steps right now. The last thing is that theres a typo SearchDefinitions Window: "SearcDefinitionsForm"
EDIT: Also an option for changing the hotkeys for compiling etc would be nice. And an option for compile on save.
Okay, that gives me something to do :)
I should be able to implement most of that..
Tbh, I wasn't aware of GUI only functions, but I see a file in the map which is changed when calling the bank preload, so it should be possible to implement. If you have a complete list of these functions lying around, it would help me when I get to this.
Some things to note is that galaxy has a keyword called static.. it makes the function/field private to the file it is in, so that is kind of the private keyword. I do think it is a bit counter intuitive though, so I might still add a #private keyword to do the same.
Also, to some of the bugs you mentioned kueken..
You mention not being able to search after the "reached the starting point of search" message.. I can press find next just fine, and it will restart the search. There were also some other errors that I wasn't able to replicate (ctrl-v, array errors, shorter names error). It might help me if you are willing to send me your script in an archive, perhaps in a PM to me? I fully understand if you don't wish to do this - there is a certain degree of trust associated with it.
Edit:
The reason you don't get a warning for b and c with "int a; int b; int c;" is that before the check for unused variables, the compiler is looking for variables it can join together, as an optimization. Since a, b and c are not used in the same scope (they are not used at all), they will be joined into one variable. So in the final code, it is really only "a" which is not used, but I'll rearrange the checks to make it more intuitive.
I have no problem with sending you my script (didn't I already send you my map script earlier for your script editor? ;) ); however you have to prepare for a huge mess :D. Some of those errors might even be caused by my bad use of galaxy, or something.
The static keyword hides the objects from other files, but you still need to use a (an? - sounds wrong here ;) ) unique name for static functions.
I only know about BankPreload as being limited to GUI-only; I just recently read about this in the forums. Maybe there are more functions, though.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
This project is dead.
http://www.sc2mapster.com/forums/resources/third-party-tools/19619-galaxy-editor/?page=27#p539
----------------------------------------------------------
Compared to modern programming languages, galaxy is lacking a lot of key features. I feel that stuff like making for loops, not worrying about having to put local variable declarations on top, and a bunch of other things are stuff that really should be a part of galaxy. For this reason I designed my own language, called galaxy
++
, and I built this editor that can convert it to normal galaxy. I designed it so that regular galaxy is a subset of galaxy++
, apart from special galaxy++
keywords. This means that existing galaxy code can be used in the editor with very minor modifications.The editor
The editor is organized as a list of projects, where each project is a collection of your galaxy
++
files and dialogs in various folders. The editor has key features, like useful error messages, the ability to test the map with a click of a button, a suggestion box which shows you suggestions to functions, keywords, variables and types as you type, and a drag and drop dialog designer. For a list of the language features, see the assets page (link at the bottom of this post).Feedback
I will be happy to get any feed back from you. Both positive and negative.
If you found any bugs, please post about them here, send me a PM, or use the error report feature. If you got some code to replicate the error, I would like that as well (you can choose to include your project in an error report, if you use the error report feature).
Of course, suggestions to improvements or new features are also welcome.
Disclaimer
Use this program at your own risk.
Although I of course try to get rid of them, I can't guarantee that it is completely bug free, so save often and make backups.
If you do run into a bug, please tell me about it, so I can exterminate it.
Download and language documentation
See the asset page for the documentation
http://www.sc2mapster.com/assets/galaxy-editor-beier
Please note: as of v2.8.5, xna 3.1 is needed. You can find it at
http://www.microsoft.com/download/en/details.aspx?id=15163
The latest versions are uploaded to
ftp://46.163.69.112/Releases/
Glad to see your still improving this tool, its really nice.
Geez man, this is great. Really nice work.
@LinkD: Go
Technically, this is a new tool.. I wrote most of it from scratch, since I wanted my own text editor and stuff this time around..
Also, I don't plan to remove my other tool, since it still serves to give useful error messages and stuff for pure galaxy.
But thanks.. glad you like it :)
Added a new version.. Some of the changes are
i++: It now functions as you would expect from other languages
++i
I'm sorry about changing the language in a way that changes the semantics of existing programs. I try to only do it when I feel it is absolutely necessary. Also, somehow I don't think that anyone has written that much code yet :)
I think you added some few Features which are common sources for errors:
This is somehow related: http://programmers.stackexchange.com/questions/62302/most-common-one-line-bugs-in-c ;)
@peeeq: Go
1
I strive to make galaxy
++
resemble languages like c# or java in terms of features, while still having regular galaxy as a subset. My main reason for implementing assignments in expressions is that this is present in those languages. I agree that it can make the code more difficult to read in some cases, but I think it's up to the individual programmer to decide when/if he wants to use it.About the if (x=5) error.. I could add a warning if you only have an assignment in an if, then that shouldn't be a problem.
3? - what happened to 2?
Like in java, the else will be connected to the closest if. So if you write
The else will be connected to the second if statement.
This is not something I'm likely to change - having to add blocks everywhere is one of those things that has annoyed me in pure galaxy. If you really consider it a problem though, I could be persuaded into making an option to give an error if braces are omitted. ;)
4
The struct/array is copied to the called method via the data table. I have to make a copy, since reference passing is not possible in galaxy, and I can not do something which is not possible in galaxy.
------------------------------------------
Edit: On second thought, it would probably be possible using struct arrays and integer pointers to them, but those arrays would sit and take memory all the time, so I like the current approach better - unless someone know about a big performance hit using data tables?
------------------------------------------
You can however mark parameters with #ref (both bulk copy types and normal types). This will make sure to copy the data back into the variable after the method returns.
When invoking struct methods, the struct you are calling on is passed to the method in this way, so you can make a p.setX method, and it will work as you would expect - with one exception. When passing a field as #ref the field will not be changed before the method has returned. If it was really reference passing, you would expect the called method to write directly to the field. This behavior can be achieved by marking the parameter with #ref and the function with #inline, but this will cause the code to take up more space if the function is called from many different places (And the function can not be recursive).
If you use getter/setter methods, I would recommend marking them as #inline if they are not too complex - then you skip passing stuff to the data table, and just inline the method where you are calling from.
Hello, I've started using your editor and well it crashed for me when writing this code. Essentially since there's no documentation it's quite hard to know how to code it properly. I think it crashes at the for line.
Ofcourse it shouldn't crash on you, but I have noticed some errors in the code. First of all, you are using non constant variables to define the bounds of an array. At this point, arrays are really just turned into arrays in galaxy, so only constant expressions can be used to define the size of an array. Secondly, you are attempting to define the size with fixed types. Having an array of size 1.25 really doesn't make scense - this should be integer type variables instead.
Also, correct me if Im wrong, but PointFromId(1) returns a point, right? Plus is not defined between point and fixed types.
Another thing, you are trying to invoke the method with Wall.Generation(). You must invoke that method on an actual instance of your Wall struct. So you must first define a variable of type Wall, and then invoke the method on that variable. Otherwise it is searching for a method called Generation in a namespace called Wall.
And lastly, when you want the struct variable DISTANCE, you should not write Wall in front of it. You should just write DISTANCE. In case you had a local variable also called distance you could write #struct.DISTANCE. Same thing apply to Wall.DX and Wall.DY
I'll look into the crash when I get home.
Edit
Uploaded a new version.
A function which returns null crashes the editor
@Kueken531: Go
Right, thanks - uploaded a fixed version.
I just added my map script (about 5k lines) to a new file. You are probably not supposed to do this, I just wanted to see, if everything works out.
And well, it laggs like hell! I cannot even select or scroll at all. Also I get hundreds of warnings about variables and functions which are never used/called/read; some of them are accurate (many dummy boolean parameters for trigger functions for example), but soe are not.
€ At first glance: Functions used by triggers do not count as "used"
€€ Seems to be it, all the dummy parameter stuff (which should) and all trigger functions (which should not) count as unused.
€ Sometimes, error messages are below the bottom of the field, you cannot read them, but you cannot scroll down further, either.
When I'm making a map with the editor, I usually split it into multiple files, so haven't tried 5k lines in one file - I might look for some places to optimize. About unused trigger functions.. I really cant think of any way to distinguish between a trigger function and a normal function that happens to return a bool and take two bools as parameters.. The problem is that triggers need to be handled differently - it is not unused, and it may not be renamed. I made the tag #trigger to specify is a function is actually a trigger.
I admit, writing that in front of each trigger in 5k lines code is tedious.. Thinking about it, I might change it so any global function that has the signature (bool, bool):bool is considered a trigger - as it is now, galaxy is fully a subset of galaxy.
You might just scan for TriggerCreate() and look up if the string it holds represents an actual function, at least for literal strings and constants.
Yes, sure, I would do the splitting as well, was just a test.
Edit: Realised that I had not added the #trigger line, it seems when you want to add that afterwords it will replace the previous line so for instance if you type out "bool blablabla ()" and then afterwards add the #trigger to the line it will replace the "bool"
I uploaded a new file.. It now checks TriggerCreate for string constants in order to identify triggers, and I also changed the behavior that you pointed out syltman :)
I'm sorry that it took so long - I'm working on a string obfuscation feature that proved more difficult than first anticipated. I wanted to include it in this release, but I feel I have postponed it too long. So it'll wait for another release.
Btw.. I don't think I mentioned it before, but I implemented a feature to search the library or user definitions for functions and stuff in case you don't remember the exact name.. Look under help.
I'm glad i'm finally getting some feedback on this :) Don't hesitate to shout if you feel your favorite feature has been left out for some reason - it's most likely because I haven't needed it in my own projects, and thus haven't thought about it.
Blame yourself - here it goes :)
I will edit this post for a while with all the stuff I find:
€ happens in like 50% of the times, when i c&p code, I am pretty sure I do not press "v" another time.
When I double-click the warning message, I get a "Could not find token" error.
and all 3 are unused, I only get a warning for the first one.
€ My debug window shows exactly 3 variables present. For the original script, there are about 130 of them.
Just got back to Sc2, because I got bored of mapping for Warcraft3, I was searching for some good scripting tools. This seems to be exactly what I want and it works great. Good job man :)
The only things I would like to have implemented would be a function list like tesh had for vjass. Also there seem to be no undo steps right now. The last thing is that theres a typo SearchDefinitions Window: "SearcDefinitionsForm"
EDIT: Also an option for changing the hotkeys for compiling etc would be nice. And an option for compile on save.
Okay, that gives me something to do :)
I should be able to implement most of that..
Tbh, I wasn't aware of GUI only functions, but I see a file in the map which is changed when calling the bank preload, so it should be possible to implement. If you have a complete list of these functions lying around, it would help me when I get to this.
Some things to note is that galaxy has a keyword called static.. it makes the function/field private to the file it is in, so that is kind of the private keyword. I do think it is a bit counter intuitive though, so I might still add a #private keyword to do the same.
Also, to some of the bugs you mentioned kueken..
You mention not being able to search after the "reached the starting point of search" message..
I can press find next just fine, and it will restart the search.
There were also some other errors that I wasn't able to replicate (ctrl-v, array errors, shorter names error). It might help me if you are willing to send me your script in an archive, perhaps in a PM to me? I fully understand if you don't wish to do this - there is a certain degree of trust associated with it.
Edit:
The reason you don't get a warning for b and c with "int a; int b; int c;" is that before the check for unused variables, the compiler is looking for variables it can join together, as an optimization. Since a, b and c are not used in the same scope (they are not used at all), they will be joined into one variable. So in the final code, it is really only "a" which is not used, but I'll rearrange the checks to make it more intuitive.
I have no problem with sending you my script (didn't I already send you my map script earlier for your script editor? ;) ); however you have to prepare for a huge mess :D. Some of those errors might even be caused by my bad use of galaxy, or something.
The static keyword hides the objects from other files, but you still need to use a (an? - sounds wrong here ;) ) unique name for static functions.
I only know about BankPreload as being limited to GUI-only; I just recently read about this in the forums. Maybe there are more functions, though.