ENIGMA Development Environment
Website is in read-only mode due to a recent attack.

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

Announcements / Christmas Plans
« on: December 24, 2012, 08:27:54 AM »
First off, Merry Christmas to all of you. Hope you are enjoying some time off for the holidays.

The parser is behaving to expectation, which is great, considering I told you all that it would do everything short of walk on water. However, there are still two problems I see in ENIGMA that I fear will go uncorrected until they bite someone in the ass; I am going to address both of them and one personal problem here.

If you are a developer, try to pay a little attention. At least to the first two.

Problem 1: The extension system is subtly broken.
I don't know if anyone noticed this (I think HaRRi has stumbled upon it?), but the extension system is not as modular as it was designed to be due to issues with uninformed sideways casting. The compiler handles all the casting; the linker is not involved. Thus, extensions think they are the only class that enigma::object_locals inherits virtually. Issue is, they are not. Thus, since alarms are first alphabetically, they're the only extension which will work.

Contrary to popular belief, extensions were designed to facilitate adding "heavy" functions as opposed to "groups of two or more" functions. By "heavy," I mean functions that have weighty dependency that might drive someone who is interested in disk and memory efficiency to drop us a complaint about it. Maybe someone doesn't need a 16 integer array in each object (talking of alarms). Maybe it really bothers someone that their objects all need a path_index variable, as well as position and time variables for their path. The point is, extensions make it so they can remove the entire system from their game, including the local variables that weigh down their objects.

To clarify, the issue is simply that when they need alarms and paths, both extensions assume that their bytes are the first in the structure, and one of them must logically be wrong. The fix is simply to do the casting from within the engine file (which is informed as to what each extension looks like and which extensions are being included). The detriment? We have data misread and life is hard.

Presently, you access the current instance (ENIGMA's equivalent of this) using a global. There are actually a few problems with doing this:
  • Casting that global to a virtual ancestor doesn't always work (as discussed above)
  • Only one object can be this per running game per femtosecond
  • All code has to be aware of any access boundaries associated with having only one object being this at a time
By the last one, I mean loops such as with() need to be extremely cautious about the length of time for which they change the current instance pointer. So far, this has only really entailed being careful to set it back at the end of the loop. It also, again, destroys any hope for threading anything to do with instances.

The solution: I am turning the instance addressing system on its ear.
The solution is actually pretty simple. We dump the globals that represent the current instances/iterators (namely, ENIGMA_global_instance and instance_event_iterator) and we replace them with a parameter given to ENIGMA functions which modify the current instance.

So basically, instead of this function:
Code: (C++) [Select]
void motion_set(int dir, double newspeed)
    enigma::object_graphics* const inst = ((enigma::object_graphics*)enigma::instance_event_iterator->inst);

We have this function:
Code: (C++) [Select]
void motion_set(enigma::object_graphics* enigma_this, int dir, double newspeed)

So, not a huge difference, but enough that it will mean some chaos.

If you are worried about the parameter, don't be. That's where the new parser comes in. I have not added this yet, as the pretty printer is not written. I want everyone on board with this idea before I ship it.

This idea has been up on the proposals board for some time; we're just finally to a point where I think I'll have the free time to deal with it. I will put everything up in the ENIGMA-JDI branch before I begin the migration. I'll make a new newspost to let you know the time has come to tackle it and do regression testing, when I'm ready for the change myself.

Again, the benefits are a fixed extension system, the option of threading, and a more stable instance addressing system.

As for the central iterator list (the list of active iterators to be conscious of when deleting shit), I am still happy with it. Though I may refactor it slightly to maintain links in the list correctly instead of moving deleted iterators back (in case an iterator is reused which is expecting one type of object and instead finds another type by mistake). For now, it should be fine.

Problem 2: The Platform-Graphics bridge is ill-conceived and horrible.
The engine directory structure gives the impression that you can use OpenGL or DirectX as your library on Windows. Presently, this isn't the case, as both systems require the window to be initialized in a special way. You may be familiar with WGL and GLX; they are, respectively, the Windows GL interface and the GL-X11 interface. Code for these monsters is found right in the Platforms folder—So far we've avoided possible issues using preprocessors, but these hurt compile time and are in general unattractive.

It's been a clusterfuck so far, because we're dealing with three entities in the Platforms folder instead of one:
  • Platform-dependent code for all manner of things, including grabbing executable name and working with directories
  • Window system code; the code that creates and manipulates windows
  • Platform-specific Graphics code, eg, WGL/GLX

It's messy to separate those three items, which is why we have issues.

Solution: Create a new folder of bridge systems.
I don't care where in SHELL this folder is created, but it needs to contain folders such as Win32-OpenGL, Win32-DirectX, X11-OpenGL, etc, for each valid pairing of Window System - Graphics System.

We may also want to separate out the window system code and put it with the widget system code. This is leading to minor technicalities on Linux: The window is governed by raw X11, while the widgets are governed by GTK+. It hasn't led to any problems, but it has the potential to do so—especially on pairings in the future (eg, if some poor bastard tries to write QT widgets).

Since much of the code in the Win32/ folder was written by me when I was 16, it may be a good idea to comb over it again, anyway. If this can serve as an excuse to do so, go ahead and let it.

Personal Problem: I return to school after two weeks.
I have 14 days of freedom before I return to school, and I already need to start making preparations for that. Depending on how I tackle this semester, it may be even more work than the last. The good news? Two things: (1) the course which will generate the most work? It's on game design. That's right, the thing we've all been doing since we were 12. (2) I am taking five courses instead of six, and one of them is philosophy. For those of you who have not taken a college philosophy course, they are an easy, effortless, and even fun A if you have an open mind and don't mind some discussion.

The bad news: The game I design has to use Ogre (or Unity or XNA—Not even considering the latter, not wanting the former since I use Linux), which I have never used before.

The other good news: I intend to deal with this gracefully by writing an Ogre extension for ENIGMA. If I have to deal with Ogre, this project may as well benefit from it.

Now you are all up to speed. In summary, brace for impact.

General ENIGMA / Re: EGMJS
« on: December 18, 2012, 12:51:41 PM »
Sounds great. As I see it, this is what you'll have to do:

1) Create methods in C++ to populate a JDI context with function and variable definitions. You'll have, for instance, a define_global(string name), and a define_function(string name, something).  I can write these for you, if you need.

2) Create Java methods which call the C++ methods. Basically, just wrappers through JNA, like we do for everything else that goes on between ENIGMA and LateralGM.

3) Create JavaScript functions through Rhino which call the JNA wrapper functions. So the JavaScript function def_function() calls the Java function DefineFunction, which uses JNA to call the C++ method define_function(). Just for example.

4) Using Rhino and JavaScript reflection, call the JavaScript functions for each member. As I left the system, each function contained a variable representing its minimum and maximum number of parameters.

Depending on if you want to support overloading, they may need to contain more information than that. It's that information which ultimately determines the other parameters to define_function(). JDI supports storing any type of function C++ supports; it's up to you how many to simulate in the JavaScript engine. It may be that all define_function() needs is name, parameter names, and minimum/maximum parameter counts (for variadic functions, the maximum would be -1).

« on: December 14, 2012, 01:57:26 PM »
TGMG's interested in maintaining the EGMJS port I started a while back, and doing that under the new parser will be pretty easy, imo.

This topic is to try to make it even easier for him.

I will record general notes to all implementers on the Wiki. Notes specifically concerning my thoughts on the implementation of EGMJS will go in this topic.

My first concern is on how TGMG will load definitions. Presently, ENIGMA uses a central JDI context to store its definitions. Since JDI is inherently a C++ parser, this is done by invoking it on the engine file directly. JDI is not a JavaScript parser. However, JDI's structure is easy to figure out, and JavaScript is capable of reflection. The way I see it, there are three ways you can go about this:

1) Choose the language that is going to host the crawler.
This can be Java using javax.script.ScriptEngine (javax.script.ScriptEngineManager.getEngineByName("JavaScript")), or in C++ using Google V8. Both methods have their advantages:
  • If you use Java's ScriptEngine class, no additional libraries need included or set up. Java's also pretty good about doing the integration for you, and building V8 for Windows is an impossible task (it requires MSVC++). The difficulty is that you have to get this information back to ENIGMA, and it adds ENIGMA.jar as a dependency to the process (meaning a CLI build without Java will be completely impossible).
  • If you use Google V8, everything can be done from within C++; you can use JavaScript reflection to call native methods directly. The C++ methods can populate JDI structures in memory while the JavaScript engine is doing the iteration. This is bound to be more efficient, as Java does not guarantee its scripting engines are even compiled, to my knowledge.

The bottom line is, by this method, you need to use JavaScript reflection to communicate a list of available functions to ENIGMA so the parser can do syntax checking.

The other method that I can see you using is having emscripten parse the JavaScript engine, and then polling it for definition names to pack into JDI classes. This method has similar advantages. On the downside, it means that EGMJS is dependent on LLVM—that's a heavy dependency that I'm in general not fond of. On the other hand, it means that you'll be asking LLVM for the definitions and (probably) using LLVM to store the code so emscripten can compile the code, which would open doors for ENIGMA to compile to other languages for which LLVM has pretty-printers. It might also introduce some issues in the translation, but from what I can tell, as long as you keep within a relatively decent-sized subset of LLVM instructions, you should avoid such issues.

I see a great amount of merit in each option, so I do not care which method you choose. If you go with the V8/ScriptEngine method, I will be happy to have a two-megabyte JavaScript export extension. If you go with emscripten, I will be happy to have LLVM as an abstraction layer. Let me know what you're thinking, though.

Announcements / Re: JDI ↔ Parser: Code formatting, completion
« on: December 11, 2012, 10:22:53 PM »
Then that's the plan.

Announcements / Re: JDI ↔ Parser: Code formatting, completion
« on: December 11, 2012, 12:53:43 PM »
Yes, I can. It'll be a bigger pain later, but only slightly.

Announcements / JDI ↔ Parser: Code formatting, completion
« on: December 11, 2012, 11:39:46 AM »
Tomorrow I take the last of my finals, and so by tomorrow evening I should, finally, be free to work on ENIGMA again. Forthevin has been doing a great job of adding things left and right, but I don't expect him (much less anyone else) to be able to help much with the parser. Especially if I haven't laid out any plans for it publicly.

I was looking at what I have done and what I need to do with it, when I noticed that one of the smaller bullet points for the parser—the ability to automatically format code neatly—is not presently possible for two simple reasons: comments and preprocessors.

Until those can be resolved, the parser will be incapable of correctly formatting code without dropping comments and potentially preprocessing away some code. The solution is simple, but it involves me editing JDI some more, which probably isn't what anyone wants to hear.

So let me present another benefit that can come from having JDI sew comments and preprocessor blocks into returned tokens: Javadoc-esque code completion.

If JDI reads comments in, ENIGMA or LGM can parse out formal comments like Javadoc and Doxygen do. Basically, we could use Doxygen to describe the purpose of GM functions in-line. When the user selects the function in the code completion menu, we could display information about each parameter and what exactly the function does, instead of just the names of the function and its parameters.

Another option is to have some duplicate code and let ENIGMA parse its own expressions independent of JDI. There is no other benefit to doing this, as JDI can handle any unary prefix, unary postfix, binary, or ternary operator already, including GML's ^^ and <> operators.

Or, I can just belay the code formatting idea all together and get the parser working how it does now.

It's up to you people, but try to decide before tomorrow when I actually have time to do some real coding.

Off-Topic / Re: Introductions
« on: December 08, 2012, 11:01:40 AM »
Welcome aboard!

We're doing our best to make ENIGMA's flavor of GML into a serious language, because most of us here feel the same way. The idea is to give the language features of C/C++ while preserving features of GML and sprinkling in some features of JavaScript and Python.

Examples are always welcome; if something in particular is preventing them from working, feel free to post a topic and I or another developer will probably help make the needed corrections to ENIGMA.


Proposals / Re: Automatic updating for particle systems
« on: December 06, 2012, 07:59:18 PM »
All right, I'll see about adding a "mode: static" setting that just puts a piece of code or function call in the event function instead of the loop. Do we want to keep "instead" for it, or just make it "code:" or something? I'm happy with leaving it "instead: ", but I'm open to input on the matter.

Proposals / Re: Automatic updating for particle systems
« on: December 06, 2012, 02:45:24 PM »
@polygone: And Ism ignored the suggestion, and I didn't push the issue. Now we have two update hacks in that file, and as ENIGMA grows, we're bound to have more legitimate events as well. Having instances use different files is by far more work for Ism in the UI than it is for me.

@forthevin: The built-in sprites sound to me like the kinds of things that can be generated with simple math functions, which beats the shit out of any compression format we'd use.

And yes. It inserts the global updater itself. Polygone hacked in the local updater the same way you did.

Also, forthevin: Are you sure you need that "default" code? Does it just not insert the event without it?

Proposals / Re: Automatic updating for particle systems
« on: December 06, 2012, 02:24:18 PM »

Point is, it needs restructuring so IDs don't need supplied. And while we're at it, we may as well make LGM use the file, too.

General ENIGMA / Re: Gamasutra article on GameMaker's recent DRM problems
« on: December 06, 2012, 01:48:22 PM »
Indeed; we've been laughing about that on the IRC for a few days now. People bitch about GPL's quirks, but it'll be a cold day in hell before a FOSS project pulls something like that.

The funniest part is that the crack, I'm told, does not exhibit that problem. They've succeeded only in hurting their user base. Fortunately for them, lawsuit likelihood is a function of age, income, and IQ—their user base in general tends to minimize one of these.

Proposals / Re: Automatic updating for particle systems
« on: December 06, 2012, 01:40:00 PM »
If particles were the only systems requiring such an event, I'd probably go with the hack, but since they certainly are not, it's definitely better to do something else about them. Polygone already hacked up events.res to update some globals in a weird spot ages ago, and I haven't gotten around to dealing with that yet, either. So for now, go ahead and push your changes to master and the issue can stew for a while until I have time to do something about it.

I'd kind of like to reformat events.res into basic e-Yaml anyway, so LGM can read it. Otherwise we can't add new events in one spot later on. This might be a good place to talk about what that system should look like.

General ENIGMA / Re: Hi. I'm MahFreenAmeh
« on: December 06, 2012, 10:29:20 AM »
Yeah, and a2h disappeared.

It's okay, though; I made changes to the structure of the site so plugging in his changes should be a snap.

The code that does the background effects, the header, and the footer now appears only once on this server in one PHP file. Even the nnosnese board uses that same header and fucks it up locally (that was a2h's doing).

General ENIGMA / Re: Hi. I'm MahFreenAmeh
« on: December 05, 2012, 11:32:11 PM »
Today I broke everything.


Announcements / Re: Thanksgiving Holiday Updates
« on: December 05, 2012, 10:59:46 AM »
I was thinking we'd make a good Red Ribbon Army.

Then I thought better of it.