ID:38503
 
Keywords: mudbase, programming
Over the years, I've noticed patterns in the way I write code. For instance, I almost always write variables in lower-case text and procedures in medial caps. I've been working on revamping my old MUDbase libraries, and one thing I've noticed is that my naming conventions aren't always consistent. In fact, sometimes they are outright random. Since these libraries are meant to work in tandem, I decided I need to sit down and figure out a set of naming conventions to use. This document describes a method of creating libraries, or "modules," with very specific naming conventions.

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)" : "")



Mmmm. Encapsulation and decoupling. Good write up and good system
I write constants in lower case, verbs with initial caps, and everything else (except for for loop vars, which are normally just vowels, as well as a few cases with procs) are long, descriptive names that pisses everyone off (which is why I make sure poeple don't have to use them). These are a few from pif_MapLoader 3.0:
load_map_on_space()
save_and_delete_all_maps()
/dynamic_map.Load_From_Template()
/dynamic_map.convert_condition_list()