Some rambling about the scripting language

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
Nightfall
Posts: 555
Joined: Thu Aug 06, 2009 4:00 am
Location: Finland

Some rambling about the scripting language

Post by Nightfall »

Disclaimer: this is more of a "if I were designing this..." thread, so that's why it's here in Editing (or maybe it should be somewhere else? I don't know). It's not really a suggestion. I'm not attempting to impose my views on anybody. I'm just providing my thoughts here, maybe it'll be of use for developers or something.

But eh, I've been recently rambling on IRC and whatnot about the scripting languages ZDoom has to offer and how they feel limited in a sort of way. I know this ZScript is coming up so I thought I'd give my input on the languages.

Anyway, I see the main things the scripting language should do are actor manipulation and environment manipulation. The former is done by the use of ACS and DECORATE, while the latter is mostly done with ACS. Thinking about the roots of these languages: ACS derives from Hexen. It was designed mainly for the environment manipulation part. Together with hubs it gave an RPGish feel on the game. DECORATE derives from a simple language that was meant to create simple decorations, now is a flowchart-like language for dynamic and powerful actor defining.

That's cool and all. But DECORATE's flow-chart design makes it clear it was mainly meant for animations and triggering events at certain positions and not a real scripting language while ACS is the inverse. This is why it feels sort of weird to see people do complex scripting on DECORATE. During my modding era here and on zandronum I've noticed that perhaps the most powerful way of making actors is to export the complex stuff to global ACS and using ACS_Execute on the key parts of the actor.

But ACS seems to be geared towards the environment part. There is no direct access to actors in the language, you haev to use a set of given functions to do things on the actor you want. Hexen tagged things with TIDs and used ACS on them to manipulate them. Teleporting them, spawning them on spots, and so on. For the complex things - like the boss monsters - it used native code and codepointers. It's not real actor control, though it does scratch the surface of it.

So what would be ideal? I'll go back to my previous paragraph: Hexen used native code for the complex actors. So what's in there? Pretty much the power to do anything on the actor. You have pointers to actors, custom fields, methods that execute every tic on the actor and when the actor starts, ability to iterate through actors and so on. Basically: you have access to pretty much any actor and pretty much any property on the said actor. ACS instead relies on actor tagging and falls short here. Because actors are tagged explicitly instead of implicitly, actors that aren't specially tagged just are not in the scope of any scripting whatsoever unless it is the calling actor.

Fine, so let's just tag everything? You'd think so at first, but risk of conflicts exist.. and you'd have to edit pretty much every single actor you're working with, add a hacky unique TID system.. instead of what could be easy access to any actor and their properties and flags.

So my ideology in a nutshell: global ACS should operate on a lower level, DECORATE should exist for the animations and that alone. Instead of TIDs, use unique actor IDs. One ID per actor, one actor per ID - and now you can emulate actor pointers in ACS. Through actor pointers, you could access their properties and flags.

Here's ACS:

Code: Select all

int t = UniqueTID (1000);
Spawn ("DoomImp", 1, 2, 3, t);
SetActorProperty (t, APROP_Health, GetActorProperty (t, APROP_Health) * 2);
So here's an Imp with double the health. To do this, we use a temporary TID which we free later on. That's cool and all. Now, later on, we make all imps fuzzy.

Code: Select all

int t = 1000;
while (IsTIDUsed (t++)) {
	if (!CheckActorClass (t, "DoomImp"))
		continue;
	SetActorProperty (t, APROP_RenderStyle, STYLE_Fuzzy);
	t++;
}
The problem here? It only makes the imps that were spawned by the ACS fuzzy. You could add an ACS_Execute call into DoomImp but now you're replacing out a stock actor and you break any compatibility with mods that could also replace imps. Said mods don't really have this call and thus the imps are not fuzzying to anything.

Now imagine, if there was proper actor IDs:

Code: Select all

int mo = NextActor (0);
while (mo = NextActor (mo))
	if (IsKindOf (mo, "DoomImp"))
		SetProperty (mo, "renderstyle", "fuzzy");
NextActor(int) is a hypothetical function that would return the first actor since the given ID. 0 would be a null-pointer equivelant, it's never valid, thus NextActor (0) would return the first actor defined. In the loop, we iterate through all actors in the kek'n game, check if they're imps or derived from imp with another hypothetical IsKindOf which operates much like the PClass one. Then we use a generic property setting function to set its renderstyle to fuzzy, no explicit tagging needed.

More possibilities:

Killing every monster that targets the activator:
Spoiler:
An imp with that pushes all actors (sorta) away if they get too close. Aside from the formalities, this is practically custom codepointers:
Spoiler:
A_KoraxChase replicated in ACS:
Spoiler:
This could all be done pretty painlessly if the scripting language had things like this. Even in the above code, TIDs remain only being used as actors tagged on the map.

Some more thoughts.. custom DoSpecialDamage() functions? Maybe a decorate property: SpecialDamageScript, takes an int parameter, calls NamedExecuteWithResult on it with one argument (the damage) and takes its result value for the mutated damage. Maybe the compiler (or an alternative one) could even integrate this GetProperty() and shorten it a little bit, like: imp->health *= 2.

Worried about abuse? Add limits and failsafes where necessary. Disallow parts that would cause bad things (for instance never allow deletion of used player bodies, don't add radius and height into SetProperty, (perhaps TryResize()?), etc)

TL;DR: If I were designing the scripting language I'd move away from TIDs for actor manipulation and use unique actor IDs and emulate pointers with them. Make DECORATE basic actor definitions and animations, complex stuff would be best off exported to ACS instead of attempted to be emulated - that only results in action functions with a ridiculous parameter count. :P

Also, I'd be grateful if my username could be changed to "Dusk" as that's what I use on pretty much every other Doom forum by now, thanks!
Blzut3
 
 
Posts: 3215
Joined: Wed Nov 24, 2004 12:59 pm
Operating System Version (Optional): Kubuntu
Graphics Processor: ATI/AMD with Vulkan/Metal Support
Contact:

Re: Some rambling about the scripting language

Post by Blzut3 »

So you rambled about how ACS is not ZScript? :P

ACS is supposed to manipulate the level. The global ACS and using it as pseudo-DECORATE-functions is more of a hack than anything.
User avatar
Nightfall
Posts: 555
Joined: Thu Aug 06, 2009 4:00 am
Location: Finland

Re: Some rambling about the scripting language

Post by Nightfall »

Blzut3 wrote:So you rambled about how ACS is not ZScript? :P
pretty much I guess
ACS is supposed to manipulate the level. The global ACS and using it as pseudo-DECORATE-functions is more of a hack than anything.
Well my point is that ACS is already in a position where it could be extended into such things. Using scripts is probably not a good idea though...
Thinking further, the extending probably deserves a completely new language. And guess where we are at again..
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: Some rambling about the scripting language

Post by FDARI »

ACS needs to remain ACS for all our ACS-dependent work to keep working. We extend it, but we do not change its nature. The existing role and implementation of ACS, which cannot be discarded, limits our freedom in giving it new roles or redesigning it. That, and lots of groundwork on zscript already covered, makes it very clear that extending ACS beyond its natural capabilities isn't sensible. It is already far beyond its intended role, and full of imaginative crutches. (Several of which are crafted by yours truly, such as StrParam and SetPointer, and the globally available pointer selection constants, all enabling ACS/decorate to deliver functionality on concepts that scarcely exist in their design. These languages are evolving monstrous patchworks that accomplish today what we could only dream of tomorrow.)
Locked

Return to “Editing (Archive)”