Jump to content


Photo

Game Maker Suggestions


  • This topic is locked This topic is locked
1176 replies to this topic

#1 xot

xot

    GMC Dismember

  • GMC Member
  • 4772 posts
  • Version:GM:Studio

Posted 24 October 2010 - 12:03 AM

This topic is for suggesting practical changes to Game Maker to make it more useful. There was a previous version of this topic, but it had become out-of-date and too large for anyone to reasonably read before posting. The YoYoGames development team do pay attention to this topic. Please respect their time (and the time of the topic participants) by taking the following topic guidelines seriously.

DO NOT suggest the following

  • Compilation - Yes, we all know compiled executables are faster. So do those developing Game Maker.
  • Bug Fixes - These should be posted to the YoYoGames bug tracker.
  • Make GM/3D/multiplayer/etc faster, easier, better - These types of suggestions are too simplistic and are always under consideration.
  • Port GM to Linux/consoles/PDAs/Phones - YoYoGames has already made significant progress in this area and will continue to do so.
  • Make GM web playable - YoYoGames are well aware of the desire for Instant Play on other websites.
  • The Infeasible - These are suggestions that are incompatible with current Game Maker methods or demand a complete philosophical change.

When making suggestions

  • Articulate your suggestion clearly.
  • Justify your suggestion.
  • Describe the challenges it solves.
  • Focus on suggestions that add functionality or increase performance by taking common expensive GML tasks and creating a single compile speed function.

Previous Game Maker Suggestions

BBGaming and Rusky have very helpfully compiled an extensive, categorized list of many of the suggestions already discussed. Please read it and avoid repeating these suggestions. If you feel the need to reintroduce any of these topics, please carefully consider the merits of doing so.

Link: Previous Game Maker Suggestions List

Link: Previous Game Maker Suggestions Topic
  • 0

#2 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 24 October 2010 - 03:31 AM

1. The packager should actually do search for unused resources and ask the user if they should be excluded. Many games tend to have resources in GMKs that never make it into the game, there's no point in letting it sit there wasting space.

2. Lower the amount of times compressed data is compressed! It would improve load/save times of executables and GMKs. You really don't need to compress what was already compressed. Just compress all as a whole.

There wouldn't be many more suggestions since that large list covers most of what is needed. However, I remember a podcast with YYG had someone say compiling wouldn't result in a noticeable speed difference, this is not true. I'm not sure all of YYG thinks compiling games would be faster.
  • 0

#3 IceMetalPunk

IceMetalPunk

    InfiniteIMPerfection

  • GMC Member
  • 9328 posts
  • Version:Unknown

Posted 24 October 2010 - 07:33 AM

One that I know I've heard suggested but don't see on that list:

draw_me function or similar - This would be equivalent to draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha), but much smaller. It's a tiny inconvenience, I suppose, but it's a line of code that's used more than any other piece of code I've ever seen, so what's the harm in making it a built-in function?

And my own suggestions:

Make string-based functions binary-safe - Most GM functions consider NULL an "end-of-string" marker, but sometimes (particularly when dealing with binary files themselves) it's more appropriate to be able to store NULLs within a larger byte string. I suppose this could be done by messing with the data types internally a bit, prepending them with their lengths, so the functions know that there are more bytes after the NULL?

Switch default show_message/show_question/etc. dialog boxes to the default OS dialog boxes - It just looks more professional, and there's already an extension for it (at least for the Windows version). If this is implemented, then perhaps you could have analogues like show_message2 or something that would display the current style dialogs, for those who want them.

Allow us to get the position/length of a sound, and set the position - I'm surprised I didn't see this on the list, but if sound instances are added (which were on the list), a natural extension would be to allow us to get the length of a sound and get/set the position of a playing sound. We can do it with CD tracks, so why not sounds?

That's all for now; I may be back another time with more as I think of them :P .

-IMP ;) :)
  • 0

#4 sabriath

sabriath

    12013

  • GMC Member
  • 3187 posts

Posted 24 October 2010 - 09:42 AM

I just want to tag this, but I do have a suggestion that isn't in the list:

DLL Extension better linking/calling convention - Meaning, instead of the 4 argument limitation when dealing with 'char*', it should handle multiple (which can be done, and I showed assembly code how to do it). ALSO, GM should take responsibility for 'char*' memory returns. To be backward compatible, the 'dll_cdecl' and 'dll_stdcall' can have 2 more options of 'dll_cdecl_own' and 'dll_stdcall_own' (or similar) to tell the definition that GM is to free the 'char*' on return.
  • 0

#5 paul23

paul23

    GMC Member

  • Global Moderators
  • 3836 posts
  • Version:GM:Studio

Posted 24 October 2010 - 11:06 AM

One suggestion that was missed in the file:

arbitrary number of alarm events post

As for the NULL- end of string character.. - Well at the moment it indeed makes no sense (as GM-strings are based on delphi strings and store a length + data). However if GM's runner is being remade in C++ I expect the string-type to also behave like C-string (char *) - thus storing a null-character would be impossible.

Edited by paul23, 24 October 2010 - 11:11 AM.

  • 0

#6 ramses12

ramses12

    6

  • GMC Member
  • 5769 posts
  • Version:GM8.1

Posted 24 October 2010 - 01:55 PM

One thing I've actually heard before, but seems not to be listed (probably because it's just a tiny improvement):

Export script folders - When you use export all scripts, folders are missed. That sometimes makes scripts much harder to organise (especially when there are a lot of them), and it probably isn't a hard thing to do.

And here are some other (also tiny) suggestions, which I have never seen before:

Template files - Like in other several programs, there should be a feature which allows you to save a file as template, and then create from that template. A workaround is saving your "template" file and load it later, modifying it and saving as something different, but having a template mechanism would make this much easier. For some people (including myself), it is already a reflex to Ctrl+S from time to time, and save the work, but in this case, that would overwrite the template file, and thus the next time the template needs to be redone. Other than that, having a quick-access template menu would be much easier than searching the whole computer for some file.

draw_roundrect with selectable chanfer amount - draw_roundrect() draws a rectangle rounded about three pixels. It should be possible to specify the amount of pixels at which the rectangle is rounded. I guess that could be simply done with an extra argument to the function. It should make things easier, because drawing a rounded rectabgle with GML code is a quite hard thing to achieve.

file_bin_insert_byte and file_bin_delete_byte - The file_bin_write_byte() function, if applied in the middle of a bin file, simply overwrites the previously existing byte at the given position. To insert a byte or a byte sequence to the file, the whole file has to be rewritten. It would be helpful to have a function like file_bin_insert_byte(), and also a file_bin_delete_byte(), to do this.

Other than these, the list seems to be very neat. Good work BBGaming and Rusky!
  • 0

#7 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 24 October 2010 - 09:12 PM

As for the NULL- end of string character.. - Well at the moment it indeed makes no sense (as GM-strings are based on delphi strings and store a length + data). However if GM's runner is being remade in C++ I expect the string-type to also behave like C-string (char *) - thus storing a null-character would be impossible.

The functions that use strings treat them as null-terminated, but they are stored with a length. See IMP's post. The string functions have unexpected behavior with null characters.

As for the C++ uses C-strings statement, welcome std::string.
  • 0

#8 xot

xot

    GMC Dismember

  • GMC Member
  • 4772 posts
  • Version:GM:Studio

Posted 24 October 2010 - 09:18 PM

draw_roundrect with selectable chanfer amount ... because drawing a rounded rectabgle with GML code is a quite hard thing to achieve.

It's really not that difficult but a better built-in function is in order.

file_bin_insert_byte and file_bin_delete_byte ... the whole file has to be rewritten.

The whole file would still need to be rewritten if using a built-in functions. I think a far better solution is faster buffered file operations so that doing it with GML wouldn't be such a burden. If I need to insert or delete 100 bytes in a large file, doing it byte-by-byte and rewriting the file 100 times makes no sense. Faster file operations for Game Maker are something Mike Dailly addressed recently.
  • 0

#9 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8173 posts
  • Version:GM:Studio

Posted 25 October 2010 - 02:12 PM

Support for some tracked music format (MOD or XM):
Tracked music formats (composed via for instance MilkyTracker or MODPlug Tracker) are a classic type of sound files: they contain a 'note sheet' as well as the sounds of the 'instruments'. They've been used since the Amiga days, and they're still used in many games (even though they get used more and more scarcely now when file size is not as great of a restriction as they were in the 16-bit days). MIDIs actually use the same concept, but with the instrument sounds being stored in the actual computer rather than in the file. While this in theory makes files smaller, it do also make the music sound a lot different - sometimes unbearable - on some computers, depending on what music set it has installed.

A built-in support for a common tracked format (it is quite easy to convert them forth and back between the tracked formats as many trackers supports all the common formats) would be a very useful extension to the current support of MIDI: the 'actual change' would be that you could include instrument sound data in your sound files; and you would be able to compose music that takes up less bytes per seconds than even OGG Vorbis manages!

Even having just the basic features - creating sound resources of the tracked type, play, stop, loop, isplaying functions - would make Game Maker a better tool to make musically pleasant games with, as the versatility of music handling would virtually skyrocket - tracked formats can make anything between chiptunes and orchestrated pieces sound equally nice, while MIDI has its crippled sound database, MP3 and OGG has their sizes, and WAV is just plain bad to use for music.

As well, I figure it would not require a whole lot of work (compared to many of the other possible suggestions) to implement an internal MOD or XM player, due to the rather basic and straightforward nature of the files (sheet music | sound clips).
  • 0

#10 Rusky

Rusky

    GMC Member

  • GMC Member
  • 2492 posts

Posted 25 October 2010 - 06:29 PM

2. Lower the amount of times compressed data is compressed! It would improve load/save times of executables and GMKs. You really don't need to compress what was already compressed. Just compress all as a whole.

Make string-based functions binary-safe - Most GM functions consider NULL an "end-of-string" marker, but sometimes (particularly when dealing with binary files themselves) it's more appropriate to be able to store NULLs within a larger byte string. I suppose this could be done by messing with the data types internally a bit, prepending them with their lengths, so the functions know that there are more bytes after the NULL?

Switch default show_message/show_question/etc. dialog boxes to the default OS dialog boxes - It just looks more professional, and there's already an extension for it (at least for the Windows version). If this is implemented, then perhaps you could have analogues like show_message2 or something that would display the current style dialogs, for those who want them.

Allow us to get the position/length of a sound, and set the position - I'm surprised I didn't see this on the list, but if sound instances are added (which were on the list), a natural extension would be to allow us to get the length of a sound and get/set the position of a playing sound. We can do it with CD tracks, so why not sounds?

DLL Extension better linking/calling convention - Meaning, instead of the 4 argument limitation when dealing with 'char*', it should handle multiple (which can be done, and I showed assembly code how to do it). ALSO, GM should take responsibility for 'char*' memory returns. To be backward compatible, the 'dll_cdecl' and 'dll_stdcall' can have 2 more options of 'dll_cdecl_own' and 'dll_stdcall_own' (or similar) to tell the definition that GM is to free the 'char*' on return.

draw_roundrect with selectable chanfer amount - draw_roundrect() draws a rectangle rounded about three pixels. It should be possible to specify the amount of pixels at which the rectangle is rounded. I guess that could be simply done with an extra argument to the function. It should make things easier, because drawing a rounded rectabgle with GML code is a quite hard thing to achieve.

I've added these suggestions to the list. However, redundant compression is solved by splitting up gmk's, and I'm not sure how possible it would be for GM to free returned strings, since the DLL could allocate the string however it wants. Maybe if there were a better-defined interface between the two, which would be required for DLL access to game resources, things would be more clear.

draw_me function or similar - This would be equivalent to draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha), but much smaller. It's a tiny inconvenience, I suppose, but it's a line of code that's used more than any other piece of code I've ever seen, so what's the harm in making it a built-in function?

I'm not quite sure this is a good idea to add to the list- it's trivially added in a script, which could be in an extension or imported from a text file.

arbitrary number of alarm events post

Support for some tracked music format (MOD or XM)

These suggestions are already on the list.

One thing I've actually heard before, but seems not to be listed (probably because it's just a tiny improvement):

Export script folders - When you use export all scripts, folders are missed. That sometimes makes scripts much harder to organise (especially when there are a lot of them), and it probably isn't a hard thing to do.

And here are some other (also tiny) suggestions, which I have never seen before:

Template files - Like in other several programs, there should be a feature which allows you to save a file as template, and then create from that template. A workaround is saving your "template" file and load it later, modifying it and saving as something different, but having a template mechanism would make this much easier. For some people (including myself), it is already a reflex to Ctrl+S from time to time, and save the work, but in this case, that would overwrite the template file, and thus the next time the template needs to be redone. Other than that, having a quick-access template menu would be much easier than searching the whole computer for some file.

I tried to avoid redundant or trivial suggestions - exporting scripts to a gmres file preserves the directory structure and copying templates rather than using save as avoids that issue.
  • 0

#11 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 25 October 2010 - 07:28 PM

sabriath would like GM to force people to use heap-allocated strings, along with forcing DLL programmers to make their own copies of data if needed since sabriath would like GM to free the memory. It's a pretty silly idea that would not fit well with GM, and not every case. You don't want to be allocating and freeing memory a lot.
  • 0

#12 sabriath

sabriath

    12013

  • GMC Member
  • 3187 posts

Posted 25 October 2010 - 09:43 PM

sabriath would like GM to force people to use heap-allocated strings, along with forcing DLL programmers to make their own copies of data if needed since sabriath would like GM to free the memory. It's a pretty silly idea that would not fit well with GM, and not every case. You don't want to be allocating and freeing memory a lot.

You misread.....yet again. GM does not use by-reference, and I merely wish that it would preserve the pointer to pass back to the DLL for cleaning. And I'm not going to even bother arguing with you over the "force people to use heap-allocated strings" part, it makes me laugh.
  • 0

#13 Rusky

Rusky

    GMC Member

  • GMC Member
  • 2492 posts

Posted 26 October 2010 - 03:19 AM

No need to get defensive. Passing the string back to the DLL is a rather involved and specific mechanism - like I said, it would be better to first work out memory management in general for any kind of value passed between the DLL and game, because the solution would likely be both more general and more well thought-out.
  • 0

#14 Revel

Revel

    ɹǝqɯǝɯ ɔɯƃ

  • GMC Member
  • 4923 posts
  • Version:GM8

Posted 26 October 2010 - 05:52 AM

If your so worried about allocating on the heap and freeing it, just use a second call to the DLL to free memory.

Something like the following
#include <stack>

std::stack<char*> allocationStack;

char* allocBlock(int size)
{//Allocate some stuff on the heap..
	char* newAllocation = new char[size];
	allocationStack.push(newAllocation); //Store pointer on stack..
	return newAllocation;
}

void memFree()
{//Free the last allocated block on our little "stack"
	if (!allocationStack.empty())
	{//Make sure stack isn't empty. If stack is empty you have done something horribly wrong anyway.
		delete allocationStack.top();
		allocationStack.pop();
	}
}

Edited by Revel, 26 October 2010 - 06:04 AM.

  • 0

#15 sabriath

sabriath

    12013

  • GMC Member
  • 3187 posts

Posted 26 October 2010 - 08:37 AM

@Revel: That was my point....when you return a 'char*' pointer back to GM, before YOUR code even is allowed to see it, GM has already copied the data into a NEW area of memory and trashed the pointer. Maybe I should have just suggested by-reference variables instead...even though that has already been suggested? At least then, your code in GM would be able to call another function to clean up the pointer.
  • 0

#16 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 26 October 2010 - 12:09 PM

@Revel: That was my point....when you return a 'char*' pointer back to GM, before YOUR code even is allowed to see it, GM has already copied the data into a NEW area of memory and trashed the pointer.

GMAPI? If you would like access to the data still, then that is already on the list. If not, the copy is fine.
  • 0

#17 sabriath

sabriath

    12013

  • GMC Member
  • 3187 posts

Posted 26 October 2010 - 12:53 PM

GMAPI?

Oh, you're right, I'm sorry....because I thought this was the topic for suggestions. Instead, I must have stumbled onto the "what DLLs would best suit the needs of ___put idea here___". My idea for GM to not throw pointers away haphazardly is obviously countered by GMAPI dll...awesome!

Why even have a topic for suggestions if someone can make a DLL to add it in...right?


Yaaaaaaayyyy workarounds.
  • 0

#18 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 26 October 2010 - 07:59 PM

Actually, you're throwing the pointer away if you expect GM to deal with it. GMAPI gives C++ DLLs access to lots of GM's internals, it doesn't "fix" your issue.

A solution similar to GMAPI is already in the suggestions, maybe you should figure out what it does. Besides, I happen to be against the use of DLLs to fix what YYG failed to provide. Your idea is just stupid, your pointer, deal with it. It's faster the way GM does it.
  • 0

#19 sabriath

sabriath

    12013

  • GMC Member
  • 3187 posts

Posted 26 October 2010 - 09:33 PM

Your idea is just stupid, your pointer, deal with it. It's faster the way GM does it.

The idea of GM using by-reference passing? Meaning no need to memcpy data? Yeah, because that's so much faster, my idea definitely is stupid.
  • 0

#20 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 26 October 2010 - 10:02 PM

Posted Image
Not speed-wise. Think about it.

It's also a Delphi thing, they aren't reconstructing the string each time. Maybe when GM9 comes YYG will take control over your pointers like you'd like. I'm looking forward to the day when returning a pointer means I have to make myself a copy since GM needs it.
  • 0

#21 sabriath

sabriath

    12013

  • GMC Member
  • 3187 posts

Posted 26 October 2010 - 10:33 PM

It's also a Delphi thing, they aren't reconstructing the string each time. Maybe when GM9 comes YYG will take control over your pointers like you'd like. I'm looking forward to the day when returning a pointer means I have to make myself a copy since GM needs it.

Wow, you really are lost aren't you? It is not only speed efficient, it is memory efficient. This is what GM does:

//str = external_call(ec); where ec is an external_define returning a 'char*'

char* (*ftn)(void) = external_defines->item[ec];
if(ftn == NULL)
  report("Error with the 'ec' not being a properly defined item");
char* ret = (*ftn)();
int retlen = strlen(ret);

string* rtn = new string();
rtn->expand(retlen);
memcpy(rtn->data, ret, retlen);

return rtn;                    //at which point 'ret' is lost

This is what I propose GM to do:

//str = external_call(ec);

char* (*ftn)(void) = external_defines->item[ec];
if(ftn == NULL)
  report("Error with the 'ec' not being a properly defined item");
char* ret = (*ftn)();
int retlen = strlen(ret);

string* rtn = new string();
rtn->size = retlen;
rtn->data = ret;

return rtn;      //which contains 'ret' so it is not lost

But then I proposed by-reference, which would be like this:

//str = external_call(ec);

string* arg0 = strings->item[argument0];
if(arg0 == NULL)
  report("Error with the 'argument0' not being a string");

double (*ftn)(string*) = external_defines->item[ec];
if(ftn == NULL)
  report("Error with the 'ec' not being a properly defined item");

return (*ftn)(arg0);

This would force DLL writers to need to know the "string" structure, which can easily be made and distributed with GM-Pro. Although this 'might' make it more strict, at least there would efficiency and proper communication between GM and links.

Although the above is pseudo-C and doesn't allow multiple arguments, it was only an example. I don't have time right now to show the assembly of what I really want to implement, which allows ANY argument types and return ANY argument type without limitation (including by-reference)...and yes, it can be done without bloating the runner.
  • 1

#22 paul23

paul23

    GMC Member

  • Global Moderators
  • 3836 posts
  • Version:GM:Studio

Posted 26 October 2010 - 11:09 PM

The problem with passing-by-pointer is: "who is the owner? of the data?" - Gamemaker or your dll?

Really I think memory management should stay outside of the scope of the GML: while it might sound great I believe it will cause more troubles than it is worth.
  • 0

#23 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 26 October 2010 - 11:54 PM

This would force DLL writers to need to know the "string" structure, which can easily be made and distributed with GM-Pro. Although this 'might' make it more strict, at least there would efficiency and proper communication between GM and links.

I've already said it, GMAPI, it's already on the list, so quit whining.

Now, I just remembered this suggestion I forgot a while ago, code completion for scripts. I checked the list of current suggestions, but I don't know if better code completion would include this.
  • 0

#24 Rusky

Rusky

    GMC Member

  • GMC Member
  • 2492 posts

Posted 27 October 2010 - 01:13 AM

This would force DLL writers to need to know the "string" structure, which can easily be made and distributed with GM-Pro. Although this 'might' make it more strict, at least there would efficiency and proper communication between GM and links.

For the third time, sabriath:

Maybe if there were a better-defined interface between [GM and DLLs], which would be required for DLL access to game resources, things would be more clear.


@TheMagicNumber: Scripts would need a formal parameter list for that to work, which I believe is already supported in extensions. The list includes "argument number-checked scripts," but I could also add argument names for intellisense if that's what you're asking for. However, it might be better to include it in some kind of extension/editor unification section- does anyone have any other ideas for how that might be accomplished before I add it?
  • 0

#25 ADHDguitar

ADHDguitar

    GMC Member

  • New Member
  • 79 posts

Posted 27 October 2010 - 01:38 AM

I'd like to see a cube root function. I'd articulate further but this one's pretty obvious.
  • 0

#26 BBGaming

BBGaming

    Programmer

  • GMC Member
  • 2470 posts
  • Version:GM7

Posted 27 October 2010 - 01:48 AM

I'd like to see a cube root function. I'd articulate further but this one's pretty obvious.

Not that this is an impossible idea, but you can do any root using the power function: power(x,1/n) is the nth root of x.

That and the fact that cube root is virtually useless when it comes to game math.
  • 0

#27 ADHDguitar

ADHDguitar

    GMC Member

  • New Member
  • 79 posts

Posted 27 October 2010 - 03:12 AM


I'd like to see a cube root function. I'd articulate further but this one's pretty obvious.

Not that this is an impossible idea, but you can do any root using the power function: power(x,1/n) is the nth root of x.

That and the fact that cube root is virtually useless when it comes to game math.

You'd think I would have thought of that having taken Pre-Calculus, but.... Thanks! :lol:
  • 0

#28 TheMagicNumber

TheMagicNumber

    GMC Member

  • GMC Member
  • 5247 posts
  • Version:Unknown

Posted 27 October 2010 - 07:39 PM

@TheMagicNumber: Scripts would need a formal parameter list for that to work, which I believe is already supported in extensions. The list includes "argument number-checked scripts," but I could also add argument names for intellisense if that's what you're asking for. However, it might be better to include it in some kind of extension/editor unification section- does anyone have any other ideas for how that might be accomplished before I add it?

Yes, extensions have the option for this. Scripts don't, unless scripts are going to be removed (I doubt it), they should be supported. It sucks having to open the script when GM tells you it's parameters are "...".
  • 0

#29 xot

xot

    GMC Dismember

  • GMC Member
  • 4772 posts
  • Version:GM:Studio

Posted 29 October 2010 - 12:28 PM

I suggested named script arguments during the GM8 beta but it was shot down.

Even though it is possible it would complicate the interface. Also it is against the design of GML in which functions do not have named arguments. (I know that this is a weakness of GML but it was done this way to make things easy for beginners. We might at some moment give GML an update but not in this version of Game Maker.


  • 0

#30 paul23

paul23

    GMC Member

  • Global Moderators
  • 3836 posts
  • Version:GM:Studio

Posted 29 October 2010 - 02:23 PM

I suggested named script arguments during the GM8 beta but it was shot down.

Even though it is possible it would complicate the interface. Also it is against the design of GML in which functions do not have named arguments. (I know that this is a weakness of GML but it was done this way to make things easy for beginners. We might at some moment give GML an update but not in this version of Game Maker.

Thus actually a good candidate to (keep) it on the suggestion list!

I saw that arguments indeed.. Made me REALLY wonder how named arguments would complicate thigns for beginners.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users