Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Please help with this code.

Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 11:59
I need a little help debugging this. Last night, I had it working (or so I thought). I then added line numbers to my notecard to doublecheck that it was getting the right notecard line. It wasn't. It was getting a completely different line, sometimes hundreds off from the random number generated. The questions and answeres we matching up though, which was good.

So I started to try and fix the line number descrepencies and ended up breaking it. Now I can't get it to fetch lines from the notecard again. :(

CODE

not needed now


Thanks for any help!
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-29-2004 15:57
I believe your doing two things wrong:

1. Missing a key (literally) component of llGetNotecardLine and the other various dataserver events.

2. Your doing absolutely nothing to set strLine to a value in the script you posted.

Unless you posted a code snippet.... in that case I would understand the empty dataserver event. Even if you are simply posting a snippet, I cant diagnose your problem with what you're posting.

==Chris
Grim Lupis
Dark Wolf
Join date: 11 Jul 2003
Posts: 762
07-29-2004 17:29
tsk, tsk Chris. It's obvious what's wrong.

Aaron, llGetNotecardLine() is not an inline function. It triggers the dataserver event.

I'll bet what happens is this:

You touch the object.
Object says "Question Number 20: ?"
So you touch again
Object says "Question Number 103: SomeQuestion?"

I'll bet, in this particular example, that SomeQuestion is actually question #20, not question #103.

You're calling llGetNotecardLine(), then immediately processing strLine. BUT, because of LSL's single-threaded, message queuing & event-driven nature, strLine has never been set by the dataserver event before you try to process the data.
_____________________
Grim

"God only made a few perfect heads, the rest of them he put hair on." -- Unknown
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-29-2004 17:32
From: someone
Originally posted by Grim Lupis
strLine has never been set by the dataserver event before you try to process the data.


I would have explained that, but strLine isnt even mentioned in Aaron's dataserver event, so I assumed that he was posting a snippet of his code, and didnt want the contents of his dataserver event in the public domain.
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 17:34
Thanks. I can't believe I had this working and broke it somehow.
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 21:01
Sadly, I was leaving nothing out, which shows I don't know enough about the dataserver event. I had it working, but broke it. :(

What do you mean that llGetNotecardLin is not an inline function? It appears in both the main script and the dataserver event in the samples in the Wiki.

Ok here's my current code. I made some alterations, and if I uncomment the line in the dataserver event to say the line it gets, it says the right line. I don't know how to get that line back up to the llParseString2List.

CODE

not needed now


Now when I click on it, it give me a seemingly random key every time... I dont know where its pulling this from.
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
07-29-2004 21:29
To get the data on the notecard what you are really doing is saying to the system 'Hey I would like this line from this notecard.' The system then responds 'Ok will do, here is your ticket number I will tell you when I have your data.' What is returned from the llGetNextNotecardLine is the ticket number for the data you requested.

When the data is ready, the system will fire the dataserver event. Until this happens, and anywhere outside this event, you have no idea what the line from the notecard is.. Now the data server event gets called with 2 pieces of information - the ticket number from llGetNotecardLine and the line of the notecard.

LSL is an event driven system. It is important to really understand that, and it may not be easy. Everything that happens in LSL is triggered by an event in the game or the script. For example you touching something is an event - so there is a touch event in LSL that executes that code when the object is touched.

In this case the system activates the dataserver event at the event of your data being ready. The values are passed in from there.

dataserver(key ticket, string data)

'data' is what actually contains your line from your notecard. In your script you aren't even doing anything with it, and you should. You should probably take everything after

strLine = llGetNotecardLine(strQFile, intQNumber);

in your function and put it in the data server event. And change the above line (leave it in the function) to:
llGetNotecardLine(strQFile, intQNumber);
_____________________
--
010000010110110101100001001000000100111101101101011001010110011101100001
--
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 21:57
Ama, I removed all refernce to "data" in my second script, renaming it "strLine"... does it have to be named "data"?

I made the change you suggested, and it just returns blanks.

How do I make the data it pulls = strLine?
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-29-2004 22:16
Aaron, have you read these pages:
http://www.badgeometry.com/wiki/llGetNotecardLine
http://www.badgeometry.com/wiki/dataserver
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 22:21
Dozens of times... I'm on the Wiki all day.

I had it working with info I got there... I must have got lucky, because I tried starting from scratch again with the samples from the Wiki, but I can't get it to work.

I'm asking people to help me figure out what I broke because I can't. When I find out what I broke, specifically, then I'll understand.

I can make the samples from the wiki run, but I can no longer get them to pull a random line from the notecard, instead of listing the whole card. I'm very distraught over this (I know it's really not that big of a deal), but I have lost sleep over this trying to rack my brain on what the hell I changed to break it so it doesn't work.
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 22:24
Do I have to have a "llGetNotecardLine" in both the main script and the dataserver event? The samples do, but someone told me that was wrong, which made me even more confused.

Also, why does dataserver seem to loop sometimes? I thought if I called llGetNotecardLine once, it goes ONCE to the dataserver, gets the data and returns... some of the code I've tried pulls the right line from the notecard, but just repeats it infinitely in the dataserver event.
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
07-29-2004 22:38
In this case yes it must be named data. Because otherwise you will confuse yourself!

The function llGetNotecardLine does NOT return the line from the notecard.

It returns a ticket number.

When the data is ready the dataserver event will be called.
* The data server event can not and will not be triggered till you finish all code in your touch event or your function.
* This means you won't get your string until you stop doing stuff in your touch event and function
* This means you can not manipulate the line from the notecard (because you don't have it) in the touch event or function

When the data is ready the dataserver event will be called.
The data in the variables of dataserver will be the ticket number that llGetNotecardLine returns and the line from the notecard.

You must rename them to ticket and data so it looks like:
dataserver(key ticket, string data)

This is for your own safety.

Any and ALL manipulation of the string can only happen after you get the string.
You only get the string in the dataserver event.
Any and ALL manipulation of the string must happen in the dataserver event.

The dataserver event will NOT interupt your function.
The dataserver event will NOT interupt your touch event.
The data that the dataserver gets will NOT travel back in time to be ready in your function.
The data that the dataserver gets will NOT travel back in time to be ready in your touch event.
The notecard line will NOT travel back in time to be ready in your function.
The notecard line will NOT travel back in time to be ready in your touch event.

Any and ALL manipulation of the string must happen in the dataserver event.

Note:Not all musts are really musts, once you have mastered the system. Check out the following for more:
www.badgeometry.com/wiki/tutorial
www.badgeometry.com/wiki/variable
www.badgeometry.com/wiki/functions
www.badgeometry.com/wiki/events
www.badgeometry.com/wiki/globalvariables
www.badgeometry.com/wiki/localvariables
www.badgeometry.com/wiki/dataserver
www.badgeometry.com/wiki/key
www.badgeometry.com/wiki/string
_____________________
--
010000010110110101100001001000000100111101101101011001010110011101100001
--
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 22:38
Ok, I got it back to where it fetches the line from the notecard. Woot.

But it is exhibiting the behavior that Grim talked about:

From: someone
I'll bet what happens is this:

You touch the object.
Object says "Question Number 20: ?"
So you touch again
Object says "Question Number 103: SomeQuestion?"

I'll bet, in this particular example, that SomeQuestion is actually question #20, not question #103.


How do I get them to match up? Here's the code I have now:

CODE

not needed now
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 22:40
Ama, I think that got it for me... I understand the dataserver event much much better now. I'm going in-game to put all my data manipulation in the dataserver event... and I think this is going to clear up all my problems!!

TY TY TY!!
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
07-29-2004 22:44
Welcome, good luck. :)
_____________________
--
010000010110110101100001001000000100111101101101011001010110011101100001
--
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 22:48
Ok one more question... I can't seem to get variables to pass from the dataserver event to my main code... the come up empty. Can I not work with the data retrieved and manipulated in the dataserver event outside of that event?
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
07-29-2004 22:52
How are you jumping to another event? There is no way to do this in LSL.

You can trigger events to start when the one you are in ends, but you can not jump to another event.

An event will not interupt another event or function.

An event will not be executed while another event or function is being executed.

An event will not pause the execution of another event or function, do its stuff, then return to the original event.

An event will do what its told and then stop.

Yes, you MUST do ALL string manipulation inside the dataserver event.
_____________________
--
010000010110110101100001001000000100111101101101011001010110011101100001
--
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-29-2004 23:27
"Yes, you MUST do ALL string manipulation inside the dataserver event."

String manipulation in the dataserver event I understand.

Ok. User clicks on object, which executes a llGetNotecardLine, which calls the dataserver event. I was thinking that the dataserver event was something like a subroutine, that's called when it's needed; when it's done it takes the data it got and then the script continues BACK UP where the llGetNotecardLine was first called.

I see now that is not the case.

The dataserver event picks a random line from the notecard, parses the information. When it's done, what happens next? Am I stuck in the dataserver event? I seem to be because the dataserver event just keeps spitting out the line it got from the notecard nonstop. I just want the dataserver event to get the line from the notecard, split it into two variables, QUESTION and ANSWER.

Do I have to call another state at the end of the datasever event in order to get out of it?

I'm sorry this is taking up so much of people's time. I've read the Wiki pages at least 15-20 times. I've done the tutorials, I understand now (mostly) how states work. I just don't get the whole dataserver event thing... is it a state? Is it a call? Is a call the same as a state?

Should I just quit SL now and save myself, and everyone else, the trouble?
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-29-2004 23:45
Yup, your basicly stuck inside the dataserver event, unless you save the data it gives you into a global variable. But still, you'll need to actually *do* something with that data.

If the process of doing something with the data involves events, save the data you get from the dataserver event into a global variable, and switch to a state where you can handle events. (Example of doing that is here )

If the process of doing something with the data does not involve additional events, then just execute the code you need to execute when you get the data (in the dataserver event).

Posting your newly revised code helps out alot when diagnosing the problem and answering the question though.
==Chris
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-29-2004 23:51
From: someone
Originally posted by Aaron Levy
"I just don't get the whole dataserver event thing... is it a state? Is it a call? Is a call the same as a state?


A function call != event != a state.

Events are functions called by the virtual machine, you have no direct control over when they execute. The dataserver event is an example of an event that you can control indirectly, via the dataserver functions (llGetNotecardLine/llRequestAgentData/etc)


Functions are blocks of code called by you.

States are blocks of events. When you switch states, the VM calls the events in your new state.

The dataserver event is a hassle to code around, Ive wrestled with it, complained about it, and generally bashed my head into the keyboard trying to get things working with it. It requires a slightly different way of thinking about code.
==Chris
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
07-30-2004 00:05
Thanks for the guidance, Chris.

I'll have another go at it.

I agree the dataserver event seems un-intuitive. I think there should be a much more simple method of llGetNotecardLine that does all the dataserver crap in the background without have to code it. You want line 3 of a note card, simply say "string data = llGetNotecardLine("notecardname", 3);" Boom. done. The string "data' now equals whatever line of the notecard you told it to fetch. So needlessly complex is the current method. IMHO.
Aaron Levy
Medicated Lately?
Join date: 3 Jun 2004
Posts: 2,147
Getting there...
07-30-2004 00:26
Ok. Update... I just cleaned up my code a bit. Here's the entire code from beginning to end... It's WORKING, but with some oddities...

CODE

not needed any more


It's still doing what Grim said it does. Here's the pattern, by click number:

1: picks question 7, displays nothing
2: picks question 6, displays question 7
3: picks question 3, displays question 6
4: picks question 9, displays question 3
5: picks question 5, displays question 9
6: picks question 8, displays question 5
... etc etc ...

I thought I wouldn't get this any more since the random line number is being generated by the touch event, and then used by the dataserver event to get that line number. I figured since the touch event can run only once, when its touched, if I generated the random number there, the dataserver would only get one line to fetch at a time. When I put the random line picker stuff in the dataever, it was picking a random line all the time, with no rhyme or reason... and they still didn't match up at all to the line numbers in the notecard.

How do I "sync" them so the dataserver just gets that one line I want, the one that it was told to fetch by the random line code?
Catherine Omega
Geometry Ninja
Join date: 10 Jan 2003
Posts: 2,053
07-30-2004 00:41
The problem is that you're still confusing the order. You need to put your llSay in your dataserver event, after it actually selects everything.

The sequence your script currently follows is this:
1. user clicks, triggering touch_start
2. a random number is generated.
3. llGetNotecardLine asks the dataserver for a line.
4. llSay tries to say a line.
5. the dataserver returns the values requested.

See? It's like Ama said -- the dataserver doesn't interrupt your touch_start event, and it's not fast enough to look up and return the values before calling llSay.

If you stick llSay at the end of your dataserver event, it'll function correctly.
_____________________
Need scripting help? Visit the LSL Wiki!
Omega Point - Catherine Omega's Blog
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
Re: Getting there...
07-30-2004 00:45
From: someone
Originally posted by Aaron Levy
1: picks question 7, displays nothing
2: picks question 6, displays question 7
3: picks question 3, displays question 6
4: picks question 9, displays question 3
5: picks question 5, displays question 9
6: picks question 8, displays question 5
... etc etc ...


This is a symptom of the single-threaded nature of LSL.

Here are the steps your script preforms:

-User Touches Object-
  1. VM triggers touch_start event
  2. Random line number computed: 7
  3. dataserver query made with parameters: ("questions", 7). Return value = 20XXYY
  4. llSay called with parameters (0, "Question number " + "7" + ": " + "" + "?";)
  5. touch_start event exits.
  6. VM triggers dataserver event, with parameters (20XXYY, "Question7*Answer7";)
  7. Question written to global variable strQuestion
  8. Answer written to global variable strAnswer


-User Touches Object-
  1. VM triggers touch_start event
  2. Random line number computed: 6
  3. dataserver query made with parameters: ("questions", 6). Return value = 19YYZZ
  4. llSay called with parameters (0, "Question number " + "6" + ": " + "Question7" + "?";)
  5. touch_start event exits.
  6. VM triggers dataserver event, with parameters (19YYZZ, "Question6*Answer6";)
  7. Question written to global variable strQuestion
  8. Answer written to global variable strAnswer


An easier way of seeing what the problem is is to declare strLine's initial value as "FOO", rather then nothing.
==Chris
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-30-2004 00:46
BAH! Curse my long-winded answers! :D

From: someone
Originally posted by Catherine Omega
The problem is that you're still confusing the order. You need to put your llSay in your dataserver event, after it actually selects everything.

The sequence your script currently follows is this:
1. user clicks, triggering touch_start
2. a random number is generated.
3. llGetNotecardLine asks the dataserver for a line.
4. llSay tries to say a line.
5. the dataserver returns the values requested.

See? It's like Ama said -- the dataserver doesn't interrupt your touch_start event, and it's not fast enough to look up and return the values before calling llSay.

If you stick llSay at the end of your dataserver event, it'll function correctly.
1 2