Modular Programming Standards
All related code is to be stored in the format of a module datum. The module is completely encapsulated in that private functions and variables are not accessed directly. Public functions are those to be called externally (by something other than the module). Private functions are those used by the module and called internally. The module is only interfaced with its public functions.
A module has two methods of identification. The first one is its name. The name should be descriptive and unique in order to avoid conflict with other modules. The second is a prefix. The prefix should be two to four characters and is always followed by an underscore. In most cases, it will be an abbreviation of the module name. It is used to name variables and objects defined outside the module itself. The module name will always be lower-case with underscores separating each word. The prefix will also always be lower-case.
Variables within a module are defined in lower-case, with underscores separating the words. Public variables are those that are allowed to be directly manipulated outside the module, and private variables are those that are not intended to be manipulated directly. Most variables will be private. If the variable is considered private, it will be prefixed by and underscore and never manipulated directly. If a variable is defined outside a module, it is prefixed with an underscore, followed by the module prefix, followed by a second underscore. All variables defined outside the module are considered private, and should not be directly manipulated. Instead, they should interface with functions.
Public functions are those that are called externally. Private functions are those that are called within the module. All functions are defined in medial caps with no separation between words. Private functions are prefixed with an underscore. All functions defined outside the module are prefixed with the module prefix followed by an underscore. A private function defined outside the module is prefixed with an underscore, followed by the module prefix, followed by another underscore.
Example module:
// BEGIN MODULE //
/*
Communication module
Name: communication
Prefix: cmm
WARNING: This code has not beed compiled. It may contain bugs or be completely nonsense.
*/
var/const/CMM_IDLE_TIME = 1800
var/communication/communication = new()
communication
var
list/_clients = list()
proc/ClientList() // this could be private, but it might be useful outside of this module as well
return _clients
proc/AddClient(client/c)
if(!(c in _clients)) _clients += c
return _clients.len
proc/RemoveClient(client/c)
_clients -= c
return _clients.len
proc/SendToAll(m)
for(var/client/c in ClientList())
c.cmm_ReceiveMessage(m)
client
var
_cmm_last_activity
proc/cmm_Initialize()
communication.AddClient(src)
proc/cmm_Denitialize()
communication.RemoveClient(src)
proc/cmm_OutputMessage(m)
cmm_Activity()
communication.SendToAll("[src] says, '[m]'")
proc/cmm_ReceiveMessage(m)
src << "[time2text(world.realtime)]: [m]"
proc/cmm_Activity()
_cmm_last_activity = world.realtime
proc/cmm_IdleState()
return (_cmm_last_activity + CMM_IDLE_TIME <= world.realtime)
// END MODULE //
client/New()
cmm_Initialize()
return ..()
client/Del()
cmm_Denitialize()
return ..()
mob/verb
cmm_Say(t as text)
set name = "say"
client.cmm_OutputMessage(t)
cmm_Who()
set name = "who"
usr << "Clients online:"
for(var/client/c in communication.ClientList())
usr << "\t"+ c.key + (c.cmm_IdleState() ? " (idle)" : "")