Quote:
Originally Posted by Kamaeru
Cool, I had noticed some of those nuances about onPlayerTouchsme via trial and error but it's good to hear it from someone who has already figured it out.
Can you give the same rundown for onPlayerEnters()? Is it different clientside and serverside?
Alsowhat is the benefit of making the server do heavy lifting? I would assume everyone uses a supercomputer these days so making as much stuff clientside would be the smart thing to do. For 2k1's server, it doesn't seem to be allocated very much memory and I had to cut the amount of birds flying in half to stop server lag.
|
onPlayerEnters() works the same both serverside and clientside I'm pretty sure, though it's finicky when you're dealing with gmaps.
What I mean about letting the server do the heavy lifting is that you don't need to worry about their computer, connection issues/lag, or things like that. The server will know they entered the level and they will trigger onPlayerTouchsme() and get warped out before their PC even gets the data. It's just faster and more efficient than detecting it clientside and then waiting for the data to get to the server and then sending it. And if they're lagging it may not happen for a while or at all. An event like onPlayerTouchsme() won't do much, while scripts like birds that are always running loops will be much more intensive.
By the way, NPCs running loops will continue to run loops even if a player is not in a level. I don't think the loop is stopped until the level is pulled from memory and cleaned up... and I think that's like 5-10 minutes. It's best to break any loops serverside(such as a timeout loop) when players.size() <= 0. Something like this:
PHP Code:
function onPlayerEnters() {
// Resume the loop, clear the idle flag.
if (this.idle) setTimer(.1);
this.idle = false;
}
function onTimeout() {
// No players so don't waste time doing things
if (players.size() <= 0) {
this.idle = true;
return;
}
// Do loop stuff
setTimer(.1);
}
It will cut down on a lot of unnecessary processing occurring in inactive levels. Anything that runs on a constant loop should implement this sort of check. The only downside is that players.size() can
sometimes be faulty causing NPCs to stop working because it thinks there are no players around. You can get around this by trying players.size() <= 0 && this.level.findareaplayers(0,0,64,64).size() <= 0 but I don't think it's necessary.
Quote:
Originally Posted by maximus_asinus
Okay another novice question here. What is the difference between serverside and clientside NPCs? I assume that clientside NPCs are only run on locally and can have different behaviors for each person depending on the script, so does serverside run for everyone? How does the client know what NPCs are clientside or serverside? Is that the purpose of //#CLIENTSIDE?
And I still think it would be better to remove the player once I executed the command. Otherwise you could just stay still to prevent being warped. But maybe this is a limitation of not making it a weapon.
|
Serverside script is run on the server, while clientside script is run on the players device. Anything clientside is being run on the players machine, therefor it can be accessed via memory editing and such. Anything secure should be done on the server. This is why it's better to do your player detection on the serverside instead of client, because depending on circumstances they might be able to bypass whether or not the script detects them there. Serverside doesn't need to worry about that, the player can't access anything there.
And yes, it works like this:
PHP Code:
function onCreated() {
echo("This is serverside code. This will appear in RC, since it's being handled by the server.");
}
//#CLIENTSIDE
function onCreated() {
echo("This is clientside code. This will appear in the F2 log window since it's being handled by the players machine.");
}
As you can see, even though you would normally not be able to have duplicate functions that will work fine because they're not even being parsed by the same machine. They work indepedently of each other, and in order to communicate between them you will need to send data to the server or have the server send data to the player via triggeraction()/triggerserver()/triggerclient(). Though there are other ways to communicate, via relying on synchronized variables like player.client/clientr.flags and player/npc.attr[1-30].
Anyways about the onPlayerTouchsme(). You don't need to worry about players entering the level and not moving. Like I said on serverside this gets called whenever the player position changes--that includes when they change position by entering the level. As soon as they enter the level it will trigger onPlayerTouchsme(). The good thing about this over onPlayerEnters() is that if for whatever reason it may fail, if they move at all they will trigger it again. And again, if you're that worried you can put a polygon on the clientside so they can't see anything anyways. Like so:
PHP Code:
function onCreated() {
// Set the NPCs shape to 1024x1024, or 64x64*16
setShape(1,1024,1024);
// You can still set an NPC to not block and it will retain its shape and trigger onPlayerTouchsme
// This is useful for instances like this, while also not making the entire level return true for any serverside onwall() checks
dontblock();
}
// The player will trigger onPlayerTouchsme() as soon as they enter the level, and again if their position changes at all
// See below for explanation
function onPlayerTouchsme() {
// Don't warp out your account
if (player.account == "maximus_asinus") return;
// Don't warp out players who are in server.warp
if (player.account in server.warp) return;
// Warp player to the designated unstickme level
player.chat = "You're banned from this level";
player.setlevel2(serveroptions.unstickmelevel,serveroptions.unstickmex,serveroptions.unstickmey);
}
//#CLIENTSIDE
function onCreated() {
setShape(1,1024,1024);
}
// Since onPlayerTouchsme() doesn't quit work like it does serverside it's best to just use onPlayerEnters()
function onPlayerEnters() {
if (player.account == "maximus_asinus" || player.account in server.warp) {
// Let's not block players who are allowed in the level
dontblock();
hideimg(200);
return;
}
// Anyone who gets to this part of the code isn't allowed in the level. The NPC will
// continue to block the level. Let's also render a polygon to obscure their vision
with (findimg(200)) {
// A polygon shape that fills the entire screen
polygon = {0,0,screenwidth,0,screenwidth,screenheight,0,screenheight};
// Make it black
red = green = blue = 0;
// A high layer
layer = 10;
}
}