diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp
index ccb6d3970e..634e7d3b57 100644
--- a/libraries/metavoxels/src/AttributeRegistry.cpp
+++ b/libraries/metavoxels/src/AttributeRegistry.cpp
@@ -17,6 +17,9 @@ REGISTER_META_OBJECT(SharedObjectAttribute)
 REGISTER_META_OBJECT(SharedObjectSetAttribute)
 REGISTER_META_OBJECT(SpannerSetAttribute)
 
+static int attributePointerMetaTypeId = qRegisterMetaType<AttributePointer>();
+static int ownedAttributeValueMetaTypeId = qRegisterMetaType<OwnedAttributeValue>();
+
 AttributeRegistry* AttributeRegistry::getInstance() {
     static AttributeRegistry registry;
     return &registry;
diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h
index b6a415bef7..f3dd9f4632 100644
--- a/libraries/metavoxels/src/AttributeRegistry.h
+++ b/libraries/metavoxels/src/AttributeRegistry.h
@@ -29,6 +29,8 @@ class MetavoxelStreamState;
 
 typedef SharedObjectPointerTemplate<Attribute> AttributePointer;
 
+Q_DECLARE_METATYPE(AttributePointer)
+
 /// Maintains information about metavoxel attribute types.
 class AttributeRegistry {
 public:
@@ -150,6 +152,8 @@ public:
     OwnedAttributeValue& operator=(const OwnedAttributeValue& other);
 };
 
+Q_DECLARE_METATYPE(OwnedAttributeValue)
+
 /// Represents a registered attribute.
 class Attribute : public SharedObject {
     Q_OBJECT
diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h
index f4e8d19ce3..f52db029b6 100644
--- a/libraries/metavoxels/src/Bitstream.h
+++ b/libraries/metavoxels/src/Bitstream.h
@@ -537,7 +537,11 @@ template<class T> int registerStreamableMetaType() {
 }
 
 /// Flags a class as streamable (use as you would Q_OBJECT).
-#define STREAMABLE public: static const int Type; private:
+#define STREAMABLE public: \
+    static const int Type; \
+    static int getFieldCount(); \
+    void setFieldValue(int index, const QVariant& value); \
+    private:
 
 /// Flags a field or base class as streaming.
 #define STREAM
diff --git a/tools/mtc/src/main.cpp b/tools/mtc/src/main.cpp
index 248c2ddd2d..598b7b10d0 100644
--- a/tools/mtc/src/main.cpp
+++ b/tools/mtc/src/main.cpp
@@ -24,10 +24,16 @@ public:
     QStringList bases;
 };
 
+class Field {
+public:
+    QString type;
+    QString name;
+};
+
 class Streamable {
 public:
     Class clazz;
-    QStringList fields;
+    QList<Field> fields;
 };
 
 void processInput(QTextStream& in, QList<Streamable>* streamables) {
@@ -66,8 +72,10 @@ void processInput(QTextStream& in, QList<Streamable>* streamables) {
 
         } else if (match.startsWith("STREAM")) {
             match.chop(1); // get rid of the semicolon
-            match = match.trimmed(); // and any space before it
-            currentStreamable.fields.append(match.mid(match.lastIndexOf(' ') + 1));
+            match = match.mid(match.indexOf(' ') + 1).trimmed(); // and STREAM, and any space before it
+            int index = match.lastIndexOf(' ');
+            Field field = { match.left(index).simplified(), match.mid(index + 1) };
+            currentStreamable.fields.append(field);
 
         } else { // match.startsWith("class")
             classExp.exactMatch(match);
@@ -90,12 +98,42 @@ void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
     foreach (const Streamable& str, streamables) {
         const QString& name = str.clazz.name;
 
+        out << "const int " << name << "::Type = registerStreamableMetaType<" << name << ">();\n";
+
+        out << "int " << name << "::getFieldCount() {\n";
+        out << "    return " << str.fields.size();
+        foreach(const QString& base, str.clazz.bases) {
+            out << " + " << base << "::getFieldCount()";
+        }
+        out << ";\n";
+        out << "}\n";
+
+        out << "void " << name << "::setFieldValue(int index, const QVariant& value) {\n";
+        if (!str.clazz.bases.isEmpty()) {
+            out << "    int nextIndex;\n";
+        }
+        foreach (const QString& base, str.clazz.bases) {
+            out << "    if ((nextIndex = index - " << base << "::getFieldCount()) < 0) {\n";
+            out << "        " << base << "::setFieldValue(index, value);\n";
+            out << "        return;\n";
+            out << "    }\n";
+            out << "    index = nextIndex;\n";        
+        }
+        out << "    switch (index) {\n";
+        for (int i = 0; i < str.fields.size(); i++) {
+            out << "        case " << i << ":\n";
+            out << "            this->" << str.fields.at(i).name << " = value.value<" << str.fields.at(i).type << ">();\n";
+            out << "            break;\n";
+        }
+        out << "    }\n";
+        out << "}\n";
+
         out << "Bitstream& operator<<(Bitstream& out, const " << name << "& obj) {\n";
         foreach (const QString& base, str.clazz.bases) {
             out << "    out << static_cast<const " << base << "&>(obj);\n";
         }
-        foreach (const QString& field, str.fields) {
-            out << "    out << obj." << field << ";\n";
+        foreach (const Field& field, str.fields) {
+            out << "    out << obj." << field.name << ";\n";
         }
         out << "    return out;\n";
         out << "}\n";
@@ -104,8 +142,8 @@ void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
         foreach (const QString& base, str.clazz.bases) {
             out << "    in >> static_cast<" << base << "&>(obj);\n";
         }
-        foreach (const QString& field, str.fields) {
-            out << "    in >> obj." << field << ";\n";
+        foreach (const Field& field, str.fields) {
+            out << "    in >> obj." << field.name << ";\n";
         }
         out << "    return in;\n";
         out << "}\n";
@@ -124,12 +162,12 @@ void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
                 out << "static_cast<const " << base << "&>(first) == static_cast<const " << base << "&>(second)";
                 first = false;
             }
-            foreach (const QString& field, str.fields) {
+            foreach (const Field& field, str.fields) {
                 if (!first) {
                     out << " &&\n";
                     out << "        ";
                 }
-                out << "first." << field << " == second." << field;    
+                out << "first." << field.name << " == second." << field.name;    
                 first = false;
             }
         }
@@ -150,19 +188,17 @@ void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
                 out << "static_cast<const " << base << "&>(first) != static_cast<const " << base << "&>(second)";
                 first = false;
             }
-            foreach (const QString& field, str.fields) {
+            foreach (const Field& field, str.fields) {
                 if (!first) {
                     out << " ||\n";
                     out << "        ";
                 }
-                out << "first." << field << " != second." << field;    
+                out << "first." << field.name << " != second." << field.name;    
                 first = false;
             }
         }
         out << ";\n";
-        out << "}\n";
-        
-        out << "const int " << name << "::Type = registerStreamableMetaType<" << name << ">();\n\n";
+        out << "}\n\n";
     }
 }