Jump to content

Photo

Script critique and advice thread


  • Please log in to reply
17 replies to this topic

#16 Avaro

Avaro

    o_o

  • Members
  • Real Name:Robin
  • Location:Germany

Posted 02 March 2020 - 04:42 PM

I'm facepalming right now at missing those logic errors. I think the Delay was generally an afterthought and I haven't been using it for diagonal ones. But yeah, good advice.



#17 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 03 March 2020 - 06:28 AM

 

Arr[indx[subindx]] has always been valid. I think end of line braces look nicer because it saves a lot of space and there are no problems. And yes, I highly suggest coding with code editors, as they greatly improve your convenience for coding.

 

 

....???

 

I actually tested this prior to posting.

 

void foo()
{
    int arr[2];
    int snd[5];
    snd[0] = arr;
    int x = snd[0[5]];
}
 

 

line 6: syntax error, unexpected LBRACKET, expecting RBRACKET or OR, on token [
 

 

Do you have a script that does this without any intermediates?

 

You can do it if you pass the first array into a function, as the function param is an intermediate, but raw access AFAIK never allowed it.



#18 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 03 March 2020 - 06:58 AM

That would be pretty easy to optimize out, wouldn't it? It's not a big deal either way, but I typically don't like implicitly casting numbers to bools.


I suppose this is simply a matter of whether you are comfortable with pure boolean statements. Optimising it might be icky. The Bison would need to compare the RHV of all != or == operations to see if it is 0, but, I suppose it's possible. This is a case where, using appropriate identifiers, I feel that a boolean if can be more readable, but it is contextual.
 
 

It can be overdone, sure. Too many functions doing too little, it can get hard to find code that actually does anything. It takes some effort, though. I think it's generally better to err on the side of too much abstraction at first. It's easier to remove excessive function calls than to find where you should have put them in the first place, and it's easier to write code without thinking about high-level behavior and low-level implementation details both at once.

The limitations of the language are an issue here, too. Most languages have instance variables. In ZScript, functions are usually the closest you can get in terms of readability, though using ffc->Misc or another array with reasonable constant indices is often good enough.



OOP languages do, certainly, but F-P don't require them. Note however, that they are on our future to-do list for class, struct, array.

I wouldn't mind seeing a snippet of where you need an instance in ZScript to accomplish a goal that is handled by function nest abstraction. The trick of course, is always balance. Having read through stuff such as the Solarus base, it's far too easy to become lost in a soup of strewn-around code.

 

Not "still"; I switched to them about a year ago, when I learned Rust. The extra vertical whitespace came to bother me more over time, and it's particularly bad in Rust, where short, inline blocks are common and braces after if and else can never be omitted.



Ah, Rust. That explains a bit. The debate over EOL/NL brace has been happening for over 45 years, and will never end. In very old specs, the standard was 72 col lines with braces at EOL, to save screen space. Most code editors simply do a better job with matching and collapsing with NL braces, but if it has become a habit due to using other stuff, then I can see it being hard to go back and forth.
 
NGINX also uses this style.
 
 
 

I would say that's a different problem. If you've got lines so long you can't see the ends of them, they're too long. And long, complex if statements are especially bad.




Indeed. I covered it earlier, and I have examples of how to fix it in the ZS style guide. In general, when i write a very long statement, I use this style:
 

if
(
    Collision(a) && Link->X > 16 && Link->Y > 16
        && Link->X < 200 && Link->Y < 180
        && Link->InputA
        && (Link->InputUp || Link->InputDown)
        && OnSizeViewPlatform()
)
{
    DoAThing();
}

This matches parens and it matches braces in a linear manner, and it presents all logical statements in an easy to view list.

(Offtopic a bit here, putting in hidden tag.)
 


 

Soooo, I suppose I can post a script for critique too. I'm not particularly looking for any, but why not? I know that there's a bit of repeated code there which could have probably been avoided with some more effort. (This is a scripted trap. Simple. Free for use.)

 
I'm going to go with Saffith here. Unless you need to worry about direction of hit, boots interaction, or specific damage amount, then you can use the this->Data to point to a combo with a damage type. If this is in 2.55, you can set up damage combos to harm the player by any arbitrary HP value. As your damage is '4', a 2-heart combo suffices.
 
Turn off the Ethereal flag to do this.
 
The entire script could simply change the ffc speed when it hits a wall. (Remember, ffcs have internal movement properties; you need only set them to *= -1 to invert them when the ffc hits a boundary.)
 
Basically:

if ( atScreenEdge(this) || atWall(this) )
{
    Game->PlaySound(SFX_CHINK);
    if ( horiz ) this->Vx *= -1;
    else this->Vy *= -1;
}

I suppose you can cache Link->Dir every frame and if HitDir != -1, set it to an appropriate dir based on his dir and the trap dir.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users