diff --git a/README.md b/README.md
index 8cccc6cc0b286689e3e2bd62cb215a63542bd1b3..5530f1ebd53484843274f064cc899ba376149fe9 100644
--- a/README.md
+++ b/README.md
@@ -127,17 +127,95 @@ To disconnect, click the output to disconnect, and then the input to disconnect
 
 # RuNDMC Architecture 
 
+![arch](doc/images/rndmc-architecture.png)
 
+Above is a somewhat-complete representation of what-all is going on in software.
+
+Essentially, we load tiny programs (```modules/sub/modulename.js```) using node.js's *require* function. These programs each have inputs and outputs, and some state. Each also has a description (an example of a complete module is below).
+
+The UI serves a representation of this through a websocket.
+
+Pardon my at-the-moment brief explanation. 
 
 # Writing New Modules 
 
- - whenever a menu is requested, the system searches ```modules/ * ``` for *anything*. include your .js of a new module there 
- - anything goes: you can run whatever code will run in node.js ... just follow these simple rules 
- - TODO: put example here, with comments 
+Whenever a menu is requested, the system searches ```modules/ * ``` for *anything*. include your .js of a new module there.
+
+These modules are written with objects inherited from ```lib/jsunit.js``` 
+
+Here's an example. This is modules/ui/number.js. 
+
+Besides Inputs, Outputs, a Description and State object, anything else goes. I.E. local functions, other Node.JS packages, etc.
+
+```JavaScript
+// boilerplate rndmc header
+const InOut = require('../../lib/jsunit.js')
+let Input = InOut.Input
+let Output = InOut.Output
+let State = InOut.State
+let Button = InOut.Button
+
+// a constructor, a fn, a javascript mess
+function uiNum() {
+
+    // this is the tiny program-as-and-object that we'll load into rundmc 
+    // description / name is required to load successfully 
+    var uinum = {
+        description: {
+            name: 'number-output',
+            alt: 'for clicking'
+        }
+    }
+
+    // the State() object is what the system scrapes for ui variables / updates from the UI
+    // this includes things like Button('title', callback), which are unique state variables
+    // they can also be found in jsunit.js 
+    uinum.state = State()
+    // alias !
+    var state = uinum.state 
+
+    state.number = 10
+    state.onChange('number', onNumberDesire)
+
+    state.button = Button('WHAM', onNumberDesire)
+
+    // inputs are required, and must be Input('type', callback) 
+    uinum.inputs = {
+        thru: Input('any', onThruInput), // makes anything into num event 
+        evt: Input('any', onNumberDesire)
+    }
+
+    // outputs: Output('type')
+    uinum.outputs = {
+        out: Output('number')
+    }
+
+    // here's our input callback, specified in the input constructor 
+    function onThruInput(input){
+        if(typeof input == 'number'){
+            state.number = input
+        } else {
+            state.number = parseFloat(input)
+        }
+        onNumberDesire()
+    }
+
+    function onNumberDesire(){
+        // here's how we fire an output. 
+        uinum.outputs.out.emit(state.number)
+    }
+
+    // gotta give the program this thing we made 
+    return uinum
+}
+
+// this for node.js's require() function 
+module.exports = uiNum
+``` 
 
 # Writing Hardware Modules 
 
- - TODO: same, also including links / explanation to atk 
+Hardware Modules are identical to other modules, but they inherit a class that can be found and examined at ```lib/atkunit.js``` which subsequently calls hardware-interfacing classes from ```lib/atkroute.js``` and often use tools from ```lib/packets.js``` (packets.js is mostly about packing 64-bit information into byte-size units).
 
 # Development Notes 
 
diff --git a/doc/images/rndmc-architecture.png b/doc/images/rndmc-architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..45a0179f37cb2d226b6e455b4ce625c024954d1e
Binary files /dev/null and b/doc/images/rndmc-architecture.png differ
diff --git a/modules/ui/number.js b/modules/ui/number.js
index 467d231b46c06e9819b18978543152bde87bbffa..bff0d2b803f7c2679e24b65c121afdfef1367de7 100644
--- a/modules/ui/number.js
+++ b/modules/ui/number.js
@@ -1,4 +1,4 @@
-// boilerplate atkapi header
+// boilerplate rndmc header
 const InOut = require('../../lib/jsunit.js')
 let Input = InOut.Input
 let Output = InOut.Output
@@ -8,14 +8,18 @@ let Button = InOut.Button
 // a constructor, a fn, a javascript mess
 function uiNum() {
 
+    // this is the tiny program-as-and-object that we'll load into rundmc 
+    // description / name is required to load successfully 
     var uinum = {
-        // descriptions are used in UI
         description: {
-            name: 'number output',
+            name: 'number-output',
             alt: 'for clicking'
         }
     }
 
+    // the State() object is what the system scrapes for ui variables / updates from the UI
+    // this includes things like Button('title', callback), which are unique state variables
+    // they can also be found in jsunit.js 
     uinum.state = State()
     // alias !
     var state = uinum.state 
@@ -25,15 +29,18 @@ function uiNum() {
 
     state.button = Button('WHAM', onNumberDesire)
 
+    // inputs are required, and must be Input('type', callback) 
     uinum.inputs = {
         thru: Input('any', onThruInput), // makes anything into num event 
         evt: Input('any', onNumberDesire)
     }
 
+    // outputs: Output('type')
     uinum.outputs = {
         out: Output('number')
     }
 
+    // here's our input callback, specified in the input constructor 
     function onThruInput(input){
         if(typeof input == 'number'){
             state.number = input
@@ -44,11 +51,13 @@ function uiNum() {
     }
 
     function onNumberDesire(){
+        // here's how we fire an output. 
         uinum.outputs.out.emit(state.number)
     }
 
+    // gotta give the program this thing we made 
     return uinum
 }
 
-// exports 
+// this for node.js's require() function 
 module.exports = uiNum
\ No newline at end of file