However, I have yet more code that is copied. (DRY principle is once more violated).In my experience this is a bad idea. Imagine that file is 10x the size. When you look at shoot() you don't know if shoot_sounds() is going to do anything or not without having to inspect that too. That's going to hurt maintainability and debugging later.
So, after picking an idea from the pdf on meerkat, I thought about this:
It's the same idea; using environment flags (which I haven't exposed in the examples) to suppress method calls if they are incorrect.
Is this an acceptable solution? Can you see any inconveniences that I've not?
I personally would prefer either a clear separation of client and server functionality or clearly labelled functionality inline. eg.
if self.is_client(self.shoot_sounds()). Explicit is better than implicit.
Or, if you don't want conditionals in the code, make it event-driven. Emit a 'shoot' event and clients and servers can decide how to handle the events in a way relevant to them. It's still fairly opaque compared to explicit conditionals, but at least you'd know that all the server/client specific behaviour is encapsulated in the event system.
EDIT: I would love it if this editor didn't completely break the formatting half the time.