I don't know if it is or not, but as far as I remember in C++ this was possible to do with function overloading. It would be kind of neat for ZScript to support that (although Graf is probably going to slap me silly for suggesting itD2JK wrote:Is it currently possible to make some of the custom function arguments optional? If yes, how do I do that?
ZScript Discussion
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
-
Rachael
- Posts: 13988
- Joined: Tue Jan 13, 2004 1:31 pm
- Preferred Pronouns: She/Her
Re: ZScript Discussion
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
Function overloading is an ugly can of worms I won't touch. I think named arguments will be more than enough to handle such things.
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
Major Cooke wrote:...randi had it for that long?
Most of the VM is old. This was the first thing to be written for the scripting stuff, somewhere around 2009-2010. Yeah, my mistake for not asking earlier.
-
Tormentor667
- Posts: 13557
- Joined: Wed Jul 16, 2003 3:52 am
- Preferred Pronouns: He/Him
- Operating System Version (Optional): Windows 11
- Graphics Processor: nVidia (Modern GZDoom)
- Location: Germany
Re: ZScript Discussion
Sorry if I sound dumb but what are the benefits of ZScript compared to Decorate?
-
Rachael
- Posts: 13988
- Joined: Tue Jan 13, 2004 1:31 pm
- Preferred Pronouns: She/Her
Re: ZScript Discussion
ZScript allows for lower-level manipulation of the game engine and sim. A lot of things that were [WFDS]'d before in the Feature Suggestions forum is now possible. Additionally, even more of the engine code is now scriptified, which means that modders can take more of the code than ever before and manipulate it for their own ends, without having to publish their own copy of the source port.
(Just waiting for the day someone manages to port an x86 CPU to ZScript and manages to run Win95 using ZDoom....)
(Just waiting for the day someone manages to port an x86 CPU to ZScript and manages to run Win95 using ZDoom....)
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
And just to prove this statement, I just had to do some major work to get rid of a ridiculous limit:Graf Zahl wrote:Interestingly, it looks like the grammar was never fed with actual production code
While testing something a bit more complex, some strange behavior started popping up, (this was on a release build) but no error messages.
Running the same stuff in a debug build triggered a few asserts that were supposed to protect a critical condition, depending on the actual input. Yes, correct! No error message, just an assert with no handling of the situation!
What happened was that I wrote a function that was copying a larger number of properties from one actor to another - I wanted to do some performance tests. Now I must explain a strange design issue in the VM: The instructions to read and write to memory all have a constant index, and these indices, along with all other integer constants are stored in a single constant table. And this table had a pitiful limit of just 256 entries per function per type, type being either int, float, pointer or string. By wildly copying around between objects and randomly setting a few values here and there I quickly exceeded that limit, but instead of an error - see above.
And it got worse: The size field for this table was - a byte! Nearly all instructions taking this offset use - a byte - to store it!
Unfortunately it was not fixable on the instruction side anymore. And the instructions were ordered in a way that made a simple, straightforward solution impossible so I had to waste several hours to add a remapping table to circumvent these one-byte instructions if the index got too large.
Yeah, some really forward thinking design at play here...
-
Major Cooke
- Posts: 8221
- Joined: Sun Jan 28, 2007 3:55 pm
- Preferred Pronouns: He/Him
- Operating System Version (Optional): Windows 10
- Graphics Processor: nVidia with Vulkan support
- Location: GZBoomer Town
Re: ZScript Discussion
Which I take it aren't in yet? Just clarifying, a lot of the recent commits dealt with argumentd in particular and it certainly didn't look like them.Graf Zahl wrote:Function overloading is an ugly can of worms I won't touch. I think named arguments will be more than enough to handle such things.
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
No, named arguments aren't in yet. But I am getting close to the end of my list of important stuff to do so if all goes well it should be in this week.
Of course, such stuff as the constant limit wasn't on my list and cost me several hours to fix. Who knows what else may be lurking in the bowels, undiscovered by the fact that the VM was never before tested on more heavyweight stuff.
Of course, such stuff as the constant limit wasn't on my list and cost me several hours to fix. Who knows what else may be lurking in the bowels, undiscovered by the fact that the VM was never before tested on more heavyweight stuff.
-
Edward-san
- Posts: 1774
- Joined: Sat Oct 17, 2009 9:40 am
Re: ZScript Discussion
I noticed this in the zscript files:
what's the call order here? Which frandom[] is executed first? It used to be a portability problem in C/C++...
Code: Select all
A_SpawnItemEx(chunks[i], 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle+90), frandom[DemonChunks](1,4.984375)*sin(Angle+90), 8, 90, ChunkFlags);
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
Always left to right. The compiler is very strict in that regard. It also creates the same code on all systems so this should never become an issue.
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
Well, now they are.Graf Zahl wrote:No, named arguments aren't in yet.
-
Eevee
- Posts: 592
- Joined: Wed Jul 16, 2003 5:26 am
Re: ZScript Discussion
I don't mind it when it's a separate operator; it just stood out as odd to have weak typing behavior here when it looks like you require type casts in a lot of other places. Honestly I'd be much happier if you erred more on the side of dynamism.Graf Zahl wrote:Uhh, that's the point of a string concatenator. Its purpose is to stringify the operands for creating something that can be printed.
Other languages with a similar operator work the same, even Java where you can write String a = "blah "+ intvar + " float = " + floatvar";
The one thing here to be aware of is that I just took the operator as-is from the grammar as Randi defined it. I'd prefer to use '+' myself but right now am not sure how to do that without creating ambiguities.
Weakly-typed overloaded + is the worst of all possible worlds, though: something is going to be converted to something, but at a glance it can be hard to figure out what. Python's + is overloaded, but only lets you add like types together.
Ironically, Lua's support for multiple return values is just a special case of multiple assignment, which is why it has the "a, b, c = 1, 2, 3" syntax you were scoffing at earlier.Graf Zahl wrote:Overall, more like something between C++ and Java. But you still need some simple means to create texts to print. And not everything in Lua is bad. e.g. ZScript supports multiple return values, although right now only for native functions. The script side implementation for this is not done yet.
It seems that both the process and the feedback would be easier if the language were mostly designed before it were implemented? But it also seems that randi had a language design in mind and then neglected to share it.Graf Zahl wrote:That's the weird thing here. Right now I am still collecting features, there is absolutely no guarantee that something I don't like won't get refactored eventually. It may easily happen that some functions will go away ultimately, should I decide that their presence will hurt the thing overall.
The biggest stand-out to me at the moment is that this is a language specifically for scripting a specific engine, but aside from what was already in DECORATE, it doesn't seem to make many engine-specific concessions. Colors, for example, seem an obvious candidate for their own type with their own literal syntax — I think they're even a distinct argument type in action functions. Bitflags are clumsy both to use and document, and a C-style type system provides no protection against using a flag in the wrong place; surely the syntax could provide some alternative. Iterators are very thin wrappers over the C++ API, which could easily be made to work with a for-in syntax.
And for what it's worth, I've been toying with a non-serious proof-of-concept embedding of Lua, and it's looking fairly viable. I think I can eliminate the distinction between DECORATE and ACS entirely, letting the same language share code and data (and an API!) between actors and level scripts. It's just slow-going, since I don't know my way around the codebase, so I can't prove it yet. I imagine similar could be done with Squirrel (which is more bracey).
Last edited by Eevee on Sun Nov 20, 2016 7:19 pm, edited 1 time in total.
-
Eevee
- Posts: 592
- Joined: Wed Jul 16, 2003 5:26 am
Re: ZScript Discussion
Oho! Very nice.Graf Zahl wrote:Well, now they are.Graf Zahl wrote:No, named arguments aren't in yet.
-
Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript Discussion
The operator isn't weakly typed at all. But it's defined to take any known integral type and concatenate a string representation of the value it represents. That's the only way such a thing can work.Eevee wrote: I don't mind it when it's a separate operator; it just stood out as odd to have weak typing behavior here when it looks like you require type casts in a lot of other places. Honestly I'd be much happier if you erred more on the side of dynamism.![]()
Don't remind me. The horrors of Javascript are still very much alive. I've never worked with another language that's this hard to debug because of all the different kinds of strange behavior caused by the lack of proper typing. I completely fail to see the point of a language that says 'You may do anything and I find a way to make it work - somehow.' Makes it impossible to find errors early-on.Weakly-typed overloaded + is the worst of all possible worlds, though: something is going to be converted to something, but at a glance it can be hard to figure out what. Python's + is overloaded, but only lets you add like types together.
But it's the only good use case. Multiple assignments only serve to make the code harder to read because they separate variable and value syntactically. But for functions they really can make things easier. The lack of multiple return values is one of those things that can make C and related languages really turn ugly, especially crippled stuff where you do not have pointers at your disposal.Ironically, Lua's support for multiple return values is just a special case of multiple assignment, which is why it has the "a, b, c = 1, 2, 3" syntax you were scoffing at earlier.![]()
As has been demonstrated by others, multiple assignments can quickly lead to unintuitive errors.
Touché. Although I only changed the language design in spots where something was lacking or just not well designed.It seems that both the process and the feedback would be easier if the language were mostly designed before it were implemented? But it also seems that randi had a language design in mind and then neglected to share it.
Spots that really bothered me in the original design which I changed were:
- C-style semantics for variable initialization.
- Make assignments an operator, not a statement, so it can be used in expressions, like in C. Of course this was also completely at odds with multiple assignments and the main reasons they were removed.
- The addition of class extensions, simply because I needed them to prevent class Actor from blowing up in my face.
- Allowing structs to have functions. This was strangely missing from the original design and also turned out to be an obstacle to clean feature implementation.
- Addition of state types, to have clean semantics of defining action functions for weapons etc. which are run in another actor's context.
- Improvement of vector declarations. The original design had 'vector<2>' instead of 'vector2' which was just awful.
- Vector literals, because, if you can define a language, these should be in, shouldn't they.
- added the missing null pointer literal.
- static constant arrays
- allow specification of default values in function prototypes. The original was desgined after UnrealScript with an 'optional' keyword.
But the one thing that really and utterly puzzled me is the lack of default values for optional parameters. The DECORATE implementation from 2004 already had this, and yet, when Randi ported the DECORATE interface to the VM it got all ripped out, being replaced by a half-baked crutch that required each function to take care of this itself. This was barely acceptable for native functions, but - oh the irony - would have made a complete and utter mess out of scripted functions, so one of the first things I had to do was to process the default values after all, and since they needed to be processed anyway, ended up using them for the native functions again (because, well, redundancy sucks!) So we were back to square one, all the access macros got changed for no good reason, making merging the old scripting branch an utter chore with nothing being gained by it.
They actually are their own type, but as it stands they haven't been completely fleshed out yet. For once, the string initializer syntax cannot deal with alpha, although that's mostly offset by just using 0xaarrggbb to set them now. But what's still missing is direct access to the four color channels (like color.a, color.r, etc.) So far I haven't needed this so it got pushed back as less important.The biggest stand-out to me at the moment is that this is a language specifically for scripting a specific engine, but aside from what was already in DECORATE, it doesn't seem to make many engine-specific concessions. Colors, for example, seem an obvious candidate for their own type with their own literal syntax — I think they're even a distinct argument type in action functions.
I know. The problem here is not the language but how the typing system tried to implement enums, which was totally broken. There's some significant groundwork needed to repair this part, that's why enums are currently forced into integers because it was the only way to go forward to a state where enough info is available to do this right.Bitflags are clumsy both to use and document, and a C-style type system provides no protection against using a flag in the wrong place; surely the syntax could provide some alternative. Iterators are very thin wrappers over the C++ API, which could easily be made to work with a for-in syntax.
As for protection, don't sell C, or at least C++ short, it's far better than you think, as long as you actually use enum types and not ints. Something like 'enumvalue + 1' is no longer an enumvalue, it's an int and cannot be passed anymore to a variable of enum type. But like I said, the entire system is so broken that it's not easy to fix.
One of the worst part here is the constant evaluator the compiler comes with, it's an utterly destructive piece of shit that was supposed to be run as a preprocessor on the AST - but aside from evaluating untyped constants it is basically useless and I ended up ignoring it complely, relying mostly on the compiler backend to evaluate my constants elsewhere. Too bad that a lot of work was invested here, but what's the use if it destroys essential information while trying to replace identifiers with possible values while lacking any context this needs to be done in?
If it's Lua it's not viable.
And for what it's worth, I've been toying with a non-serious proof-of-concept embedding of Lua, and it's looking fairly viable. I think I can eliminate the distinction between DECORATE and ACS entirely, letting the same language share code and data (and an API!) between actors and level scripts. It's just slow-going, since I don't know my way around the codebase, so I can't prove it yet. I imagine similar could be done with Squirrel (which is more bracey).
Sorry, but that "language" goes way beyond my tolerance level of stupid. It's really a shame that scripting has devolved to this level - even Javascript is better.
As for VM vs. ACS, yes, it would be possible to translate ACS to VM but it's the kind of stuff that really only makes sense if you are hell-bent on proving that it can be done. I go by the axiom of 'if it ain't broke, don't fix it' here, meaning that ACS works, why should it change? What may make sense at a later stage is to clean up the function interface so that both parts can share implementation. I see no reason to expose the entire list of ACS, and maybe even FraggleScript functions in a shared namespace for all 3 languages to use. But keep in mind that both ACS and FS have a concept of latent functions that can wait for an action to happen and continue at a later time. The VM can't do that, and I'm not sure if it can be changed to do that without having some serious impact on handling. At the moment it just executes code like a CPU in the same thread as all the other game code.
-
Tormentor667
- Posts: 13557
- Joined: Wed Jul 16, 2003 3:52 am
- Preferred Pronouns: He/Him
- Operating System Version (Optional): Windows 11
- Graphics Processor: nVidia (Modern GZDoom)
- Location: Germany
Re: ZScript Discussion
@Eruanna - Thanks for the explanation 