ZScript "Standard Library" - Brainstorming

Post your example zscripts/ACS scripts/etc here.

Re: ZScript "Standard Library" - Brainstorming

Postby Major Cooke » Sat Mar 04, 2017 9:03 am

Not trying to rain on your parade but:

  1. Consider using a regular zip file instead of .7z so people can open it up with SLADE.
  2. I don't really see what purpose this may serve, honestly.

Maybe I'm just blind to what it could be for, but one could easily replace it with something like this:

Code: Select allExpand view
if (!master) return Destroy();
double mpitch = master.pitch;
double mang = master.angle;
Vector3 StickerPos = master.Vec3Angle(cos(mpitch) * 20, mang, -sin(mpitch) * 20);
SetOrigin(StickerPos);


And if you just want the roughest degree to be a whole number, turn mpitch and mang into ints.
User avatar
Major Cooke
Slaughterer of Sewers
 
Joined: 28 Jan 2007
Discord: Major Cooke#0846

Re: ZScript "Standard Library" - Brainstorming

Postby Matt » Sat Mar 04, 2017 1:13 pm

You're also the guy who told me it wouldn't make any difference making the same calculation 6 times in a row as opposed to storing a variable.

However, I did finally get around to benchmarking it:
Code: Select allExpand view
class CrudeSiner:IdleDummy{
   states{
   spawn:
      BAL1 A 1 nodelay{
         for(int i=0;i<10000000;i++){
            speed=(HDLib.CrudeSine(self,24));
         }
         A_LogInt(speed*1000);
      }wait;
   }
}
class FineSiner:IdleDummy{
   states{
   spawn:
      BAL1 A 1 nodelay{
         for(int i=0;i<10000000;i++){
            speed=(sin(24));
         }
         A_LogInt(speed*1000);
      }wait;
   }
}
and while the native sin function on the bottom got me around 1300ms per frame, that number went up to over 27000ms with the lookup table, so unfortunately it is useless.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
 
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: ZScript "Standard Library" - Brainstorming

Postby Major Cooke » Sat Mar 04, 2017 1:30 pm

I was in a rush, didn't read it properly, that's all. I thought it was an organization thing you were asking, not what you had originally asked.

Anyway, yes. I figured the sine table would've been problematic, and that's why I suggested the other thing.
User avatar
Major Cooke
Slaughterer of Sewers
 
Joined: 28 Jan 2007
Discord: Major Cooke#0846

Re: ZScript "Standard Library" - Brainstorming

Postby Gez » Sat Mar 04, 2017 1:38 pm

Vaecrius wrote:while the native sin function on the bottom got me around 1300ms per frame, that number went up to over 27000ms with the lookup table, so unfortunately it is useless.

Yeah, the overhead from calling a VM function is so great that the gain from using a precomputed table is irrelevant.
Gez
 
 
 
Joined: 06 Jul 2007

Re: ZScript "Standard Library" - Brainstorming

Postby ZZYZX » Sat Mar 04, 2017 2:07 pm

What happens if you use an array without a function, like sintab[int(angle)%360]? Does it give any performance boost?
User avatar
ZZYZX
I SEE WHAT YOU DID THERE
 
Joined: 14 Oct 2012
Location: Ukraine

Re: ZScript "Standard Library" - Brainstorming

Postby Matt » Sat Mar 04, 2017 4:12 pm

How do you do that, though? Please don't tell me we need to do sintab[0]=0 all the way through 360...
User avatar
Matt
Putting the XD into *xdeath since 2007
 
 
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: ZScript "Standard Library" - Brainstorming

Postby ZZYZX » Sat Mar 04, 2017 4:19 pm

Fill it somehow. For example, on BeginPlay of a persistent thinker. for (int i = 0; i < 360; i++) sintab[i] = sin(i);
User avatar
ZZYZX
I SEE WHAT YOU DID THERE
 
Joined: 14 Oct 2012
Location: Ukraine

Re: ZScript "Standard Library" - Brainstorming

Postby Matt » Sat Mar 04, 2017 4:50 pm

> asks how to process a large group of numbers on a computer
> use the computer

:oops:

Anyway:
Code: Select allExpand view
/*
vid_fps 1;summon cs;
vid_fps 1;summon fs;
*/

class cs:Actor{
   double sintab[360];
   states{
   spawn:
      BAL1 A 10 nodelay{
         for(int i=0;i<360;i++){
            sintab[i]=sin(i);
         }
      }
      BAL1 A 1{
         for(int i=0;i<10000000;i++){
            speed=sintab[24];
         }
         A_LogInt(speed*1000);
      }wait;
   }
}
class fs:Actor{
   states{
   spawn:
      BAL1 A 10;
      BAL1 A 1{
         for(int i=0;i<10000000;i++){
            speed=sin(24);
         }
         A_LogInt(speed*1000);
      }wait;
   }
}


cs:~1550 ms/frame

fs: ~1440 ms/frame

So the native sine calculation is still faster.
User avatar
Matt
Putting the XD into *xdeath since 2007
 
 
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: ZScript "Standard Library" - Brainstorming

Postby Nash » Sun Mar 05, 2017 1:32 am

Vaecrius wrote:How do you do that, though? Please don't tell me we need to do sintab[0]=0 all the way through 360...


Make a Console.Printf that writes code for you, and use Logfile before you execute it.

This was what I did to pre-generate array assignments for ~379,000 x 3 variables. It generated a 112 MB ZScript source file. >8D Of course, as I found out, the program actually froze at startup as it tried to compile...

So to answer the question, no, pre-generating your arrays probably won't help either.
User avatar
Nash
 
 
 
Joined: 27 Oct 2003
Location: Kuala Lumpur, Malaysia

Re: ZScript "Standard Library" - Brainstorming

Postby Matt » Sun Mar 05, 2017 2:25 am

Could your situation have been helped if you somehow broke it up so you only did like a few dozen lines per tic or something?
User avatar
Matt
Putting the XD into *xdeath since 2007
 
 
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: ZScript "Standard Library" - Brainstorming

Postby Nash » Sun Mar 05, 2017 2:32 am

Hmm actually my situation is a little different. There were 379k things placed in the map. The map editor would crash if I attempted to add more.

So I had the idea that, instead of pre-placing the things and then at World Load, do a 379-thousand-step for loop to fill in the array (like what you did above)... what if I pre-generate the coordinates and classes into an array list. So I can delete all the things in the map, and the trees would have been "placed" via array definitions instead.

There's no way I'm going to type 379,000 times tree[0].x, tree[0].y, tree[0].class "blah"... so I used a Console.Printf and +logfile to help write code for me. x3

That wasn't a good idea at all, because the program won't even start.

The for loop on map load was actually faster, MUCH faster!

Anyway it wasn't a serious project, just wanted to mess around with ZScript and see what works and what doesn't.
User avatar
Nash
 
 
 
Joined: 27 Oct 2003
Location: Kuala Lumpur, Malaysia

Re: ZScript "Standard Library" - Brainstorming

Postby ZZYZX » Sun Mar 05, 2017 12:10 pm

Nash wrote:Make a Console.Printf that writes code for you, and use Logfile before you execute it.

This was what I did to pre-generate array assignments for ~379,000 x 3 variables. It generated a 112 MB ZScript source file. >8D Of course, as I found out, the program actually froze at startup as it tried to compile...

So to answer the question, no, pre-generating your arrays probably won't help either.

Or write a Python script already and stop trying to use ZScript as a general purpose language :P
At least not until file(lump) reading/writing is done properly, lol.
User avatar
ZZYZX
I SEE WHAT YOU DID THERE
 
Joined: 14 Oct 2012
Location: Ukraine

Re: ZScript "Standard Library" - Brainstorming

Postby Graf Zahl » Sun Mar 05, 2017 1:51 pm

Vaecrius wrote:and while the native sin function on the bottom got me around 1300ms per frame, that number went up to over 27000ms with the lookup table, so unfortunately it is useless.


The native sine function already uses a table, so you'll have a very hard time beating that. I optimized the hell out of it and it's possibly the most precise fast sine function you'll ever get.
And that doesn't even factor in the VM overhead for calling a script function, which alone is a lot more than the sine function requires to do its job.
User avatar
Graf Zahl
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: ZScript "Standard Library" - Brainstorming

Postby Matt » Tue Mar 07, 2017 7:59 pm

Good to know! I did notice in my subsequent attempts to benchmark stuff that sine functions were abnormally fast compared to what I had been expecting relative to everything else.

(Though I suppose given how relevant these calculations are to projectiles, movement, weapon bobbing, etc. etc. etc. I guess I shouldn't have expected anything less!)
User avatar
Matt
Putting the XD into *xdeath since 2007
 
 
 
Joined: 04 Jan 2004
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: ZScript "Standard Library" - Brainstorming

Postby ZZYZX » Fri Mar 24, 2017 2:37 pm

Hello so I made this https://github.com/jewalky/zgui

You can use it like so:
Code: Select allExpand view
class Doom3Element : Element
{
   TextureID mMouseCursor;
   
   override void OnCreate()
   {
      mRect = Rect.FromXYWH(0, 0, Screen.GetWidth(), Screen.GetHeight());
      mScale = 2;
   
      mMouseCursor = TexMan.CheckForTexture("graphics/D3Mouse.png", TexMan.Type_Any);
      AddChild(new('Doom3Doom').Init());
   }

   override void Draw()
   {
      Drawer d = GetDrawer();
      vector2 mouse = GetMouseXY();
      d.DrawTexture(mMouseCursor, false, mouse.x, mouse.y);
   }
}

class Doom3Menu : ListMenu
{
   Element e;

   override void Init(Menu parent, ListMenuDescriptor desc)
   {
      Super.Init(parent, desc);
      DontDim = true;
      
      e = new('Doom3Element').Init();
      e.OnCreate();
   }

   override bool OnUIEvent(UiEvent ev)
   {
      if (e) return e.OnProcessUi(ev);
      return false;
   }
   
   override bool OnInputEvent(InputEvent ev)
   {
      if (e) return e.OnProcessInput(ev);
      return false;
   }

   override void Drawer()
   {
      if (e) e.OnDraw();
   }

   override void Ticker()
   {
      if (e) e.OnTick();
   }
}

What it does: it allows you to have a WM-style hierarchy of Elements with automatic scaling, clipping, text align and wrapping.
Each Element can have a position inside the parent Element (mRect field), and scale of child elements (mScale field). The scale also affects perceived width/height of the Element (the client rect).
Topmost Element has mParent=null which means that it's using the real screen coordinates and scale of 1.0.

Functions exposed to the user are these:
Code: Select allExpand view
   virtual void OnCreate()
   {
      
   }
   
   virtual bool Process(ElementEvent ev)
   {
      return false;
   }
   
   virtual void Tick()
   {
      //
   }
   
   virtual void Draw()
   {
      //
   }

The preferred way of constructing Elements is calling "new ('Element').Init()", for example. That automatically sets certain fields to the initial values, otherwise you might end up with a wild null pointer error.
Unobviously enough, OnCreate is actually called when you add a child element, on the child. For a root element, you have to call OnCreate manually or it won't get a chance to initialize.

You can draw things by receiving an instance of Drawer class:
Code: Select allExpand view
Drawer d = GetDrawer();
And then using it's methods to draw things as opposed to directly using Screen.
Alternatively, you can instantiate a drawer by using
Code: Select allExpand view
Drawer d = Drawer.Create(self);
or even
Code: Select allExpand view
Drawer d = Drawer.CreateMod('Drawer', self);
The latter option is for custom Drawer classes if you want to do some fancy stuff.

Also, the system doesn't care about your input/rendering backend — you can provide OnProcessUi/OnProcessInput/OnTick by an event handler, and OnDraw by DrawPowerup (I blame Graf for consistently removing any ways to draw anything while playing the game and providing no alternative), or you can do all this in a menu.
The system is able to receive mouse input both from UiEvent and InputEvent — the elements will receive an uniform ElementEvent anyway. This means that it transparently supports both enabled and disabled mouse in menus.
ElementEvent is the same as UiEvent, except there is no information about pressed modifier keys (yet?)
Also, you can receive the current mouse coordinates relative to the current element (including all scaling) by using GetMouseXY() — which returns a vector2, see the example.

What it doesn't have yet is setting arbitrary clipping values in a Drawer. That'll be added eventually.
Added, actually.

The system is kinda new and untested, pls report bugs if anyone is actually going to use this.
User avatar
ZZYZX
I SEE WHAT YOU DID THERE
 
Joined: 14 Oct 2012
Location: Ukraine

PreviousNext

Return to Script Library

Who is online

Users browsing this forum: No registered users and 1 guest