Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Is using states a bad idea?

Fractality Birks
Registered User
Join date: 14 Oct 2006
Posts: 15
06-14-2007 16:51
Hi,

I am currently working on my first script. It is going OK, however, one question pops up: is using the states really a good idea? It seems to me that there are a lot of events where I can't be sure of the state the script is in. For example on_rez or listening to configuration messages. With the states I would have to duplicate those methods in all possible states.

Perhaps it is better to just stay in the default state and use my own state mechanism (integer state and switch{})?

Edit: the problem seems to be the event methods. Is there a way to make them available for several states at the same time?

Many thanks in advance for your opinions!


Fractality
RJ Source
Green Sky Labs
Join date: 10 Jan 2007
Posts: 272
06-14-2007 16:55
Some events do cross state boundaries (like the timer).

But I don't think you can make a general statement as to whether states are good or bad. You mentioned one drawback, but it really depends on what you are trying to accomplish overall, your approach, and the efficiency, and maintainability, of your code, as to the efficacy of using states one way or the other.
DoteDote Edison
Thinks Too Much
Join date: 6 Jun 2004
Posts: 790
06-14-2007 17:05
I think states are very useful in situations in which you need the script to function differently depending on the situation. For instance, you have a vendor... you may want the vendor to work normally for customers, or to open a special mode for owner programming, or enter a 3rd mode when empty or borked. States are great for this, because you don't want a customer to be able to click to buy a product when the owner is programming the vendor.

The same can be said about a game. When a game is in progress, you enter an active state which blocks out all the events and functions that are available in the non-active state.

On the other hand, if your product needs to handle multiple situations willy-nilly, then states aren't the best method. In that case, you might use custom functions to handle the various situations.
Salvador Nakamura
http://www.sl-index.com
Join date: 16 Jan 2007
Posts: 557
06-14-2007 18:29
Hi,

Pehaps you can use functions for some actions ?

to be placed before default;

------
integer touchcount;

do_this { llWhisper(0,"function call: "+(string)touchcount); }


default {

touch_start(integer no) { ++touchcount; do_this(); }

}

------
Ultralite Soleil
Registered User
Join date: 31 Aug 2006
Posts: 108
06-14-2007 19:00
I think states complicate a script needlessly. It's hardly ever a requirement to use states.
Jim Guyot
Tinkerer
Join date: 21 Apr 2007
Posts: 38
06-14-2007 19:15
From: Ultralite Soleil
I think states complicate a script needlessly. It's hardly ever a requirement to use states.


I have to disagree here. For some things, states are frivolous and unnecessarily complicated. Other times, however, using states can make or break the functionality of a script. Vendor scripts are a prime example of this. I don't want people to willy nilly buy things from my store when I am editing it. So my vendors all include an offline state where data is loaded, and there is no ability to make payments into the vendor. When I am finished, it goes into a sales state, which doesn't allow me to edit, but allows people to purchase the goods.

Using states, while not required, can make your code much more efficient. Learning to use them at the right times is the most important concept. If you don't use states properly, then they add more complexity than is needed.

And yes, it's usually not a necessity to use states for most things. Simple if..else clauses work wonderfully, as do user defined functions. If you have other questions about using states effectively, there is a lot of information on the wiki, at lslwiki.net.
Malachi Petunia
Gentle Miscreant
Join date: 21 Sep 2003
Posts: 3,414
06-14-2007 19:26
If you replace the word "state" with "set of event handlers currently active" it may make more sense. If you read "state" as you would in "finite state machine" you'll likely get the wrong conceptual model.
_____________________
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
06-14-2007 20:28
its wrong to use states, you should respect them then they will give you their natural talents

really tho it depends on the situation
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
06-14-2007 21:02
Personally, I don't care for them but this is probably because I'm not used to 'em.

I do like that things like listens are cleaned up on state changes, though. This appeals to my lazy side.
Jake Trenchard
Registered User
Join date: 31 May 2007
Posts: 104
06-14-2007 22:49
From: Malachi Petunia
If you replace the word "state" with "set of event handlers currently active" it may make more sense. If you read "state" as you would in "finite state machine" you'll likely get the wrong conceptual model.

But they are states like finite state machines! As well as event handler sets, if the states define event handlers. They're weird in that you have to write them to be self-transitioning, at least weird if you're used to numerical-table implementations of state machines.

And I really didn't like that I couldn't do a transition in a global function. I wanted a 'whatnow' kind of function called from every state at certain points to determine what state to transition to. I ended up instead making a state 'Changing' to move to, which decides which state comes next after that.

They're also kind of like function calls with no return path which may make them useful for certain kinds of recursion.

Any-way, like any language tool, if using them would make something harder and more complicated - don't. If using them would solve a problem in more neatly than doing without them, then go ahead and use them. They are just one piece of syntax available.
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
06-15-2007 02:24
One thing for which I've found states indispensable is to enable and disable event handlers, as DoteDote mentioned above. A specific example is making the Touch text and cursor only appear when the script wants to process a touch; if you have just one state, those UI hints will always be present if touch is handled at all by the script.

Within a state one may respond to tightened filters on events like listen and sensor because you're only interested in a specific thing at that point; of course you can tighten the filters without states, but state-specific handlers need not conditionalize around events that can't be generated in that state.

Also, it's very often convenient to have a state to which the script can return itself that is not the same as the default that one gets from a hard reset. I often use one or more "preparatory" states before getting down to business, revisited upon different levels of user-defined "resets." Such states may have to handle events not otherwise used in the main body of the script (reading settings from notecards, for example). In such cases, the state_entry and state_exit handlers can often make the rest of the code simpler.

I do sometimes long for something akin to interrupt priorities: a handler I define to span states. Maybe come Mono...
Ace Albion
Registered User
Join date: 21 Oct 2005
Posts: 866
06-15-2007 04:37
I used states recently. My lights I just made have three. A just rezzed state that gives an option of two modes of working- one leads to basic touch only control, the other to touch and some channel listen gubbins. I could have put switch/toggle variables in, but it seemed to make sense to do it with states.
_____________________
Ace's Spaces! at Deco (147, 148, 24)
ace.5pointstudio.com
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
06-15-2007 09:48
From: Ultralite Soleil
I think states complicate a script needlessly. It's hardly ever a requirement to use states.

Funny, that's the way I feel about LSL. I just build the VM op codes directly, by hand.
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
06-15-2007 09:52
From: Malachi Petunia
If you read "state" as you would in "finite state machine" you'll likely get the wrong conceptual model.

i agree with the other guy who said, they ARE finite state machines. Well, to be precise, they are Turing machines, except they do not have infinite memory.

Some problems are difficult to model. Some sort of state-tranisition model, on paper, is a good way to work out your design. Converting that design into LSL is almost automatic, *because* LSL has states.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
06-15-2007 10:18
Like almost any other programming model, states have both advantages and draw backs. They help encapsulate functionality which is always a good thing. I tend to use them to simplify control flow while waiting for data processed in another script to complete (for example) which would be more complex if states where not being used.

That said probably 80% of my scripts are single state, they just dont warrent anything more.
_____________________
I'm back......
Shadow Subagja
Registered User
Join date: 29 Apr 2007
Posts: 354
06-15-2007 10:42
States are very important for managing resource useage in your scripts, at least for non trivial scripts. One way to think of state and their benefit is a cheesy analogy as follows:

You are a student, you have a test every morning, so every night you:

w/o states:
read entire library, because you know your text book is in it. Your time is booked, your night is gone.

w/ states:
read the required reading for your test tomorrow morning, then go do something productive with the rest of your time.

The scripting engine has to go through the event handled in each state and do all of the work therein, but not other states. So if you have listeners set that are only needed when you are doing something in particular, or data events that are only needed while you are initializing, etc.. you can bundle them into states and have many less checks to deal with while your script is running at any given time. Thats less work for the sim to have to do on your script, and that both contributes to making your scripts run faster, and making the sim run faster.

A quick example I can think of is a multimedia script I wrote. I wanted to manage my parcel music, video, and allow pictures.

One option was to set a listener in one giant state for all funtionality, and anytime something is said check against all the commands for all the things my script might do.

Another option, and the one I went with, was to use one menu to select what mode I am in, and then switch states to deal with that mode, and have each state be very specific for a given function. This makes the code less cluttered, and reduces the script load on the sim (in this case not very much, but in an always sensing script for example that could make a HUGE difference).

I also use one state per notecard when initializing, to keep the code clean and running faster. I find that people that do not use states still DO use them. So instead of:
state a
{
dataserver
{
parse a_type_line();
when done, go to state b;
}
}

state b
{
dataserver
{
parse b_type_line();
when done, go to state ACTIVE;
}

}

They wind up with (in my opinion, much less readable and much quicker to get out of control as you toggle various state information unnecessarily trying to keep track manually of what states give you for free):

mygiantn00bstate
{
dataserver
{
if(reading_a) parse a_type_line();
if(reading_a, and done reading)
{
reading_a = FALSE;
reading_b = TRUE;
llNoteCardLine(b)..
}
if(reading_b) parses_b_type_line();
if(reading_b and done reading)
{
reading_b = FALSE;
active = TRUE;
}
}
}

State machines are very powerful in that they let you compartmentalize code so that only relevant stuff is being done in any one place.
RJ Source
Green Sky Labs
Join date: 10 Jan 2007
Posts: 272
06-15-2007 11:13
Another potential disadvantage of states is the overhead needed to swap between them. So many rapid state changes could be bad, and might better be recoded without them, or with less state changes.

Another big advantage of states, in my opinion, is in debugging. It can help greatly to narrow down what is going on when chasing bugs, or reducing the potential impact of newly introduced code changes that go awry.
Monica Balut
Beam-Me
Join date: 18 Feb 2007
Posts: 311
06-15-2007 12:43
I them indispensible when you want to read several different notecards to configure a script. I use a different state to read each notecard. If you try read several notecards from within one state, the dateserver event gets all tripped up. I just move from one notecard state to another and when the last one is read, move into an "active" state.
Marcush Nemeth
Registered User
Join date: 3 Apr 2007
Posts: 402
06-17-2007 11:43
From: Ultralite Soleil
I think states complicate a script needlessly. It's hardly ever a requirement to use states.

States are invaluable to a good programmer, even more when you know others will be working on your sourcecode. Using proper naming conventions and solid state definitions will make things more readable for everybody, a lot easier to debug, and as a very useful extra, may actually reduce lag tremendously by aforementioned tighter listening and detection filters.
Programmings something old fashioned linear makes things unnessecary complicated really. You may be able to do almost everything without states that you could also do with them, but updating a stateless scripts gives you a bigger risk to get unexpected results because some code was accessed at a moment you didn't expect it to then when you're using states which create natural bounderies between seperate effects the code creates.
Tiarnalalon Sismondi
Registered User
Join date: 1 Jun 2006
Posts: 402
06-18-2007 07:51
I stress that it really depends on what you're doing and what kind of code you're dealing with.

There are some scripts that are relatively short, but are exceedingly simple and bug free to code using states - doors for example with a default - state open - state closed, that set the position at the start of the particular state are pretty safe and easy. It can be accomplished with integers and if statements, but I just find the state method on this easier and it looks cleaner.

I had a friend who came to me with a problem with a vehicle script he had. Someone had heavily modded what appeared to be one of Jillian Callahan's freebie learners, but they had made this script contain no less than 8 states! They had default, state active, state start, state stop, state vehicle, etc. Pretty much every little change initiated a new state. After asking him what all he used in the script and he just said "I just want it to fly properly", I deleted almost everything in it and gave him a script with only 2 states and about half the code that flew perfectly.

So it really breaks down to what you're actually doing. The 2 examples I gave show a really short script that is made simpler with states, and a really long script that is made needlessly complicated by them. Some things may break down to where it's actually better to use multiple scripts instead of multiple states.

It all just depends on what you're trying to do.
Kisiri Mfume
Registered User
Join date: 28 Aug 2005
Posts: 21
06-18-2007 09:43
From: Qie Niangao
I do sometimes long for something akin to interrupt priorities: a handler I define to span states. Maybe come Mono...


Oddly enough, after doing a copy/paste of yet another common, cross-state event handler in one of my scripts last night, I finally opened up JIRA and made a feature request. Would definitely be nice to be able to have a 'global' block of event handlers every now and then, even if it's implemented in an ugly fashion on the server side... at least it would clean up my code a bit. Feel free to vote this one up, fellow scripters!

https://jira.secondlife.com/browse/SVC-338
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
06-18-2007 11:28
From: Ultralite Soleil
I think states complicate a script needlessly. It's hardly ever a requirement to use states.


Failing to use states when they're appropriate will complicate scripts unnecessarily. There is no requirement to ever use states other than default, though.

They're a great tool when used appropriately. As mentioned above, avoid using different states when the responses to most events are the same. When some behaviors are the same, use functions to handle the states. And if state transitions result from behaviors, the functions can return values to indicate what state to change to -- you can't change state from within a function. At lease, not without a kluge.

As a software engineer working in real-time control and communications for 30 years, I often have to train other workers in the appropriate use of state machines. It's an excellent tool for reducing analytical complexity, but it's also no silver bullet.

I usually have a ddefault state that doesn't do much except perhaps invoke auto-upgrade function (so I can drag in a script without deleting the old one). I usually have a separate state for reading the config notecard, and a "reconfig" state that simply goes straight to the config state, in case I want to bail out and re-start the config state. I then usually have "active" and "inactive" states for whether the object is in service or not, or similar.

I don't use states to handle subtle difference in function, because it usually means unnecessary duplication of code (even when using behavior functions).