At essel's request I've made ACS usable via the DOOM map format in concert with ExtraData, as a hold-me-over until the Hexen and UDMF map formats are fully usable.

You can set an acsscript variable in MapInfo to point to the script lump for your map, and it'll get loaded just like the BEHAVIOR lump would for a Hexen map.

I have also implemented some more specials: Thing_Projectile, Thing_ProjectileGravity, Thing_Activate, and Thing_Deactivate. For the latter two, support has also been added for Active and Inactive states in DECORATE state blocks, activestate and inactivestate for EDF thingtypes, and an activatesound and deactivatesound for EDF thingtypes as well. Thing_(De)activate are capable of toggling the already-existent DORMANT flag for killable monsters too.

So if a DOOM format map can now include a BEHAVIOR lump - how are you going to tell the difference between DOOM and Hexen format maps?

My point being that if the name chosen in Eternity's MapInfo for the ACS bytecode lump is "BEHAVIOR" (which I'm sure most experienced DOOM/Hexen modders will try to use) any existing port will misinterpret the map and think its in Hexen format.

Edit: Not to mention Eternity itself won't be able to tell the difference when you do support Hexen.

The way I understood this, it works like the Strife convo scripts -- the script lumps are not technically a map lump, they're floating anywhere else in the wad file and are given names like SCRIPT01 or whatever. (Personally, I'd recommend looking only in the ACS namespace A_START/A_END by the way. That way modders can also include the source lumps with the same name without risking conflicts. Maybe more importantly, you also take advantage in this way of the already-existing toolchain for ZDoom's ACS library system in programs such as SLumpEd or SLADE 3.)

In fact the lump should specifically NOT be named BEHAVIOR just to avoid the possibility that it could end up sorted next to a map and break that map.

One problem esselfortium is running into is that a lot of the tools that are being produced now have no option to generate Hexen-format bytecode. EE doesn't support ZDoom's extended bytecode format currently and support for it is not on the short-term TODO list either, seeing as how I have no use for such things as localization support and writing code to skip over it all is a PitA.

Quasar said:
seeing as how I have no use for such things as localization support and writing code to skip over it all is a PitA.

Actually, the original localization support is long gone and has been replaced by a much more useful option to access the global string table (which can be localized but that's not really ACS's problem.)

Quasar said:
One problem esselfortium is running into is that a lot of the tools that are being produced now have no option to generate Hexen-format bytecode.

ACC just needs to be given the -h parameter. I've just added in SLADE the option to call ACC with or without that parameter; and even made SLADE's entry type detection functions identify precisely which version of ACS bytecode is used for your lump.

Gez said:
ACC just needs to be given the -h parameter. I've just added in SLADE the option to call ACC with or without that parameter; and even made SLADE's entry type detection functions identify precisely which version of ACS bytecode is used for your lump.

Quasar said:
In fact the lump should specifically NOT be named BEHAVIOR just to avoid the possibility that it could end up sorted next to a map and break that map.

Indeed. You could always reserve that name and refuse to load from lumps with that name outside of map-scope. That would avoid any potential for user/tool error.

One problem esselfortium is running into is that a lot of the tools that are being produced now have no option to generate Hexen-format bytecode.

I see I'm not the only one feeling the pain and I'm getting a bit fed up with situation in all honesty.

Whats worse is that this modified version of ACC will quietly "promote" your script to ZDoom's enhanced format if it encounters anything that isn't part of the standard defined by Hexen, regardless of what you actually ask it to produce. Given that this is often masked by editing tools like DB2 and SLADE the mod author is often completely unaware of it.

After some tests I've determined that ACC will use the lowest compatibility level it can to successfully compile a script lump when the -h parameter is given. That means that most ZDoom maps will have their scripts recompiled as ACSE rather than the default of ACSe (since some ZDoom-exclusive ACS features are used, but not the most recent additions).

Anyways, SLADE will from now on tell you what bytecode format you get, so if you chose the "Hexen" compile option but you see you still get an Enhanced or ZDoom bytecode, it's because there are non-vanilla features used in your script.

I mentioned this to Quasar a while back on IRC, but I'd like to mention it again here:

It would be a great addition if there was a designated default lump name that would be checked for within a Doom-format map's lump block, like DOOMACS or whatever name you want to give it.

The benefit to this would be that a modified Doom Builder 2 configuration could be created that allows for editing and compiling this lump just as directly from within the editor as you can for a Hexen-format or ZDoom map.

esselfortium said:
I mentioned this to Quasar a while back on IRC, but I'd like to mention it again here:

It would be a great addition if there was a designated default lump name that would be checked for within a Doom-format map's lump block, like DOOMACS or whatever name you want to give it.

The benefit to this would be that a modified Doom Builder 2 configuration could be created that allows for editing and compiling this lump just as directly from within the editor as you can for a Hexen-format or ZDoom map.

And if you recall, the technical limitation that prevents addition of "optional" lumps to a DOOM map is that there is no terminator lump. This is specifically why UDMF defined the ENDMAP lump, so that a set of arbitrary lumps could be placed after a map and the map loader would know where it could stop scanning in the wad directory for additional lumps.

While I could add ENDMAP support to DOOM wads, EE would be the only port having any use for it, since no other ports have the ability to use ACS with DOOM maps in that sort of manner (ZDoom only allows its use through combining libraries with a custom linespec translation).

If the optional lumps have to be placed in a specific order and there's a finite number of them (in this case, two - the compiled lump, and the plaintext script - and EE only needs to care about the first one), is it still an issue? If no DOOMACS (or whatever) lump is found immediately after the last expected map lump, it isn't loaded for that map. Or am I oversimplifying somehow? >_>

esselfortium said:
If the optional lumps have to be placed in a specific order and there's a finite number of them (in this case, two - the compiled lump, and the plaintext script - and EE only needs to care about the first one), is it still an issue? If no DOOMACS (or whatever) lump is found immediately after the last expected map lump, it isn't loaded for that map. Or am I oversimplifying somehow? >_>

I think this would be a bit too involved for something that's supposed to be just a band-aid until UDMF is finally implemented.

esselfortium said:
If the optional lumps have to be placed in a specific order and there's a finite number of them (in this case, two - the compiled lump, and the plaintext script - and EE only needs to care about the first one), is it still an issue? If no DOOMACS (or whatever) lump is found immediately after the last expected map lump, it isn't loaded for that map. Or am I oversimplifying somehow? >_>

You are because there are a number of other lumps that one could argue EE should support in this manner and all of them must be optional, and therefore capable of appearing in any order. Those are:

* ExtraData lump for a map
* Small script lump for a map
* Finale text lump for a map

I didn't end up allowing any of these for the exact same reasons. There are too many tools that won't copy the lumps along with the map, it's impossible to tell where the map ends when scanning the wad directory, and it is unreasonable IMHO to require all of them to appear but be 0 length when many maps won't use any of them.

printz said:
Why not just support direct parsing of text mode ACS? EDF is understood this way, ACS doesn't look very different.

Sorry to double post but this is worthy of its own completely separate answer.

ACS is, despite appearances, significantly more complex than EDF. ACS is a language requiring a LALR(1) parser, similar to one used for the C language on which it is based.

Not only that, but parsing ACS, which ultimately is not that difficult, is approximately 1/16th of the work required. You'd then need to generate a syntax tree, do semantic analysis/verification, and then binary code generation. Or in other words, write a new compiler.

I tried to get the ACS compiler GPL'd so that it would be possible to integrate it into GPL DOOM ports directly and have "JIT-compiled" ACS scripts, but unfortunately James Monroe seems to have forgotten about it or didn't consider it worth the trouble. Until someone writes a fully original and compatibly licensed embeddable compiler with rock-solid stability, JIT ACS is a pipedream. One that would be worth reaching for, though. I'm the wrong guy for that job though. My previous attempts at writing compilers failed miserably in the semantic analysis stage.

Quasar said:
You are because there are a number of other lumps that one could argue EE should support in this manner and all of them must be optional, and therefore capable of appearing in any order. Those are:

* ExtraData lump for a map
* Small script lump for a map
* Finale text lump for a map

I didn't end up allowing any of these for the exact same reasons. There are too many tools that won't copy the lumps along with the map, it's impossible to tell where the map ends when scanning the wad directory, and it is unreasonable IMHO to require all of them to appear but be 0 length when many maps won't use any of them.

Given that the benefit in this is specifically to make it possible for mappers to use DB2's built-in ACS editor, and DB2 will copy the lumps if it's told of their existence in the Eternity CFG (and yes, they can be optional), I'm not sure what tool issues there are.

SLumpEd, Slade3, and XWE are going to have you select and copy the lumps that make up your map individually, and the possibility of screwing with someone else's map using another map editor without considering feature compatibility is just user-error anyway. I don't think EE should really be limiting its editability convenience features for the off-chance of someone reordering their wad and having to spend a few minutes fixing it.

Plus, Small is officially deprecated and its use is discouraged, and Finale text doesn't require tools to compile it, doesn't entail regular checks against map content (tags and such) while writing it, and doesn't commonly get applied to more than a few maps in a wad. It makes enough sense for that to be attached via mapinfo.

Plus, even with those four all as optional lumps, you only have to scan forward a total of 4 lumps to check for their existence; there's no sense in a setup allowing for an infinite recursion through the entire wad here. :P

Gez said:
I think this would be a bit too involved for something that's supposed to be just a band-aid until UDMF is finally implemented.

Perhaps, but convenient in-editor feature support has been a problem for EE features since the beginning. I was able to hack together a DB2 config that looks for and edits an ACS lump that I attached to one of my maps in EMAPINFO, but that doesn't work as a solution for any of my other maps and can't really be made available as a general-purpose cfg for other people to implement ACS into their own maps with.

Quasar said:
I tried to get the ACS compiler GPL'd so that it would be possible to integrate it into GPL DOOM ports directly and have "JIT-compiled" ACS scripts, but unfortunately James Monroe seems to have forgotten about it or didn't consider it worth the trouble. Until someone writes a fully original and compatibly licensed embeddable compiler with rock-solid stability, JIT ACS is a pipedream. One that would be worth reaching for, though. I'm the wrong guy for that job though. My previous attempts at writing compilers failed miserably in the semantic analysis stage.

Working on it... slowly. At this point the assembler is working (before any one asks, yes it can assemble to Hexen compatible scripts), but the compiler is only an expression evaluator.

ACC++ will be BSD licensed and able to be turned into an embeddable library.

Graf Zahl said:
I wonder if that would actually be fully compatible with the shitty single pass compiler Raven made...

Well LALR(1) is technically a description of the language's formal grammar, rather than the PDA that can parse it, and since they didn't write a formal grammar, I doubt their parser is specifically constructed on that theoretical framework :P You can always hack around and get by with a lot less than what you'd expect from a formal language theory POV :>

I would think that given ACS's known/documented syntax can be considered a logical subset of C, it would be unlikely that one would encounter any problems retroactively defining a formal grammar (bar for any esotericisms in ACC itself, which could be mitigated through the use of a pre-parse transform if necessary).

An alternative to JIT ACS would be a bytecode reverse-compile to a language with a formally defined grammar, which you can then feed into an existing JIT compiler if thats what you want. This is similar to what dengteam are doing for our Doomsday Script system.

DaniJ said:
An alternative to JIT ACS would be a bytecode reverse-compile to a language with a formally defined grammar, which you can then feed into an existing JIT compiler if thats what you want. This is similar to what dengteam are doing for our Doomsday Script system.

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

Create a new lump, name for example MAP01_S. That'll be our source script lump for MAP01.

Create another couple of lumps named A_START and A_END to determine an ACS namespace. Important: the A_ markers should be after the script source lump.

Now edit the EMAPINFO lump. Tell your MAP01 definition that it has an acsscript property set to MAP01_S.

Click on your MAP01_S lump. Click on the "edit as text" and start writing some script. Then save.

Now right-click on it. Choose "Compile ACS (Hexen bytecode)". A new MAP01_S lump should automatically appear between the A_ markers.

Once the initial setup is done, you can follow just these steps:

Open wad in both SLADE 3 and Doom Builder 2.

Edit the map in DB2, and alt-tab to SLADE 3 to edit the script.

Whenever you change the script, click on save, then right-click->compile ACS Hexen as explained above. Then save the wad.

After that, save or test in DB2.

Note 1: Each map can have its own map script lump. Just give them a different name, that's why I'd recommend simply appending _S to the name of the map.

Note 2: If you're using Linux or MacOS rather than Windows, you'll need a map editor that works like Doom Builder 2 for map saves: DB2 only writes the map when it saves, and reloads the rest of the wad from the disk, so you can edit a map simultaneously in both SLADE 3 and DB2 Just remember to save the first in SLADE 3 (so all non-map lumps are to their latest version), and then in DB 2 (so all map lumps are in their latest version).

Note 3: The reason I'm advocating SLADE 3 instead of, say, XWE is not just a question of personal bias. A given wad file cannot be opened in both XWE and anything else, so the setup explained above wouldn't work and you'd have to instead save quit and reload to alternate between both the lump editor and the map editor, which would be tedious. Plus, I don't know if you can give arbitrary parameters to ACC with XWE, so I can't guarantee you'd get a compatible bytecode.

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.

A way to make Gez's suggested setup easier still is to put your ACS lump(s) in a separate wad from your map, and tell DB2 to load the separate wad as a resource (so it'll get loaded when you hit Test Map to load it in EE).

This way, you don't have to worry about remembering to save in DB2 after each time you save your script in SLADE. I usually keep my ExtraData lumps in separate wad the same way.