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

Issues Help Desk / Re: gamepad
« on: April 30, 2016, 05:51:04 PM »
Can you show us the code you are using to load the joystick? There are some caveats to it which I'm having trouble remembering at the moment.

Issues Help Desk / Re: LGM Stops Working When Using Build Menu Items
« on: April 17, 2016, 05:28:36 PM »
He should always have permissions to his own home folder.

Make sure the directory ~/.enigma exists, and make sure you're the owner (running tools as root leads to folders being created as the root user, meaning you might not own them).

Issues Help Desk / Re: READ BEFORE POSTING: Help Request Guidelines
« on: April 17, 2016, 02:28:56 PM »
Hey guys, I've had some requests to add a guideline.

It would be helpful if people could start marking solved issues by adding "[Solved]" to their post titles. Preferably at the beginning. It makes it easier to tell who still needs help, so those willing to contribute time to solving people's issues aren't wasting any of it reading old, solved topics. Doing this helps everyone.


General ENIGMA / Re: Pure ENIGMA
« on: March 28, 2016, 09:57:14 PM »
You'll always want the parser to handle locals; it's just too much boilerplate, otherwise. You'll find there's a tradeoff between how pretty the code looks, and how pretty the object declarations look. I'm afraid you can't have both.

I'd recommend creating a sort of vtable class containing references to locals for each object.

In my plans for the newer ENIGMA, I described using instance_t to refer to instances, instead of int. This would allow you to swap out the typedef to int for something better—or possibly just a wrapper class around it.

Code: (C++) [Select]
struct instance_t {
  object_locals *ref;
  enigma_vtable *vtable;
  instance_t(int compatibility_id): instance_t(
      (object_locals*) fetch_instance_by_int(compatibility_id)) {}
  instance_t(object_locals *direct_ref):
      ref(direct_ref), vtable(ref->get_vtable()) {}
  enigma_vtable* operator->() { return vtable; }

If you set your vtable up correctly, access would then look something like inst.ref->*inst->x.

I've pasted a quick proof of concept.

You can squeeze a little more pretty out, if you really need, by creating convenience functions in instance_t or some derivative thereof, of the calibur int &one() { return ref->*vtable->one; }. Makes life just a little more complicated, as this means you can't declare instance_t using partial types (currently, only the implementation of the constructor actually depends on anything concrete, and that dependency is easily moved and/or eliminated).

Unfortunately, that's genuinely the best I can give you. You still have to parse the code for local variable declarations, or else write a whole lot of boilerplate. Or, I guess, just a little boilerplate, so you have a separate list of locals. Still, ew.

General ENIGMA / Re: Pure ENIGMA
« on: March 27, 2016, 02:00:56 PM »
I like the idea, and encourage you to go for it. Macros in C++ can do a lot of what the parser does, if you keep your code syntactically correct. It's a bit ugly to do that, but that's what it takes, sometimes.

Please don't get me wrong—I also see ENIGMA as a diamond in the rough. But I believe a huge contributing factor to that was the IDE. However, even implementing a GM-like engine for single applications in other languages led to simpler, more beautiful code for me, in the past, so there is probably something to the idea of trying for a pure-code implementation.

I'm sorry if I give the impression of not caring about the project. While you have been looking at the engine and seeing the potential for what it could be without Game Maker holding it back, I have been looking at the frontend and imagining what it could be. I think you'll find that in both cases, offering about 85% feature parity is trivial, and as you hinted, that's all ENIGMA has really ever done.

So, by all means, keep us posted. Know that on the IRC, ideas are constantly being kicked around for what an IDE should look like. Robert's off to college, and other maintainers are getting on with their lives. It might surprise you to learn that Quadduc is actually hanging around the IRC, though he doesn't say much. Sad thing is, I think others (particularly Robert) are waiting for me to make a move, and I'm waiting for confidence that I'm not going to blow it. As my life at work continues to solidify into something that I don't have the power, and therefore the need, to influence, I am beginning to invest more and more time into thinking this through.

I'm going to go ahead on a bit of a rant, because I find it therapeutic. You can probably stop reading here.

I recognize that I am making a classic mistake of overthinking actions before taking them. As a kid, I didn't have this problem. Not to take credit for the countless hours of hard work you've put into this project in the last eight years, but my childlike belief that just slapping code down would make everything work is a huge  part of why this project exists right now. And as I work close to other engineers who don't commit anything without PRDs and design docs and tests and all this other administrative minutia that I'd have gawked at as a child, and as Rusky occasionally bombards newcomers with articles from others like us who have discovered how easy it is to point out design practices that are not correct, I continue to think about the ones that are. I guess at this stage in my life, ENIGMA as it stands today is the answer to "What would happen if I just cowboy-coded everything?" ...and I remain unconvinced that it can ever be the best answer. Or even close to it. I'm not looking for mathematical perfection; I'm looking to remove all these little gotchas and bugs.

When I was younger, I always felt like this was all fine, because the things that suck can just be recoded. But I recoded that damn compiler, what, four times since I was 15? Each time I came into it knowing five times as much as I did the last time, easily. Hell, the first time I wrote a GML→C++ parser, it was in GML. I knew hardly any C++ at the time; I was fourteen. Talk about bootstrapping.

But now that I'm a full-time employee, working for a company that maintains projects dozens of times larger than ENIGMA, and am surrounded by people who all share the same fears that started forming in my mind when I was 20, I'm seeing the costs that came about every time I recoded the parser. Each new version did a dozen things better, and exhibited a half a dozen regressions. Did you know that the second time I recoded it, I forgot to add comments until I tested it out on a full-blown game?

You might be thinking, why not just recode pieces of it? In general, that's a better idea, but all of these pieces have a fundamental dependency in them that is not easily upheld: JDI. We'll get back to that in a bit.

After all, I'm smarter now; I feel as if I'm a hundred times better at coding than I ever was when I was working on ENIGMA. As a consequence, the compiler seems daunting to me—not because it's so much code, or a hard problem, but because it does so many weird, little things to get everything right, and then it still doesn't get everything right. It never has; it's always been some weird maximization problem that I never fully established had a solution. Because as a kid, I didn't plan the whole project out; I just built the pieces of it, and they indeed fit together into something that looked like what I set out to build. It wasn't just "build a compiled Game Maker." It never was. That's an easy project; it'd take me a few weeks to do that. It was "build something that looks like Game Maker, but compiles to C++ and is really fast." I could even do that much now, with a few executive decisions that would just be made. But then, look at "really fast." What does that even mean?

I know you were able to get your tool to run really fast in ENIGMA, but ENIGMA is a game engine. Part of making ENIGMA really fast is handling things like sprite batching (which Robert implemented something like) and spacial partitioning for collisions (an idea that as a kid, I could never work out). Even now, I don't have a great answer for how to do it seamlessly—without the user having to manage it—in a way that's actually efficient. Does GM even do that? For fuck's sake, Dr. Overmars was teaching a class on collision handling. That was his thing! Yet he designed GM to use an x variable and a y variable. Now I have to update the quad tree twice every time you move the object yourself! It's that kind of little shit that bugs me about this whole operation. How do I design around that? Do I choose to just not care? Kid me wouldn't have thought about it for more than ten minutes, I suspect, as much as kid me loved efficiency. But then, kid me wasn't so great at that, anyway.

I made a lot of weird decisions as a kid. Did you know the first local variable access code literally copied all the variables out into temporary storage so they could be accessed generically? The entire instance was copied somewhere every time you needed to access some_obj.x. This only existed for a few weeks, before I coded the current implementation, but even now, I'm not sure that the current implementation is the best way. Look how fast some of these new scripts are, using lookup tables for their variables. That would have made things easier.

Not to mention the decisions I made involved maintaining a C++ parser for ENIGMA's purposes. If anything is going to show you how dangerous an idea that is, it should be C++11, which JDI still doesn't support. As much as I think LibTooling is a fucking cow, it would have been worth using just to narrow the scope of the project. These words are bitter and they hurt me as I type them; it's such a vapid, meaningless statement, until you realize just how much work actually goes into maintaining all these little-shit dependencies. You just have to accept you can't have a non-bloaty ENIGMA compiler while still supporting the ever-changing C++ specification in the background.

It's 2016, now, and LibTooling still isn't where I needed it to be as a kid. My argument for keeping my C++ compiler (JDI) around was that it not only granted us the definitions we needed from the engine, but a lot of the logic needed in parsing C++ was also intrinsic to EDL. Consider overload resolution: ENIGMA has really poor overload handling, and for a while, I expected JDI to be the cure for that. It was unfortunate coincidence that I finished JDI just as C++11 was coming out; if I had known all the new features of C++11, and baked them into JDI, we might be having a very different conversation right now. But then, if I'd known those features, maybe that'd leave me where I am today, and I wouldn't have written JDI at all, for an understanding that maintaining two compilers just isn't a good idea—even if they're compiling virtually the same language.

Perhaps instead, I'd have modified LibClang to add support for with(). I'm not sure; I was an industrious kid. It still wouldn't have bought me out of the quad tree problem, but it would have at least spared you the problems you've been having.

The one philosophy I had as a child that I will always keep with me is that when you design something, you need to take a step back, stop thinking in terms of the tools you have, and start thinking about the best possible way to say something. Thinking outside the box, as it were. I remember designing ENIGMA's show_menu functions in GTK. I'm still a little proud of them, even though they're a little backward. It doesn't meet every use case, but it meets a few of them superbly. And even now, at this huge company I work for, that's exactly what the engineers around me seem to be trying to realize.

So I'm looking at the big picture—bigger than I ever looked as a child—to find what I really believe is the best way, end to end, to make a damn game. And if I find it, you can bet your ass that I'll be back.

That's enough rant. The point is, I don't have all the answers, anymore. In truth, I never did; I was just happy to keep working without a plan, and that's changed for various reasons, but possibly not right reasons. Some soul searching is still in order, I suspect. I can't make you any commitments, other than that I'll be around.

General ENIGMA / Re: ENIGMA progress 28.01.2016
« on: January 29, 2016, 06:17:03 PM »
I love CSG. Why isn't this topic in Announcements?

That 3D work is very impressive, and truly fascinating.

As for replacing EDL: you'd have a much better time of that if you could declare local variables somewhere specific in LGM.

Programming Help / Re: Getting the parent id
« on: December 21, 2015, 12:56:44 PM »
I'm not sure it doesn't work, but I suppose you'd have to hard-code it, if that's the case. Not ideal, but...

Issues Help Desk / Re: Extension .egm does not match EGM?
« on: November 15, 2015, 06:41:28 PM »
If you're interested in XML, you may as well use it for everything. And for that price, you may as well use GMX. My understanding is that the two aren't very disparate.
Of course, LateralGM still (and presumably always) sucks at working with both of those formats, so it's not as though binary room data is our only fish to fry.

General ENIGMA / Re: Splashscreens
« on: November 07, 2015, 10:41:00 PM »
My favorites are your first and thirteenth, Harri's, and your very latest.

Personally, I get enough of Material at work. It's not that it's a bad design concept—it just gets old, and it's pretty much Google's thing. That said, if construction paper's just your thing, here's a quick version with that:

So Robert's first remark was that the version I linked isn't saturated enough. So I doctored the construction paper scans:

I believe it's time to invest in replacing LGM. LateralGM follows the three-tier architecture, which is different from what Robert has linked but which does mean that there should, theoretically, never be a reason to replace it. As code from any layer becomes obsolete, it can be replaced as needed to keep current. However, due to some neglect, and some happenstance, all three tiers are obsolete.
  • The presentation tier is obsolete. Swing is a lousy framework with long-lived problems that developers refuse to correct. The inability to support mouse horizontal scroll is an example. Not to mention, people prefer native widgets. This isn't entirely out of the question in Java. Either way, this tier should be scrapped.
  • The logic tier is mostly solid, but makes fundamental assumptions of how the data tier interacts with data. Specifically, it assumes that passing all resources to the data tier will accomplish the task of writing out a game file. It offers no way of detecting whether a resource has actually been modified, and changing this is a TON of work. I think Robert once tried to invest this work, but I'm not sure if he ever got anywhere. By a "ton of work," I mean enough that recoding this tier correctly, from scratch, is not out of the question, even if we stuck with LGM. Game load times are similarly affected; the load mechanism requests that all resources are loaded up front, which includes massive MP3 files and long animations. If meshes were to be supported, they would also have to be loaded up front. This is a huge problem for LGM's progress into serious game development.
  • The data tier makes, of course, the same assumption. It serializes all data at once, doing no change detection, which means that saving a GMX/EGM document takes the same amount of time as saving the equivalent GMD/GM6/GMK/GM81. Actually, it takes longer on Windows due to filesystem overhead. Saving a document with only one changed resource should take virtually no time for GMX/EGM, and the entire game time for GMD/6/K/8/81. The same problem applies to game load. For later, I'll mention that five different people, Robert included, have already ported all relevant pieces of this tier to other languages.
  • All three tiers are written in Java. A lot of users have issue with Java, and 75% of our incoming tracker tickets are from people using the wrong JVM architecture on Windows.
With respect, I believe that people who choose the second option do so from a usability standpoint, unaware that their few problems with the IDE require an entire recode, in Java or in any language.

I forward that since a huge recode, even if not a complete recode, is required for the further progress of the LGM project, this recode should be done in a framework that does not tow the JVM behind it, and preferably one which uses native widgets. Sound (cogent) logic—and there's a lot of it; I know because I wrote some of it—should be preserved or ported, and the rest is being scrapped, anyway.

Works in Progress / Re: Flappy Wheels
« on: September 27, 2015, 08:30:27 AM »
Sounds like a board permissions issue. I've scrubbed board settings.

Developing ENIGMA / Re: Migrate Releases
« on: September 05, 2015, 07:44:36 PM »
There's hardly a more descriptive change title than "Hacks in a fix for multidimensional array subscripts. Fixes #904." The Git spirit is small commits with simple change descriptions. Coming from Subversion initially, I prefer larger commits with more detailed messages, to which git is also conducive. The list you gave essentially embodies the spirit of source control.

Google does not use git itself. Google3 is a completely linear, monolitchic codebase. It is not possible to commit code to Google3 that does not build, unless you issue commands to bypass the mechanisms in place. If you do that, you had better know what you are doing.

Anyway, it's clear to me that you know what these commit messages should look like. You may find tags or merge commits helpful. That is, do your work in your own branches with lax commit messages, and then either flatten them for commit to enigma-dev/master, or merge them and specify a useful commit message. You might consider annotating these with some kind of searchable token so that you can create changelogs between versions automatically. Following this, even if you were not careful to annotate all merges to master, you could still crawl all commits for useful changelog points. This could be as simple as putting Changelog point: before each line in a commit description that actually contains noteworthy text.

Just some ideas.

Developing ENIGMA / Re: Migrate Releases
« on: September 04, 2015, 10:38:09 PM »
It's true that I never tagged a release as r4. Things kept changing—more than anything, my expectations. You could number from there, or you could just call it V1. Or V1 RC1 and have fifty of those before you just call it V1. It's up to you. I prefer rolling releases. The way version control is supposed to work is that master is supposed to be stable at all times; ready for a nightly build whenever. You then have multiple work branches that might not build, or might not work. This never really came to be in ENIGMA... my attempts to introduce it ended badly.

GitHub can tag releases for you, yes.

For a long time, the "Developer" tag was just a repaint of "Administrator," but I eventually fixed that (they're regular SMF membergroups, now, and I hard-coded tags for them). I wasn't very diligent with updating assignments, though. Of course, Harri is a privileged member—just not an administrator. This is mostly because the admin panel is duct-taped together, and it's very easy to break something in it, so I tend to stay out of it myself and don't see a reason to give anyone else access. But yes, I only fixed his "Developer" badge a few months ago. In my defense, there were political reasons that had nothing to do with my own feelings which prevented this change in the earlier stages of the board.

General ENIGMA / Re: Joshedit
« on: August 26, 2015, 09:24:55 PM »
They are the only things I need. But I think I would try implementing all of that differently. Was there a reason you didn't want to do all of that with classes? Like one class per object. Then object.somevar would literally be correct C++ syntax to getting and setting a variable. The only reason it wouldn't work now is because you can assign a variable at any point (even inside a with(){} statement which cannot be determined at compile time). So what I suggest is making "local somevar" declaration mandatory. This would allow creating a list of variable in the class. Actually you could still use a map inside the class for variables that are undeterminable at compile time (like it is done now). Int to instance conversion could also still be possible.
GM's overall design is not conducive to that. It's similar to something that would be conducive to that, but it's not immediately conducive to that. Take instance_nearest, for example. The correct GM syntax is instance_nearest(x, y, obj_target), where obj_target is the integer ID of your target object, or any other identifying integer in GM (namely the any constant, but it's technically valid to pass noone or an instance ID, which guarantees that the given ID is returned). The return type is also integer.

What you would want in a better language is something more like instance_nearest<obj_target>(x, y). To contrast,
Code: (C++) [Select]
// Current prototype; gives no useful information
int instance_nearest(double x, double y, int object);

// New prototype to support the above proposal
template<typename object> object& instance_nearest(double x, double y);
any& instance_nearest(double x, double y);

This code assumes the existence of a type called any which represents the highest object tier (object_locals). Using instance_nearest<any>(x,y), you can still implement RTTI (probably in the form of just accessing object_index) to ascertain the type of the returned object and correctly cast to it, but otherwise, no casting is necessary. Without totally redoing all of ENIGMA's instance functions in this manner, however, your code would have to look up the object and cast it every time before you can access nearest.somevar at all. This will bloat your code, look hideous, and be a general pain in the ass to write and maintain.

Quote from: TheExDeus
I can be less dirty, but I don't think it needs a billion features. Just make it load and compile egm. Compilation is done trough makefile flags anyway. The only thing CLI actually does is it parses EDL and then adds resources to the compiled exe.
Not so much about it being dirty as it is about making it long lasting, etc. Josh's library has something to do with parsing command line flags, you should ask him about it.
I would hope the CLI has more options than that, but yes; at its most basic, the point of the CLI is just to build a GMK/GMX/EGM, and that can probably be accomplished by verifying argc==2 and taking argv[1]. Odds are, though, you want to support things like --syntax-check myfile.edl or --attach-resources resource_directory ouput.exe. The library I wrote that Robert is talking about is called DeepFlags, not GFlags. You might be interested in either project, though.

A few other things to address.

(1) Robert also wanted me to mention the language I'm designing in my spare time. I haven't put any code down that is specific to it, and even if I had, I'm not sure that it immediately offers a solution to this problem, but I'll go so far as to say that providing a means by which you can address the instance_nearest problem described here and the choose problem described elsewhere (and elegantly address the problems we've already solved, such as script_execute) is a lot of the motivation behind the language's design—not out of regard for Game Maker/ENIGMA, but in response to places where C++ has limited our ability to do this naturally. I'm happy to talk about features of this language; I occasionally do on IRC.

(2) I'm still and always very interested in IDE development, though I'm not, as I've told Robert a couple times over the last two weeks, presently "in the mood" to write an IDE. I believe that the IDE is ENIGMA/Game Maker's number-one asset. It's far more valuable than the language to the success of these two projects. I don't think a CLI is a replacement for a proper IDE. The room editor is indescribably important, and the Overworld resource I described would make a huge difference, as well. I'm also interested in numerous other editors. I'd like to try my hand at a FSA editor, for instance. Happy to talk more about this, as well.

(3) According to Robert, you're under the impression that I want some graph bullshit instead of coding. No; that would be insane. There is no "instead of coding." Coding is what makes things happen. But coding is everywhere: Every toolkit has coding. What makes Game Maker cool? You don't have to write code to place objects in a room. You just place objects in a room, visually. That's what made GM stand out. More editors have surfaced that do that, of course, so it seems less unique; less important. I'm arguing that it's still the most important part. Offering a way to construct a FSM to handle, say, animation or AI for an NPC, is another way to remove some boilerplate and code complexity. Like, how much of your code is if (current_state == running) { sprite_index = spr_player_running; do_run_behavior(); }? Wouldn't your life be improved if you just had a "running" behavior you could edit, and a FSM entity that governs transitions sprites and the trivial bits of the transition logic for you? The Overworld resource I mention from time to time is another critical asset. Another great asset would be a way to visually account for game unlockables. Think of stars and star coins in the Mario series. Wouldn't it be nice to see a list of which levels contain those? Where they're placed? Wouldn't it be nice if the code to organize that was all generated for you transparently? This is what I'm talking about.

Anyway, I think that's what needs said, for now.