Because the Patch manages the creation of the SynthDef and also manages the Synth that is created at the time of play, it is possible to do some tricks that make client-server communication a bit easier.
Keep in mind that when the sc lang code that is inside a SynthDef or an Instr is run when the the SynthDef or InstrSynthDef is compiled. Its compiled into bytecode that is then sent to the server but then when the synth itself runs there is no sc language. There are no functions or 'if' statements.
So once you have that concept clear in your head, here's how to violate it.
On receiving a trigger (a non-positive to positive transition) evaluate the function IN THE CLIENT LANGUAGE. A value may also be passed in which will be polled and passed to the function.
You could also spawn more synths.
What is happening is that a ClientOnTrigResponder is added to the InstrSynthDef's stepchildren. When a Patch plays it also plays its children (the inputs to the patch) and its stepchildren. The ClientOnTrigResponder adds an OSCpathResponder when the synth starts and removes it when the synth stops.
Samples and BufferProxies can insert kr rate beat calculation UGens into the InstrSynthDef
see Sample
Tempo.kr will insert a UGen with the current Tempo
Experimental, but can be fun.
The player inside the instr registers itself as a dependent, is prepared and spawned at the same time as the player and inserts an In.ar into the SynthDef to play its output.
The SFP (soundfile player) will require a buffer, a bus, and various stages of preparation.
The better approach is still to use Patch which will manage the preparation process in a more clear fashion.