Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Josh @ Dreamland

Proposals / Compile Scripts
« on: July 16, 2013, 07:42:59 am »
A lot of what other toolkits have going for them is the capability of reflection. RTTI is useful; ENIGMA already has it to some extent by virtue of having object_index. While further reflection is, to some extent, planned, I do not want it to be a heavy emphasis in the engine.

I notice that a lot of what people try to do with reflection should have been done by their environment at compile time. Like listing classes that have <x>, or do <y>. The compiler does shitloads of this while compiling games; without proper compile-time reflection, there would be no way to translate EDL to C++. The issue is, the compiler's behavior is really static, and the compiler is the only entity with this capability.

Thus, I'm considering a mechanism I'm calling compile scripts. In this context, they are scripts of EDL run by the compiler which offer full reflection of all game entities. Scripts, objects, rooms, paths, timelines... If it's in the game, you can iterate it with the compiler. Having this mechanism would allow users to define functions which would otherwise require runtime reflection, but generally should not. Game Maker, for the part, provides a lot of functions to offer reflection in a somewhat efficient manner. For example, sprite_get_name(). What it lacks is a sprite_get_first() and sprite_get_next(). I am not proposing we add those directly. While they might be convenient for some games, they just waste space in others. I'm proposing a system that would allow users to define them.

Code: (EDL) [Select]
global map item_sprites = [];
foreach (sprites as sprite) {
  if ("spr_item_")) {

Coupled with JDI, EDL's AST incorporates everything that is required to interpret that code, except the string and map object representations, which should be easy. Meanwhile, behind the scenes,

Code: (C++) [Select]
  jdi::value cs_map_define(cs_map* cs_this, jdi::AST_Node_Parameters *anp, jdi::error_handler *herr) {
    if (anp.params.length() != 2)
      return (herr->error("Expected two parameters to map::define"), value());
    cs_this->definitions.push_back(value_pair(anp->params[0].eval(), anp->params[1].eval()));
  compile_scripts::objects["map"].functions["define"] = cs_map_define;

The above code is approximate, as it doesn't bail on the first error, and assumes that cs_this can be cs_map rather than a generic cs_object.

In other words, the define() operation only adds a key to be defined to some vector in the map object; the actual work is done elsewhere.
  • At syntax check time, it is up to ENIGMA to define that item_sprites is a global variable, if it is intended to be used in user code. If it is only intended to be used in library code, eg, in our definitions resource, we leave it out of our syntax checking definitions. I think this would be the preferable behavior.
  • At compile time, the cs_map object is asked to generate code to ensure that the item_sprites object is what the library implementer thinks it is.

So, in the C++ module, the map object does this:

Code: (C++) [Select]
  string obj_map_cpp::get_code() {
    string res;
    for (value_pair_vector::iterator it = definitions.begin(); it != definitions.end(); ++it)
      res += "    item_sprites[" + it->second->first.toString() + "] = " + it->second->second.toString() + ";\n";
    return res;

In the javascript model, it does this:
Code: (C++) [Select]
  string obj_map_cpp::get_code() {
    string res = "    item_sprites = {\n";
    for (value_pair_vector::iterator it = definitions.begin(); it != definitions.end(); ++it)
      res += "      \"" + it->second->first.toString() + "\" : " + it->second->second.toString() + ",\n";
    return res + "    }\n";

Optimizations will be made in the C++ version to ensure that all keys have the same type (all VT_INTEGER or VT_DOUBLE, or all VT_STRING), and the correct jdi::value cast will be used. This is because all keys are string in JavaScript, and the benefit of ensured compatibility outweighs the benefit of letting users mix types in a map. Use two maps.

That said, to implement such a compiler extension, the user will give something similar to the pseudo-EDL above, coupled with a regular Definitions resource which can use its results. The pseudo-EDL is the compile script, and is interpreted by the compiler. The Definitions resource is a script which defines functions run during the game.

Speaking of the Definitions resource: I want Definitions to allow scripting in each native language, as well as in EDL. It is looking as though EDL could easily be made to compile to any of the even vaguely planned backend languages, some of which might lead to it being a popular prototyping language outside the game design space. EDL could be a "write-once, compile in any of the languages that claim to be write-once, compile anywhere" language, which would make it even more useful to the sort of people who use GML for quick prototyping.

So, an example Definitions resource to go with the above psuedo-code would be this:

Code: (C++) [Select]
int item_get_sprite(string itemname) {
  return item_sprite[itemname];

This allows the other EDL code in the game to be oblivious to the existence of that map. Equivalently, this should be able to be accomplished using the new EDL spec, still in progress, simply by adding the word "function" to the beginning.

The purpose of this topic is not for more stargazing, but rather for everyone else to present capabilities they think will be needed by these scripts. If you have an idea, shoot.

Issues Help Desk / Re: missing surface functions?
« on: July 14, 2013, 05:55:44 am »
Those functions should all exist. Are they throwing a syntax error? Or just not working? Some cards (pre-1990 NVidia cards, pre-2005 ATI cards, modern Intel cards) don't support GL FrameBuffer Objects. That could cause them not to work correctly, but not throw a syntax error. If you have a syntax error, it means someone deleted them.

Also, which graphics system are you using? You might try switching to OpenGL3 under the APIs tab in Enigma Settings. If that works, let me know so I can kill Robert.

General ENIGMA / Re: Cross Compiling
« on: July 13, 2013, 07:03:11 pm »
If your current machine is 32-bit, then any version of MinGW64 will come with all the correct settings and libraries to build for 32-bit. You should be all set.

Robert: My plan for ENIGMA is "build anywhere, run wherever you build." The best I intend to offer is a distribution mechanism which builds your game for each platform, for you.

Issues Help Desk / Re: audio_play_music() making game crash!
« on: July 13, 2013, 06:59:50 pm »
ENIGMA can load MP3's fine. Which audio system do you have set, lolman? It'll be under Enigma Settings, in the APIs tab.

Issues Help Desk / Re: Wait until an instance is destroyed
« on: July 12, 2013, 10:11:13 am »
The idea is to have functions such as instance_set_thread(), to move an instance to a different thread (instance_deactivate moves it to the dead thread), and script_thread(), to run a piece of code in a brand new thread.

The latter is already implemented on ENIGMA for Linux, but it's useless unless you know how to use it. If you call it on a script that modifies instances using the ENIGMA library functions, you'll more than likely get an access violation due to the problem mentioned earlier. So it really only works with completely isolated functions.

Issues Help Desk / Re: Wait until an instance is destroyed
« on: July 12, 2013, 06:37:58 am »
Well, in a room, don't we have objects running in parallel (in the step event) ?  Also when i call the instance_create to start the animation, it's like an asynchronous call.

Unfortunately, no; in a typical game, contention would foreseeably bring the entire engine to its knees. Functions like background_delete are a nightmare. At present, the engine isn't even set up for threading because seemingly harmless functions such as motion_add() require knowledge of who the current instance is, and because of instance_destroy(), that object may not have a linked iterator to it, anymore. ENIGMA solves the former by giving access to the currently active event iterator to all functions, and the latter by forcing iterators to register themselves so that in the event their data is unlinked, their iterator's next pointer can be updated.

The first of those solutions is hostile to threading; having only one iterator for the current instance means that threads can't have unique instances. The new compiler uses a replacement mechanism which also fixes another problem in the engine. Basically, in the new compiler, I have stapled on a mechanism similar to the extension mechanism in C#: any object which needs to know the current instance must take object_class *ENIGMA_this as a first parameter, where object_class is any tier or extension component to which a cast may be required of the current instance.

Because this is done compiler side, the pretty printer is the only device which needs to be concerned with it. These functions will be passed the correct cast of the correct current instance pointer regardless of thread, with() statement, or what have you.

The other problem that fixes is the extension system, which you may recall from the other issue you posted here. The path_start() function doesn't work because it has no idea how to cast from enigma::object_basic to HaRRi's object_path, since the cast is virtual. This new mechanism allows the compiler to deal with that in each object.

I.e, this is why the new compiler is so important.

General ENIGMA / Re: Cross Compiling
« on: July 11, 2013, 08:15:42 pm »
MinGW64 should offer an -m32 flag like the rest of the GNU compilers. But you'll need the 32-bit libraries, and I'm not sure if they're included. Obtaining 32-bit native libraries is a chore; obtaining cross-compiler libraries is a huge chore; I can't imagine obtaining the 32-bit cross-compiler libraries. Good luck. ;)

Issues Help Desk / Re: "Having a Turd" on OS X
« on: July 10, 2013, 05:21:37 pm »
Two ≠ several.

General ENIGMA / Re: Cross Compiling
« on: July 08, 2013, 06:05:51 pm »
Sorry; for some reason, I missed your question.

That package installs fine here, though I am on 13.04. Make sure you're on a 64-bit system, and have Universe enabled as a package source.

If you find a different cross-compiler package, that's fine, as long as the binary names are the same or you update them in the configuration file (Compilers/Linux/MinGW*.ey).

General ENIGMA / Re: Overuse of the CPU ?
« on: July 05, 2013, 03:18:40 pm »
I just couldn't believe that Sleep() implementation is so stupid. Operating systems are supposed to love Sleep, because they can all but completely ignore a sleeping thread until its condition is met. Does Notepad use 13% CPU on your machine? :P

General ENIGMA / Re: Overuse of the CPU ?
« on: July 04, 2013, 05:43:22 pm »
It uses 13% CPU at 1 FPS?

Proposals / Re: Adding a 'Donate' button
« on: July 03, 2013, 03:36:44 pm »
There are concerns with fairness, among other reasons.

ENIGMA is, at this point, a long-standing project which is quite unlikely to die. But it has serious issues with usability. A recent example of what I do not want this project to be is the Parakeet IDE that took the GMC by storm. We are, in many ways, the opposite of that project.

Parakeet is a proprietary IDE maintained by a small team of developers "contracted" by one GMC user. It is ostensibly vaporware; a download is available with limited features which was last updated May 2. If I had to guess, I'd say the project is dead. Before it died, though, it collected several hundreds of dollars from naïve twelve-year-olds loose with their parents' money. This is more than the net cost of running ENIGMA, and more than ENIGMA has ever drawn in, eg, via the ads on the home page.

I do not want ENIGMA to be that. What we have right now is basically solid, but it's missing the degree of polish that justifies selling a program. I don't want to personally accept donations until I feel that the project has reached a point where, were it not designed to be completely free, we could sell it. I understand that you, and many others, are old enough and responsible enough to choose whom and which projects you would like to donate to. I respect that, and appreciate the sentiment.

But when a project has a donate button, it seems to imply that donations will in some way help the development, and people feel obligated, however slightly, to consider donating. Tossing money at ENIGMA will not help its development. Donations to the project should all be in your spirit of, "I see the work you have done, and I appreciate it; this is a token of that appreciation" rather than the Parakeet "WOW THE CONCEPT OF THIS IS PRETTY COOL AND IF YOU ACTUALLY MADE IT DO THE THINGS YOU SAY IT WILL IT'D TOTALLY BE WORTH THIS MONEY BUT ANYWAY HERE TAKE MY MONEY."

So basically, I want donations to be reactive, not proactive, first and foremost. Moreover, looking over my work in the project, I do not personally consider it to be worth accepting donations as of now. When the project inevitably reaches a point where that opinion changes, there arises the question of who gets the money. Do we split it evenly amongst all developers? Well, if we did that, it likely wouldn't cover ENIGMA's (relatively small) running costs. If the developers instead trusted me to be fair in deducting those costs first, then dividing up the remainder, we have a new problem: not all of our contributors generate the same amount of code, or put the same amount of work into the project. The proportion of work to code varies, too. Then on top of that, the quality varies. It wouldn't be hard for me to generate a hierarchy of contributors I would pay the most were doing so in my power, but in a transparent, donation-based environment, there could be hurt feelings.

What's more, imposing incentives for work in the field of computer science never ends well, period. Most lines of code? Enjoy 10,000 shitty lines of code to do the work of 300 clever lines. Most functions? Well, we have enough problems with function specialization and verbosity as it stands. In the case of donations, this wouldn't be about the money so much as about sheer competition. A developer's code style should not be influenced by any metric, save maintainability. which is itself not quantifiable.

We could allow you to contribute to each member based on your own judgment, which solves the bulk of the political issues. As it stands, though, none of the developers have requested that, so I assume they feel roughly the same way as I do about accepting donations at this phase of the project. This also makes it into a popularity contest; you might be inclined to donate to me, simply because I founded the project, despite the fact that I'm in third or fourth place by my own ranking system. You might also not be as inclined to donate to forthevin, simply because he is one of our less social developers, despite the surprisingly large number of nice things I have to say about him and his work on the project. Robert, on the other hand, is often the first on the scene with a response to a question, be it a useful one or a decorated shitpost.

I suppose my point here is that it is hard to maintain a fair and positive donation environment in a completely free project with multiple significant contributors.

In summary, this is what we don't want:
  • Hurt feelings
  • Donations from over-optimistic children (or adults) in the false hope that they will catalyze the completion of the project
  • Unfairness based on a lack of an objective and uncontested ranking system of merit to the project
  • Popularity contests and code-metric pissing contests, which only serve to hurt feelings and the project

SHUPAER123'S HOME / Re: I like to sux off Robert
« on: July 03, 2013, 03:15:31 pm »
So this is topic 1337.

Issues Help Desk / Re: Compiling
« on: July 02, 2013, 12:01:37 pm »
As far as I know, compile works except on Windows, wherein you have to add ".exe" to the filenames because three years later, LGM still doesn't do that.

Cross-compiling is constantly changing; I can't guarantee it works, at all. It'll probably never work on Windows.
What we might do is look into having a server build games for other platforms for you.

Issues Help Desk / Re: Problems Compiling NaturalGM
« on: July 01, 2013, 07:29:36 am »
Hah; that's technically more up-to-date; he's going back over his existing code. Apparently he didn't commit anything past the tree.

As I understand it, he's presently on a mandatory vacation with his family. He'll be back before the end of the month.