• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Opinion nGML: A 3rd party GameMaker language [WIP]

C

CedSharp

Guest
Hey all folks!

-- Discussing how the language should look like and the feature it should have --

I love the simplicity of Game Maker, like most of you do.
I also have grown a bit more advanced in using it over the past few years.
I'm starting to feel the chains of limitation that Game Maker has to be
able to be so easy to use.

Many of you probably know of the 3rd party IDE called Parakeet IDE 2.
This editor adds many nice features like intellisense and more feature-full
room editor. It also lets you forget the UI of gamemaker and let you code
the events directly in code using a special syntax.

But in the end, you still need to work with the treeview in order to create objects,
you still need to play with the GUI to change some properties, etc.

So I had an idea...
What if I created a language that wouldn't require nothing more than notepad to
create a full Game Maker game?

Then I started day-dreaming like crazy, what if it could also support variable typing,
interfaces, extending, overloading etc etc etc

Well I decided to actually give it a try. Making a good lexer and parser for the language was
within my level, even if quite challenging.

Here I am, with a language that I named ngml ( New Game Maker Language ),
which, when completed, will let those of you who prefer a plain text editor
to a full featured ide code in a fully OOP language.

What will nGML look like?
Code:
// file   Player.ngml
class Player extends GMObject implements ICreateEvent, IStepEvent, IDrawEvent {
    private int size;
    private hex color;
    private int xspeed;
    private int yspeed;

    void new( int size, hex color ) { // method new will be called when class is instanciated
        this.size = size;
        this.color = color;
    }

    void CreateEvent() { // method CreateEvent will be called just after new()
        this.xspeed = 2;
        this.yspeed = 4;
    }

    void StepEvent() {
        this.x = this.xspeed;
        this.y = this.yspeed;
    }

    void DrawEvent() {
        draw_set_alpha( 1 );
        draw_set_color( this.color );
        draw_rect( this.x, this.y, this.x+this.size, this.y+this.size, false );
    }
}


// file     Controller.ngml
import Player; // have different object imported from files! :O

class Controller {
    private Player player;

    void new() { // method new will be called when object is instanciated
        this.player = new Player();
    }
}

What has been done?
1. The tokenizer is completed, every "word" now makes sense for my compiler.

2. The lexer is completed, "statements" are now understood ( assignments, conditions, loops, classes, etc )

3. The gml which will be used when converting the code. ( ex.: how to convert a class into valid gms gml. )

Screenshots

On the left, example of ngml code, on the right, the result of compilation.

What needs to be done?
- Analyzing the syntax of the statements.
For example, at the root of the file, you can only have imports and class definitions.
You cannot do a property declaration or a variable assignment.

- Creating the scopes and validating that the variables, classes and functions "exists".

- Checking the types of the values to make sure they match. ( ex.: can't add an Integer with a String )

- Converting the parsed code into a valid GM : S project.

Why would I want to use it?
1. nGML will work completly outside of GameMaker, you don't even need GameMaker installed
to use it! ( note: nGML will generate a GameMaker project, but it cannot run it, so you need GameMaker to build and test the actual project )

2. nGML is an OOP language, that means that you can create classes, add methods and properties to them,
make those private or public to the other classes, etc. It will also support interfaces, another feature
that gamemaker doesn't have.

3. The classes that you create don't necessary become GameMaker objects. Unless you actually
extends the special object "GMObject", every object will instead become a data-structure.
This way, your 'Point' class that contains just a few properties and methods will be incredibly smaller
than if you actually created the same class as an object in GameMaker.

4. With the addition of typing to my language, many stupid debugging errors will be avoided.
When you do something like this:
Code:
Int num = 32;
num = "test";
my compiler will report a type missmatch, and return the line and number of it. Hours of searching skipped!

5. Because the language is typed, you will be able to create scripts/method that take parameters of
a specific type. No need to validate those types yourself, my compiler will generate the needed checks
automatically.

6. and a lot more, hopefully even more than I can think of because you guys probably
will have some awesome ideas and feature-requests.

When will it be available?
I have no idea at all, it depends on how much time I put into this, it depends on how much interest
the forums shows into this projects and it also depends on the features that you guys will request :p

How did you do it? ( more technical )
- I'm using javascript for my compiler because I'm, at the same time, building an editor
that will support syntax highlighting, intellisense, and many other cool little features
specially for ngml. It will be built using electron, which works cross platform, and using
ace.io, an awesome free open-source code editor that works very similar to sublime text.

- I've followed the excellent tutorial for creating a parser from here
I had to add many things in order to support my more complex language,
but the basic structure is pretty much the same.

- The language that I'm creating is heavily inspired by C#. Actually,
it's basically the C# language with many less features haha. ;)

- If you're interested, I'm coding using the Atom.io code editor,
and I'm using stylus for my css post-processing which then goes through
autoprefixer. I'm using rollup with the babel plugin to code in ES7 but still
being able to generate valid vanilla javascript for browsers.

I would like to know if this project is a good idea, who's interested, who's not, what can be added, etc.

Thanks a lot for taking the time to read my chunk of text haha

Regards,
CedSharp
 
Last edited:

Mercerenies

Member
First off, I love the idea. GM is great for beginners but not so great for people who have seen what other languages are capable of. OOP feature set in a language with the graphical and gaming capabilities of GM is a wonderful idea. That said, here's the thing. Based on the code sample you shared, your language is literally JAVA. My personal opinions about JAVA aside, if you're going to rewrite the JAVA parser, why not just write the entire thing as a JAVA library in the first place? Alternatively, why not invent a little bit of different syntax to differentiate yourself? The way a language "feels" to the programmer is a vastly underappreciated concept in language design, and the way your language "feels" is as a limited subset of JAVA which is used for game design.

Your project actually reminds me of Elm. It's a language that's designed to improve on traditional server-side (PHP/ASP) scripting by making it more strongly typed, and it's a great idea and does a good job, but the language itself just feels like a weakened subset of Haskell, which is what it's intended to be based on. If I were you, I would change the syntax cues to look less like an existing language and more like it's own independent thing. Functionally, it's equivalent, but from a design standpoint it would make you stand out from the crowd.

Just my two cents. Like I said, I love the idea :)
 
C

CedSharp

Guest
First off, I love the idea. GM is great for beginners but not so great for people who have seen what other languages are capable of. OOP feature set in a language with the graphical and gaming capabilities of GM is a wonderful idea. That said, here's the thing. Based on the code sample you shared, your language is literally JAVA. My personal opinions about JAVA aside, if you're going to rewrite the JAVA parser, why not just write the entire thing as a JAVA library in the first place? Alternatively, why not invent a little bit of different syntax to differentiate yourself? The way a language "feels" to the programmer is a vastly underappreciated concept in language design, and the way your language "feels" is as a limited subset of JAVA which is used for game design.

Your project actually reminds me of Elm. It's a language that's designed to improve on traditional server-side (PHP/ASP) scripting by making it more strongly typed, and it's a great idea and does a good job, but the language itself just feels like a weakened subset of Haskell, which is what it's intended to be based on. If I were you, I would change the syntax cues to look less like an existing language and more like it's own independent thing. Functionally, it's equivalent, but from a design standpoint it would make you stand out from the crowd.

Just my two cents. Like I said, I love the idea :)
The language I'm taking inspiration of is not Java, but rather C#.
If it looks similar, that is because the basic princible of the C-style languages is the same.
GML being a c-style language, I wanted to stay in the same branch.

My goal wasn't exactly to create a new different syntax, I want to keep as much as I can from the original GML language.
My goal was to do what typescript does to javascript, aka add features.

I originally thought of using a language more flash-based, so like this:
Code:
public var x:Float;
instead of
Code:
public Float x;
But I decided to go in the C# family because it takes less time to write
( less time to write the code, the compiler itself is actually more complex )
and it also removes some of the symbols ( no need for ":" in C# when defining a type )

Hell, I could even create a weird language like
Code:
define public var x of type float;
If you have any proposition as for a new syntax, I am very interested tho. I didn't originally consider this,
and depending on what the new language would look like, it could be and extremly good idea :D

If you could further develop on any ideas you have, I'd deeply appreciate your time.

Regards ~
Cedsharp
 

Mercerenies

Member
I'm glad to see you're willing to take criticism on this point. I could write a textbook on my problems with the ALGOL family of languages, but I'll just briefly point out some of the pitfalls I'd avoid if I were you.

Here's what you have in your image.
Code:
class Player extends GMObject implements ICreateEvent, IStepEvent, IDrawEvent {

    public void CreateEvent() {}
    public void StepEvent() {}
    public void DrawEvent() {}

}
First off, C++ got the "extend"/"implement" thing right, in that having a whole word for that feature is sort of pointless. All you need is to list out the derivatives; there's never any ambiguity, so it should be sufficient to say:
Code:
class Player : GMObject, ICreateEvent, IStepEvent, IDrawEvent
Or something like that. As for the methods, 99% of the time, programmers intend for methods to be public and instance variables to be private. Ruby got this right; in Ruby, the default is public for methods and private for fields. So really, it would save several characters per method if you let the programmer do this:
Code:
void CreateEvent() {}
If they want a private method, they can say so, but otherwise it can assume public, since that's usually what's desired. The main point here is to try and anticipate what the programmer would want and plan for that. The C/ALGOL-family of languages did some things right but also made a lot of mistakes, and its an easy pitfall to trap yourself in. If you try to copy another language, you'll fall into the same traps it did. In C#'s case, this would be its wordiness.

E: I'm not sure how far along you are in this, but you did ask for my recommendation for alternative syntaxes, so I'll give it. I'm a Lisper, so I like expression-based languages. I wouldn't recommend going full-Lisp unless you want to lose all of your followers, but I'm particularly fond of Ruby's syntax when it comes to imperative languages. It's short, to the point, and expression-based, and it supports OOP and functional-style programming equally well. Elixir (a BEAM language) picked up Ruby-like syntax, and Python has been borrowing Ruby ideas for nearly a decade now.
 
C

CedSharp

Guest
I'm glad to see you're willing to take criticism on this point. I could write a textbook on my problems with the ALGOL family of languages, but I'll just briefly point out some of the pitfalls I'd avoid if I were you.

Here's what you have in your image.
Code:
class Player extends GMObject implements ICreateEvent, IStepEvent, IDrawEvent {

    public void CreateEvent() {}
    public void StepEvent() {}
    public void DrawEvent() {}

}
First off, C++ got the "extend"/"implement" thing right, in that having a whole word for that feature is sort of pointless. All you need is to list out the derivatives; there's never any ambiguity, so it should be sufficient to say:
Code:
class Player : GMObject, ICreateEvent, IStepEvent, IDrawEvent
Or something like that. As for the methods, 99% of the time, programmers intend for methods to be public and instance variables to be private. Ruby got this right; in Ruby, the default is public for methods and private for fields. So really, it would save several characters per method if you let the programmer do this:
Code:
void CreateEvent() {}
If they want a private method, they can say so, but otherwise it can assume public, since that's usually what's desired. The main point here is to try and anticipate what the programmer would want and plan for that. The C/ALGOL-family of languages did some things right but also made a lot of mistakes, and its an easy pitfall to trap yourself in. If you try to copy another language, you'll fall into the same traps it did. In C#'s case, this would be its wordiness.

E: I'm not sure how far along you are in this, but you did ask for my recommendation for alternative syntaxes, so I'll give it. I'm a Lisper, so I like expression-based languages. I wouldn't recommend going full-Lisp unless you want to lose all of your followers, but I'm particularly fond of Ruby's syntax when it comes to imperative languages. It's short, to the point, and expression-based, and it supports OOP and functional-style programming equally well. Elixir (a BEAM language) picked up Ruby-like syntax, and Python has been borrowing Ruby ideas for nearly a decade now.
I understand the point of using ':' to extend/implement stuff, but like i said I was trying to create a language free of those symbols.
Most people that I help in Game Maker ( advanced users too ) often rather use 'and' and 'or' rather than '&&' and '||'. They will also avoid using '(' and ')'.

If I was to avoid using all symbols, instead of being a C#-like language it would be like visual basic:
Code:
if player.score >= stats.hightscore then
    stats.highscore = player.score;
endif
The problem I have is that in such type of language, typing takes forever ( "endif compared to '}' and "then" compared to '{' ).

Also, the way you wrote it there is no way to know if the first word is a class extend or an interface ( what if I don't want to extend anything but I want to implement stuff? )

I agree with the public thing, that's actually already implemented in my language haha, no visibility modifiers = public by default.
 
Last edited:

Mercerenies

Member
( what if I don't want to extend anything but I want to implement stuff? )
That's what I meant by there not being ambiguity. There's never going to be a case where you don't know whether the programmer intends to extend or implement. If a class inherits another class, it's "extend". If a class inherits an interface, it's "implement". If an interface inherits an interface, it's "extend". There's never any overlap.

I understand the point of using ':' to extend/implement stuff, but like i said I was trying to create a language free of those symbols.
That's a fair view, then. If that's a design decision, then it's valid. But it's one I have to personally disagree with, since I'd much prefer careful use of symbols to extreme verbosity.
 
C

CedSharp

Guest
That's what I meant by there not being ambiguity. There's never going to be a case where you don't know whether the programmer intends to extend or implement. If a class inherits another class, it's "extend". If a class inherits an interface, it's "implement". If an interface inherits an interface, it's "extend". There's never any overlap.
I could do that, but I'd have to rewrite my stuff, right now,

1. I tokenize, so
Code:
class Player : GMObject, ICreateEvent, IStepEvent, IDrawEvent {}
becomes this:
Code:
{ type:"keyword", value: "class" }
{ type:"identifier", value: "Player" }
{ type:"punctuation", value: ":" }
{ type:"identifier", value: "GMObject" }
{ type:"punctuation", value:"," }
...
2. I lex all the tokens, so it now becomes this:
Code:
{
  type:"class",
  name: { type:"iden", value:"Player" },
  extends: ??
  implements: ??
  body: { type:"bool", value:false }
}
At this stage, I still don't have a table of all the classes, all variables, etc.
There is no way for my lexer to know if a value is a class or an interface.
( I could do something about gamemaker special objects, but what about user-created classes and interfaces? )

I would need to rewrite the lexer to actually process all classes and interfaces first, and
I don't know how to do it if I didn't lex beforehand :/
 
C

CedSharp

Guest
Java, Javascript, PHP, c++, C, they are all the most used and most appreciated languages currently.
Some others are python and ruby. I could use a syntax that makes strong use of symbols, but the learning curve would be higher.
I could make a language like python, where almost not symbols are used, but I need to implement something
to "detect" that a statement ends or starts. both python and ruby solved that by using indentations and newline as delimiters
( instead of ';' in c-like languages )

In c-like language, you can all of those:
Code:
if( a == b )
{
    stuff();
}

if (a == b) {
    stuff();
}

if (      a    ==              b)
                         {
stuff();
              }

if
(
a==
b){
stuff();}

if(a==b){stuff();}
in python, there is only one way to write it, you can't add newlines, you can't change indentation...
you absolutly need to follow python's way or die. xD

Tose other languages that aren't C-like often include limitations that forces you to code in a specific way.
My greatest wish would be to create a language that is easy to learn, simple to use and beautiful to look at
( take php as an anti-example, it looks horrible )

The language should also be very lenient in the indentation and formatting,
but strict in the language itself.

The best I can think of all gathers around 2 very popular languages: C and ActionScript.
The major difference being the order of the typing ( In c its before, in actionscript its after )
 

sylvain_l

Member
First off, C++ got the "extend"/"implement" thing right, in that having a whole word for that feature is sort of pointless. All you need is to list out the derivatives; there's never any ambiguity, so it should be sufficient to say:
Code:
class Player : GMObject, ICreateEvent, IStepEvent, IDrawEvent
why why so many useless symbols ?

I mean
Code:
class Player GMObject ICreateEvent IStepEvent IDrawEvent
is already clear.(as long as class/interface names can't have space; only reason it can be used it help just for reading, cause in natural language like english we are so used of coma for list of things)

in python, there is only one way to write it, you can't add newlines, you can't change indentation...
you absolutly need to follow python's way or die. xD
Now I'm a big fan of the python way (not the first day I start learning it, cause comming from PHP I have so bad coding habits XD )
enforcing coding standard/naming convention/and all those things, directly in the language grammar, is the best way to offer the community peace and just do what matter easier: reading, sharing, maintenaing code of everyone.
 

Surgeon_

Symbian Curator
This is an interesting idea.

But I'm not a fan of this static typing. First off, since this is going to be executed inside Game Maker's runner, there's no optimization / speed boost to be gained from it. And since this is targeted towards more experienced users I doubt that types are going to cause many serious bugs. But at the same time you're cutting off a large chunk of functionality and sacrificing versatility which many users (including myself) like to utilize. Luckily, there's a very diplomatic solution and that would be to choose (upon starting your project) whether you want it untyped or not and the compiler would behave accordingly.
 
C

CedSharp

Guest
why why so many useless symbols ?

I mean
Code:
class Player GMObject ICreateEvent IStepEvent IDrawEvent
is already clear.(as long as class/interface names can't have space; only reason it can be used it help just for reading, cause in natural language like english we are so used of coma for list of things)
I can't agree with this syntax. First of all you need more time to read the code because it lacks lisibility. Sure, maybe it would work without trouble, but when you read the code after a good week of a break,
you need some time to assimilate the code, it lacks the visual guides that helps skim a code easily and fast.

In this regard, i'd rather use symbols rather than having nothing at all. ( I still prefer using english words to symbols tho )


Now I'm a big fan of the python way (not the first day I start learning it, cause comming from PHP I have so bad coding habits XD )
enforcing coding standard/naming convention/and all those things, directly in the language grammar, is the best way to offer the community peace and just do what matter easier: reading, sharing, maintenaing code of everyone.
This is something that I'm trying to avoid. The goal of my language is not to teach one type of naming or one type of convention. Everyone should code in their one way.
I do agree that python, strict as it is, is good to learn for beginners who needs learn some of the best conventions but my language isn't made to be used by beginners.
The goal is to add OOP to gml. Not exactly to create a whole new language that isn't related to gml anymore.

Luckily, there's a very diplomatic solution and that would be to choose (upon starting your project) whether you want it untyped or not and the compiler would behave accordingly.
OMG.
Now that's an awesome idea. I knew when I made the choice to add typing to my language that it could make some users less happy, because being able to have structures
with whatever values inside them does make some functionalities possible where in a typing system it would take more complex structures to achieve.
This is a great idea.

Just to point out your remark about no optimization / speed boost to be gained:
If you create your own "objects that aren't objects" yourself, you surely know how painful it can be sometimes to setup everything in order to use them,
and of course free them.

The main goal of my language wasn't the typing system, it was to add classes, being able to extend them, and add promises ( aka interfaces ).
The such created classes should intelligently either create a ds_ structure or create a standard GameMaker object depending on the features
you need.

The second goal is to be able to make the game without using the UI of GameMaker. I love the ui of gamemaker but I feel it does nothing else
than slow me down more often than anything.

I'm very sorry if I show myself less open than I initially thought, but some of the ideas I had probably won't change, for example staying as close as possible
to gml is quite a fondamental point of my language, it being the 'New GML' xD

Thankyou all for you valuable opinions, I'm taking notes, lots of them, of your ideas.

Regards ~
CedSharp
 

sylvain_l

Member
everyone has it way ;)

sounds strange to me to read that forcing people to add symbol in their code for readability is fine, but not to enforce a unified coding style through grammar ^^
in a perfect world, I prefer delegate most of that to the IDE ! Highlighting code as autoformatting is its job.
 
C

CedSharp

Guest
everyone has it way ;)

sounds strange to me to read that forcing people to add symbol in their code for readability is fine, but not to enforce a unified coding style through grammar ^^
in a perfect world, I prefer delegate most of that to the IDE ! Highlighting code as autoformatting is its job.
My goal ( yes I know, I have tons of goal xD ) is to create an easy to use, yet flexible language.
By imposing an "unified grammar" to the user, my language will lose a lot in it's flexibility.
like I mentionned above, the indentation, the spacing and many other "in between keywords" style of formatting
should be left completly to the user.

On the other hand, how the language itself works is another matter.
It would add a whole level of complexity if I was to remove seperators for, example, the extends and implements area of a class definition
because my compiler will have to do more job than what I think it needs to do.
Keyword: what I think.

I'm open to remove all those symbols and all that verbosity, if this is what you guys want, I'm just doubting that the majority would like
to see a language void of separators.



An idea of syntax I had that removes verbosity and fixes the issue of "not knowing" for my compiler is simply changing the order of the declaration to something like this:
Code:
class Controller INotifyPropertyChanged {
    private Player player;

    void new() {
        this.player = new Player( 26, 148 );
    }
}

GMObject Player IDrawEvent {
    private int size;
    void new( int x, int y ) {
        this.x = x;
        this.y = y;
        this.size = 32;
    }

    void DrawEvent() {
        draw_set_alpha( 1 );
        draw_set_color( #0000FF );
        draw_rectangle( this.x, this.y, this.x+this.size, this.y+this.size, false );
    }
}
If class keyword is specified than the class doesn't extend anything.
If interface keyword is specified than it is not a class ( and interfaces can only extend, so no ambiguity here )
If no class and no interface ( and not import either ) then the word is considered a class to be extended.

Validating if the class actually exists is done in the next process which i didn't code yet,
( and will wait a bit to make sure I implement all features that you guys want )
it will build a list of all classes, all variables for each classes, and all the scopes to make
sure that over-shadowed variables are correctly used.

In this case, Player extends GMObject, where Controller doesn't extend anything, and in both cases what follows are interfaces.

It ads a bunch of rule to remember ( which is why I'd rather have verbosity ) but it require almost no changes to what I already made
and it removes ambiguity completly.

Let me know what you think ~
CedSharp
 

Mercerenies

Member
the spacing and many other "in between keywords" style of formatting
should be left completly to the user.
That sounds great in theory, but in practice, it leads to this. That is a Wikipedia page with more than 20,000 characters discussing the various equally correct ways people like to code in C++. If two programmers with different style ideas get together on a C++ project, one of them is going to be disappointed when he has to write in the other guy's coding style. A language like Python averts this problem entirely by defining it's own style, which encourages collaboration.
 
C

CedSharp

Guest
That sounds great in theory, but in practice, it leads to this. That is a Wikipedia page with more than 20,000 characters discussing the various equally correct ways people like to code in C++. If two programmers with different style ideas get together on a C++ project, one of them is going to be disappointed when he has to write in the other guy's coding style. A language like Python averts this problem entirely by defining it's own style, which encourages collaboration.
And when I have to edit any type of python language, I'm this guy who is disapointed to write in such language due to the imposed formatting style, which is not of my taste to begin with.
Of course, when collaboration is involved, it's near impossible to make everyone happy because everyone has different tastes.

I like to write using this style:
Code:
if( something ) thenDoOneThing();
else {
    do();
    many();
    things();
}
in python, one cannot do such thing and is forced to use a newline even if there is only one statement:
Code:
if something:
    thenDoOneThing()
else:
    do()
    many()
    things()
( note-1: If there is no else it is possible to actually write the statement on one linel ike this: if somthing: statement1 )
( note-2: There are other ways of doing it, but I'm specifically talking about standart if-else statement and not any of those post-condition that python supports )

If most of you want a strict formatting style of language, I will, like I mentionned above, make it happen. I just want to make sure that I'm the only one
who thinks that forcing people to use a format is not a good idea.

In my opinion, a strict format is not necessary. If you want to use one coding-style, then
use it. If others don't want to follow your coding style, it's their own right to do so. Generally
speaking, when I do collaborative work, we generally discuss of the structure of the folders and files,
the conventions we want to use... and the formatting that should be used for the code.

Instead of having the compiler impose your a format, I believe you should simply come with
a convention in human comunication instead. This way, your team will not have the same
conventions as another team, for example, and that's good, it's called diversity :D

Like it was mentionned above, in the worst case, you can always rely on your IDE or code editor to
format the code for you anyways. I think that adding this limitation is just a loss for the language itself.

Regards,
CedSharp
 
Last edited:

Mercerenies

Member
@CedSharp

Are you quite sure you're using the most recent version of Python? I tried
Code:
if something: thenDoOneThing()
else:
    do()
    many()
    things()
And it did exactly what you would expect.
 
C

CedSharp

Guest
If python is not strict as I thought it was, then my argument is destroyed. ( oopsies :oops: )

But then, what do you mean by this:
Mercerenies said:
Python averts this problem entirely by defining it's own style
If python is not imposing it's formatting and alow different formatting, how does that differ from my will to have a free-form syntax?
 

Mercerenies

Member
I was more referencing the fact that the lack of braces (Python uses newlines rather than braces) negates arguments about where braces go, and the mandatory indentation negates arguments about when to/not to indent. It doesn't completely block individuality (that would, I hope, not be seen as a good thing); it's simply much more restrictive than a language like C++ in terms of syntactic choices.
 
C

CedSharp

Guest
Oh, now I see what you mean.
Gosh I think I had the wrong idea up until now. ( 2nd woopsies :oops: )

Now that I understand where you're comming from I agree with you.

I've been looking at a couple of languages.
Some of them that don't even make use of symbols ( or barely at all ).

There is a nice language called Monkey-X.
It's another game language with it's own set of libraries.
it's heavily based of visual basic.

Another language for games is this petit-computer game for nintendo 3ds.
It uses sun-basic, again a language strongly based out of visual basic.

App Game Kit also uses visual basic as a focal reference point.

They all seem to avoid as much as possible the use of braces and brackets.
So your point is quite made with those languages haha ( including ruby and python )

So then, let us rethink the whole language from scratch.

  1. it should avoid any type of punctuation where possible;
  2. it should be as less verbose as possible, using simple logic to determinate what's what;
  3. the language should be as simple to use as possible with as less rules to remember as possible
  4. the language should end up appealing to look at and easy to read
  5. the language should limit the potential differences of styles of formatting so that any coder understand any code in the language

I think if the language can follow all those steps, I'll be happy, and your point is integrated as well.
Now, should I go towards the path of python, ruby, visual basic, a mix of all of them?

Let's start pitching ideas here.
The way I wrote my compiler, the only thing I need to change is the tokenizer so that it detects the new words,
the language basics in general doesn't change, a class is still a class and a variable assignation is still a variable assignation ^^

Hopefully we end up with something so amazing that languages start taking inspiration from nGML! xD
CedSharp
 
Last edited:
C

CedSharp

Guest
I'll start with the following idea, it makes use of all 3 type of elements: simple class, GMObject class and interface.
Starting from this syntax, let's modify and add/remove to it. I think it's way better to do it here rather than letting me include stuff without you seeing it haha.

File ISerializable.ngml
Code:
interface ISerializable
    String serialize < Void
File PushButton.ngml
Code:
require ISerialize

GMObject PushButton : ISerialize, ILeftMouseButtonPressed
    private Bool pushed
    private Hex color

    Void new < Hex color
        this.pushed = false
        this.color = color

    String serialize < Void
        return '"pushbutton":{ p:'+this.pushed?'true':'false'+', c:"'+this.color.toString+'" }';

    Void leftMouseButtonPressed < Void
        this.pushed = !this.pushed

File Controller.ngml
Code:
require PushButton

class Controller
    private PushButton button

    Void new < Void
        this.button = new PushButton #0000FF
I decided to switch "import" for "require" since import potentially could mean "include the content of the file here, at this position" and that's
not the purpose of it in the language. Instead, require, which stands for "make sure the file was included before executing this" is a better fit.

The notation I chosed is not too verbose, but doesn't rely only on symbols either.

class notation looks like this:
Code:
{class keyword or class to extend} {Name of class} : {Interfaces to implement} {Second interface} {third interface} ...
variable declaration is like before:
Code:
{visibility, public by default} {type of variable} {Name of variable}
method decraration, this is the big change:
Code:
{Return value type} {name of method} < {arguments}
A method that has no arguments needs to secify 'Void' to say that it expects nothing.

Because I removed the ';' at the end of each statement, and because I'm not using any block delimiter, I need a way to differeciate
a variable from a function, so I used the '<' simple which means "which takes as parameter".

So it read "A {type} function of name {name} which takes as parameter an argument of {type1} named {name1}, of {type2} named {name2}, ...

This is a start. Far from perfect.
I'll be expecting some opinions, ideas and modifications from your guys ;)
 
M

MishMash

Guest
A few important thoughts to consider before people derive too many features from other languages. We would need something that would work with the design of GML, so looking at some fundamentals:

  • GM has hybrid memory management, but primarily is built around the notion of programmer-handled memory allocation and de-allocation (similar to that of C/C++).
  • Following on from this, GM has centralised resource management in which you use factory methods to allocate new resources and then get returned an index for that resource, rather than a pointer to that direct resource (protection, this will be important to consider later.)
  • Centralised resource management means that logic is based around polling for resources, rather than assuming a resource exists.
  • GM is built around the idea of event loops, this is obvious. Where objects can be given a set number of specific events which run in a given sequence.
  • Scripts allow groups of functionality to be easily shared between different objects without the need for inheritance.
Despite a lot of people giving GML a bad rep, it actually has some fantastic features in terms of its meta design that make it fantastic for Game development. The big one of interest for me, which alot of people overlook is the idea of how dynamic resources (new objects, data structures, surfaces etc) are allocated. One qualm I had with Unity using C# is that C# doesn't really lend itself all that well to a dynamic game environment. It's far easier to have central instance tracking systems where you can check if instances exist, and happily destroy/unload instances at will, without having to make sure no other object is still referencing that instance.
Naturally, this can be achieved in Java/C#, but the way you have to do it is generally messy.

When paradigms and design patterns are built directly into a language, things become far more effective and easy to write code in. The point of these comments will become clear in a minute

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Keeping the design focus of GML in mind, what are we missing? object-specific functions/methods? Complex inheritance? Custom events? Some of these features seem obvious, but from an actual game design stand point, you really have to ask, what would really be useful? I'm of the mind that styling features after languages like Java/C# is bad for games, and we can do far far better than that. The important thing we need to consider is how design patterns that are used directly within our games can be part of language features.
(If you don't know what I mean by design pattern, its just an umbrella term for certain ways you can approach organising code/data structures/systems within a software project)

Object Specific functions/conventional inheritance (Nah.. Income components):

  • Object specific functions, or class methods really aren't all that useful in many game environments. If we want something to be an enemy, do we have to model it after a parent enemy? Well, what if that enemy also needs to be a collide-able wall half of the time? Darn.. We're stuck.. We can't inherit from both an enemy super-class, and a static collision super-class.
    Now enter the world of COMPONENTS. I view these as an expected (guaranteed) behaviour that a given object can have. If we wanted to create an enemy which was also collidable, well, easy! We just give it the enemy component and the collision component. This object will now have behaviour from both of those objects.

    This is something that is actually quite easy to achieve in GM, though not very strict. At the moment, we can simply create a group of scripts dedicated to this. I imagine that at some point, everyone has created scripts like: health_init, health_step, health_remove, health_give... These scripts grouped together make up a virtual component, a group of behaviour an object can have. Now this is still achieveable in other languages such as Java, but it gets increasingly complex when you actually want to make use of this in-game.

    What happens if we want to find all objects which have the "health" component and do damage to them for some area-of-effect attack? Well, we can give every object in game a map, then keep track of which components it has by doing a component_register in health_init().. The problem with this is we are wasting time and complexity creating a design pattern for something that could easily be a native feature. Imagine if you could just query every object (using a with style construct) that is targetable. Or only allow you to give items to other players that have the inventory component without knowing in advance whether that object has an inventory.

    All of that without inheritance, and to get even more powerful, if we could abstract away knowledge of what an object was and just assume that if an object has a health component, even if we dont know the type of the object, we can still perform functions such as health_remove on it. This becomes exceedingly powerful for all sorts of organisation when you can start using components to both give behaviour, and tag specific instances with certain things.

    One thing that bugs me atm with GM is that for collisions, functions like place_meeting rely on certain collision properties to be set. If you want to apply this to a group of objects, the only way to do it is by using a parent object like par_collision. The solid tag exists as a bit of a weird "hacky" work around, but it isn't nice to work with, especially if you wanted to have different tiers of collision so that certain things didnt collide with each other, but did collide with other objects.

    - Things like the default GM motion, or ability to path-find could also be treated as components.
Custom Events:
  • This is another interesting area. Say we didn't want to just stick to using the fixed events in GM, but rather we want to have more complex interactions. This is yet another thing that can be achieved with components. Lets say you had the ability to override the component function for when you received damage (this is more like a java style interface now). You now have an implicit event/group of events for a specific interaction that has happened in the game.

  • Any time any old object does damage to you, it fires off an event with paramters which you could capture, and alter. Say an enemy is invincible, well, we can just cancel the event.

  • With this, now networking can also become a component where any networked object fires off a specific network event for that object. I created something similar for my current game using event_user(n) functions which each represented an interaction event with packets, and now I have a really powerful event system, though I had to do a lot of work to set it up, when it could just be in there.

What I am trying to do here is to get people to look beyond what is assumed to be a language. Personally, I think alot of programming languages are bad. Languages built for a specific purpose are often fantastic, whereas Java and C#, whilst they are useful have flaws as they don't really do any extra work to make design patterns easy to use. You end up with alot of data-structures, event listeners, lists, queues.. blah blah.
Now again, all of this is possible in almost any programming language, but the point of discussion is how massively complex data structures could need to get to support the range of functionality. With information about things like this at compile time, meta-data can be pre-generated and this info can be polled very very quickly.

I personally don't even think Inheritance is a huge necessity. Its often good for creating similar objects which share a base line set of functionality, though component inheritance is waay more intersting, atleast for game dev :D!

What I see in this topic is a lot of people getting hung up on the syntax and alot of the petty things. This isn't language design, this is syntactic sugar and not really all that exciting. It doesn't revolutionise the way we develop games, it doesn't make our engines more powerful. We want a language that can enable us to do what we do better. Something that allows our code to be more extensible by design. How many times have you run into a situation where you feel like you have made your code adaptable, but realise one area of your game is limited?

- A recent example of me doing this was having all objects that were network synced use this WorldObject parent which handled automatic syncing and a beautiful system for events and packet syncing, however, as I needed it to be collidable, I couldn't set its parent to par_collide. Instead, I had to have it create a secondary object on top of itself that acted as the collision mask. This worked, but suddenly becomes quite a bit more gross.

Hope some people found this post a little more insightful :D!
 
C

CedSharp

Guest
@MishMash, I love you. <3

First and most critical point you mentionned to me that like popped up a light above my head: Components.
Of course! Duh! Why the hell would one go in making a monomorphism hierarchy ( which is already available in GameMaker via parents ) when compared to components,
which makes a lot more sense in a game than a "parent and childs".

First point granted.
Second point granted because of same idea as me: Custom events.
It's already implemented in my language. Actually its just a bunch of classes.
EventDispatcher being the critical one.

It has the following methods:

on( event, handler ) Adds a handler for an event
off( even, handler ) Removes a specific handler for an event
fire( event ) Sends an event to all the handlers ( for now, no way to stop it, but we could add a stopPropagation or something like that )
clear( event ) Remove all handlers for an event ( useful if you don't know the handlers beforehand )



The main reason I wanted to create this language is to be able to have "objects" that aren't GameMaker object.
The best example I can make is a class representing a 'Point'.

the following code:
Code:
class Point {
    int x;
    int y;
    void new( int x, int y ) {
         this.x = x;
         this.y = y;
    }
}
would convert into this in GameMaker:
Code:
/// ngml_c0(a,b)
var c = ds_grid_create(1,2);
c[#0,0] = argument[0];
c[#0,1] = argument[1];
return c;
and this code:
Code:
Point point = new Point( 4,16 );
show_debug_message( point.x );
would convert to this:
Code:
var point = ngml_c0( 4,16 );
show_debug_message( string( point[#0,0] ) );
So basically you work with classes, but they aren't even objects in GameMaker.
They are just a representation of data, and the language aliases it so it's easy to use.

Of course, type checking is done in the language so no type checking is needed in GameMaker anymore.
the language will also support some casting automatically, for example here you can see an int converted to string
automatically by the compiler.

Hopefully ngml will prove useful and not just a nice idea.

Regards,
CedSharp
 
-snip-
Custom Events:
  • This is another interesting area. Say we didn't want to just stick to using the fixed events in GM, but rather we want to have more complex interactions. This is yet another thing that can be achieved with components. Lets say you had the ability to override the component function for when you received damage (this is more like a java style interface now). You now have an implicit event/group of events for a specific interaction that has happened in the game.

  • Any time any old object does damage to you, it fires off an event with paramters which you could capture, and alter. Say an enemy is invincible, well, we can just cancel the event.

  • With this, now networking can also become a component where any networked object fires off a specific network event for that object. I created something similar for my current game using event_user(n) functions which each represented an interaction event with packets, and now I have a really powerful event system, though I had to do a lot of work to set it up, when it could just be in there.
I actually use this type of thing for animations. Every animation that the player can do, an NPC can also do, because they share scripts and variables. All I would have to do is set one variable to true (in either the player, or NPC), like "mining=true", then the mining animation would start playing.
I also agree how GML lends itself easily to game design, while with other languages, one might have to make a convoluted way of doing things
 

Freddy Jones

Your Main Detective
Instead of it being class based, you can make it more dynamic like a prototypal language. It's already a scripting concept like GML is.

*Something I love in functional languages that's semi-supported in game maker is First Class functions. Functions that can be passed as arguments to be used later.
- dynamic variable access this["name"]
- Lambdas functions, first class, are pretty handy.
- I feel like this would be a very complex addition to put in.
- Custom events are very useful -> I have this set-up in a complex gui framework of my own. With the exact functionalities you described above.
- Mutable variables. Protected variables. Private variables.
- Functions that are class based, and open utility like. Private, Static, protected etc.
- Custom Asynchronous events.
- Getters and Setters ( I hate it trying to debug code where a state-change occurred and the exact source is mysterious )
- Better literal support
IE: array literal = [1,2,3,4, [ 1,2,3,] ]
map literals: {"boss":"", "etc..":""...}
etc
- function chaining ( can return "this" from functions that return instances and such )
- this.changeName("jared").applyChanges();
- code that adds a variable dynamically to an instance should throw an error ...
-This kind of behaviour is really unpredictable and hard to debug. Especially when you're using "var" and miss-typed one of them later
- destructuring
- this is something available in javascript, and somewhat Golang.
- it could be useful when you want to return an array with two or more variables and grab them like this :
- var name, sprite, map = my_script_that_returns_three_values();

Just some suggestions. I'm basing quite a bit of my suggestions off of JavaScript, but TypeScript might be a better language to build from.
 
C

CedSharp

Guest
@Freddy Jones thank you for your time and suggestions!

1. this["name"]: easily feasible the way my compiler works.

2. very easy again. Not that it could quickly become innefficient: I still need to convert to valid GameMaker GML, so each lamda would acutally become a script.
In certain situations, a lamda changes at each loop iteration ( if in a loop ofc ) so it would create a different script for each iteration. Hopefully I can find some
good documents on how to better optimize this tho. I'm a fan of es7's double arrow functions ( ()=>{} ) so we can do something similar.

3. Like I said, custom events already implemented ( yay )
The EventDispatcher class ( or component, we'll see where we are heading ) has a map of events.
Each event has a list of handlers. When you call 'on' you add to this map, when you call 'off' you remove from this map.
When you call 'fire' it loops through all handlers of the events ( if there is any ) and sends the data to them.
If the listener is a GMObject then the handler will execute inside a 'with()' statement so that variables are all accessible.

If coupled with number 2., handlers could actually become lamdas!
Code:
switch.on( "switched", ( source, event )=>{
     if( event.state == "on" ) source.open = true;
});
4. I'm not sure about mutable variables, but currently my language supports public, private and protected scope visibility.

5. Properties and methods for classes is already supported by my language ( ex.: method 'move' private to player and property 'state' private to button )

6. Getters and Setters: I'm still debatting with myself if yes or no I should include this. There is no getters/setters in GML so I end up creating
scripts to do so, and I'd rather let the user create the structure they want instead of imposing my own getter/setter structure. But adding the
syntax to support them in my language would indeed make stuff so much easier... if you use a lot of classes that it.

7. Better Literals: Very good idea, taking a good note of this, very useful.

8. Function chaining: It's not a language feature, it's the way you use your things. You can do chaining in any language. You just need to 'return this' in each calls.
C++ can do it, php can do it, lua can do it, python can do it, any language that has a referece to itself can do chaining :p

9. My language already doesn't allow you to create a variable without defining it because of it's strictly typed nature.
( to create an instance variable... you need to declare it as a property of the class... so no dynamic vars )

10. Multiple value assignment desconstruction: I'm not sure I want to implement this in my language as I don't see a benefit in adding this feature compared the complexity it would add
to the compiler itself.

Very good suggestions, taking notes, notes and notes.

Regards,
CedSharp
 
Last edited:

Freddy Jones

Your Main Detective
@Freddy Jones thank you for your time and suggestions!

1. this["name"]: easily feasible the way my compiler works.

2. very easy again. Not that it could quickly become innefficient: I still need to convert to valid GameMaker GML, so each lamda would acutally become a script.
In certain situations, a lamda changes at each loop iteration ( if in a loop ofc ) so it would create a different script for each iteration. Hopefully I can find some
good documents on how to better optimize this tho. I'm a fan of es7's double arrow functions ( ()=>{} ) so we can do something similar.

8. Function chaining: It's not a language feature, it's the way you use your things. You can do chaining in any language. You just need to 'return this' in each calls.
C++ can do it, php can do it, lua can do it, python can do it, any language that has a referece to itself can do chaining :p
1. I don't actually think what I suggested is possible.. now that I think of it.. Even if you could do this["variable_name"] it would not be possible without getters or setter functions because
variables in game maker cannot be dynamically accessed. For example, you can't do :
var myChangeableName = choose("val1", "val2")
this[myChangeableName] = 0;
Would be very complex to convert back to GML. There's no native equivalent. You'd have to make some sort of wrapper like this:

Code:
///custom_class_var( ... )
if( argument_count == 0 ){
     switch( name ){
        case "val1": return val1;
       break;
      .... etc
}
else{
     switch( name ){
        case "val1": val1 = argument[0];
       break;
      .... etc
    }
}
And in the middle of that you'd have to make sure it access the inherited variables as well from parents, and implementations.

2. Lambdas seem very complicated to me and I don't know how easy it would be to actually convert that back into GML because it's a very dynamic feature. Most dynamic languages can't be compiled to non-dynamic languages (which GML theoretically isn't dynamic). So something as complicated as implementing a dynamic loop function to operate over a dynamically referenced function would be very complicated.
I was thinking you break apart functions that have lambdas into individual scripts but at that point supported something like a closure would be very difficult to mimic. Instead, I was thinking you could convert functions using lambdas and compile them into one large script that somehow pushes the execution stack flow in a creatable order.

8. How would you compile this feature into GML?
I posted an algorithm that's now been lost in the old GM suggestion box that converted function(....).function(...).function();
into function( function( function(...), ....), .... );
With your class methods will you be converting their GML to script_something( instanceID, .... ) ?
 

Freddy Jones

Your Main Detective
And I'd have a suggestion to an approach you could use for transpiling a lambda feature to GML:

Something like your language:
Code:
lambda forEach( array, lam:lambda ){
  for( var i in array ){
    lam( array[i], i, array );
  }
}

lambda logArray( array ){
  forEach( array, lambda( val ){ show_debug_message(val); } );
}
logArray to GML

Code:
// log array to GML:
var array_logArray = argument0;
var array_forEach = array_logArray;
for( var i_forEach = 0; i_forEach < array_length(array_forEach); i_forEach ++ ){
  var val_lambda1_logArray = array_forEach[i_forEach];
  show_debug_message( val );
}
Something like this, it'd be a little bit more complicated once you start dealing with return values and how you want to reference values outside of the scope of inner lambdas.
 
C

CedSharp

Guest
1. I don't actually think what I suggested is possible.. now that I think of it.. Even if you could do this["variable_name"] it would not be possible without getters or setter functions because
variables in game maker cannot be dynamically accessed. For example, you can't do :
var myChangeableName = choose("val1", "val2")
this[myChangeableName] = 0;
Would be very complex to convert back to GML. There's no native equivalent. You'd have to make some sort of wrapper like this:

Code:
///custom_class_var( ... )
if( argument_count == 0 ){
     switch( name ){
        case "val1": return val1;
       break;
      .... etc
}
else{
     switch( name ){
        case "val1": val1 = argument[0];
       break;
      .... etc
    }
}
And in the middle of that you'd have to make sure it access the inherited variables as well from parents, and implementations.

2. Lambdas seem very complicated to me and I don't know how easy it would be to actually convert that back into GML because it's a very dynamic feature. Most dynamic languages can't be compiled to non-dynamic languages (which GML theoretically isn't dynamic). So something as complicated as implementing a dynamic loop function to operate over a dynamically referenced function would be very complicated.
I was thinking you break apart functions that have lambdas into individual scripts but at that point supported something like a closure would be very difficult to mimic. Instead, I was thinking you could convert functions using lambdas and compile them into one large script that somehow pushes the execution stack flow in a creatable order.
You seem to be misunderstanding a fundamental point about my language, and I shall rectify this misslead point right away:
nGML converts to GML without problem because I can do whatever I feel like doing. I can create table of values and indexes, I can do whatever
I want, so basically nGML could convert whatever I feel like to GML.

BUT, that's only because I decided that nGML will produce FINAL gms projects, aka the code compiled is not intended to be used
by human. First of all it will be mostly unreadable, and second, because all the types validation have been done at compilation time,
there is no need to use type checking in GM itself, so the code will assume that everything is right from the get go, something that you
can't possibly do if you write the code yourself.

Basically, ngml will build a table of all the properties and methods that each class have.
so its easy to check if a value exists or not.
Also, the example you posted is completly wrong:
Code:
var myChangeableName = choose( "val1", "val2" );
In this piece of code you created a 'var' variable, aka a local temporary variable.
It is not part of the instance so it won't be accessible via 'this'.

The only way you'd have to access a variable in this way is when you define the properties in a class:
Code:
class Player {
    int x;
    int y;
    void new() {
        this["x"] = 5;
        this["y"] = 27;
    }
}
in such context, my compiler has no problem indexing the variables, making sure they exists and validating the type of values.
So yes, I can implement this super easily, thanks to the strcitly typed nature of my language.

8. How would you compile this feature into GML?
I posted an algorithm that's now been lost in the old GM suggestion box that converted function(....).function(...).function();
into function( function( function(...), ....), .... );
With your class methods will you be converting their GML to script_something( instanceID, .... ) ?
I've just realized I said something missleading: point 8., about chaining:

In GameMaker, you cannot access the object directly, there is a level of abstraction where you use an index.
Inside of game maker, it is hence impossible to chain scripts because even if you store a script inside a variable,
what you're actually storing is an index to that script, so you can't simply do this:
Code:
player.script = scr_show_message;
player.script();
because this is impossible, chaining in gamemaker is not possible.
I could add chaining support to my languge, but it requires a new level of complexity.
 
Last edited:
C

CedSharp

Guest
And I'd have a suggestion to an approach you could use for transpiling a lambda feature to GML:

Something like your language:
Code:
lambda forEach( array, lam:lambda ){
  for( var i in array ){
    lam( array[i], i, array );
  }
}

lambda logArray( array ){
  forEach( array, lambda( val ){ show_debug_message(val); } );
}
logArray to GML

Code:
// log array to GML:
var array_logArray = argument0;
var array_forEach = array_logArray;
for( var i_forEach = 0; i_forEach < array_length(array_forEach); i_forEach ++ ){
  var val_lambda1_logArray = array_forEach[i_forEach];
  show_debug_message( val );
}
Something like this, it'd be a little bit more complicated once you start dealing with return values and how you want to reference values outside of the scope of inner lambdas.
Creating a lamda is basically creating a no-name function ( I usually call them anonymous functions ) on the go, which has access to the scope where it has been defined.
In this matter I intended to follow the same logic that 'haXe', another game language, uses for those:

Creating a 'type' that represents a function.

Basically in haXe, you can do this:
Code:
class Test {
    private test:Int->String->Void; //  this declares a 'function type' as follow: Void function( Int a, String b ){}
    public function new() {
        this.test = this.something;
        this.text( 25, "test" );
    }
    private function something( a:Int, b:String ):Void {
         // some code
    } 
}
In haXe you can't create lamdas, but you can define a function type.
In my case, I can add the function type, and simply create a script on the go for each lamdas,
so my typing system won't complain and you'll have your lamdas.

BUT, like I said, this could become very inneficient.
If I take the following example:
Code:
${Int>${Int>Int}} adder = ( Int x )=>{
    return ( Int y )=>{ return x+y; };
};

${Int>Int} add10 = adder( 10 );
Int num12 = add10( 2 );
In the above example, the first lamda returns a second lamda.
The second lamda has access to the scope of the first lamda.
The problem tho is that the value of this scope can change!
My compiler being intelligent, it will create a new script each time. yay.
What if you were to call this in a loop from 0 to 100?
or worst, from 1 to 100 000?

This kind of lamda would generate tons and tons of scripts.
My compiler won't have any problem, but the result would be completly inneficient.

While I consider the usage of lamdas very nice, it is not a good practice in a typed language ( my own opinion ).

It is feasible, the real question is should I add it or no...
 

Freddy Jones

Your Main Detective
You seem to be misunderstanding a fundamental point about my language, and I shall rectify this misslead point right away:
nGML converts to GML without problem because I can do whatever I feel like doing. I can create table of values and indexes, I can do whatever
I want, so basically nGML could convert whatever I feel like to GML.

BUT, that's only because I decided that nGML will produce FINAL gms projects, aka the code compiled is not intended to be used
by human. First of all it will be mostly unreadable, and second, because all the types validation have been done at compilation time,
there is no need to use type checking in GM itself, so the code will assume that everything is right from the get go, something that you
can't possibly do if you write the code yourself.

Basically, ngml will build a table of all the properties and methods that each class have.
so its easy to check if a value exists or not.
Also, the example you posted is completly wrong:
Code:
var myChangeableName = choose( "val1", "val2" );
In this piece of code you created a 'var' variable, aka a local temporary variable.
It is not part of the instance so it won't be accessible via 'this'.

The only way you'd have to access a variable in this way is when you define the properties in a class:
Code:
class Player {
    int x;
    int y;
    void new() {
        this["x"] = 5;
        this["y"] = 27;
    }
}
in such context, my compiler has no problem indexing the variables, making sure they exists and validating the type of values.
So yes, I can implement this super easily, thanks to the strcitly typed nature of my language.



I've just realized I said something missleading: point 8., about chaining:

In GameMaker, you cannot access the object directly, there is a level of abstraction where you use an index.
Inside of game maker, it is hence impossible to chain scripts because even if you store a script inside a variable,
what you're actually storing is an index to that script, so you can simply do this:
Code:
player.script = scr_show_message;
player.script();
because this is impossible, chaining in gamemaker is not possible.
I could add chaining support to my languge, but it requires a new level of complexity.
You seem to be misunderstanding a fundamental point about my language, and I shall rectify this misslead point right away:
nGML converts to GML without problem because I can do whatever I feel like doing. I can create table of values and indexes, I can do whatever
I want, so basically nGML could convert whatever I feel like to GML.

BUT, that's only because I decided that nGML will produce FINAL gms projects, aka the code compiled is not intended to be used
by human. First of all it will be mostly unreadable, and second, because all the types validation have been done at compilation time,
there is no need to use type checking in GM itself, so the code will assume that everything is right from the get go, something that you
can't possibly do if you write the code yourself.

Basically, ngml will build a table of all the properties and methods that each class have.
so its easy to check if a value exists or not.
Also, the example you posted is completly wrong:
Code:
var myChangeableName = choose( "val1", "val2" );
In this piece of code you created a 'var' variable, aka a local temporary variable.
It is not part of the instance so it won't be accessible via 'this'.

The only way you'd have to access a variable in this way is when you define the properties in a class:
Code:
class Player {
    int x;
    int y;
    void new() {
        this["x"] = 5;
        this["y"] = 27;
    }
}
in such context, my compiler has no problem indexing the variables, making sure they exists and validating the type of values.
So yes, I can implement this super easily, thanks to the strcitly typed nature of my language.



I've just realized I said something missleading: point 8., about chaining:

In GameMaker, you cannot access the object directly, there is a level of abstraction where you use an index.
Inside of game maker, it is hence impossible to chain scripts because even if you store a script inside a variable,
what you're actually storing is an index to that script, so you can't simply do this:
Code:
player.script = scr_show_message;
player.script();
because this is impossible, chaining in gamemaker is not possible.
I could add chaining support to my languge, but it requires a new level of complexity.
There's no point to having the notation this["variableName"] if you can't do the snippet of code I suggested. It's basically accessing the variable dynamically. I was suggesting a number of dynamic features, but if your language is non-dynamic then it wouldn't be possible to know the type you're dealing with until run-time with this[ variable_with_a_string_value_that_references_any_variable ] notation. That's basically the only benefit of being able to access variables with that notation.
I don't see how typing this["variable"] makes a more syntactical difference than this.variable besides being a different way. But if you made it so that this[variable_with_string_value] worked it would be something to consider.

Chaining in GameMaker is not impossible. The algorithm I showed you is exactly how you would make it work. If you're planning on having class methods then you're going to need to figure out a way -> I showed you one way it could work. Your transpiler would just have to add in the translation from a chained-script to a nested script.


I wish you luck with your language, I'll get off the train before I'm kicked off haha. I hope my suggestions give you some room to work with!
 
C

CedSharp

Guest
There's no point to having the notation this["variableName"] if you can't do the snippet of code I suggested. It's basically accessing the variable dynamically. I was suggesting a number of dynamic features, but if your language is non-dynamic then it wouldn't be possible to know the type you're dealing with until run-time with this[ variable_with_a_string_value_that_references_any_variable ] notation. That's basically the only benefit of being able to access variables with that notation.
I don't see how typing this["variable"] makes a more syntactical difference than this.variable besides being a different way. But if you made it so that this[variable_with_string_value] worked it would be something to consider.
Old text that I started typed but doesn't make sense now that stupid me finally realised I misunderstood something again...
The big problem that I have is that I convert to gml, hence I have no power over runtime, unless I add tons of overhead to about everything that the code does.
I was indeed wondering why you would've wanted to access the class with a string rather than the variable itself...
You said yourself that you don't want to initilize dynamic variable in an instance, but you want to be able to create local variables
and reference them dynamically?

The language I'm making is OOP oriented, and unlike Javascript where everything is Closure-oriented,
you can't dynamically create variables in every scope at runtime.

My language being statically typed, I think this is not possible like you mentionned.

I'm stupid, let me call myself stupid, because I am.

Code:
var aVar = choose( "var1", "var2" );
this[ aVar ] = 0;
is a completly valid code, even in my strictly typed language.
What I actually thought you meant is this:

Code:
var aVar = "whatever";
this["aVar"] = "whatever else";
So what I meant is that 'this' could not access a 'local var'.
but of course what I said doesn't make sense because that's not what you meant
in the first place. Please accept my apologies :'(

Yes, that is possible, and will actually be implemented, I can clearly see the
use of this now.

Again sorry about my confusion.

Chaining in GameMaker is not impossible. The algorithm I showed you is exactly how you would make it work. If you're planning on having class methods then you're going to need to figure out a way -> I showed you one way it could work. Your transpiler would just have to add in the translation from a chained-script to a nested script.
Let me first show you one of my above posts:
Code:
class Point {
    int x;
    int y;
    void new( int x, int y ) {
         this.x = x;
         this.y = y;
    }
}
would convert into this in GameMaker:
Code:
/// ngml_c0(a,b)
var c = ds_grid_create(1,2);
c[#0,0] = argument[0];
c[#0,1] = argument[1];
return c;
and this code:
Code:
Point point = new Point( 4,16 );
show_debug_message( point.x );
would convert to this:
Code:
var point = ngml_c0( 4,16 );
show_debug_message( string( point[#0,0] ) );
So basically you work with classes, but they aren't even objects in GameMaker.
They are just a representation of data, and the language aliases it so it's easy to use.

Of course, type checking is done in the language so no type checking is needed in GameMaker anymore.
the language will also support some casting automatically, for example here you can see an int converted to string
automatically by the compiler.
I couldn't find your algorythm for converting chaining functions, but my point is that to be able to chain functions,
my script would need to validate at runtime that a value returned by a function is not null,
that the value returned supports calling the chaining function, etc.

In theory, it should already work in my language, you'd get no compilation errors.
My problem is transpiling it into valid gml that will work in any cases.


The above piece of code is a very basic transpilation example or a simple class 'Point'
There is no tracking of nothing.
Once in gml, the code will be mostly unusable because I don't
want to manage the code on both sides.
Since all the analysis and validations are done ngml-side,
then on gamemaker it just needs to run, no need to re-check everything just
because user added some more code.

NGML will compile into a valid GMS project, and this project should only be compiled and runned in GameMaker.
It is not intended to be read/modified.
( you can attempt to do so, but the code won't use words, it will use the IDs and indexes that my compiler will have generated )
 
Last edited:
C

CedSharp

Guest
The more I think about what I would like my language to support, and the more I think I should drop the idea of "not doing anything at run-time".
And while adding some checks for dynamically testings stuff, might as well make the code readable with comments etc.

To achieve this, right now the idea that I have is to create "helpers" that will let my language create classes in GameMaker.

I'll have to create maps to store the name of each classes and interfaces,
in which I'll store every properties and methods.

Some helper scripts will let you define and create classes from gamemaker directly,
but it won't be as easy as using ngml tho haha.

Every 'method' will have argument checking to match the typing,
and dynamic features will work because GameMaker is dynmic, so I can mix both.

for example, if I make a component system in ngml, I would use stuff like 'is'.
is() would basically return true or false if a class has an interface.

Code:
if( is( this, IHealth ) ) {
    // do stuff with health
}
This would make the language very possible, I still need to figure out a good way of transpiling this into GML.

But ye, letting you guys know that I abandonned the idea of "if you work in ngml you don't work in GML"
and will include a mix of both strictly typed and dynamic variables, with some limitations.

Regards,
CedSharp
 
C

CedSharp

Guest
Quick question tho, an interface being a "promise that a method is available", should I allow defining properties in the interface?
Because making an interface actually act like a component would probably be best.

A class that wants say the "move" component would implement, say the "IMoveComponent" ( I don't know lol ) which would define properties such as x,y,speed, etc, and methods such as 'move' etc.
Each class needs to implement the component tho, so we lose the component aspect, unless we instead go for a component managing system.

In such cases, interfaces would force the implementation of properties, and Component managers, or "executers", would run the logic.

Or, I can make components being classes themself, and have an Entity class that can contain a list of components.
This Entity class would have a 'hasComponent" method that checks if a component is linked to this instance.

I'm not sure of how to implement this, because there seems to be more than one way to implement components
and I don't know which method would make most users happy.

- help -

CedSharp
 
M

MarcoLizza

Guest
Hello everybody.

Perhaps I'm missing something, but these days I'm giving GMS a try and I'm puzzled by GML (and I expressed these doubts in a thread).

While I think I can guess the rationale for its creation, I can find a reason for not being replaced with a more common language during the years. What's the point in not adopting C# or Lua (for example, but any other embeddable language can do)?

A solution for backward compatibility can be devised, in my opinion.

My point is that I have the feeling that sticking with a custom proprietary language could be a limit and a burden in the long run.
 
C

CedSharp

Guest
Hello everybody.

Perhaps I'm missing something, but these days I'm giving GMS a try and I'm puzzled by GML (and I expressed these doubts in a thread).

While I think I can guess the rationale for its creation, I can find a reason for not being replaced with a more common language during the years. What's the point in not adopting C# or Lua (for example, but any other embeddable language can do)?

A solution for backward compatibility can be devised, in my opinion.

My point is that I have the feeling that sticking with a custom proprietary language could be a limit and a burden in the long run.
By creating a custom language, they support exactly what they want to support.
GML is very permissive. You can use C-like syntax like you can use VB/Lua style syntax.

It's super user-friendly and also is made specially to work with handles.
It doesn't support features that aren't supported in GameMaker like Classes and functions.

If, for example, they implemented C# as the language, then they'd have to support classes, interfaces, iterators, operator overloading, types, etc.

A custom language made specially for the engine you're using and which perfectly fits all it's features was a very good decision in my opinion.
It lacks "programmer goodies" but that's just because we're used to other languages.

GML is user-friendly and sticks to all the gamemaker features without allowing weird unsupported stuff.
 
M

MarcoLizza

Guest
By creating a custom language, they support exactly what they want to support.
True. But they also take the burder to properly design and develop the language. Lua, for example, is a well tested and efficient language that can be embedded quite easily.

It doesn't support features that aren't supported in GameMaker like Classes and functions.
This is something I'm missing. Why functions aren't supported? This seems so odd to me...

If, for example, they implemented C# as the language, then they'd have to support classes, interfaces, iterators, operator overloading, types, etc.
With the C# example in mind, they should have designed the GameMaker API around classes, of course. But adapting to C# requirements it would have been a plus, in my opinioin. Not a waste of time.

A custom language made specially for the engine you're using and which perfectly fits all it's features was a very good decision in my opinion.
It depends. Nowadays, IMO, designing yet-another-language is a waste of time and effort. One can choose among some very goods easy-to-embed languages without struggling with the definition and development of the language.

It lacks "programmer goodies" but that's just because we're used to other languages.
GML is user-friendly and sticks to all the gamemaker features without allowing weird unsupported stuff.
I can't agree with that, or perhaps I'm viewing from the wrong point of view. If Lua,C# or Python were chosen as scripting language we didn't have "weird unsupported stuff" or "programmer goodies"... but full fledged languages, supported and well known, with a plentiful of libraries and books as a support.

GML seems to me *too* simple and I fear it won't stand the passing of time. Is there someone from the staff that could, please, motivate this choice? I'm just curious, I'm not bragging or criticizing.
 
C

CedSharp

Guest
This is something I'm missing. Why functions aren't supported?
By "they aren't supported" I mean that in GameMaker, objects are handles. There are no functions, instead you have handles for scripts.
The whole engine itself doesn't support classes or any other features of OOP.

With the C# example in mind, they should have designed the GameMaker API around classes, of course. But adapting to EcmaScript requirements it would have been a plus, in my opinioin. Not a waste of time.
Because GameMaker doesn't let you use pointers, that would be a huge pain to implement. They'd have to create a new engine completly.

It depends. Nowadays, IMO, designing yet-another-language is a waste of time and effort. One can choose among some very goods easy-to-embed languages without struggling with the definition and development of the language.
I agree that it's easy to choose some pre-existing languages, but I think one of the main selling-point of GML is that it's very permissive. Compare it to many other languages, and I'm sure you'll agree that they have more strict rules to follow.
Also, GML is unique in the sense that you can simply mix it with the drag'n'drop. One of the main goal is to provide quick easy and cheap scripting when drag'n'drop is not enough, while still having tons of features if you use only GML.

but full fledged languages, supported and well known, with a plentiful of libraries and books as a support.
Because GameMaker doesn't let you access the "real" data, it's all abstracted by handles, then you couldn't use much libraries could you?
And again, by the nature of the GameMaker Engine, classes, typing and other "missing features" aren't possible, or would mean rewriting huge chunks of the engine.

GML seems to me *too* simple
That's GML's selling point. It's simple, so it's easy to learn, it's cheap to interact with, and it's permissive.

NOTE: I agree with you that I would love seeing a 'real' programming language take roots in GameMaker. Something like ES2016 javascript or C# would be wonderful.
But sadly, I also think that it wouldn't suit GameMaker in it's whole, it would defeat the "easy to learn and permissive" point that it kept until now.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
With the C# example in mind, they should have designed the GameMaker API around classes, of course. But adapting to C# requirements it would have been a plus, in my opinioin. Not a waste of time.
GML actually predates C#. GML was invented in 1999/2000 while C# was invented in 2001... ;)

As for this topic, I'm in two minds as to whether to keep it open or not... It's an interesting discussion, for sure, but if your are actually going to create a your own language and a parser and bypass GMS all together to create games, then it has no place on these forums.
 
T

ThunkGames

Guest
GML actually predates C#. GML was invented in 1999/2000 while C# was invented in 2001... ;)

As for this topic, I'm in two minds as to whether to keep it open or not... It's an interesting discussion, for sure, but if your are actually going to create a your own language and a parser and bypass GMS all together to create games, then it has no place on these forums.
It looks like OP wants to compile this language into a GM:S project, which I don't believe to be in violation of the terms and conditions.

- Converting the parsed code into a valid GM : S project.
 
M

MarcoLizza

Guest
By "they aren't supported" I mean that in GameMaker, objects are handles. There are no functions, instead you have handles for scripts.
This is quite "odd" to me. It somewhat resembles Visual Basic, that way (which also had functions, however).

The whole engine itself doesn't support classes or any other features of OOP.
Well, I'm perfectly fine with this. I'm confident with OOP to the point that I prefer to it other approaches, most of the time (the single most useful thing beign classes as containers). ;)

Because GameMaker doesn't let you use pointers, that would be a huge pain to implement. They'd have to create a new engine completly.
Are you sure? I wasn't talking about pointers at all. Of course exposing the API through classes would require an almost complete overhaul of the engine... but adopting a non-classes-oriented language (Lua and Javascript come to mind) would be much simpler, IMO.

I agree that it's easy to choose some pre-existing languages, but I think one of the main selling-point of GML is that it's very permissive. Compare it to many other languages, and I'm sure you'll agree that they have more strict rules to follow.
I agree that there languages more complex that GML, but I don't feel that GML is simpler or easier to learn than Lua, or Perl, or PHP (the latter twos just mentioned for comparison of the grammar, not that I would use them at all as embeddable languages!).

Also, GML is unique in the sense that you can simply mix it with the drag'n'drop. One of the main goal is to provide quick easy and cheap scripting when drag'n'drop is not enough, while still having tons of features if you use only GML.
That would have been still possible adopting an existing language grammar and syntax-wise, IMO.

Because GameMaker doesn't let you access the "real" data, it's all abstracted by handles, then you couldn't use much libraries could you?
Libraries (expecially with the the overmentioned Lua language) come also in the form of scripts. For example, a library to implement linear algebra operations, or enhanced string manipulation, or pathfinding... well, I guess you got it.

And again, by the nature of the GameMaker Engine, classes, typing and other "missing features" aren't possible, or would mean rewriting huge chunks of the engine.
Again, C# was just an example. In fact more variant-oriented languages, like the aforementioned, would suit better.

That's GML's selling point. It's simple, so it's easy to learn, it's cheap to interact with, and it's permissive.
NOTE: I agree with you that I would love seeing a 'real' programming language take roots in GameMaker. Something like ES2016 javascript or C# would be wonderful.
But sadly, I also think that it wouldn't suit GameMaker in it's whole, it would defeat the "easy to learn and permissive" point that it kept until now.
I understand your point. But, again, I don't think that Lua and Javascript are more difficult to learn than GML for the "average user" (not to the programmer). And as a seasoned programmer, on the contrary, I fell somewhat limited and without a proper array of tools if I choose the avoid DnD and indulge in using just scripts.

GML actually predates C#. GML was invented in 1999/2000 while C# was invented in 2001... ;)
Of course C# was just and example. Back in 2000-something both Javascript and Lua already existed (and the second one was already used in commercial games as a scripting language). :D
 
Last edited by a moderator:

trg601

Member
Unfortunately, I don't have time to read through all these posts right now, but I just wanted to say that the idea of a third party Gamemaker language, especially if it adds extra functionality XD!

I think it would be wonderful to have another language choice we could use with Gamemaker, and perhaps also other languages, like Java or C#. I don't know if you have any plans for that, but I think there could be value to making a parser for ngml in other languages, but that's just an idea.
(I also just recently had the idea of a native GML parser in another language, so that is where this idea is coming from XD)
 
C

Chris

Guest
I actually also had a similar idea to this. I originally thought it would be cool to have a language that was basically a superset of GML, just like TypeScript is to javascript. You would write in this new language using cool stuff like classes and interfaces and type annotations and it would compile down to plain GML that you could use in within GM:S. But this is definitely really cool!
 
C

CedSharp

Guest
I actually also had a similar idea to this. I originally thought it would be cool to have a language that was basically a superset of GML, just like TypeScript is to javascript. You would write in this new language using cool stuff like classes and interfaces and type annotations and it would compile down to plain GML that you could use in within GM:S. But this is definitely really cool!
This is what my language does.

It adds classes and interface, so more need to create a controller object in gamemaker that updates, is checked for collision and has millions of uneeded variables!

It adds a typing system. Some will love it, some will hate it. That's a personal choice of mine, it helps me debug the code and makes sure someone using my
code will not break it by accident.

It adds file imports. Having the code for one object inside one file is clean and easy to work with.
You want to use the object in another file? just import it. ( note: I haven't met that problem yet, but I don't think my code handles circular imports, I'll have to handle that, added on todo list! )

Finally, it's still GameMaker, so when you create a class, you can "inherit" from the 'GMObject' class, which will make your class a normal gamemaker object. You then have access
to any of the GameMaker scripts.

This is a limitation of my language: Because you can create data-structure-based classes ( not gm objects ), some functions will obviously be
unavaiable. For example, if you don't extend 'GMObject', you can't call place_meeting, because you don't have neither a sprite neither the 'x' and 'y' variables
that GameMaker uses. I'll have to go through ( and hopefully with the help of others ) all the functions and decide what is "public" and what is "GMObject-only".

Originally I wanted to just "add" features, but then I realized that some of them make the normal gml language unusable. ( specifically, the typing system ).
 
C

Chris

Guest
This is what my language does.

It adds classes and interface, so more need to create a controller object in gamemaker that updates, is checked for collision and has millions of uneeded variables!

It adds a typing system. Some will love it, some will hate it. That's a personal choice of mine, it helps me debug the code and makes sure someone using my
code will not break it by accident.

It adds file imports. Having the code for one object inside one file is clean and easy to work with.
You want to use the object in another file? just import it. ( note: I haven't met that problem yet, but I don't think my code handles circular imports, I'll have to handle that, added on todo list! )

Finally, it's still GameMaker, so when you create a class, you can "inherit" from the 'GMObject' class, which will make your class a normal gamemaker object. You then have access
to any of the GameMaker scripts.

This is a limitation of my language: Because you can create data-structure-based classes ( not gm objects ), some functions will obviously be
unavaiable. For example, if you don't extend 'GMObject', you can't call place_meeting, because you don't have neither a sprite neither the 'x' and 'y' variables
that GameMaker uses. I'll have to go through ( and hopefully with the help of others ) all the functions and decide what is "public" and what is "GMObject-only".

Originally I wanted to just "add" features, but then I realized that some of them make the normal gml language unusable. ( specifically, the typing system ).
That's amazing. File imports? You're my hero. I would love to develop for GM this way, sounds like a dream.
 
T

Turbine

Guest
EnigmaGM is pretty similar in a lot of ways. But I feel your idea would catch on more.
 
C

CedSharp

Guest
EnigmaGM is pretty similar in a lot of ways. But I feel your idea would catch on more.
EnigmaGM is an attempt to clone GameMaker in a cross-platform engine. It also uses LateralGM, which is literally a clone of the GameMaker studio IDE.
This is not at all what I'm trying to achieve.

My goal is to create a new language, not even comparable to the current GML, but without creating the whole Game engine, since it already exists.
I want to be able to use Everything that GameMaker has to offer ( objects, views, rooms, sprites, etc ) but program in a language that feels more confortable with.
In the end, you'll still be making a GameMaker project, that didn't change at all... But instead of using the GameMaker IDE, you'll be using a text-only based language.

To me, nGml is what the 'GML mode' in GameMaker Studio 2 should have been ;)
 
S

Shadowblitz16

Guest
wow this is cool
the yoyo devs should add this as a optional gms2 language
 

Ihato

Member
First off, I love the idea. GM is great for beginners but not so great for people who have seen what other languages are capable of. OOP feature set in a language with the graphical and gaming capabilities of GM is a wonderful idea. That said, here's the thing. Based on the code sample you shared, your language is literally JAVA. My personal opinions about JAVA aside, if you're going to rewrite the JAVA parser, why not just write the entire thing as a JAVA library in the first place? Alternatively, why not invent a little bit of different syntax to differentiate yourself? The way a language "feels" to the programmer is a vastly underappreciated concept in language design, and the way your language "feels" is as a limited subset of JAVA which is used for game design.
Yea that is why it surprised me nobody mentioned the Processing language.
Not only is this exactly what OP wants to make but all nGML code I've seen in this thread has turned to be perfectly valid Processing code as well!
They have even made the "notepad" OP was talking about.



Deja Vu huh?

I don't want to abandon the idea of a minimalist game making language though. That's I think it's better to make game engine for Processing (inspired by Game Maker) because Processing is a general purpose language.

Or if we still want to create a new language we need to consider its advantages.
Know that maintaining a compiler is a nightmare compared to maintaining a library.
 
Last edited:
Top