Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
Sign in to follow this  
Doolittle

Argh! client/server woes

Recommended Posts

Every time I think I have it all figured out....

Okay, I really don't get this. I have the CLIENT createVehicle. Then I publicVariable this vehicle object. Then I have another script that runs when that variable changes to not isNull. This assigns the "Killed" event to that object. I am using the "Killed" event to run a script that cleans up the vehicle when it dies.

The question is this: do "events" only run on client machines?? And never on dedicated server side scripts??? I am guessing I need to make every client & server attach the "Killed" event?

If just the client that created the vehicle added the "Killed" event to it....how can that even work because when the client leaves the vehicle it is no longer local to that client...right? Also if that client leaves the game then noone else will be checking for that "Killed" event on the vehicle because the client that left was running that check.

Arghh!!!

Doolittle

Share this post


Link to post
Share on other sites

I created a simple cleanup system that will delete any object that is no longer alive.  Its real easy to setup.  Feel free to give it a shot.  Its three scripts:

bldClnUpLst.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

?!(local Server): Goto "Exit"

_object = _this Select 0

mgCleanupLst=mgCleanupLst+[_object]

#Exit

exit

cleanup.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

?!(local Server): Goto "Exit"

_i=0

~1

#CleanupObjects

?(_i > count mgCleanupLst):_i=0

_object= mgCleanupLst Select _i

?(!(alive _object)):[_object] exec "deleteObject.sqs"

?(!(alive _object)):mgCleanupLst set [_i, "DELETE_NODE"]

?(!(alive _object)):mgCleanupLst = mgCleanupLst - ["DELETE_NODE"]

~1

?(!(alive _object)):goto "CleanupObjects"

_i=_i+1

?(count mgCleanupLst > 0):goto "CleanupObjects"

goto "Exit"

#Exit

exit

deleteObject.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

?!(local Server): Goto "Exit"

_object = _this Select 0

~10

deleteVehicle _object

#Exit

exit

Directions:

1st Save these scripts to your mission folder

2nd Create Game Logic called Server

3rd Place '[] exec "cleanup.sqs"' in your 'init.sqs' in the mission folder

4rth For objects you wish to cleanup after they are dead, place [this] exec "bldClnUpLst.sqs" in there init.  It can me any object soldier, tank, airplane, or chopper.

I use it in a few of my missions.  It helps out alot when you have alot going on in one map.  Plus its easy to use; all you have to do is place [this] exec "bldClnUpLst.sqs" in the objects you want to remove once they are dead.

Share this post


Link to post
Share on other sites

In my case I a createVehicle....but thanks anyways.

My problem is more with events and wondering if the server ever runs them.

Doolittle

Share this post


Link to post
Share on other sites

Ok, heres the lowdown.  I just tested 'addeventhandler' with clients connected.  The server will execute an added eventhandler if addeventhandler is ran on the server.  However, the added eventhandler only executes on the machine(s) 'addeventhandler' was called on.  In other words it is definitely not globally added to all clients if it is called off one machine.  In order for the added 'killed' event handler to be executed on all clients, you will have to run on all machines.  This includes the server if you want the server to execute as well.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

example addEventHandler ["killed",{titletext["Called Here","PLAIN"]}]

I know this must seem confusing; generally eventhandlers in the config are ran on all clients (1.92), but 'addeventhandler' seems to be an exception to this rule.  I hope this helps...

Share this post


Link to post
Share on other sites

Ok! Man, so confusing. Thanks Pennywise! I guess I'll just have to have all clients set addEventHandler.

Doolittle

Share this post


Link to post
Share on other sites

Yeah it is confusing, I think BIS will be redoing all this MP mumbo jumbo for OFP2, because there is too much to worry about to write anything stable.

Share this post


Link to post
Share on other sites

Of course, with all this confusion, you feel like you're figuring out some programming language or something. unclesam.gif

Doolittle

Share this post


Link to post
Share on other sites

I just realized something else. If an object isn't LOCAL to the client but the client attached an event to it, how can it know when that event happens?!

Doolittle

Share this post


Link to post
Share on other sites

When the information is broadcast. tHis varies on the type of event.

For example, killed and fired events are always broadcast.

Damage is sometimes broadcast

Fuel is broadcast to oabjects within a certain range.

I imagine getin/getout is a guaranteed broadcast (since on MP games, you have to wait for every client to acknowledge that the transfer before getin/getout trips).

Share this post


Link to post
Share on other sites
When the information is broadcast.  tHis varies on the type of event.

For example, killed and fired events are always broadcast.

Damage is sometimes broadcast

Fuel is broadcast to oabjects within a certain range.

I imagine getin/getout is a guaranteed broadcast (since on MP games, you have to wait for every client to acknowledge that the transfer before getin/getout trips).

Interesting... The official comref says this:

Quote[/b] ]MP notes: "Killed" and "Hit" event handlers are executed where given unit is local. All other event handlers are executed on all computers.

...which I, together with reports of differing event behaviours have interpreted as follows:

<ul>[*]The "Killed" and "Hit" events are not broadcast

[*]All other events are broadcast (to some extent, "fuel" being one example)

About the "Fuel is broadcast to objects within a certain range" - does that mean "fuel events are broadcast to those client machines that have units local to that client (such as the player or AI:s under his/hers control) close to the vehicle the event originated from?

Share this post


Link to post
Share on other sites

yes. Found this out working on the UA obelisk.

You're probably right about the hit and killed EH.

Share this post


Link to post
Share on other sites

I also think that an event is NEVER run on the dedicated server. Events will only run on client machines...just like "hint" will only run for a client.

Doolittle

Share this post


Link to post
Share on other sites

Sorry Doolittle, that's not the case. If it were, UA would not work on a dedicated server (it uses Init and Fired EHs, and it used to use Fuel EHs, so I can say that at least for those, it works on a ded server).

Share this post


Link to post
Share on other sites

Noticed this today (1.92): code in the init parameter of a createUnit call seems to run on all machines and not

only on the one where createUnit is called. E.g:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">; somespawner.sqs

?!(local Server):exit

...

...

"Man" createUnit [_pos, somegroup, {dude = this; [] exec "initstuff.sqs"}]

...

...

will have the createUnit call run only on the hosting machine (due to the "local Server" check). However, from my testing,

it seems that the init part, i.e. "{dude = this; [] exec "initstuff.sqs"}" will be run on all connected machines.

This is different from 1.91, right? Or have I missed something? It makes some sense, though, now that the init event is broadcast in 1.92. And I like it.

All we need now is for all events to always be broadcast... *cough* "killed" *cough*

Share this post


Link to post
Share on other sites

No actually createUnit used to run the init line on all machines before as well. I know because I used it a bit in the Enemy Stack.

Share this post


Link to post
Share on other sites
Quote[/b] ]"Man" createUnit [_pos, somegroup, {dude = this; [] exec "initstuff.sqs"}]

If publicVariable can't send strings to other clients, I doubt this could. In order for that to work on all machines, the clients would need to receive the "dude = this; [] exec "initstuff.sqs""...and that ain't gonna happen, I think.

Doolittle

Share this post


Link to post
Share on other sites

That was my first thought too. But trust me (and bn880)...or better yet test it. The whole enchilada is run on all machines.

"Consistency in implementation and documentation" and "OFP" don't work in the same sentence. tounge_o.gif

Share this post


Link to post
Share on other sites

Yep, just test it, I know it wasn't good enough to pass strings, but something was going on globaly. Or my memory of it is totally screwed.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×