

/client/Mouse[Action]() is called, which calls /atom/Mouse[Action]()
Oftentimes in BYOND games, different types of mobs have entirely different means of interacting with the world.
Let's say we have a team-based MOBA that we are working on. Active players will interact with the world differently than observer players. Let's say we want the player to shoot when they click on something, and we want the observer to change the player their camera is following when they click on something. There are several ways to achieve this, all of which are valid.
Method #1: Check player type
client
Click(atom/object,atom/location,control,params)
if(istype(mob,/mob/player))
mob:Shoot()
..()
mob
Click(location,control,params)
if(istype(usr,/mob/observer))
usr.client.eye = src
observer
player
This method is one that I would consider to be pretty bad. It works, and it is incredibly simple, but it can't be easily expanded to encompass many different types of players.
Method #2: polymorphic capability flags
Another method is to take advantage of polymorphism and define flags representing what behavior something is capable of.
client
Click(atom/object,atom/location,control,params)
if(usr.canshoot) usr.Shoot()
..()
mob
var
canshoot = 0
isobserver = 0
proc
Shoot()
Click(location,control,params)
if(usr.isobserver) usr.client.eye = src
observer
isobserver = 1
player
canshoot = 1
This is marginally faster than the first example, and a little bit easier to expand, but we still suffer from a major downfall in that this creates a large number of bloated variables in the root /mob type. This will increase your memory footprint and slow down your game.
Method #3: polymorphic execution chain
There are a number of ways to implement a polymorphic execution chain. What this method does is define a set of hooks on the mob that can be overridden to change the behavior of inputs drastically from one type of mob to another. Let's look at one example in particular:
client
Click(atom/object,atom/location,control,params)
usr.onClick(object,location,control,params)
..()
mob
proc
onClick(atom/object,atom/location,control,params)
observer
onClick(atom/object,atom/location,control,params)
if(istype(object,/mob))
client.eye = object
player
proc
Shoot()
onClick(atom/object,atom/location,control,params)
Shoot()
This method is extremely flexible and allows you reciprocal functions in the form of mob/onClick() and atom/onClick(). There are some speed costs to this approach, but this form of input will start making more sense once we start talking about modality a bit further on down the line. The primary advantage of this approach is that it sacrifices speed for code segmentation for easier debugging and readability so long as you understand the callchain.
Roughly, our execution chain now begins to look like this:

Introducing modality:
Modality is a concept that means that there are multiple ways, or modes that something expresses itself. In our case, we want modality to be modular in that we can change from one input mode to another on the fly and completely change what buttons and keys do with a few keystrokes. This is powerful and will save you tons of spaghetti later on as your game grows.
Method #1: if-statement soup
mob
var/tmp
input_mode
menu/menu
player
onKeyPress(bind)
switch(input_mode)
if(null)
switch(bind)
if("MoveNorth")
client.North()
if("MoveSouth")
client.South()
if("MoveEast")
client.East()
if("MoveWest")
client.West()
if("Accept")
client.Interact()
if("menu")
switch(bind)
if("MoveNorth")
menu.Up()
if("MoveSouth")
menu.Down()
if("MoveEast")
menu.Right()
if("MoveWest")
menu.Left()
if("Accept")
menu.Select()
if("Cancel")
menu.Back()
menu
proc
Up()
Down()
Left()
Right()
Select()
Back()
This approach isn't alltogether a bad one, but it's got an awful lot going on in that onKeyPress function. Every time you create a new mode, you wind up creating a fairly long bit of code in an already long function. We can improve on this by delegating the onKeyPress function to an abstract prototype for handling keypresses. This will disperse the code into the individual menu objects. Let's name an object that consumes the player's input an /interface datum.
Method #2: Modal delegates
client
Click(atom/object,atom/location,control,params)
. = usr.onClick(object,location,control,params)||..()
mob
var/tmp
interface/focus
onClick(atom/object,atom/location,control,params)
if(focus) . = focus.Click(object,location,control,params)
interface
proc
Click(object,location,control,params)
Now that we've implemented this, we can fully change the player's input completely by introducing a handcrafted /interface datum into the mix and setting the mob's focus to that interface. We can even prevent mouse actions from registering at the /atom level by returning 1 to consume the input. If /interface/Click() returns 1, you can bail out of /mob/onClick() without doing the default action. This means that if you only want to change one or two inputs using a modal interface, you can do so while leaving the default /mob actions in place. If /mob/onClick() returns 1, client/Click() will not call /atom/Click() for the clicked object. This means you can prevent individual atoms from responding to events at either the /mob prototype level, or the /interface prototype level. This is a nifty little concept I stole from Javascript.
Now this is what our execution chain looks like (roughly):

Sometimes Code grouping is good for readability and flexibility
I decided later that sometimes I wanted individual hudobjs to handle inputs differently based on what interface they are a part of. I wrote a system for handling many hudobjs as part of a single /interface datum, and each hudobj was given a string-based id. Sometimes, generic hudobjs would have behaviors that were defined under /hudobj/Click(), and other times, the behaviors were delegated to the /interface datum as a separate hook. Essentially, there are downsides to both approaches, but with both available, I was able to get the best of both worlds when the downsides of one approach became too cumbersome.
I redefined the callchain a little bit like so:
client
Click(atom/object,atom/location,control,params)
return usr.onClick(object,location,control,params)||..()
mob
var/tmp
interface/focus
onClick(atom/object,atom/location,control,params)
return focus&&focus.Click(object,location,control,params)
interface
proc
Click(object,location,control,params)
onClick(object,location,control,params)
hudobj
parent_type = /obj
var
id
tmp/interface/owner
Click(location,control,params)
return owner&&owner.onClick(src,location,control,params)
The new execution chain winds up looking something like this:

Now, some of you may be reading this and asking why I went around my elbow to get to my nose like this. I did this so that I had many, many options of implementation based on the specific system I wanted to implement, while also being able to have the minimal CPU impact that I could based on the needs of the implementation. Yes, this longer callchain will result in more proc call overhead, and will not automatically make your code more elegant. However, it will result in fewer actual instructions being processed for very complex input control schemes, and allows individual components of the game to hijack control of parts of the input without having to be strung into the game's core code or split off any more behavior than I already have. Using this approach, I've managed to implement a wide array of interfaces using a minimum of code, complex and bugfree modal input schemes, and all of it uses a methodology that inherently reduces the number of lines of code I wind up having to write and the number of variables I have to define on root-level objects.
As for the speed hit, calling Move() is several orders of magnitude higher than this expanded callchain, so CPU concerns are pretty much a non-issue.