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

ZDCode 2.0: DECORATE on steroids, for Grandmadronum!

Recommended Posts

ZDCode II: The language that compiles to compatible DECORATE!


Take this example:

class RunZombie inherits ZombieMan replaces ZombieMan #2055
{
    set Gravity to 0.4; // high up...
    set Speed to 0;
    is NOBLOCKMONST;
    set Speed to 0;

    label See
    {
        POSS AB 5 A_Recoil(-0.7);
        TNT1 A 0 A_Chase;
        POSS A 0 A_FaceTarget();
        POSS AB 4 A_Recoil(-0.7);
        TNT1 A 0 A_Chase;
        POSS A 0 A_FaceTarget();
        POSS ABCD 3 A_Recoil(-0.7);
        TNT1 A 0 A_Chase;
        POSS A 0 A_FaceTarget();
        goto RunLoop;
    };

    function Jump
    {
        while ( z == floorz )
        {
            POSS A 5 [Bright];
            POSS A 11 ThrustThingZ(0, 30, 0, 1);
        };
        POSS AB 2 A_Chase;
    };

    label RunLoop
    {
        x3
        {
            POSS ABCD 2 A_Recoil(-0.7);
            TNT1 A 0 A_Chase;
            POSS A 0 A_FaceTarget();
        };

        if ( health > 5 )
            call Jump;

        loop;
    };
}

 

This is what happens when that beauty goes through ZDCode II:

Actor _Call0 : Inventory {Inventory.MaxAmount 1}


Actor RunZombie : ZombieMan replaces ZombieMan 2055
{
    Gravity 0.4
    Speed 0.0
    
    +NOBLOCKMONST
    
    States {
        F_Jump:
        _WhileBlock0:
            TNT1 A 0 A_JumpIf(!(z == floorz), 4)
            POSS A 5  Bright
            POSS A 11 ThrustThingZ(0.0, 30.0, 0.0, 1.0)
            TNT1 A 0 A_Jump(255, "_WhileBlock0")
            TNT1 A 0
            POSS A 2 A_Chase
            POSS B 2 A_Chase
        
        
        See:
            POSS A 5 A_Recoil(-0.7)
            POSS B 5 A_Recoil(-0.7)
            TNT1 A 0 A_Chase
            POSS A 0 A_FaceTarget
            POSS A 4 A_Recoil(-0.7)
            POSS B 4 A_Recoil(-0.7)
            TNT1 A 0 A_Chase
            POSS A 0 A_FaceTarget
            POSS A 3 A_Recoil(-0.7)
            POSS B 3 A_Recoil(-0.7)
            POSS C 3 A_Recoil(-0.7)
            POSS D 3 A_Recoil(-0.7)
            TNT1 A 0 A_Chase
            POSS A 0 A_FaceTarget
            goto RunLoop
        
        RunLoop:
            POSS A 2 A_Recoil(-0.7)
            POSS B 2 A_Recoil(-0.7)
            POSS C 2 A_Recoil(-0.7)
            POSS D 2 A_Recoil(-0.7)
            TNT1 A 0 A_Chase
            POSS A 0 A_FaceTarget
            POSS A 2 A_Recoil(-0.7)
            POSS B 2 A_Recoil(-0.7)
            POSS C 2 A_Recoil(-0.7)
            POSS D 2 A_Recoil(-0.7)
            TNT1 A 0 A_Chase
            POSS A 0 A_FaceTarget
            POSS A 2 A_Recoil(-0.7)
            POSS B 2 A_Recoil(-0.7)
            POSS C 2 A_Recoil(-0.7)
            POSS D 2 A_Recoil(-0.7)
            TNT1 A 0 A_Chase
            POSS A 0 A_FaceTarget
            TNT1 A 0 A_JumpIf(!(health > 5.0), 3)
                TNT1 A 0 A_GiveInventory("_Call0")
                Goto F_Jump
            _CLabel0:
                TNT1 A 0 A_TakeInventory("_Call0")
            TNT1 A 0
            loop
    }
}

 

Yes, I know – the output code is quite cryptic, but you're not meant to touch that – just slap the output in your WAD and...look at what happens!

mr5wJ85.gif

 

Available on GitHub.

Share this post


Link to post

Well, that's kinda neat. Some questions about your script:

  • What is "x3"? Does that mean "repeat 3 times"?
  • Some of it seems to purposefully change syntax. For example: you use "set Gravity to 0.4;" to generate DECORATE "Gravity 0.4". Why not just support "Gravity 0.4" in your script? Is it a parsing issue?

I would like to make a suggestion: I think you should model your script to match DECORATE syntax as closely as possible. I say this, because it will create confusion otherwise, I think. Other than that, this is pretty neat stuff - I can tell you've done a lot of work.

Share this post


Link to post
26 minutes ago, kb1 said:
  • What is "x3"? Does that mean "repeat 3 times"?

 

Exactly. You can also use the repeat keyword, if I recall correctly.

 

26 minutes ago, kb1 said:
  • Some of it seems to purposefully change syntax. For example: you use "set Gravity to 0.4;" to generate DECORATE "Gravity 0.4". Why not just support "Gravity 0.4" in your script? Is it a parsing issue?

 

I want it to seem intuitive, and adopted a syntax where you can choose your syntax better, to suit users' needs and preferences. As for properties, there is likely an alternate way, but the lexer I wrote is a bit messy, and the documentation is sub-optimal. Let me take a look.

Share this post


Link to post

Oh, and before someone asks me about ZScript, I have to clarify: this programming language targets older versions of ZDoom and ZDoom-derived source ports like Zandronum, most of which don't support ZScript. Thus, it is advised to use ZDCode only as a compatible alternative to DECORATE, not as a more flexible one (even though it is still more powerful).

Share this post


Link to post
On 10/19/2018 at 9:40 PM, Gustavo6046 said:

 

Exactly. You can also use the repeat keyword, if I recall correctly.

 

 

I want it to seem intuitive, and adopted a syntax where you can choose your syntax better, to suit users' needs and preferences. As for properties, there is likely an alternate way, but the lexer I wrote is a bit messy, and the documentation is sub-optimal. Let me take a look.

Don't get me wrong here. Your syntax is probably more intuitive, indeed. But there's a strength in avoiding there being more than one syntax out there, and that is confusion avoidance. Programmers are used to seeing 10 different ways to define things. But, I guarantee you that, for a lot of mappers, DECORATE is as deep as they have been into programming. Adding another way of defining things causes confusion, with no real benefit.

 

It causes people to think: "How do I define gravity? Let's see... I'm using DECORATE (I think), so I use syntax A. Now, I'm in ZDCode - I need to use this other syntax B... which gets converted back to syntax A - Aargh!"

 

It's just a friendly suggestion. To formalize that suggestion, I'd say to keep ZDCode syntax identical to DECORATE, except for the things that only ZDCode can do. I might even go so far as to add that ZDCode-specific commands are surrounded by brackets, or start with a special non-DECORATE prefix, making it absolutely clear that you're looking at pre-processed ZDCode vs. DECORATE.

Share this post


Link to post

I wanted a different syntax, to completely replace DECORATE. I'm not sure if that kind of confusion is common, but I wanted something easier than DECORATE; maybe eventually similar to what C is to Assembly (obviously not to the same extent - C was a complete revolution of programming, whereas this is just an utility language for when ZScript isn't available).

 

Also, people need to learn how to program. My friend Madcat (from the SUN clan) refuses to learn programming things because no time is available to him. Really, it's all easy to learn the basics of programmer logic and structure otherwise. With just a bit of time, any one could try ZDCode, and with more timely investment, they could even fathom ZScript (and then Zandronum would not be supported).

Share this post


Link to post
23 hours ago, Gustavo6046 said:

I wanted a different syntax, to completely replace DECORATE. I'm not sure if that kind of confusion is common, but I wanted something easier than DECORATE; maybe eventually similar to what C is to Assembly (obviously not to the same extent - C was a complete revolution of programming, whereas this is just an utility language for when ZScript isn't available).

Ok, well *now* you're talking - but that's a bit different than what you've represented so far. To take this to its natural conclusion, you might consider adding your parser to a source port. But (and this is debatable), DECORATE is currently king of the hill. Also, arguably, you'd get 10x the support if your language was "DECORATE++", vs. something else... *especially* when your language *is* a superset of DECORATE, after all.

 

I'm not trying to dictate - I want you to succeed, which means to have a lot of mappers using your tools.

Here's the scenario I'm trying to help you avoid:

  1. I open up some DECORATE code, containing the line "X = 3".
  2. I add some ZDCode goodness, but I have to convert that line to "set X to 3" (or whatever).
  3. I compile, and the ZDCode compiler converts "set X to 3" to "X = 3".

Can you see where I'm going with this? I can't edit the output of ZDCode, and run it back through the ZDCode compiler. What you're doing is really close to being awesome, but I think compatibility is going to be the difference between something great, and something that's difficult to work with.

 

Quote

Also, people need to learn how to program.

The ability to program is like the ability to draw, or compose music - some people have a knack at it, and some just don't. That is where having *really* straight-forward, easy-to-learn tools can make the difference. Because there are some people that can build the most beautiful maps, yet cannot grasp programming. Programming is a passion not shared by everyone. To others, it may be a necessary evil, to get the job done. For those people, dedication, great examples, great documentation, and easy tools can make the difference, and allow them to slowly start to put together the pieces. Learn at a pace they are comfortable with. Silly little syntax hangups and difficulties are the enemy of someone trying to learn programming via game scripting.

 

You have to forget that you're a proficient programmer for a minute, and try to emphasize with a mapper that just needs to open a door when the boss dies, or even implement a weapon merchant stand in a Doom WAD. Anyway, that's my two cents. Good luck with your language - it looks promising.

 

 

Share this post


Link to post

Indeed, I think another solution would be to create a GUI (or web page... Electron?) that allows graphical programming, something similar to (but more powerful than) Scratch. It would have to output ZDCode, which is probably not going to be a very easy task, but then again, if I went this far, what can't be done?

 

Thank you all guys for the support you give for me to keep ZDCode running. You guys are awesome.

Share this post


Link to post

Added sometimes statement, which makes a block (or single state) execute randomly, supplied a chance from 0 to 100%:

 

label Death {
  sometimes 96 {
    TNT1 A 0 A_Log("RED ALERT: New high-level threat detected!");
    TNT1 A 0 A_SpawnItemEx('MonSpawnR', 0, 0, floorz - z);
  };

  x 5 sometimes 8
    call Duplicate;

  x 20 call MakeParticle;
  TNT1 A 1;
  Stop;
};

 

I now also have the else that goes along if statements.

Share this post


Link to post
On jeudi 25 octobre 2018 at 3:40 AM, Gustavo6046 said:

I wanted a different syntax, to completely replace DECORATE. I'm not sure if that kind of confusion is common, but I wanted something easier than DECORATE;

Honestly, I don't think "set gravity to 8" is easier than "gravity 8". It just adds some boilerplate.

 

Anyway, this is rather neat! Much better than I was expecting, so keep up the good work.

 

 

Share this post


Link to post

@Gez The "to" is optional; it just helps make the line between the property's name and its value clearer. One can easily just do

 

set Gravity = 8;

 

The set keyword just helps the parser discern between properties, flags, etc., without using a symbol hell (+, -, etc).

 

Also, thanks for the compliment!

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
×