Page 2 of 3

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Wed Nov 20, 2019 11:15 am
by Gustavo6046
I am in the process of adding a condition system, where one can use AND, OR and NOT to check conditions (which are state action templates that jump a given number of states only in the desired condition). Those are special macros that can be used as components in conditions (in statements like while, if, etc.).

Code: Select all

class FrogBoots extends Inventory {
    set Inventory.MaxAmount to 1;
}

class Tired extends Inventory {
    set Inventory.MaxAmount to 3;
}

class FrogZombie extends ZombieMan replaces ZombieMan {
    condition<Offset> C_HasInventory(InventoryName, Amount = 1) {
        TNT1 A 0 A_JumpIfInventory(InventoryName, Amount, Offset);
    }

    condition<Offset> C_Closer(Distance) {
        A_JumpIfCloser(Distance, Offset);
    }

    condition<Offset> C_OnFloor() {
        A_JumpIf(z < floor + 1, Offset);
    }

    label Spawn {
        TNT1 A 0;
        TNT1 A 0 A_Give("FrogBoots");
        goto Super.Spawn;
    }

    macro Jump {
        TNT1 A 0 {
            A_FaceTarget();
            ThrustThingZ(0, 30, 0, 0);
            ThrustThing(angle * 256 / 360, 25, 1, 0);
        }
    }

    label See {
        if (HasInventory("Tired"))  POSS ABCD 10 A_Chase;
        else                        POSS ABCD 4  A_Chase;

        sometimes 15 if (C_HasInventory("FrogBoots") && !C_Closer(128) && !C_HasInventory("Tired", 3) && C_OnFloor()) {
            TNT1 A 0 {
                A_Give("Tired", 1);
                inject Jump;
            };
        }
    
        sometimes 20 TNT1 A 0 A_Take("Tired", 1);

        loop;
    }
}
ZDCode will internally use offset jumps to compute these conditions in the generated DECORATE output.
CBM wrote:anything in zcode II that will make generation of actors based soly on frame information very easy?
What exactly do you mean frame information?

Also, a complete specification & documentation of the language is still in the todo list. I haven't gotten to do it yet.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Wed Nov 20, 2019 1:24 pm
by TDRR
Gustavo6046 wrote:Also, a complete specification & documentation of the language is still in the todo list. I haven't gotten to do it yet.
If it helps, i have been doing a tutorial of sorts that runs through various use-cases of ZDCode. Thing is, i don't have many use cases for all of the new features ZDCode has.
I only got basic conversion from DECORATE to ZDCode, and usage of functions and macros to this point. If you think it may be useful to you i can send it over though it's not much.

SLADE should support ZDCode, that would be really awesome. At least compiling from SLADE directly instead of compiling and putting that into the .pk3, and syntax highlighting would be cool but just that would be nice. Ever thought of asking SLADE's dev for such a thing?

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Fri Nov 29, 2019 8:12 pm
by Gustavo6046
I took a brief break from ZDCode, but development will resume either Saturday or Sunday.

Good night.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Sun Mar 29, 2020 8:32 pm
by Gustavo6046
A new update has come out! Welcome to ZDCode 2.6.1. Template classes, abstract labels and macros, many things that can be parametrized (from expressions to repeat and chance values to freaking sprite names!), and much, much more! You're excited? So am I! It's available in the GitHub repository. You can run it using Python and "dist/zdcode.pex", which comes with all the libraries needed to run it. You'll still need Python 3, though.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Tue Mar 31, 2020 9:42 am
by Kappes Buur
Gustavo6046 wrote:A new update has come out! Welcome to ZDCode 2.6.1.
It appears that Github has only up to 2.5.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Tue Mar 31, 2020 3:01 pm
by Gustavo6046
That's odd. Its latest commit is the 2.6.4 one, and that should be reflected when you download ZDCode in either the pex or source format. I'm not sure what you mean.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Tue Mar 31, 2020 3:31 pm
by Kappes Buur
Gustavo6046 wrote:I'm not sure what you mean.
When I click on the Github link in the OP I get this
Spoiler:
releases 2.5.0 and below

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Tue Mar 31, 2020 7:07 pm
by Gustavo6046
Oh. I forgot to add a Release. Thank you for pointing this out!

I will still be unable to annex a .exe file. Remember, this is still Python, and even the top freezers (like PyInstaller) can't build against a system other than the host one! And using Wine does not seem to fix this. However, I will add a .pex file, which requires only the Python runtime, and does not need any further setup. Win win!

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Mon Apr 06, 2020 11:25 am
by Gustavo6046
I feel like I should have addressed this question waaay ago.
TDRR wrote:SLADE should support ZDCode, that would be really awesome. At least compiling from SLADE directly instead of compiling and putting that into the .pk3, and syntax highlighting would be cool but just that would be nice. Ever thought of asking SLADE's dev for such a thing?
I think sirjuddington has more to worry about than a random convoluted Python project that compiles a silly syntax to a language superseded to ZScript. This thing would have made so much more sense a few years ago, when "DoomScript" was but a rumor.

Besides, I was thinking, maybe we should instead make the ecosystem, where ZDCode projects are bundled into a single DECORATE file. In fact, this ZDCode part would just be an extension to the actual ecosystem, whose actual job would be to build PK3 files from a filesystem project. So I don't have SLADE in mind right now.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Fri May 01, 2020 1:27 pm
by Gustavo6046
v2.8.0 is out! Conditional flow is now great again!

Code: Select all

    macro Tick_Chase {
        TNT1 A 0 A_FaceTarget(2);

        // bite if possible!
        TNT1 A 0 A_JumpIfTargetInsideMeleeRange("Melee");

        // "more realistic eye movements"
        sometimes 15 ifjump A_JumpIfTargetInLOS($offset, 15) {
            x 4 TNT1 A 0 A_SetAngle(angle + Random(-5, 5));
        };

        // chase!
        ifjump A_JumpIfTargetInLOS($offset) TNT1 A 0 {
            A_FaceTarget(12);
            A_Recoil(-0.55);
        };

        // can't see target... :c
        else {
            TNT1 A 0 A_ClearTarget;
            goto Idle;
        };
    };
...and A_Jump(255) pays for it!

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Sun May 17, 2020 3:48 pm
by Gustavo6046
You know what? Since it is often needed to interoperate between separate lumps (like keeping TEXTURES, SNDINFO, DECORATE, ACS stuff, etc in sync with each other), I will
slowly deprecate ZDCode II in favor of something much larger, much prettier, and a powerful, convenient all-in-one modding and project organization solution. Please hang on as I work on the ZDK!


EDIT: This idea for ZDK (or Zad) is actually not a good idea and has been scrapped. I was instead thinking about having it being a framework to generate ZDoom mods with definitions in a language like Python. Probably not Python.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Tue Aug 11, 2020 12:03 pm
by Gustavo6046
ZDCode is still being maintained. In fact, I added a few nifty features lately. Check the README in the repository for a somewhat comprehensive list (not including minor things like frame unrolling, state keyword parameter expansion, etc).

One of the shiniest additions is the dynamic state modifier block. "Dynamic" is a bit of a misnomer - it is compile-time, as eveything else in ZDCode ever -, but it is very powerful and not too difficult to understand.

A modifier is composed of clauses, where each clause applies a set of one or more effects to a state selector. Modifiers are declared and applied separately, using the class-level mod blocks and the state-level apply blocks, respectively.

Code: Select all

class DiscoZombie extends Zombieman {
    mod DiscoLight {
        (sprite(TNT1)) suffix TNT1 A 0 A_PlaySound("disco/yeah"); // now we can use TNT1 frames to play some weird sound!

        (all) +flag Bright; // Always bright, all the time!
    };

    label Spawn {
        apply DiscoLight {
            POSS AB 4;
        };

        loop;
    };

    // You can also apply the modifier to other state labels (like See or Missile)
    // using the apply syntax, but you get the gist.
}
State selectors can actually use boolean operators, which is cool but in retrospect does not seem all that useful really. But hey, it's cool!
It also supports multiple effects per selector, and effects that take a state as argument (such as prefix or suffix) can actually take a state block, too.

Code: Select all

class LitZombie extends Zombieman {
    mod Lit {
        // Only lit POSS frames, and only if they have the BRIGHT keyword.
        (sprite(POSS) && flag(Bright)) {
            prefix invisi A_SpawnItemEx("OooShinyZombieFlare");
            -flag Bright;
        };
    };

    label Spawn {
        apply DiscoLight {
            POSS AB 4;
        };

        loop;
    };

    // You can also apply the modifier to other state labels (like See or Missile)
    // using the apply syntax, but you get the gist.
}
There is also a more advanced effect, called manipulate, that basically allows you to replace affected states, as you supply a replacement block of states, and may inject the original state as if it were a macro.

Code: Select all

class SpinZombie extends Zombieman {
    mod SpinAndRepeat {
        (!sprite(TNT1)) {
            +flag Bright;
            manipulate State {
                x 24 {
                    invisi A_SetAngle(angle + 15);
                    inject State; // state duration effects (and selectors) will be added soon(TM)
                };
            };
        };
    };

    label Missile {
        POSS E 10 A_FaceTarget;
        apply SpinAndRepeat POSS F 8 A_PosAttack;

        POSS EDE 10; // phew!..
        goto See;
    };
}
Also, what about the Zad? The Zad is not necessary. We have many tools, already. SLADE, etc. It would be more productive to add PK3 and UDMF support to Eureka or something, I don't know. Maybe for asset organization and artifact output, such as producing variations of a mod with omitted lumps and different ZDCode preprocessor definitions. Or just building C libraries, I don't know if ZDoom already has some FFI interface for code placed in PK3s or whatever.

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Fri Aug 14, 2020 2:17 pm
by Gustavo6046
Sorry for this yet another post in what may have become a spree, but I am very stoked now as I announce that I have successfully finished the build system, Zake.
(get it? Make, but with a Z.. haha I'm hilarious)

Rather than having to write command-line arguments, simply write a Zake.ini file!
This example from GitHub demonstrates the capabilities well:

Code: Select all

# Builds the ZDCode example mod, as 'ZDWorld';

[General]
Name: ZDWorld
Version: 2.11.1
Targets: debug release

[Paths]
Inputs = example/assets
Bundle.Asset: example/out/${name}-${version}-${target}-asset.pk3
Bundle.Code: example/out/${name}-${version}-${target}-code.pk3
Decorate: example/out/${name}-${version}-${target}.dec

[Definitions.debug]
# only define it, no value (ifdef checks for key presence anyway)
DEBUG =

  • The General section specifies the name and the version of the project (currently used only as parameters to format other text), as well as a set of targets.
  • The Paths section specifies inputs (a set of entry points ZDCode is to process) and outputs (the location of the output asset PK3, code PK3, and the DECORATE output for debugging purposes).
  • The Definitions section is a list of preprocessor definitions to be used in source files compiled by ZDCode.
For each target, there can be "subsections", which are values specific to the build of that target, overriding the more general values. In the example above, there is [Definitions.debug], which means that DEBUG is only set in the debug build.

What this means is that you can have things like this...

Code: Select all

            manipulate State {
                x 12 {
                    invisi A_SetAngle(30 + angle);
                    inject State;

                    #ifdef DEBUG // <-- here
                        invisi A_LogFloat(angle);
                    #endif
                };
And ZDCode will, of course, build each target with its respective settings and paths:



And, if you compare the DECORATE outputs of both builds, you'll see that the A_LogFloat calls are, indeed, omitted entirely from the Release build:

Code: Select all

Actor SpinZombie : Zombieman // debug
{
    
    States {
        Missile:
            POSS E 10 A_FaceTarget
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_LogFloat(angle)
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_LogFloat(angle)
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                ...
    }
}

Code: Select all

Actor SpinZombie : Zombieman // release
{
    
    States {
        Missile:
            POSS E 10 A_FaceTarget
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                TNT1 A 0 A_SetAngle(30 + angle)
                POSS F 4  Bright A_PosAttack
                ...
    }
}

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Sun Oct 18, 2020 10:05 am
by CBM
Gustavo6046 wrote:
CBM wrote:anything in zcode II that will make generation of actors based soly on frame information very easy?
What exactly do you mean frame information?

Also, a complete specification & documentation of the language is still in the todo list. I haven't gotten to do it yet.
anything really that can easy the use of 3d models in gzdoom...

here are some examples, instead of this

Code: Select all

Model ultramarinetactical
{ 
   Path "Models\spacemarine"
   Model 0 "tacticalmarine.md3"

	SurfaceSkin 0 0 "Models\spacemarine\default_2.tga"
	SurfaceSkin 0 1 "Models\spacemarine\default_2.tga"
	SurfaceSkin 0 2 "Models\spacemarine\default_2.tga"	
	SurfaceSkin 0 3 "Models\spacemarine\default_1.tga"
	SurfaceSkin 0 4 "Models\spacemarine\default_2.tga"
	SurfaceSkin 0 5 "Models\spacemarine\bolter.tga"
	SurfaceSkin 0 6 "Models\spacemarine\fire.tga"
	
   Scale 1.15 1.15 1.15
   offset 1.0 1.0 1.0
   
   // 1 standing
   FrameIndex umta A 0 0	
   
   // 164-176 walk
   FrameIndex umta B 0 166	
   FrameIndex umta C 0 170	
   FrameIndex umta D 0 175
   
   // 137-139 attack
   FrameIndex umta E 0 134	
   FrameIndex umta F 0 272	
   FrameIndex umta G 0 138
   
   // 34 pain
   FrameIndex umta H 0 135
   
   // 58-80 death 
   FrameIndex umta I 0 58	
   FrameIndex umta J 0 59	
   FrameIndex umta K 0 60
   FrameIndex umta L 0 61	
   FrameIndex umta M 0 62	
   FrameIndex umta N 0 63
   FrameIndex umta O 0 64	
   FrameIndex umta P 0 65	
   FrameIndex umta Q 0 66
   FrameIndex umta R 0 67	
   FrameIndex umta S 0 68	
   FrameIndex umta T 0 69
   FrameIndex umta U 0 70	
   FrameIndex umta V 0 71	
   FrameIndex umta W 0 72
   FrameIndex umta X 0 73	
   FrameIndex umta Y 0 74	
   FrameIndex umta Z 0 79
}
I would rather write this

Code: Select all

Model ultramarinetactical
{ 
   Path "Models\spacemarine"
   Model 0 "tacticalmarine.md3"

	SurfaceSkin 0 0 "Models\spacemarine\default_2.tga"
	SurfaceSkin 0 1 "Models\spacemarine\default_2.tga"
	SurfaceSkin 0 2 "Models\spacemarine\default_2.tga"	
	SurfaceSkin 0 3 "Models\spacemarine\default_1.tga"
	SurfaceSkin 0 4 "Models\spacemarine\default_2.tga"
	SurfaceSkin 0 5 "Models\spacemarine\bolter.tga"
	SurfaceSkin 0 6 "Models\spacemarine\fire.tga"
	
   Scale 1.15 1.15 1.15
   offset 1.0 1.0 1.0
   
   // 1 standing
   FrameIndex umta A 0 0	
   
   // 164-176 walk
   FrameIndex umta B 0 166	
   FrameIndex umta C 0 170	
   FrameIndex umta D 0 175
   
   // 137-139 attack
   FrameIndex umta E 0 134	
   FrameIndex umta F 0 272	
   FrameIndex umta G 0 138
   
   // 34 pain
   FrameIndex umta H 0 135
   
   // 58-80 death 
   FrameIndex umta I-Z 0 58-79	
}
and instead of this

Code: Select all

actor ultramarinetactical : ChaingunGuy 
{
	//$Category Models/Ultramarines
	//$Title Ultramarines Tactical Marine
  Health 300
  SeeSound "umsg/sight"
  PainSound "umsg/pain"
  DeathSound "umsg/death"
  ActiveSound "umsg/active"
  DropItem "Backpack" 
 Obituary "%o was shot, ripped and teared to death by a tactical ultra marine."
   States
  {
  Spawn:
    umta A 10 a_look 
	loop
    See:
    umta AABBCCDD 2 Fast A_Chase
    Loop
  Melee:
  Missile:
	umta E 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta G 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta E 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta G 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta E 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta G 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta E 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta G 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta E 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta G 1 A_FaceTarget	
	umta F 1 BRIGHT A_CPosAttack
	umta E 1 A_FaceTarget	
	umta G 1 BRIGHT A_CPosAttack	
	Goto See
  Pain:
    umta H 2 Fast
    umta H 2 Fast A_Pain
    Goto See
  Death:
    umta IJ 4
    umta KLM 4	
    umta NOP 8 A_Scream
    umta QRS 4
    umta TUV 4 A_NoBlocking
    umta WXY 4
    umta Z -1
    Stop
  Raise:
    umta ZYXWVUTSR 5
    umta QPONMLKJI 5
    Goto See	
  }
}
Id rather write this

Code: Select all

actor ultramarinetactical : ChaingunGuy 
{
	//$Category Models/Ultramarines
	//$Title Ultramarines Tactical Marine
  Health 300
  Sounds "umsg"
  DropItem "Backpack" 
 Obituary "%o was shot, ripped and teared to death by a tactical ultra marine."
   States
  {
  Spawn:
    umta A 10 a_look 
	loop
    See:
    umta AABBCCDD 2 Fast A_Chase
    Loop
  Melee:
  Missile:
        loop E,F,G 1 12 times
{ 
       A_FaceTarget	
       BRIGHT A_CPosAttack
      A_FaceTarget
}
	Goto See
  Pain:
    umta H 2 Fast
    umta H 2 Fast A_Pain
    Goto See
  Death:
    umta IJ 4
    umta KLM 4	
    umta NOP 8 A_Scream
    umta QRS 4
    umta TUV 4 A_NoBlocking
    umta WXY 4
    umta Z -1
    Stop
  Raise:
    umta ZYXWVUTSR 5
    umta QPONMLKJI 5
    Goto See	
  }
}

Re: ZDCode II - The pretty language that compiles to DECORAT

Posted: Sun Oct 25, 2020 7:38 pm
by Gustavo6046
@CBM I think you mean looping states. Yes, that functionality does exist and is implemented in ZDCode; in fact it's one of the earliest additions to the language! The keyword "x", followed by a number, will repeat the succeeding state or block of states that number of times.

However, there is no GLDEFS support; ZDCode can only compile to DECORATE. The bundler can include GLDEFS lumps, and any other lumps, if you specify a PK3 as an input file in the command line (which automatically converts ZDCODE.* into DECORATE lumps, as well as optional dependency resolution ). The bundler can only operate with PK3 files, not WADs. I never actually used GLDEFS, so there are no warranties that any conditions or restrictions required by GLDEFS be respected by the DECORATE code generated by the ZDCode compiler.