Ideka
|
|
Reply #15 Posted on: April 03, 2014, 08:10:24 pm |
|
|
Joined: Apr 2011
Posts: 85
|
Anyway my point was that even though you can get pretty much anything done in GM, its language is rather limited, as you should clearly be able to see, being a C++ programmer yourself. I truly don't see that.
Really? So you never found yourself missing, say, classes, when programming in GML? Or static-typing? Or exceptions? Or how about some sequence type that you can actually pass around without having to bother to clean up after you don't need it? Wouldn't you at least agree that, if GML had these features, you could get more done in less time, structure your programs more efficiently and/or write more robust and understandable code with it? You could do it in assembly if you really wanted. True. You could do it even writing only 1 instruction for a million times (on a one instruction set computer http://en.wikipedia.org/wiki/One_instruction_set_computer).
Right. So either you're going to argue that assembly isn't limited (even if it lacks such things as, say, variables and functions), or your "GM isn't limited, I could use it to remake Bastion" argument is invalidated.
|
|
« Last Edit: April 03, 2014, 08:13:54 pm by Ideka »
|
Logged
|
|
|
|
Darkstar2
|
|
Reply #16 Posted on: April 03, 2014, 09:23:12 pm |
|
|
Joined: Jan 2014
Posts: 1238
|
Wow nice debate Off topic indeed, but I read something and feel I should step in and add my 2 cents. First, I think saying that the simplicity of GM and the likes are reasons why there are more sloppy games is not entirely true in my opinion. Sure, like there will be more of them made with a fast engine than a sloppy game written in several tens and thousands lines of C++ The reason for sloppy ass games in GM is not really due to its simplicity and speed really, who said GM was simple? It can be as complex as you want it. There are some very advanced stuff you can do with GML and most people don't even use a fraction of its capacity. That said, I think the biggest reason people make sloppy games is lack of skill. Skill goes far beyond the coding part but the content. You can be a good coder, but if you lack creativity and all the areas that make a good game you are useless. If you can't draw sprites, design graphics, build your own unique content to your game, then you are stuck ripping other people's gfx or using stuff you find online or copying the same fucking clones of games. Some people lack the skill and resources to make good content for a game and/or don't have the necessary software or know that there are many free software out there,but still without skill you go nowhere. So you can give anybody the fastest engine and easiest to learn language, if the person does not have the skill and foundation, forget it. You can have all the materials but if you don't have the right designer and planner you go nowhere and at that point you just do some random shit. Here's an example of such concept..... FPS Creator. How more easier can you get in making your own 3D FPS right ? just clicking prefabs and building levels........Or 3D GameMaker, another ready made pre-fab game creation just click and build type. Well people still make shitty games with those even though not a single line of code is necessary, again, going back to the same arguments as above, lack of skill. True that YYS has some limitations and they removed raped some windows function and some of the stuff they do is sloppy at best, BUT.....with people the right skill/talents they could make really good games, mind you not optimal performance/speed, and there are limits, but still people could do far FAR better with GM than the utter shit that it's currently made. So provide someone with an engine and full turn key approach to game making, they still will not be able to making anything half decent without skill. Same for someone starting from scratch using coding. And BTW, using the slower approach has not stopped people from making really REALLY bad games, proof is all out there.....and there are bucket full of games that are really shit that were not made with GM or any similar game engine Just thought I'd add my 2 cents
|
|
|
Logged
|
|
|
|
TheExDeus
|
|
Reply #17 Posted on: April 04, 2014, 10:32:06 am |
|
|
Joined: Apr 2008
Posts: 1860
|
So you never found yourself missing, say, classes, when programming in GML? Not at all. Objects are classes in GM/ENIGMA. They at least fulfill most of the requirements classes are used for. Or static-typing? Dynamic types aren't really bad. GM had a great system for detecting undeclared variables anyway and it worked like a charm. But this wholly is the programmer preference. And it sure as heck doesn't make the code smaller as you actually have to type more in static-typing. It doesn't make a language limited in any way. Just different. Or exceptions? Never been a big fan of exceptions. I almost never use them in C++ either. And GM just doesn't require them. Like how exactly this makes a language better: ifstream file; file.exceptions ( ifstream::failbit | ifstream::badbit ); try { file.open ("test.txt"); while (!file.eof()) file.get(); } catch (ifstream::failure e) { cout << "Exception opening/reading file"; } Than this?: file = file_text_open_read("test.txt"); if (file == -1){ show_error("Cannot load the file!",false); } while (!file_text_eof(file)) { file_text_readln(file); } file_text_close(file); It's actually easier to understand the GML version than the C++ one. And even in C++ I never use extensions, because, for example, file.good() returns whether you successfully opened it. So GM's lack of exceptions is also not a limitation. It's just a different. Or how about some sequence type that you can actually pass around without having to bother to clean up after you don't need it? You mean std::containers? I guess the fact that we don't have reference counters or out of scope garbage collection is a limitation. But it's not necessarily a language problem, but the implementation problem. This is harder to do because scopes are not as strictly defined as in C++. But this is the only of your examples were I agree it could be done better and could be considered a limitation. Garbage collection is a little problem with GM/ENIGMA. Wouldn't you at least agree that, if GML had these features, you could get more done in less time, structure your programs more efficiently and/or write more robust and understandable code with it? By the examples I given no, I don't think those features would make GML any better (except for reference counting). But EDL does support (or plan to at least) some of the features together with GML. So you can give types if you want (that doesn't make it statically-typed of course). You can technically make classes and structs as well (but I think they currently don't work because of parser bugs). But using the features won't make your code smaller (it will probably make it bigger) or more understandable. They might make the code more efficient of course, but that is not a limitation of the language, but the parser/compiler. GCC wasn't built to compile parsed EDL into super optimized exe. Right. So either you're going to argue that assembly isn't limited (even if it lacks such things as, say, variables and functions), or your "GM isn't limited, I could use it to remake Bastion" argument is invalidated. I don't argue that. It's just that you took assembly as an example and I made a step further. It's not really relevant to the discussion.
|
|
« Last Edit: April 04, 2014, 10:36:24 am by TheExDeus »
|
Logged
|
|
|
|
Ideka
|
|
Reply #18 Posted on: April 04, 2014, 12:58:24 pm |
|
|
Joined: Apr 2011
Posts: 85
|
Don't tell me GM objects are the same as classes. They're not. You can make them work as classes, sort of, but it's a pain in the ass. I didn't say dynamic typing was bad. But don't you think it'd be good if you could specify something like "this function should always take one int" and then the compiler telling you if you ever call it wrongly? Don't you think that might help you find and squash some (potentially subtle) bugs? Exceptions carry more information than a -1 return value. An exception might be able to tell you not only that the file wasn't loaded properly, but also why. Also if your examples were inside a function, you could catch the error from outside with exceptions. You mean std::containers? Maybe. Not necessarily. You can make your own containers in C++ because C++ has -guess what- classes. Actual classes. I don't argue that. It's just that you took assembly as an example and I made a step further. It's not really relevant to the discussion. So you accept that if GM isn't limited, is not because you can use it to remake Bastion. Otherwise you'd be making no sense.
|
|
|
Logged
|
|
|
|
TheExDeus
|
|
Reply #19 Posted on: April 04, 2014, 02:13:34 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
I didn't say dynamic typing was bad. But don't you think it'd be good if you could specify something like "this function should always take one int" and then the compiler telling you if you ever call it wrongly? Don't you think that might help you find and squash some (potentially subtle) bugs? It might, but it would also mean I need to have several functions for several data types (or templates in C++). But if you use templates, then it wouldn't trow an error when you tried to pass one 'string' instead even though you only want it to take double, int, long etc. So saying "function takes one int" wouldn't make it necessarily better. You get some, you lose some. And so the way GM does it isn't a limitation.. it's just a different (I get a feeling I have to say it too much in this topic). Don't tell me GM objects are the same as classes. They're not. You can make them work as classes, sort of, but it's a pain in the ass. For what kind of things wouldn't it work correctly? There are subtle differences, but they are essentially classes. You have constructor, destructor, parenting, overloading (when using parenting), they have data in them, functions in them (thou in this case it would be "User defined event", as "functions" are "scripts" in GM and they are not tied to objects). The biggest difference really are that in C++ classes you have member functions, while in GM you cannot have them inside the object and you need to use "User defined event" to simulate them. That is actually a downside I think we should fix. Basically allow having script like resource inside the object. It would probably be creatable as a custom event (Robert you think it might be feasible?). You can make your own containers in C++ because C++ has -guess what- classes. Actual classes. If you used an object as the container, then it would be a lot more trivial to implement garbage collection. So you accept that if GM isn't limited, is not because you can use it to remake Bastion. Otherwise you'd be making no sense. Bastion was just the example. Because originally this wasn't about the specific of GML. It was the specifics of GM and how people create crappy games with it just because its "limited". I pointed out that it is not because GM is limited. It's because GM is just easy to use. To expand on my point about "limits" is the FPS creator Darkstart mentioned. There are also RPG creator and so on. THEY are limited. They are limited because they allow you to do make basically only 1 type of game. Even if they have some kind of scripting language (like RPG creator) even then ALL of the games made in it will look and play basically the same. And I just wanted to differentiate between GM (which doesn't have these limits) and these creators, which have.
|
|
|
Logged
|
|
|
|
Ideka
|
|
Reply #20 Posted on: April 04, 2014, 03:09:39 pm |
|
|
Joined: Apr 2011
Posts: 85
|
OK, here's why using objects as classes is a pain in the ass: 1) They are destroyed when you change the room by default. You have to make sure to set them all to persistent. PITAA (pain in the ass alert). 2) When set to persistent, they behave as if they were allocated with new/malloc, so you have to manually destroy them when you don't need them anymore. Otherwise you'd be leaking memory. Leaking memory in Game Maker. It's so ridiculous it even sounds funny. PITAA. 3) They have a bunch of variables by default that are probably useless to you but can't be disabled. Some of them you have to be careful not to use because they may have undesirable effects when modified (like hspeed affecting the x variable). PITAA. 4) You can't pass arguments to its "create" function. Instead you have to do some BS like: with (instance_create(0, 0, SomeObject)) { // (Don't forget the required x and y parameters that you probably don't need but have to specify anyway.) some_variable = 3; } And then if you actually want to use these values, you can't do it in the create event because it's executed before the content of the with. So you have to do some OTHER BS in step like: if (!variable_local_defined("recieved_parameters")) { do_something_with(some_variable); recieved_parameters = true; } And I'm actually not even sure if that works (and it definitely doesn't work in ENIGMA), I usually add this in create: alarm[0] = 1; And then in the alarm 0: do_something_with(some_variable); So yeah, you basically have to wait one fucking step for your "class" to be actually fully instantiated, not to mention take care of all of this boilerplate when creating a new "class". MPITAA (major pain in the ass alert). 5) No member functions. Sure, you can use scripts and call them like in C but... PITAA. 6) No multiple inheritance. Not really a PITA but a limitation nonetheless. Bastion was just the example. Because originally this wasn't about the specific of GML. It was the specifics of GM and how people create crappy games with it just because its "limited". I pointed out that it is not because GM is limited. It's because GM is just easy to use. I agree with that. I'm talking about a different kind of limitation here.
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #21 Posted on: April 04, 2014, 04:07:04 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Data structures are important, but Game Maker does offer a C-Like interface to them. Yes, it uglies up the code, but what HaRRi is arguing is that it isn't a limitation in the strictest sense.
I consider the missing structures to be GML's greatest downfall. With those, a user could work around GM's other major flaws, including my personal pet peeves: 1) The inability to name script parameters. This encourages documentation in the ugliest way possible, but otherwise damages code readability. 2) The unavailability of virtual methods in classes. Game Maker offers user events, but these also cannot be named, and there is a strict limit of 16. Emphasis: limit. 3) The lack of proper encapsulation. This only really aggravates me when creating a data structure gives you a sequential integer that must be freed when you are done. We can't do anything to make your life easier; we have all the same problems as C for new users. Close your files, or you'll run out of file handles. Delete your data structures, or you'll run out of memory. If we had data structures as objects, they'd be freed when they left scope. 4) The lack of a well-defined passing convention. Want to pass an array? Create a list structure, pass the ID. See problem list in (3). 5) The inability to hold non-integer objects, thereby constraining the number of object types you can offer–creating them is a pain in the ass.
If you don't miss structs, Harri, then my guess is that A* is the most complicated algorithm you've ever written in GML. Because if you had to store more than three values for any given node or grid cell, you'd quickly go insane. Three values in a grid requires three grids. N values in a grid requires N grids. Each value requires a call to ds_grid_*, which is bulky and ugly. Enter map. Now it's also slow.
If we wanted an iterator for them, we could have ds_map_iterator_*, so that you could construct iterators and work with them by integer. But now we need an array of iterators. What a joke. This puts burden on developers, so it doesn't happen, which puts burden on users, because now their code is slow because it's doing N log M operations for N variables in M objects. This is on top of the already obnoxious overhead for accessing a variable.
This also further exacerbates problem (3). Your iterators wouldn't have an owner, and so you'd need to explicitly denote you are finished with an iterator so the system can destruct it. Now your code is illegibly hideous; ISO C++ is officially prettier than your "high-level" GML.
The rate at which your code blows up is a good metric for whether there are limitations. A rope ladder leading to the moon does not, in itself, remove a limitation. Yes, you could climb to the moon, but the resources required would be insurmountable. Yes, you COULD write a compiler in GML. But I'd advise you to instead do something more fun and productive, like cutting off your limbs in one-inch increments. Even if you managed, it'd run like shit. Even if you compiled it with ENIGMA. Why? Because your code is bad. Even if you can't see it. Being low-level in nature (ie, being a pain in the ass to use), does not imply you will have faster code. Allocating and freeing iterators yourself through those functions would make the code slower, anyway, because now we need to dereference more than just the current frame to figure out where your iterator is to dereference it and figure out where your data is.
And that concludes my rant, for now.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #23 Posted on: April 04, 2014, 04:19:34 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
The things you are suggesting should be high-level would remove the "programming a game" aspect of programming a game. We could go the stencyl route and include be_a_green_koopa(), be_a_red_koopa(), be_a_block(), be_mario(), be_link(), and fly_around_in_circles(), and then, of course, include a UI to pick which of those you want to call as tiles. But I have this crawling feeling you'd quickly notice a shift in the sorts of games made in ENIGMA. Yes, they'd all behave well; yes, it'd be easy to develop games; and yes, we could easily predict all behavior for purposes of, eg, rewinding time. But somehow, I think interest in the project as a development platform would actually dwindle.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #25 Posted on: April 04, 2014, 05:05:06 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
I find Unity has too much emphasis on certain game features, too; the most obvious being that everything's 3D. In a game design class I took as an elective, other teams used Unity (my team was the only one that did not). We were the only team with a 2D menu, not because we did less work, but because making a 2D menu in Unity was more work for the other teams. Multiple groups mentioned this specifically. They might have just been dumb—one of those teams was trying to draw a targeting reticle as a 3D sprite and doing (lots of poor-quality) math to figure out how to make it appear the right size on screen.
But anyway, if you have a specific example that doesn't over-constrain the sort of games ENIGMA can make, I'm interested in hearing it.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #27 Posted on: April 04, 2014, 07:49:20 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Build mode, as in the context of the original ENIGMA build mode?
Behavior components are simple enough to add. But be careful how you refer to them. In EDL, we're dealing with two types of objects. The more obvious type is the "Objects" we inherit from GML, which all inherit from a base object that has eleventy godzillion locals, and is entirely event-driven.
For these, I was originally going to do so through multiple inheritance, but since everyone seems to like that ridiculous [snip=GML]event_inherited()[/snip] nonsense, doing so isn't straightforward. We can't really maintain a complete dichotomy between behaviors and object inheritance, because if two behaviors require an object to have mana, we want them to be able to pool mana, while if two behaviors require ammo, we want them to safely utilize separate ammo. If these behaviors were separate, an object would still need to have multiple parents in order to inherit these shared fields from multiple parents, anyway.
This does, of course, assume you would want to use behaviors for available weapons, which is fine by me as I am a fan of the concept of interfaces. It makes sense to do this, anyway, as you will want [snip=GML]with (obj_some_type)[/snip] to affect all objects inheriting behavior from obj_some_type, which makes much more sense of they're actually objects.
The second kind of object we work with is exclusive to EDL, and in fact, exclusive to the flavor of EDL for which I wrote the first half of a parser before my final year of college picked up. The new parser supports structures, which will support functions (I hadn't finished ENIGMA's function syntax before I got involved in the whole "Graduating" thing). These will support inheritance and virtual functions. While I had not considered it, ENIGMA already supports using C++ classes as Object components: It's how extensions currently work. It wouldn't be hard to allow doing the same with ENIGMA structures, if there'd be any point to it. For instance, if one of these were intimate with obj_mage, or whatever, it could be used as a magic weapon interface, and its children could be stored in an array of current weapons or assigned to different attack buttons. This would allow the child Object to have more control over how its behaviors are used, as well (the object has a weapon and assigns it to 'X' instead of inheriting a weapon that is fired with 'X'). As usual, it comes down to the "has a" vs "is a" problem, so offering both options would certainly help with that.
Now that I'm done ranting on that for the umpteenth time, I fail to see how that is a "high level" design concept, except by virtue of being higher than C. GM already has some high-level functionality. If you want a dumb-ass, dumpy, "high-level" approach to shit, use [snip=GML]my_object.behaviors += script_get_text(scr_my_behavior);[/snip]; then in the step event, [snip=GML]execute_string(behaviors);[/snip]. Done.
|
|
« Last Edit: April 04, 2014, 07:51:11 pm by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
TheExDeus
|
|
Reply #29 Posted on: April 05, 2014, 08:26:16 am |
|
|
Joined: Apr 2008
Posts: 1860
|
1) They are destroyed when you change the room by default. You have to make sure to set them all to persistent. PITAA (pain in the ass alert). 2) When set to persistent, they behave as if they were allocated with new/malloc, so you have to manually destroy them when you don't need them anymore. Otherwise you'd be leaking memory. Leaking memory in Game Maker. It's so ridiculous it even sounds funny. PITAA. So you are arguing that GM destroys objects and frees memory by default and when you don't want it to do so, then it doesn't? Because how and when do you think it should do so? Rooms are the biggest scope (besides global) GM has. If you want something to go out of Room, then it is the same as declaring everything in global scope in C++... it will never be deleted until the program ends. So I really don't see how this is a problem. Even if we implement structs or classes, they would still be inside objects. And that means you would have the same imaginary problem. 3) They have a bunch of variables by default that are probably useless to you but can't be disabled. Some of them you have to be careful not to use because they may have undesirable effects when modified (like hspeed affecting the x variable). PITAA. They wouldn't have any effects if you didn't use them. Like it doesn't matter what x/y position the object has or if its going left in 1000pixels/step. If you don't use them, it won't change anything. And the useless variables do take a bunch of bytes which otherwise could be free. I actually once (years ago) mentioned that to Josh and how we could make the default variables optional. Like maybe create a default variable manager in LGM and you could change for each object whether you want to use that variable or not. It should technically be possible to implement with just some #ifdef's in the code. There would be some problems when disabling x,y and then trying to draw default sprite. But that all of that could be checked in LGM's side. If you don't miss structs, Harri, then my guess is that A* is the most complicated algorithm you've ever written in GML. Because if you had to store more than three values for any given node or grid cell, you'd quickly go insane. Three values in a grid requires three grids. N values in a grid requires N grids. Each value requires a call to ds_grid_*, which is bulky and ugly. Enter map. Now it's also slow. Why do you need a grid for every value? I have implemented A* even in pure GML and I just did this: grid = ds_grid_create(500,500); for (i=0; i<ds_grid_width(grid); ++i){ for (c=0; c<ds_grid_height(grid); ++c){ ds_grid_set(grid,i,c,ds_grid_create(1,4)); } } And now every node has 4 values. I could change that 4 to 1000 and that node would have a 1000 values. This is how I made all my "widget classes" in GM and ENIGMA. I have, for example, "scr_init_buttons()" which creates the larger grid (size of 0 at start) holding all buttons (as it is local, then I can have different buttons for different objects) and then I have "scr_button_add(x,y,"Text",enabled,toggleable,...etc);" which resizes the grid to add a button and in the second dimension add all the values. And then in draw I have "scr_buttons_draw()" which also take care of all the logic. Usually I created a "scr_button_execute()" which had a "switch(name)" in it that would add behavior to a button when pressed, but I could also just add a script callback to the scr_button_add as in scr_button_add(x,y,"Text",scr_to_execute_when_pressed) and then use execute_script(). So I essentially made a struct with not only values (data), but also functions. And it didn't take much more time than it would take to make it with structs or classes (maybe even less). Technically I could ditch grids and just use 2D array for that and it would be a little faster. 4) The lack of a well-defined passing convention. Want to pass an array? Create a list structure, pass the ID. See problem list in (3). GM:S actually allows you to pass and return arrays from scripts. They even allow deleting arrays now, by just "= 0". So they have a way to differentiate. They even have it set up that the array is passed by reference if the array is not modified in the script, so it works a lot faster. Read more here: http://docs.yoyogames.com/source/dadiospice/002_reference/001_gml%20language%20overview/401_06_arrays.htmlThese functions also use arrays by reference: http://help.yoyogames.com/entries/28707818-Matrix-FunctionsI personally think there should be a method to implement everything you want from C++ in ENIGMA, because the only difference is that everything has an integer ID instead of an address and a pointer. So even things like out-of-scope automatic deleting should be possible. Also, would it be worse if we actually returned objects or pointers? Like if "grid = ds_grid_create(10,10);" returned an actual grid object instead of an integer ID? Couldn't we make it work with that and be transparent? Because the only time it would break something is if user actually tried to use an integer as ID, like "ds_grid_set(0,10,10,"Ass");", but that is almost never used and is a bad practice anyway. I do remember some codes from like 2005 where someone actually relied on everything being an integer and doing things like: grid = ds_grid_create(10,10); ds_grid_create(20,20); //This is grid2 but no way to access it ds_grid_set(grid+1,15,15,"ass"); //This actually accesses grid2 But as I said. No sane person should be doing this and it's not something we should necessarily support. I guess it was just way to save memory for a few variables (so variable grid2 isn't needed... yey a few bytes). I think if we started returning real objects, then 99% of the games and examples would still work. Also, the GM way of returning an integer is actually like returning a reference. Because "b = grid;" wouldn't ever copy a grid, it would give b the same grid and thus be faster. That is why passing everything by reference actually makes calling scripts faster than it would be otherwise. So yeah, you basically have to wait one fucking step for your "class" to be actually fully instantiated, not to mention take care of all of this boilerplate when creating a new "class". MPITAA (major pain in the ass alert). I used user defined events for that. You can call them instantly and don't have a 1 step delay. Unity just happens to have been built for 3D, and they only recently tacked on 2D. But that is actually my point. If rendering 2D sprite correctly required changes by Unity DEV's, then clearly something is very limited. GM and now ENIGMA on the other hand allows you to code whatever you want. And that sadly creates feature and performance problems. Like we could also add shit-ton-of-stuff that allows you to make really cool looking 3D games just like Unity or UE4, but then you wouldn't be able to make ray-tracer or robot planner. Just like you cannot really make anything like that in Unity or UE4. You must choose - limited to certain things (like 3D), but do it really good - or - unlimited, but slower and harder. And while GM leans towards the latter I personally think it's the only tool which at least made a partial merge between the two. Because 2D games ARE EASY in GM. Any 2D game ever. edit: Like would Unity or UE allow me make this: or or in the same tool with all projects taking from 100 to 1000 lines of code? Okay, the circuit drawer was several thousand, but that's mostly because the elements were hard coded and I didn't make an external format to load them. Otherwise it was also like 2-4k max. Also, I didn't add any 3D stuff because I just haven't made much 3D in GM. The reason I showed them was not to make a point about 2D or 3D capabilities, but just to show that all 3 of those examples are totally different in every way. One is a sound mixer, another a tool to draw circuits (both with latex style text syntax and output to .svg files) and the other is a planner for robots. They are not "3D FPS shooter", "3D 3rd person shooter", "3D side scrolling shooter" and so on which are basically everything you make when using ready made 3D engines. Like the circuit drawer would probably be impossible or at least very impractical even when using 2D engines.
|
|
« Last Edit: April 05, 2014, 08:50:32 am by TheExDeus »
|
Logged
|
|
|
|
|