Jump to content

I'm bored, lets debate something, STATES!


Ichi Rexen
 Share

You are about to reply to a thread that has been inactive for 1038 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

On the subject of flushing variables (listen handles and whatever), I have found that it's quite handy to create a separate state for that purpose.  For example:
 

state cleanup
{
    iMode = 0;
    kUser = NULL_KEY;
    iLoopCounter = 0;
    fAlpha =1.0;
    state new_victim;
}

I could do the same things with a user-defined function or with a state_exit event, although I would need to close listen handlers explicitly if I used those approaches.  Again, it comes down to convenience for me as the scripter.  Especially if my script already has other states, separating the "reset these things" functions into a nice clean module keeps me from forgetting one or more of them.  Purely a matter of style, but it helps keep me sane.  (Or as sane as I can hope for.)

 

    

  • Like 3
Link to comment
Share on other sites

40 minutes ago, steph Arnott said:
41 minutes ago, Wulfie Reanimator said:

"=!" is not an operator. It is two operators; "=" (assignment) and "!" (logical not).
"!=" is an operator. It means "not equal".

Means the same thing.

I don't like how you jump on people and tell them they don't know what they're talking about, when you make that same mistake in the same thread. Those two things do completely different things. The fact that you try to deny that there's a difference between assignment and comparison just makes it obvious to anybody else reading that you're not knowledgeable. Put this into a script and study it:

integer a = 1;
integer b = 2;
integer result;

result = (a != b); llOwnerSay( (string)result );
result = (a = !b); llOwnerSay( (string)result );
result = (a=!b);   llOwnerSay( (string)result );

Also, please answer my earlier question to you.

And just to echo what others have already said, I don't find states very useful beyond disabling touch and clearing listens. Fragmenting the logic of a script into multiple pieces is something I would want to avoid as much as possible, to keep the script easy to maintain for myself and whoever else might look at it.

Edited by Wulfie Reanimator
Removed a bit as I missed the context.
  • Like 4
Link to comment
Share on other sites

10 minutes ago, Wulfie Reanimator said:

I don't like how you jump on people and tell them they don't know what they're talking about, when you make that same mistake in the same thread. Those two things do completely different things. The fact that you try to deny that there's a difference between assignment and comparison just makes it obvious to anybody else reading that you're not knowledgeable. You also try to pull the "good/bad code or practice" card, but you use code without any spacing which is very bad practice. It has clearly lead you to wrong conclusions about very simple things. Put this into a script and study it:


integer a = 1;
integer b = 2;
integer result;

result = (a != b); llOwnerSay( (string)result );
result = (a = !b); llOwnerSay( (string)result );
result = (a=!b);   llOwnerSay( (string)result );

 

And just to echo what others have already said, I don't find states very useful beyond disabling touch and clearing listens. Fragmenting the logic of a script into multiple pieces is something I would want to avoid as much as possible, to keep the script easy to maintain for myself and whoever else might look at it.

'I don't like how you jump on people and tell them they don't know what they're talking about' so a new state invokes 5KBs, or that inisgniifcant byte code invokes 500bytes is NOT bull? Also all you did with that code is prove my point, thank you. FYI i do not care what you 'like'. I was not involved in your 'lets praise them even if they dumb' education mentality. Where i was educated results are FACTUAL results.

Edited by steph Arnott
  • Sad 1
Link to comment
Share on other sites

17 minutes ago, Wulfie Reanimator said:

I don't find states very useful beyond disabling touch and clearing listens. Fragmenting the logic of a script into multiple pieces is something I would want to avoid as much as possible, to keep the script easy to maintain for myself and whoever else might look at it.

Yup.  I think a lot of scripters will probably feel the same way.  It's a matter of what you feel most comfortable with, like many choices we make in writing code.  Sometimes it is most important to write code that saves memory or executes very quickly or meets some other task imperative.  For me, though, my top priority is almost always writing code that will be easy for me to debug and easy to pirate later for other projects.  My own mind sees scripting challenges most easily in bite-sized chunks, so I often opt to use states so that I can focus on one chunk at a time.  Many other scripters find it easier to code within a single state so that they don't need to carry global variables around or risk forgetting to keep listen handlers open.  Our minds don't all work the same way, I guess, but it's nice that LSL allows us each to do what makes the most sense.  😎

Edited by Rolig Loon
  • Like 3
Link to comment
Share on other sites

53 minutes ago, Rolig Loon said:

States can be handy as a way to isolate one set of operations from others.  While that may not make a script more compact, it can make it easier to manage conceptually.  It can also give you functional modules that can be lifted out and plugged almost verbatim into other scripts -- a timesaver if you do a lot of scripting.

I will often use the default state as a place for assigning initial values, building internal lists of important links, reading configuration data from notecards or KVP, and whatnot.  Those sorts of things need only be done once, so it's handy to put them in a state that will only be executed when the script resets.

If I am creating a vendor system, I will often use one state to handle the way a user browses through products and then put functions related to money in a second state.  The two sets of operations are best kept separate anyway, so that there's no confusion about what the buyer is paying for.  Although I could easily code everything in a single state, a modular approach forces me to be sure that product selection (with any options about size, color, delivery method, etc) is complete before a money event is available for the buyer.

I could come up with plenty of other examples.  The bottom line for me is making a script clean and easy for me to follow when I come back to it months later or when I am trying to debug some strange behavior.  I don't want to have to chase all over a long script to remind myself of the flow of logic.  If I can isolate my later questions to a single modular state, I am much happier.

Neat!. Thanks for the input Rollig, very interesting. I usually just contained it all into the same state, mostly due to personal preference, but I can see how it would make it easier to debug in the long run if you had your various functioned sectioned off in a modular fashion. I did used to use states at one point but the more I coded over the years the less I started using them as I found other ways to do things that seemed to be less taxing memory in some of the larger scripts I was writing than having a whole extra state included and I guess that followed me through into other areas of coding. Thank you though for responding!

Edited by Ichi Rexen
wrong word
Link to comment
Share on other sites

I find switching states is necessary when reading a notecard to set new or reinforce old defaults, where you don't want anything else happening until you've completed the read. It's also useful where you have something like a chair that is going to have two quite different forms of use, such as a person just sitting normally on it, and then being tied to it and interrogated, where some of the events are going to require significantly different activities, for example the sitter may touch the chair for a menu to adjust their position or posture when in the default state, but when in the captive state they are not allowed any menu options, the captor now gets those.

Just sliding sideways a bit, it's rather amusing to see a debate about states resulting in people getting into states. Not looking at anybody in particular, just saying :)

  • Like 4
  • Haha 1
Link to comment
Share on other sites

24 minutes ago, Wulfie Reanimator said:

And just to echo what others have already said, I don't find states very useful beyond disabling touch and clearing listens. Fragmenting the logic of a script into multiple pieces is something I would want to avoid as much as possible, to keep the script easy to maintain for myself and whoever else might look at it.

Im definitely on your side of the fence on this. My personal preference is to keep everything contained into a single state as I find the flow of logic easier to manage but maybe thats just because iv been doing it for such a long time that it became second nature. Clearing out the event buffer is an interesting use though as stated earlier. I knew that all listens, variables etc were cleared from one state to the next but I never thought to use them specifically for mass clearing.

But this is part of the reason why I started this discussion. I seldom found reasons to actually need to use states and I was a little curious as to what reasons other people would come up with to see if it really was worth abandoning them entirely or whether they could have their uses under certain circumstances. Its interesting when we are able to have these discussions because whilst I will probably not ever really use states all that often, I have still discovered ways that I never thought of before for using states to achieve specifically useful results.

Thanks for you for taking the time to input into this though it was greatly appreciated.

  • Like 2
Link to comment
Share on other sites

5 minutes ago, Profaitchikenz Haiku said:

Just sliding sideways a bit, it's rather amusing to see a debate about states resulting in people getting into states. Not looking at anybody in particular, just saying :)

😂 That is specifically what I was trying to avoid. I guess its not meant to be in this part of the forum as of late. 

Link to comment
Share on other sites

Many times in this forum I have made the observation that scripting is 90% logic and 10% syntax, or words to that effect.   Your success as a scripter depends on how well you can envision the decision tree that your code will need to follow.  Actually writing the code to do it is almost anticlimactic.  As Steph points out, what counts in the end are results, so we can each find our own way to handle that last 10% of the job as long as all of our scripts reach the same correct outcome.   I began writing code when Fortran II (and then Fortran IV) was the standard, but I was never a professional coder. I did what worked as long as it gave me useful scientific results.  I came to LSL late in a career, with a lot of accumulated baggage but without a professional coder's bias about what's "best".  I get to script the way I want to.  That's definitely cool. 

Edited by Rolig Loon
  • Like 4
Link to comment
Share on other sites

14 minutes ago, Rolig Loon said:

I began writing code when Fortran II (and then Fortran IV) was the standard,

Been there, and PDP11 Macro, I still find what I learned with the terseness those early languages forced on you made you think long and hard about even adding an extra variable, when there might be a way of setting a bit in an existing one to use it in a second way without upsetting the existing use. You've made me realise that there's a similar challenge to writing in LSL with the memory limits. Must be one of the reasons I enjoy it so much.

  • Like 3
Link to comment
Share on other sites

1 minute ago, Profaitchikenz Haiku said:

Been there, and PDP11 Macro

Then maybe you also remember the PDP 8S, which was called the 8S because it had 8K of memory.  We'd use sense switches to boot up the paper tape reader, where we would feed in a compiler, followed by our program.  The compiler would compile the program and overwrite itself so that the final code all still fit into the 8K limit.  It was terse indeed.  I learned many lessons doing that.  The most important one was: Keep It Simple, Stupid.  It's a good lesson.  I'm just glad that I can ignore it when I want to these days.  :)

  • Like 2
Link to comment
Share on other sites

back to topic:

I was using states when I added a flight mode to Tapple Gao's carriage script for horse avatars. The controls in flight mode were completely different than in ground mode...

I use states in a state machine much more often but usually I have a flag variable called "state" and "if" / "else" if to check what the thing should do depending on the state variable. Only if the "if"ses check stuff too often I use constructs like state to program my stuff - and of course if other circumstances demand the use of the state construct.

Edited by Fionalein
  • Like 3
  • Thanks 1
Link to comment
Share on other sites

14 minutes ago, Rolig Loon said:

Then maybe you also remember the PDP 8S, which was called the 8S because it had 8K of memory. 

Slightly before my active period. But what you've jogged my memory about is overlays: and I've realised there's some similarities to them and states.

For those not yet conceived when us oldies were bashing the keys and sticking tape over holes punched by mistake, you only had a small amount of working memory, and if the program you were developing grew too large, you split it up into chunks, one of which would be loaded into working memory at any one time. That chunk had to be self-contained in that it couldn't jump to or call anything in one of the other overlays. If it absolutely had to make such a jump or call that required unloading one overlay and loading up another. There's a similar set of issues here when we change states, but we do have the luxury of global functions.

States must have a purpose, otherwise Linden wouldn't have included them in the language specification. I think the key here is going to be the memory overhead each state requires and time taken changing states, because of a lot of stuff going on such as clearing listeners and event queues, which is not easy to quantify. The increased complexity of written code when states aren't used won't be so important because it all goes to byte code and possibly gets optimised as well, and again, that's not easy to examine in detail.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

4 minutes ago, Profaitchikenz Haiku said:

Slightly before my active period. But what you've jogged my memory about is overlays: and I've realised there's some similarities to them and states.

For those not yet conceived when us oldies were bashing the keys and sticking tape over holes punched by mistake, you only had a small amount of working memory, and if the program you were developing grew too large, you split it up into chunks, one of which would be loaded into working memory at any one time. That chunk had to be self-contained in that it couldn't jump to or call anything in one of the other overlays. If it absolutely had to make such a jump or call that required unloading one overlay and loading up another. There's a similar set of issues here when we change states, but we do have the luxury of global functions.

States must have a purpose, otherwise Linden wouldn't have included them in the language specification. I think the key here is going to be the memory overhead each state requires and time taken changing states, because of a lot of stuff going on such as clearing listeners and event queues, which is not easy to quantify. The increased complexity of written code when states aren't used won't be so important because it all goes to byte code and possibly gets optimised as well, and again, that's not easy to examine in detail.

LSL does not work the way you think. The whole script is allocated memory and is read downwards. An addition state entry just clears stored variables from the last state.

Link to comment
Share on other sites

12 minutes ago, steph Arnott said:

LSL does not work the way you think. The whole script is allocated memory and is read downwards. An addition state entry just clears stored variables from the last state.

That's true, Steph, but I don't think that's what Profaitchikenz is getting at.  If I understand correctly, I believe the point is that it looks like there may be no performance or memory penalty to using states instead of writing everything as a single block of code.  As he says, it's not easy to tell for sure.  If that's true, though, it really does leave us free to use multiple state or not, as we choose for personal stylistic reasons.  Ichi and Wulfie are most comfortable with a single state. I can go either way, depending on the project.  If neither choice has a technical advantage, we can all win.

  • Like 4
Link to comment
Share on other sites

2 minutes ago, Rolig Loon said:

That's true, Steph, but I don't think that's what Profaitchikenz is getting at.  If I understand correctly, I believe the point is that it looks like there may be no performance or memory penalty to using states instead of writing everything as a single block of code.  As he says, it's not easy to tell for sure.  If that's true, though, it really does leave us free to use multiple state or not, as we choose for personal stylistic reasons.  Ichi and Wulfie are most comfortable with a single state. I can go either way, depending on the project.  If neither choice has a technical advantage, we can all win.

As i stated before, state change has a valid purpose but it also has the added usage when learning scripting. Most of my heavy scripts process data in a function. Functions which i could put after the main but which LSL does not accept. What is more important is the un-needed use of functions for that cost 1/2 KB each.

  • Like 1
Link to comment
Share on other sites

Yes, that's a good reason.  In the grand scheme of things, if Profaitchikenz is right, we can fold that justification into our reasons for using multiple states and we won't be penalized for doing it.  As I see it, the debate is not really so much about whether using multiple states is more or less efficient as it is about what other stylistic advantages we see in them.  In the absence of definitive performance information, I am most concerned about satisfying myself. I am personally quite happy doing whatever seems easiest and fits my own quirky mind.  I'm lazy that way.

Edit:  Or maybe just pragmatic.

Edited by Rolig Loon
  • Like 3
Link to comment
Share on other sites

3 minutes ago, Rolig Loon said:

Yes, that's a good reason.  In the grand scheme of things, if Profaitchikenz is right, we can fold that justification into our reasons for using multiple states and we won't be penalized for doing it.  As I see it, the debate is not really so much about whether using multiple states is more or less efficient as it is about what other stylistic advantages we see in them.  In the absence of definitive performance information, I am most concerned about satisfying myself. I am personally quite happy doing whatever seems easiest and fits my own quirky mind.  I'm lazy that way.

Edit:  Or maybe just pragmatic.

If it works i could not careless. Women have have a far better priority list in life than men trying to do one up manship

  • Sad 1
Link to comment
Share on other sites

21 minutes ago, Rolig Loon said:

Yes, that's a good reason.  In the grand scheme of things, if Profaitchikenz is right, we can fold that justification into our reasons for using multiple states and we won't be penalized for doing it.  As I see it, the debate is not really so much about whether using multiple states is more or less efficient as it is about what other stylistic advantages we see in them.  In the absence of definitive performance information, I am most concerned about satisfying myself. I am personally quite happy doing whatever seems easiest and fits my own quirky mind.  I'm lazy that way.

Edit:  Or maybe just pragmatic.

If you consider standard “code refactoring”, would single state end up as two, or vice-versa? 

Link to comment
Share on other sites

usually in a discussion about states and events then the general approach, general meaning fallback, tends to follow our life coding experience as programmers

typically those raised on procedural languages tend to write LSL code procedurally within a single state. The equivalency being a C program:

main() { initialise(); program_loop; exit();)

those who are raised on event-driven object-oriented languages tend toward using states, along the design principles:

state initialise();
state main();
state exit();

am not sure what people's experience of tools like C# and Delphi Pascal are. You will find the latter construction in these languages. And we find intuitive flow control structures in them like this:

begin {
   initialise() {

   }
  
   try {

   } 
   except {

   }
   finally {

   }
}

intuitive meaning intuitive to a person conversant with object-oriented event-driven programming

basically in these languages we don't initialise as we go. We initialise first, try/execute the code, handle the exceptions, then finally tidy up. When the interaction with the player/other object fails then we deal with it by exception, go back to the beginning when we can, re-initialise and try again

a example of this, using the event-driven state model inherent to LSL

default()
{
   state_entry()
   {
      .. initialise ..
      .. load notecards, etc ..    
   }

   data_server( .. )
   {
       if (..EO initialise..) exit;
          state main;
   }

state main()
{
   ... wait for player ...
   ... on acquire player exit
        state play;
}

state play()
{
    .. try
         play events
    .. except
         state exception();
    .. finally
          discard player and exit
          state main(); (and wait to acquire the next player)
}

state exception()
{
   state_entry()
   {
      ... show exception visually
      settimer();
   }

   touch() or listen() for player input
   {
      ... wait for player acknowlegement, when obtained exit
      state player(); 
   } 
   
   timer()
   {
      .. finally
      ... discard player and exit
      state main();
}

what this approach means is that the if is and if that decisions typically found in procedurally coded programs are lessened, coding exceptions for listeners and inputs are reduced to only those necessary for the state that the program is in as the program flow unfolds

when we see code of fairly large and complex interactive LSL programs then is noticeable what the life code experience of the person who wrote it is

 

  • Like 2
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1038 days.

Please take a moment to consider if this thread is worth bumping.

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
 Share

×
×
  • Create New...