Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Quasar

ACS availability increased

Recommended Posts

Gez said:

The following recipe should work, I think:
Note 4: I don't think Eternity actually implements the ACS namespace (since it's something originally invented by ZDoom for its script libraries). This is merely a convenience thing as it allows SLADE to automatically perform the export-text-lump,-compile-import-bytecode-lump rigamarole, so it's handy. But since EE will look in the global namespace, it's important that the text lumps come first so what it sees during its backward search is the compiled lumps.

I can add this; the technical argument for it is compelling enough.

Share this post


Link to post

So, you can ACS in EE now? Finally, a scripting language to use. Is this going to be permanent, or a make-do until the next thing comes along..?

Share this post


Link to post

It's to be permanently supported, given that it's required for Hexen. The hope is for it to be eventually supplemented with a more powerful scripting language, but not replaced.

Share this post


Link to post

Very glad to hear it. Always felt the lack of a scripting language really held Eternity back, in terms of being accepted more widely by the modding community.

Share this post


Link to post

In fact all ACS functions will be available in Aeon (regardless of what it ends up being based on) courtesy of an ACS interpreter object that will be visible there. So those people looking to transition from ACS will have a compatibility layer inside Aeon to fall back on to accomplish things they don't feel like doing in a more flexible but probably necessarily more complicated manner.

Share this post


Link to post
Quasar said:

I can add this; the technical argument for it is compelling enough.

I think it'd be a good idea. Not hard to implement and no apparent drawback.

Share this post


Link to post
Quasar said:

I could see ZDoom going that route with Doomscript because it's a bespoke compiler that they have complete control over. I doubt we'd be trying to do that with Aeon, which could possibly end up being based on TraceMonkey or JaegerMonkey at this point (now that C++ code is easily available to us). Ever looked at their code? Yikes :P

I think you didn't understand. DaniJ talked about making a simple translator from ACS bytecode to Javascript (or Doomsday Script, in case of Doomsday) (like those from Brainfuck to C) and then feeding the result to JavaScipt engine. You don't need to know what the engine does with it.
And BTW, SpiderMonkey isn't the only open source JS engine.

Share this post


Link to post
tempun said:

I think you didn't understand. DaniJ talked about making a simple translator from ACS bytecode to Javascript (or Doomsday Script, in case of Doomsday) (like those from Brainfuck to C) and then feeding the result to JavaScipt engine. You don't need to know what the engine does with it.
And BTW, SpiderMonkey isn't the only open source JS engine.

I did understand, it's just that such high-level translation is unlikely to actually work. For example ACS supports a "suspend" operation and there is no such thing in JavaScript.

And no it's not the only one but it's the best one for embedding into other programs. That is my opinion after having looked at several of them. Why do you say this? You have some alternative in mind?

Share this post


Link to post
Quasar said:

I did understand, it's just that such high-level translation is unlikely to actually work. For example ACS supports a "suspend" operation and there is no such thing in JavaScript.

Naturally you would have to select or design a language with at least the same level of runtime functionality as the ACS interpreter or it obviously won't work. I didn't think I needed to point that out.

Why JavaScript? If it were me planning a complete design change I'd probably go for something like Lua :P

Share this post


Link to post
DaniJ said:

Naturally you would have to select or design a language with at least the same level of runtime functionality as the ACS interpreter or it obviously won't work. I didn't think I needed to point that out.

Why JavaScript? If it were me planning a complete design change I'd probably go for something like Lua :P

IMHO, Lua's interface to C/C++ is rubbish. In JavaScript I can define structures which mirror the layout of my native structs (or don't mirror them exactly, as is necessary) to define objects. Methods that run on those objects are called directly through function pointers.

In Lua I have to push and pop a stack, it's like the difference between writing assembly or writing, well, JavaScript.

I don't really know why JS has such a bad reputation except that people are only accustomed to it via the DOM, which is not a particularly well-designed JS class library if you ask me. The DOM is more like the kind of design that would come randomly out of one of those tornadoes-in-a-junk-yard that creationists are always trying to use to explain away evolution.

Share this post


Link to post

I believe we are at crossed purposes here. The discussion was about ACS and which other script engines one could lean on to replicate that functionality. I wasn't actually presuming that Lua was suitable for your purposes (which would seem to be a little different given your emphasis on the performance of complex object construction and/or exchange). My facetious point was that it is a different design philosophy but that it would still meet the overarching requirement of applicability to ACS.

As for JavaScript, I don't really have anything against it personally. I was genuinely interested in your reasons for selecting it as a potential candidate alongside an ACS bytecode interpreter, given the context of the SMALL "false-start".

Share this post


Link to post
DaniJ said:

I believe we are at crossed purposes here. The discussion was about ACS and which other script engines one could lean on to replicate that functionality. I wasn't actually presuming that Lua was suitable for your purposes (which would seem to be a little different given your emphasis on the performance of complex object construction and/or exchange). My facetious point was that it is a different design philosophy but that it would still meet the overarching requirement of applicability to ACS.

As for JavaScript, I don't really have anything against it personally. I was genuinely interested in your reasons for selecting it as a potential candidate alongside an ACS bytecode interpreter, given the context of the SMALL "false-start".

Right, it's largely about the following:

  • A language a lot of users might know already
  • A language with familiar syntax
  • A language that supports structured and OO programming on both sides of the interpreter (user and native interface).
  • A language of sufficient expressivity to replicate anything that can be done in native code including object hierarchies and metatables
  • A language which executes at or near native code speed (TraceMonkey and JaegerMonkey especially accomplish this outstandingly).
Out of all the languages I've considered thus far, JavaScript and Python are the two closest to meeting all those criteria. Out of those two, JS seems to be significantly easier to embed and obviously that's a huge plus in my book.

printz said:

Is the new language planned to be interpreted, unlike Small?

Small is interpreted, at the bytecode level. JavaScript is also interpreted, at a bytecode level. The difference is that embedding the Small compiler into your application cannot happen by design, and if done anyway at great effort, you end up with a program that crashes constantly.

*Monkey's bytecode compiler on the other hand is an integrated component of the library which is explicitly designed to be embedded, and has been stability-tested by millions of FireFox users. When using TraceMonkey or JaegerMonkey, the bytecode is also subsequently selectively transformed just-in-time into native CPU instructions where it executes at blazing speeds compared to plain bytecode interpretation.

Share this post


Link to post

SLADE shows your compiled script as "Compiled ACS (ZDoom)" so there's one step you haven't followed correctly.

Works for me when using either Randy's ACC with the "Hexen bytecode" option or the original Raven Software ACC.

Share this post


Link to post

I'm not found any comments in SLADE about Hexen or ZDoom (using 3.0.1)
But it works if compile scripts through cmd line on Raven's exe and import the bytecode to wad

Share this post


Link to post
cybermind said:

I'm not found any comments in SLADE about Hexen or ZDoom (using 3.0.1)

Please upgrade to the latest SVN build and you'll see what I mean. The official 3.0.1 does not make any difference between the three ACS bytecode formats.

And this way, you will see the "Compile ACS (Hexen bytecode)" option in addition to just "Compile ACS".

Share this post


Link to post
Quasar said:

I don't really know why JS has such a bad reputation except that people are only accustomed to it via the DOM, which is not a particularly well-designed JS class library if you ask me. The DOM is more like the kind of design that would come randomly out of one of those tornadoes-in-a-junk-yard that creationists are always trying to use to explain away evolution.


The DOM is pretty horrible, and the general JS development cycle is pretty horrible too. I guess my opinion is that JavaScript's general design is something I like very much, but once it goes beyond that it's extremely irritating; I think JS is a seriously sloppy language. Well, I should say that because of 15 years of hacks it's become a horrible monster. This site shows some quality WTFs with JavaScript, but I still have some beefs of my own:

  • function arguments are always optional, and always default to undefined
  • primitives and objects are different, false !== new Boolean(0)
  • ...unless JavaScript automatically converts them for you: "hello".charAt(0) == 'h'
  • All numbers are internally represented as doubles, with all the awesome inefficiency and 754-inaccuracy that entails.
  • JS will add semicolons to your code.
  • "label" lets you specify which loop "break" or "continue" will apply to
  • you can assign to Array.length to truncate (or presumably grow?) an array
  • hidden keywords like "constructor" and "arguments".
  • other random retardations
Like, when you look at JS at first, it looks really simple:

- {} is an object
- [] is an array
- zzz() is a function
- 0-9 are integers
- 0.0-1.0 are doubles
- "hey there" is a string as is 'hey there'
- throw/try/catch/finally handle exceptions
- for/while/do-while handle loops

But then you actually try to use this stuff, and it's just frustration after frustration. Like, how many ways are there to loop through a "thing"? Let's see:
for (property_thing in object_thing) {
  /* do some stuff */
}
The problem with this is that it conflates an object with a mapping, and while an object is certainly a derivative of a mapping, treating them the same with a built-in construct like this is pretty insane. Why would you ever want to do this:
for (x in new String("BAHAHAHAHAHAHAHA")) {
  alert(x)
};
Try it, you wouldn't. Even the docs say you shouldn't use them this way. So in JavaScript, the preferred way to iterate through an array is:
for (var i = 0; i < x.length; i++) {
  /* do stuff */
}
Seriously. I can't even think of another scripting language that makes you do this. -- OH, I found the non-standard (though it's in Mozilla's *Monkey engines) array.forEach() method. I do like this, even though you're forced to define a whole new function (anonymous or not) for this loop... which is something you just get used to in JavaScript (function() everywhere for no good reason), and that it's not yet standardized.

Let's see, what else. Oh yeah for each:
for each (x in new String("BAHAHAHAHAHA")) {
  /* do stuff here */
}
This looks a lot like for in, but this returns the values of the object, not the property names. Of course, this has exactly the same drawbacks and pitfalls of for in, so it's hard to see why you would ever want to use this instead of for in; using for in you have access to both the property name and value, for each only gives you the value.

There are, of course, other constructs. There are array comprehensions... but they use for each and don't modify the array they're built from (unless reassigned). There's map(), but it doesn't modify the array it's called on. Then, of course, there's Iterators and Generators... but after reading that page you'll cry out for God to spare you. I really have to define my own iterator and modify the Iterator prototype? ROFL.

===

I won't pretend that Python doesn't have serious dumbness as well, and I have no knowledge about embedding it other than what Kate has said in IRC. But I fully believe it's a much more reasonable, rational language that JavaScript ever will be.

Share this post


Link to post

I have heard similarly heated arguments against every existing language, including C, C++, Java, C#, php, etc. Frankly very little of it should matter for EE's purposes. If you want to get fancy and use those half-assed functional programming features the language has, they'll be in there. But it's not going to be necessary to make effective use of the Aeon API, IMO.

Share this post


Link to post
Quasar said:

Frankly very little of it should matter for EE's purposes.

Even the lack of proper integers?

Share this post


Link to post
tempun said:

Even the lack of proper integers?

Unsure what you mean of that. Any JSVal can be cast back to an integer using the API. The value won't necessarily be valid if the JSVal doesn't really represent an integer value, of course.

JavaScript does have integers; it just automatically promotes results to floating point (of double precision) when this is necessary; ie., the result is out of range for a 32-bit integer, or a division operation is used. The latter can be a bit of a pain at times. But it should also be noted that an integer division method could be provided to the language through a native function too.

Share this post


Link to post

All Scripting languages suck! Fuck Grace Hopper! Derp!



You guys are incredible. You all would probably find a flaw in the Smithsonian Crystal ball.

Share this post


Link to post

It's not that JS doesn't have integers. It's that the runtime represents "integers" as doubles internally. In a scripting context this is typically not a big deal; you won't be managing a screen buffer (1920x1200 is 2,300,400 pixels) or you won't be adding something 10,000,000 times. I just use it as an indicator of how sloppy JS really is; any serious language needs "real" integers, not integers that are "mostly integers" until you do something special with them.

There's a big gap between FraggleScript (inherently insecure, prone to bugs & crashes) and JS. For all of JS's irritations, as Quasar points out it's extremely well-tested and really quite fast - and getting faster. I'm sure that whichever direction Quasar goes Aeon will be awesome, I'm just arguing for my side that's all :) .

Quas:

Haha I guess I sound a little heated. I'm not though honest! I just love to argue and talk about programming... which you will see shortly :) .

I think that as far as using an API goes, it's hard to find a language that isn't "suitable". I guess in that context the key factor is ease of embedding, "mainstream-ness" and memory management, with some smaller considerations like functions and datatypes. So really, we're really talking about any given scripting language that isn't PHP (too specialized), but it probably boils down to Perl, Python, JavaScript, Ruby, Lua, Tcl and Squirrel. Tcl & Squirrel are probably too obscure, everyone hates Perl, and you say Lua's C/C++ interface is awful, so we're down to Python, JavaScript & Ruby.

In the context of Python vs. JS vs. Ruby, I think arguments like, "looping through arrays is clumsy", "__init__" is ugly, and "really when you call a function, () around the arguments shouldn't be optional" are valid. But like you point out, a lot of the argument really is subjective. I personally prefer Python because I prefer explicitness, so when I want to define an object:

class ThisIsAnObject(object):

    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2

my_object = ThisIsAnObject()
Compared to how you would do this in java script:
function ThisIsAnObject(arg1, arg2) {
    this.arg1 = arg1;
    this.arg2 = arg2;
}

my_object = new ThisIsAnObject();
In another life I was an English major, so this semantic dissonance (is a "function" a "class"... what?) irks me. Pragmatically it's not a big deal, but it irks me nonetheless.

I prefer Python's inheritance, because JavaScript has no concept of "inheritance". Rather you have to hack it on yourself. Plus, you're not creating a "type", it's just another Object with some members and methods.

I prefer Python's iteration:
this_is_an_array = ['apple', 'banana', 'cherry']
for fruit in this_is_an_array:
    print fruit
compared to JS:
this_is_an_array = ['apple', 'banana', 'cherry'];
for (var i = 0; i < this_is_an_array.length; i++) {
    print(this_is_an_array[i]); // [CG] Whatever 'print()' is in JS
}
And you can explicitly create iterable classes in Python, without having to rely on "everything is really just an 'object' so just use for in/for each and hope for the best" by implementing the __iter__ method in your class (yes ugly, but still).

I believe that Python's syntax for "private" members is superior over various hacks used to make members private in JS, even though it's ugly as shit (self.__this_is_a_private_variable = 'seeeecrets'). Furthermore, Python's "property" concept is really strong. This is a contrived example but:
class Rectangle(object):

    def __init__(self, width=1, height=1):
        self.__width = 1
        self.__height = 1
        self.width = width
        self.height = height

    def _get_width(self):
        return self.__width

    def _set_width(self, new_width):
        if new_width <= 0:
            raise ValueError('Width must be > 0')
        self.__width = new_width

    def _get_height(self):
        return self.__height

    def _set_height(self, new_height):
        if new_height <= 0:
            raise ValueError('Height must be > 0')
        self.__height = new_height

    width = property(_get_width, _set_width)
    height = property(_get_height, _set_height)

    @property
    def area(self):
        return self.width * self.height

    @property
    def perimeter(self):
        return (self.width * 2) + (self.height * 2)
Creating even this extraordinarily simple class in JavaScript is a horrible pain in the ass. Read-only members: hack. Bounds checking on assignment: hack. Private member variables: hack. And when you're done in JS, you don't have a Rectangle. You have an Object with a few big hacks inside.

And again, I think the "you probably shouldn't be writing a big program using Aeon" holds some weight. Like you said, if it's really only there as an interface to EE's Aeon API then everything else is kind of tertiary. But why accept limitations for no reason? Were EE to grow C/S multiplayer functionality, I think it would be really cool to implement game modes using Aeon. It certainly beats extending the engine in C++. And indeed, many game engines work this way, Civ IV for example is basically a core engine and a ton of Python scripts and XML. I mean, I don't want to go the XML route, but I think it's a compelling architecture, and certainly more accessible to Doom's large community of mappers and modders.

It's maybe also worth arguing that there's no such thing as a small, lightweight JS engine. The *Monkey engines are terrifyingly enormous, and V8 is tens of thousands of lines of code... which honestly isn't that much but it's still more than you'd expect for an "embedded scripting language". Of course, JS is more than that, but a lot of people think that JS is so simple that its implementation is straightforward and small - it isn't. I'm not saying Python isn't huge - it is, but just that JS is far from popping a 128K DLL in the EE distribution.

===

CSG: Admiral Hopper was a scholar, a sailor, a scientist and a Class A lady, and she'd probably wash yr dirty mouth out with soap for using such foul language. And you would deserve it.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×