Server Script Issues


#1

Just getting started and I’m having several issues with server scripts:

When I call Entities.findEntities from within a server script in an entity, it only seems to find entities that also have a server script in them. Entities that do not have a server script in them are invisible to findEntities called from a server script. Is this a bug or an undocumented feature? I have resorted to putting a DoNothing.js script in the server script slot of entities that I want to be able to detect.

Once I put a server script into an entity, how do I get rid of it? Deleting the URL from the create dialog does not stop it from running. I can see things changing as if the script was still there AND the Server Script Status still says Running. I’ve had to resort to putting the URL of my DoNothing.js script in to stop the previous script.

How do you debug server scripts? Fortunately, when I make a syntax error, the Server Script Status displays it and the line number so I can mend my ways. But when I put print() calls in a server script they do not appear on the Debug Window like when I’m debugging a regular entity script. Where do print() messages go from a server script? Is there another window someplace where I can see them?

I’ve resorted to debugging as an entity script and then moving it over to a server script when working well. This is a bit risky when the script is not stateless and an unexpected guest can cause a second copy of the script to start… I’m considering learning how to use the Messenger interface to send debug messages around…


#2

Entitity Server Scripts

Lets start by prefacing to make sure there is understanding on how it (should) work.

Entity Server Scripts run on the Entity Script Server (Assignment-client), instead as an unique instance on every client connected to the domain.

Technically you can develop them as regular Entity Scripts, until you are ready to run them on the server, if you are alone on your domain, that is.

You can read more on the General Scripting at


(I need to get around to update this someday)

Now for the answers:

I’ll try to answer them in bullet point, since there were quite a few:

  • FindEntities does seem bugged from when running it outside of an Entity Wrap, or the Client. Probably something related to trying to get the Entity information prior to even having information on the entities, while the server only knows about the ones with entityScripts. Normally everything should work same as in the client. Instead try running the EntityServerScript wrapped under a preload like in an Entity Script.
(function () {

    return {
        preload: function (entityId) {
            console.log("Finding Entities " + entityId);

            var location = Entities.getEntityProperties(entityId, ["position"]).position;
            var range = 15;

            var objectKeyList = Entities.findEntities(location, range);


            console.log(JSON.stringify(objectKeyList));
            
            // Only if running on a local client instead of Entity Server Script.
            Script.scriptEnding.connect(this.unload);
        },
        unload: function() {
            console.log("clean up here");
        }
    }
})

That should give you more consistance results.

  • If the script has an error, it may actually cause the script to stick around, like they do on entity instances, even after the serverURL has been removed from the Entity. Normally, you have to manually unbind any script creating listeners, or have to restart the client. Rule of thumb: IF you also bind something to any of listeners, you must also clean up via unload in EntityServerScripts, or via scriptEnding in Entity and Client Scripts, on entity removal.

  • You can, and probably should develop and debug the scripts by running the script directly as an EntityScript first: They after all are just Entity Scripts, run by the Server, instead of the Client. Note that functionality related to your MyAvatar will be unavailable. Click Interactions also will not be available, as the Client will not be aware of any interfaces if the server is the only thing running them: Only thing the script knows is position of objects and joints. Physics also are completely out of its control, aside from application of properties.

  • You can also see the logs of entity script run assignment clients via Developer > Entity Script Server Log which you can enable get to be making sure Advanced Menu and Developer Menu are enabled under Settings.


I suggest avoiding update loops in EntityServerScripts, and instead utilize the Listeners and Messaging stuff to their fullest. You can find more on the messaging system in the thread I linked.

I hope that helps.


#3

Thanks for the reply!
OK, I’m already spending a lot of time alone so I can debug these as regular entity scripts, I guess that is SOP.
I’m already doing the preload and unload you suggest, and yet the scripts keep running when I delete the URL.
I have looked at the Entity Script Serve Log, but there is a constant stream of messages in there, hiding any of mine that might come along. And when I bring up the Create dialog to start or reset a script, the log window always closes! I can’t have them both active at the same time!
I don’t think the script has an error, since it seems to be running fine until I try to stop it. I suppose I could have an error in my unload? It is just a one line function… I’ll pare down a version of the script and drop a copy of it in here later.


#4

OK, here is a complete example. Point the Entity Server Script at this and it should start moving around in a circle.
Delete the URL and it keeps running in circles (eventually spiraling farther and farther away).
The only way I can get it to stop is to replace the URL with a DoNothing.js script.

indent preformatted text by 4 spaces
// Circle.js
//      Kayaker Magic Nov 14th 201
//      Released under Creative Commons
//      Sample JavaScript program for High Fidelity
//      Make the entity move around in a circle
//		(sort of, it will spiral out of control after a while)
//      Should be an Entity Server Script, but
//              will work as an entity Client Script if nobody els is around
(function ()
{
print("hello world");
var mps=10.0;       //number of moves per second
var radius=2.0;     //radius of turn          
var center;         //center point to rotate around
var self = this;            //save this for later
var myID;                   //place to store my entityID for Orbit

function Orbit()    //function to move the Entity around an approximate circle
{
                                            //get the current position of this entity
    var mypos = Entities.getEntityProperties(myID, ["position"]).position;
    var del = Vec3.subtract(mypos,center);  //vector from center
    var del2= {x:0, y:0, z:0};
    del2.x = del.x + del.z/32.0;            //poor man's circle algorithm
    del2.y = del.y;
    del2.z = del.z - del.x/32.0;
    var vel = Vec3.subtract(del2,del);      //vector in direction moving
    mypos = Vec3.sum(mypos,vel);
			//Rotate in the direction you are going
    var look = Quat.lookAt({x:0,y:0,z:0},vel,{x:0.0,y:1.0,z:0.0});
    Entities.editEntity(myID,{position:mypos, rotation:look});
} //end Orbit

this.preload = function(entityID)
{
    myID = entityID;        //sve the entity id for orbit
    center = Entities.getEntityProperties(myID, ["position"]).position;
    center.x -= radius;     //pick a point to rotate around
    self.intervalID = Script.setInterval(Orbit,1000/mps);
}; //end loading preload

this.unload = function()
{
    Script.clearInterval(self.intervalID);
}
} //end main function
)

#5

As I said in my earlier post: you have to delete the entity to trigger the unload event, removing the script wont do it because Server Scripts unload will not trigger. This is currently a side effect of the Entity Server Scripts not triggering unload from entity update with an empty string and is definitely something that hifi needs fixing (@OmegaHeron post a bug report a few months back), as regular scripts do this when the script is updated…

The error comment was just to say its also possible that it can happen via that, because it is also a probable cause: but it is also not the only cause an unload event doesnt get fully triggered.

For now, that is why its better to first develop them as regular entity scripts, then translate them over to EntityServer script: and for that you need to connect the unload a via Script.scriptEnding, that way if you remove the script

And when I bring up the Create dialog to start or reset a script, the log window always closes! I can’t have them both active at the same time!

Thats odd: the Entity Server Log window and Log windows are separate windows from High Fidelity, by default it comes ontop. Never had them get closed. I usually have them on a separate screen. Are you using Windows or Mac?