commit d433b50e2eca543e2387859bccad7324c87faaf9
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Dec 6 00:59:55 2021 +0100

    In the 'magic' app, ObjectType is now only used in RubikObject and RubikObjectList classes and nowhere else.
    This is a major step towards being able to download objects from an online repository.

diff --git a/src/main/java/org/distorted/config/ConfigActivity.java b/src/main/java/org/distorted/config/ConfigActivity.java
index 7a93ee7d..35613d33 100644
--- a/src/main/java/org/distorted/config/ConfigActivity.java
+++ b/src/main/java/org/distorted/config/ConfigActivity.java
@@ -37,7 +37,8 @@ import org.distorted.jsons.ObjectJson;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.main.R;
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectType;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 
 import java.io.InputStream;
 
@@ -188,10 +189,10 @@ public class ConfigActivity extends AppCompatActivity
       ConfigSurfaceView view = findViewById(R.id.configSurfaceView);
       view.onResume();
 
-      if( mObjectOrdinal>=0 && mObjectOrdinal< ObjectType.NUM_OBJECTS )
+      if( mObjectOrdinal>=0 && mObjectOrdinal< RubikObjectList.getNumObjects() )
         {
-        ObjectType obj = ObjectType.getObject(mObjectOrdinal);
-        changeIfDifferent(obj,view.getObjectControl());
+        RubikObject object = RubikObjectList.getObject(mObjectOrdinal);
+        changeIfDifferent(object,view.getObjectControl());
         }
       }
 
@@ -214,11 +215,17 @@ public class ConfigActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    private void changeIfDifferent(ObjectType type,ObjectControl control)
+    private void changeIfDifferent(RubikObject object,ObjectControl control)
       {
-      InputStream jsonStream = ObjectJson.getStream(type,this);
-      InputStream meshStream = ObjectMesh.getStream(type,this);
-      control.changeIfDifferent(type.ordinal(),jsonStream,meshStream);
+      if( object!=null )
+        {
+        int jsonID = object.getJsonID();
+        int meshID = object.getMeshID();
+
+        InputStream jsonStream = ObjectJson.getStream(jsonID,this);
+        InputStream meshStream = ObjectMesh.getStream(meshID,this);
+        control.changeIfDifferent(object.getOrdinal(),jsonStream,meshStream);
+        }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -304,10 +311,10 @@ public class ConfigActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void changeObject(ObjectType newObject)
+    public void changeObject(RubikObject object)
       {
       ConfigSurfaceView view = findViewById(R.id.configSurfaceView);
       ObjectControl control = view.getObjectControl();
-      changeIfDifferent(newObject,control);
+      changeIfDifferent(object,control);
       }
 }
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
index d9049a34..3820317d 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
@@ -38,7 +38,6 @@ import android.widget.TextView;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.network.RubikScores;
-import org.distorted.objectlib.main.ObjectType;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenPlay;
 
@@ -80,9 +79,9 @@ public class RubikDialogNewRecord extends AppCompatDialogFragment
         if( name.length()>0 )
           {
           RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-          ObjectType object = play.getObject();
+          int object = play.getObject();
 
-          bundle.putInt("tab", object.ordinal() );
+          bundle.putInt("tab", object );
           bundle.putBoolean("submitting", true);
 
           RubikDialogScores scoresDiag = new RubikDialogScores();
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPattern.java b/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
index b5a8e436..e3472225 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
@@ -39,10 +39,10 @@ import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import org.distorted.objectlib.main.ObjectType;
-
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 import org.distorted.patterns.RubikPatternList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.ScreenList;
@@ -94,9 +94,10 @@ public class RubikDialogPattern extends AppCompatDialogFragment
 
     for(int i=0; i< RubikPatternList.NUM_OBJECTS; i++)
       {
-      ObjectType type = RubikPatternList.getObject(i);
-      int iconSize    = RubikActivity.getDrawableSize();
-      int iconID      = type.getIconID(iconSize);
+      int ordinal  = RubikPatternList.getObject(i);
+      RubikObject object = RubikObjectList.getObject(ordinal);
+      int iconSize= RubikActivity.getDrawableSize();
+      int iconID  = object==null ? 0 : object.getIconID(iconSize);
 
       ImageView imageView = new ImageView(act);
       imageView.setImageResource(iconID);
@@ -131,7 +132,7 @@ public class RubikDialogPattern extends AppCompatDialogFragment
   private int getPatternOrdinal()
     {
     RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-    ObjectType obj  = play.getObject();
+    int obj  = play.getObject();
     int ret = RubikPatternList.getOrdinal(obj);
 
     if( ret<0 )
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
index 2b0cb9d0..d48a7f57 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
@@ -27,7 +27,6 @@ import android.widget.ExpandableListView;
 import android.widget.FrameLayout;
 
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectType;
 
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
@@ -96,7 +95,7 @@ public class RubikDialogPatternView extends FrameLayout
         {
         RubikPattern pattern = RubikPattern.getInstance();
         int[][] moves   = pattern.reInitialize(mTab, groupPosition, childPosition);
-        ObjectType object = RubikPatternList.getObject(mTab);
+        int object = RubikPatternList.getObject(mTab);
         ract.changeIfDifferent(object,control);
         control.initializeObject(moves);
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScores.java b/src/main/java/org/distorted/dialogs/RubikDialogScores.java
index d9537a2f..bb2680b0 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScores.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScores.java
@@ -38,10 +38,10 @@ import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import org.distorted.objectlib.main.ObjectType;
-
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -104,13 +104,13 @@ public class RubikDialogScores extends AppCompatDialogFragment
     tabLayout.setupWithViewPager(viewPager);
 
     viewPager.setCurrentItem(curTab);
-    ObjectType type;
     int iconSize = RubikActivity.getDrawableSize();
+    int numObjects = RubikObjectList.getNumObjects();
 
-    for (int object = 0; object< ObjectType.NUM_OBJECTS; object++)
+    for (int object=0; object<numObjects; object++)
       {
-      type = ObjectType.getObject(object);
-      int iconID = type.getIconID(iconSize);
+      RubikObject robject = RubikObjectList.getObject(object);
+      int iconID = robject==null ? 0 : robject.getIconID(iconSize);
       ImageView imageView = new ImageView(act);
       imageView.setImageResource(iconID);
       TabLayout.Tab tab = tabLayout.getTabAt(object);
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
index 962de79b..3e131a38 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
@@ -30,11 +30,10 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
-import org.distorted.objectlib.main.ObjectType;
-
 import org.distorted.main.R;
 import org.distorted.network.RubikScores;
 import org.distorted.network.RubikNetwork;
+import org.distorted.objects.RubikObjectList;
 import org.distorted.screens.RubikScreenPlay;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -109,7 +108,6 @@ class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikNetwork
     {
     prepareView();
 
-    ObjectType[] types = ObjectType.values();
     int MAX = RubikScreenPlay.LEVELS_SHOWN;
     int toDo=0;
     int[] toDoTab = new int[mNumTabs];
@@ -118,7 +116,7 @@ class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikNetwork
 
     for(int i=0; i<mNumTabs; i++)
       {
-      lastTab[i]= RubikScreenPlay.getDBLevel(types[i]);
+      lastTab[i]= RubikObjectList.getDBLevel(i);
       maxTab[i] = Math.min(lastTab[i],MAX);
       toDoTab[i]= 0;
 
@@ -209,7 +207,7 @@ class RubikDialogScoresPagerAdapter extends PagerAdapter implements RubikNetwork
     {
     mAct = act;
     mDialog = diag;
-    mNumTabs = ObjectType.NUM_OBJECTS;
+    mNumTabs = RubikObjectList.getNumObjects();
     mViews = new RubikDialogScoresView[mNumTabs];
     mViewPager = viewPager;
     mIsSubmitting = isSubmitting;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
index 59ef6dad..a085b3fc 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
@@ -148,7 +148,7 @@ public class RubikDialogSetName extends AppCompatDialogFragment
           RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
 
           Bundle bundle = new Bundle();
-          bundle.putInt("tab", play.getObject().ordinal() );
+          bundle.putInt("tab", play.getObject() );
           bundle.putBoolean("submitting", true);
 
           RubikDialogScores scores = new RubikDialogScores();
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
index 8f657a1f..83d7af4f 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogTutorial.java
@@ -43,7 +43,6 @@ import com.google.android.material.tabs.TabLayout;
 
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.main.ObjectType;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.ScreenList;
 import org.distorted.tutorials.TutorialList;
@@ -130,7 +129,7 @@ public class RubikDialogTutorial extends AppCompatDialogFragment
   private int getTutorialOrdinal()
     {
     RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-    ObjectType obj  = play.getObject();
+    int obj = play.getObject();
 
     int ret = TutorialList.getOrdinal(obj);
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
index 33a31740..d019fc6c 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
@@ -35,11 +35,11 @@ import androidx.fragment.app.FragmentActivity;
 
 import com.google.firebase.analytics.FirebaseAnalytics;
 
-import org.distorted.objectlib.main.ObjectType;
-
 import org.distorted.main.BuildConfig;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 import org.distorted.tutorials.TutorialList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -76,7 +76,7 @@ public class RubikDialogTutorialView extends FrameLayout
     String packageName = act.getPackageName();
 
     TutorialList list  = TutorialList.getObject(position);
-    ObjectType objType = list.getObject();
+    int object = list.getObject();
 
     View tab = inflate( act, R.layout.dialog_tutorial_tab, null);
     LinearLayout layout = tab.findViewById(R.id.tabLayout);
@@ -95,7 +95,7 @@ public class RubikDialogTutorialView extends FrameLayout
 
       int countryID = res.getIdentifier( coun, "drawable", packageName);
 
-      View row = createRow(ract,countryID,desc,url,auth,widthT,objType,colorB,colorT);
+      View row = createRow(ract,countryID,desc,url,auth,widthT,object,colorB,colorT);
       layout.addView(row);
       }
 
@@ -112,7 +112,7 @@ public class RubikDialogTutorialView extends FrameLayout
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private View createRow(final RubikActivity act, int countryID, final String desc, final String url,
-                         final String auth, int size, final ObjectType obj, int colorB, int colorT)
+                         final String auth, int size, final int obj, int colorB, int colorT)
     {
     float textSize = 0.5f*size;
     View row = inflate( act, R.layout.dialog_tutorial_row, null);
@@ -158,7 +158,7 @@ public class RubikDialogTutorialView extends FrameLayout
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void analyticsReport(RubikActivity act, String desc, String author, ObjectType obj)
+  private void analyticsReport(RubikActivity act, String desc, String author, int obj)
     {
     String message = desc+" ("+author+")";
 
@@ -172,9 +172,11 @@ public class RubikDialogTutorialView extends FrameLayout
 
       if( analytics!=null )
         {
+        RubikObject object = RubikObjectList.getObject(obj);
+
         Bundle bundle = new Bundle();
         bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, message);
-        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, obj.name());
+        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, object==null ? "NULL" : object.getName() );
         analytics.logEvent(FirebaseAnalytics.Event.TUTORIAL_BEGIN, bundle);
         }
       }
diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index 7d3a6aaa..55c0a752 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -49,13 +49,14 @@ import org.distorted.library.main.DistortedLibrary;
 
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.TwistyObject;
-import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.effects.BaseEffect;
 
 import org.distorted.dialogs.RubikDialogError;
 import org.distorted.dialogs.RubikDialogPrivacy;
 import org.distorted.network.RubikScores;
 import org.distorted.network.RubikNetwork;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.tutorials.TutorialActivity;
@@ -256,7 +257,7 @@ public class RubikActivity extends AppCompatActivity
         }
 
       RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-      ObjectType object = play.getObject();
+      int object = play.getObject();
       changeIfDifferent(object,view.getObjectControl());
 
       if( mIsChinese && !mPolicyAccepted ) PrivacyPolicy();
@@ -438,7 +439,7 @@ public class RubikActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void changeObject(ObjectType newObject, boolean reportChange)
+    public void changeObject(int newObject, boolean reportChange)
       {
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
       ObjectControl control = view.getObjectControl();
@@ -447,6 +448,8 @@ public class RubikActivity extends AppCompatActivity
 
       if( reportChange && oldObject!=null )
         {
+        RubikObject robject = RubikObjectList.getObject(newObject);
+        String newName = robject==null ? "NULL" : robject.getName();
         float fps = view.getRenderer().getFPS();
         fps = (int)(fps+0.5f);
         StringBuilder name = new StringBuilder();
@@ -454,7 +457,7 @@ public class RubikActivity extends AppCompatActivity
         name.append(' ');
         name.append(fps);
         name.append(" --> ");
-        name.append(newObject.name());
+        name.append(newName);
 
         if( BuildConfig.DEBUG )
           {
@@ -476,11 +479,11 @@ public class RubikActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void changeIfDifferent(ObjectType type,ObjectControl control)
+    public void changeIfDifferent(int ordinal, ObjectControl control)
       {
-      InputStream jsonStream = ObjectJson.getStream(type,this);
-      InputStream meshStream = ObjectMesh.getStream(type,this);
-      control.changeIfDifferent(type.ordinal(),jsonStream,meshStream);
+      InputStream jsonStream = ObjectJson.getStream(this,ordinal);
+      InputStream meshStream = ObjectMesh.getStream(this,ordinal);
+      control.changeIfDifferent(ordinal,jsonStream,meshStream);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -584,20 +587,20 @@ public class RubikActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void switchTutorial(String url, ObjectType object)
+    public void switchTutorial(String url, int objectOrdinal)
       {
       Intent myIntent = new Intent(this, TutorialActivity.class);
       myIntent.putExtra("url", url);
-      myIntent.putExtra("obj", object.ordinal());
+      myIntent.putExtra("obj", objectOrdinal);
       startActivity(myIntent);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void switchConfig(ObjectType object)
+    public void switchConfig(int objectOrdinal)
       {
       Intent myIntent = new Intent(this, ConfigActivity.class);
-      myIntent.putExtra("obj", object.ordinal());
+      myIntent.putExtra("obj", objectOrdinal);
       startActivity(myIntent);
       }
 }
diff --git a/src/main/java/org/distorted/main/RubikObjectLibInterface.java b/src/main/java/org/distorted/main/RubikObjectLibInterface.java
index 7b932b3f..a44704a4 100644
--- a/src/main/java/org/distorted/main/RubikObjectLibInterface.java
+++ b/src/main/java/org/distorted/main/RubikObjectLibInterface.java
@@ -38,11 +38,12 @@ import org.distorted.objectlib.BuildConfig;
 import org.distorted.objectlib.helpers.BlockController;
 import org.distorted.objectlib.helpers.ObjectLibInterface;
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectType;
 
 import org.distorted.dialogs.RubikDialogNewRecord;
 import org.distorted.dialogs.RubikDialogSolved;
 import org.distorted.network.RubikScores;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.RubikScreenReady;
 import org.distorted.screens.RubikScreenSolver;
@@ -99,11 +100,13 @@ public class RubikObjectLibInterface implements ObjectLibInterface
     {
     RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
     RubikScores scores  = RubikScores.getInstance();
-    ObjectType object   = play.getObject();
-    int level           = play.getLevel();
-    String name         = scores.getName();
 
-    String record = object.name()+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
+    int object  = play.getObject();
+    int level   = play.getLevel();
+    String name = scores.getName();
+    RubikObject obj = RubikObjectList.getObject(object);
+
+    String record = obj+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
 
     if( BuildConfig.DEBUG )
        {
@@ -431,7 +434,7 @@ public class RubikObjectLibInterface implements ObjectLibInterface
     RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
     int color = solver.getCurrentColor();
     RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-    ObjectType currObject = play.getObject();
+    int currObject = play.getObject();
     mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
     mLastCubit = cubit;
     mLastCubitFace = face;
diff --git a/src/main/java/org/distorted/network/RubikNetwork.java b/src/main/java/org/distorted/network/RubikNetwork.java
index 259949a6..fbc3019b 100644
--- a/src/main/java/org/distorted/network/RubikNetwork.java
+++ b/src/main/java/org/distorted/network/RubikNetwork.java
@@ -37,7 +37,7 @@ import org.distorted.library.main.DistortedLibrary;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
 
-import static org.distorted.screens.RubikScreenPlay.MAX_LEVEL;
+import static org.distorted.objects.RubikObjectList.MAX_LEVEL;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/network/RubikScores.java b/src/main/java/org/distorted/network/RubikScores.java
index e1847076..64db538d 100644
--- a/src/main/java/org/distorted/network/RubikScores.java
+++ b/src/main/java/org/distorted/network/RubikScores.java
@@ -28,11 +28,12 @@ import android.telephony.TelephonyManager;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
-import static org.distorted.screens.RubikScreenPlay.MAX_LEVEL;
 import org.distorted.main.BuildConfig;
 import org.distorted.objects.RubikObject;
 import org.distorted.objects.RubikObjectList;
 
+import static org.distorted.objects.RubikObjectList.MAX_LEVEL;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // hold my own scores, and some other statistics.
 
diff --git a/src/main/java/org/distorted/objects/RubikObject.java b/src/main/java/org/distorted/objects/RubikObject.java
index e8e01092..d5fce5db 100644
--- a/src/main/java/org/distorted/objects/RubikObject.java
+++ b/src/main/java/org/distorted/objects/RubikObject.java
@@ -19,13 +19,13 @@
 
 package org.distorted.objects;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 import org.distorted.dmesh.ObjectMesh;
 import org.distorted.jsons.ObjectJson;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.patterns.RubikPatternList;
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 public class RubikObject
 {
   private static final int NUM = 4;
@@ -39,18 +39,18 @@ public class RubikObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikObject(int ordinal, ObjectType type)
+  RubikObject(ObjectType type)
     {
     mIconID = new int[NUM];
     for(int i=0; i<NUM; i++) mIconID[i] = type.getIconID(i);
 
     mName        = type.name();
     mNumScramble = type.getNumScramble();
-    mOrdinal     = ordinal;
-    mJsonID      = ObjectJson.getJsonID(type);
-    mMeshID      = ObjectMesh.getMeshID(type);
+    mOrdinal     = type.ordinal();
+    mJsonID      = ObjectJson.getJsonID(mOrdinal);
+    mMeshID      = ObjectMesh.getMeshID(mOrdinal);
 
-    int patternOrdinal  = RubikPatternList.getOrdinal(type);
+    int patternOrdinal  = RubikPatternList.getOrdinal(mOrdinal);
     mPatterns = RubikPatternList.getPatterns(patternOrdinal);
     }
 
diff --git a/src/main/java/org/distorted/objects/RubikObjectList.java b/src/main/java/org/distorted/objects/RubikObjectList.java
index 105a5bfb..b551d411 100644
--- a/src/main/java/org/distorted/objects/RubikObjectList.java
+++ b/src/main/java/org/distorted/objects/RubikObjectList.java
@@ -19,6 +19,7 @@
 
 package org.distorted.objects;
 
+import org.distorted.objectlib.main.ObjectConstants;
 import org.distorted.objectlib.main.ObjectType;
 
 import java.util.ArrayList;
@@ -28,10 +29,25 @@ import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
 
 public class RubikObjectList
 {
+  public static int MAX_LEVEL;
+
   private static RubikObjectList mType;
   private static int mNumObjects;
   private static ArrayList<RubikObject> mObjects;
 
+  static
+    {
+    int max = Integer.MIN_VALUE;
+
+    for (int i=0; i<NUM_OBJECTS; i++)
+      {
+      int cur = getDBLevel(i);
+      if( cur>max ) max = cur;
+      }
+
+    MAX_LEVEL = max;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private RubikObjectList()
@@ -49,7 +65,7 @@ public class RubikObjectList
     for(int i=0; i<NUM_OBJECTS; i++)
       {
       ObjectType type = ObjectType.getObject(i);
-      RubikObject obj = new RubikObject(i,type);
+      RubikObject obj = new RubikObject(type);
       mObjects.add(obj);
       mNumObjects++;
       }
@@ -57,6 +73,33 @@ public class RubikObjectList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// historically older versions of the app had lower 'maxScrambles' in case of several objects and
+// those got remembered in the server-side DB already, so we need to keep using them. This function
+// provides a map between 'maxScramble' of an object and its 'dbLevel'. All new objects will have
+// those two values the same.
+
+  public static int getDBLevel(int ordinal)
+    {
+    if( ordinal==ObjectConstants.CUBE_3 ) return 16;
+    if( ordinal==ObjectConstants.CUBE_4 ) return 20;
+    if( ordinal==ObjectConstants.CUBE_5 ) return 24;
+    if( ordinal==ObjectConstants.PYRA_4 ) return 15;
+    if( ordinal==ObjectConstants.PYRA_5 ) return 20;
+    if( ordinal==ObjectConstants.MEGA_5 ) return 35;
+    if( ordinal==ObjectConstants.DIAM_2 ) return 10;
+    if( ordinal==ObjectConstants.DIAM_3 ) return 18;
+    if( ordinal==ObjectConstants.REDI_3 ) return 14;
+    if( ordinal==ObjectConstants.HELI_3 ) return 18;
+    if( ordinal==ObjectConstants.SKEW_3 ) return 17;
+    if( ordinal==ObjectConstants.REX_3  ) return 16;
+    if( ordinal==ObjectConstants.MIRR_3 ) return 16;
+
+    ObjectType type = ObjectType.getObject(ordinal);
+    return type.getNumScramble();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static RubikObject getObject(int ordinal)
     {
diff --git a/src/main/java/org/distorted/patterns/RubikPatternList.java b/src/main/java/org/distorted/patterns/RubikPatternList.java
index 8fb8568f..caa30417 100644
--- a/src/main/java/org/distorted/patterns/RubikPatternList.java
+++ b/src/main/java/org/distorted/patterns/RubikPatternList.java
@@ -19,25 +19,25 @@
 
 package org.distorted.patterns;
 
-import org.distorted.objectlib.main.ObjectType;
+import org.distorted.objectlib.main.ObjectConstants;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public enum RubikPatternList
   {
-  CUBE2 (ObjectType.CUBE_2, PatternCube2.patterns),
-  CUBE3 (ObjectType.CUBE_3, PatternCube3.patterns),
-  CUBE4 (ObjectType.CUBE_4, PatternCube4.patterns),
-  CUBE5 (ObjectType.CUBE_5, PatternCube5.patterns),
-  PYRA3 (ObjectType.PYRA_3, PatternPyraminx3.patterns),
-  PYRA4 (ObjectType.PYRA_4, PatternPyraminx4.patterns),
-  PYRA5 (ObjectType.PYRA_5, PatternPyraminx5.patterns),
-  MEGA3 (ObjectType.MEGA_3, PatternMegaminx.patterns),
-  MEGA5 (ObjectType.MEGA_5, PatternGigaminx.patterns),
+  CUBE2 (ObjectConstants.CUBE_2, PatternCube2.patterns),
+  CUBE3 (ObjectConstants.CUBE_3, PatternCube3.patterns),
+  CUBE4 (ObjectConstants.CUBE_4, PatternCube4.patterns),
+  CUBE5 (ObjectConstants.CUBE_5, PatternCube5.patterns),
+  PYRA3 (ObjectConstants.PYRA_3, PatternPyraminx3.patterns),
+  PYRA4 (ObjectConstants.PYRA_4, PatternPyraminx4.patterns),
+  PYRA5 (ObjectConstants.PYRA_5, PatternPyraminx5.patterns),
+  MEGA3 (ObjectConstants.MEGA_3, PatternMegaminx.patterns),
+  MEGA5 (ObjectConstants.MEGA_5, PatternGigaminx.patterns),
   ;
 
   public static final int NUM_OBJECTS = values().length;
-  private final ObjectType mObject;
+  private final int mObject;
   private final String[][] mPatterns;
 
   private static final RubikPatternList[] objects;
@@ -55,28 +55,28 @@ public enum RubikPatternList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static String[][] getPatterns(int ordinal)
+  RubikPatternList(int object, String[][] patterns)
     {
-    return ordinal>=0 && ordinal<NUM_OBJECTS ? objects[ordinal].mPatterns : null;
+    mObject   = object;
+    mPatterns = patterns;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikPatternList(ObjectType object, String[][] patterns)
+  public static String[][] getPatterns(int ordinal)
     {
-    mObject   = object;
-    mPatterns = patterns;
+    return ordinal>=0 && ordinal<NUM_OBJECTS ? objects[ordinal].mPatterns : null;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static int getOrdinal(ObjectType object)
+  public static int getOrdinal(int objectOrdinal)
     {
     for(int i=0; i<NUM_OBJECTS; i++)
       {
-      if( objects[i].mObject == object )
+      if( objects[i].mObject == objectOrdinal )
         {
         return i;
         }
@@ -87,7 +87,7 @@ public enum RubikPatternList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static ObjectType getObject(int ordinal)
+  public static int getObject(int ordinal)
     {
     return objects[ordinal].mObject;
     }
diff --git a/src/main/java/org/distorted/screens/RubikScreenPattern.java b/src/main/java/org/distorted/screens/RubikScreenPattern.java
index c845eda9..46122091 100644
--- a/src/main/java/org/distorted/screens/RubikScreenPattern.java
+++ b/src/main/java/org/distorted/screens/RubikScreenPattern.java
@@ -29,7 +29,6 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectType;
 
 import org.distorted.main.R;
 import org.distorted.dialogs.RubikDialogPattern;
@@ -61,11 +60,11 @@ public class RubikScreenPattern extends RubikScreenAbstract
   void leaveScreen(RubikActivity act)
     {
     RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-    ObjectType object = RubikPatternList.getObject(mPatternOrdinal);
+    int object = RubikPatternList.getObject(mPatternOrdinal);
 
     if( !play.setObject(act,object) )
       {
-      act.changeObject(play.getObject(),false);
+      act.changeObject(object,false);
       }
     }
 
diff --git a/src/main/java/org/distorted/screens/RubikScreenPlay.java b/src/main/java/org/distorted/screens/RubikScreenPlay.java
index a3403d60..678da582 100644
--- a/src/main/java/org/distorted/screens/RubikScreenPlay.java
+++ b/src/main/java/org/distorted/screens/RubikScreenPlay.java
@@ -35,8 +35,8 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 
+import org.distorted.objectlib.main.ObjectConstants;
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectType;
 
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
@@ -47,9 +47,10 @@ import org.distorted.dialogs.RubikDialogTutorial;
 import org.distorted.helpers.TransparentButton;
 import org.distorted.helpers.TransparentImageButton;
 import org.distorted.network.RubikScores;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 
 import static android.view.View.inflate;
-import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -57,8 +58,7 @@ public class RubikScreenPlay extends RubikScreenBase
   {
   public static final int NUM_COLUMNS  = 4;
   public static final int LEVELS_SHOWN = 10;
-  public static int MAX_LEVEL;
-  public static final ObjectType DEF_OBJECT= ObjectType.CUBE_3;
+  public static final int DEF_OBJECT= ObjectConstants.CUBE_3;
 
   private static final int[] BUTTON_LABELS = { R.string.scores,
                                                R.string.patterns,
@@ -73,7 +73,7 @@ public class RubikScreenPlay extends RubikScreenBase
   private TransparentImageButton mObjButton, mMenuButton, mSolveButton, mScrambleButton;
   private TransparentButton mPlayButton;
   private PopupWindow mObjectPopup, mMenuPopup, mPlayPopup;
-  private ObjectType mObject = DEF_OBJECT;
+  private int mObject = DEF_OBJECT;
   private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mPlayLayoutWidth;
   private int mLevelValue;
   private float mButtonSize, mMenuItemSize, mMenuTextSize;
@@ -82,20 +82,6 @@ public class RubikScreenPlay extends RubikScreenBase
   private int mUpperBarHeight;
   private boolean mShouldReactToEndOfScrambling;
 
-  static
-    {
-    ObjectType[] types = ObjectType.values();
-    int max = Integer.MIN_VALUE;
-
-    for (ObjectType type : types)
-      {
-      int cur = getDBLevel(type);
-      if( cur>max ) max = cur;
-      }
-
-    MAX_LEVEL = max;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void leaveScreen(RubikActivity act)
@@ -107,6 +93,7 @@ public class RubikScreenPlay extends RubikScreenBase
 
   void enterScreen(final RubikActivity act)
     {
+    int numObjects = RubikObjectList.getNumObjects();
     float width = act.getScreenWidthInPixels();
     mUpperBarHeight = act.getHeightUpperBar();
 
@@ -114,7 +101,7 @@ public class RubikScreenPlay extends RubikScreenBase
     mButtonSize   = width*RubikActivity.BUTTON_TEXT_SIZE;
     mMenuItemSize = width*RubikActivity.MENU_ITEM_SIZE;
 
-    mRowCount = (NUM_OBJECTS + NUM_COLUMNS-1) / NUM_COLUMNS;
+    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
     mColCount = NUM_COLUMNS;
 
     // TOP ////////////////////////////
@@ -192,7 +179,7 @@ public class RubikScreenPlay extends RubikScreenBase
           final int maxHeight= (int)(0.9f*(height-mUpperBarHeight) );
           View popupView = mPlayPopup.getContentView();
           popupView.setSystemUiVisibility(RubikActivity.FLAGS);
-          final int dbLevel = getDBLevel(mObject);
+          final int dbLevel = RubikObjectList.getDBLevel(mObject);
           final int levelsShown = Math.min(dbLevel,LEVELS_SHOWN);
           final int popupHeight = (int)(levelsShown*(mMenuItemSize+margin)+3*margin+mMenuItemSize*(LAST_BUTTON-1.0f));
           final int realHeight = Math.min(popupHeight,maxHeight);
@@ -255,7 +242,7 @@ public class RubikScreenPlay extends RubikScreenBase
     objectGrid.setRowCount(mRowCount);
 
     LinearLayout bottomLayout = view.findViewById(R.id.bottomLayout);
-    setupBottomLayout(act,bottomLayout,2*mObjectSize,mObjectSize);
+    setupBottomLayout(act,bottomLayout,2*mObjectSize);
 
     mObjectPopup = new PopupWindow(act);
     mObjectPopup.setFocusable(true);
@@ -273,11 +260,13 @@ public class RubikScreenPlay extends RubikScreenBase
       colSpecs[col] = GridLayout.spec(col);
       }
 
-    for(int object = 0; object< NUM_OBJECTS; object++)
+    int numObjects = RubikObjectList.getNumObjects();
+
+    for(int object=0; object<numObjects; object++)
       {
-      final ObjectType type = ObjectType.getObject(object);
+      final RubikObject robject = RubikObjectList.getObject(object);
       int iconSize = RubikActivity.getDrawableSize();
-      int icons = type.getIconID(iconSize);
+      int icons = robject==null ? 0 : robject.getIconID(iconSize);
       int row = object/NUM_COLUMNS;
 
       ImageButton button = new ImageButton(act);
@@ -289,8 +278,8 @@ public class RubikScreenPlay extends RubikScreenBase
           {
           if( act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
             {
-            mObject = type;
-            act.changeObject(type, true);
+            mObject = robject==null ? 0 : robject.getOrdinal();
+            act.changeObject(mObject, true);
             if( mPlayLayout!=null ) adjustLevels(act);
             mMovesController.clearMoves(act);
             }
@@ -313,7 +302,7 @@ public class RubikScreenPlay extends RubikScreenBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void setupBottomLayout(final RubikActivity act, final LinearLayout layout, int width, int height)
+  private void setupBottomLayout(final RubikActivity act, final LinearLayout layout, int width)
     {
     int iconD = RubikActivity.getDrawable(R.drawable.ui_small_info,R.drawable.ui_medium_info, R.drawable.ui_big_info, R.drawable.ui_huge_info);
     int iconT = RubikActivity.getDrawable(R.drawable.ui_small_tutorial,R.drawable.ui_medium_tutorial, R.drawable.ui_big_tutorial, R.drawable.ui_huge_tutorial);
@@ -419,7 +408,7 @@ public class RubikScreenPlay extends RubikScreenBase
     switch(button)
       {
       case 0: Bundle sBundle = new Bundle();
-              sBundle.putInt("tab", mObject.ordinal() );
+              sBundle.putInt("tab", mObject );
               sBundle.putBoolean("submitting", false);
               RubikDialogScores scores = new RubikDialogScores();
               scores.setArguments(sBundle);
@@ -471,8 +460,8 @@ public class RubikScreenPlay extends RubikScreenBase
       @Override
       public void onClick(View v)
         {
-        RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-        int numScrambles = play.getObject().getNumScramble();
+        RubikObject object = RubikObjectList.getObject(mObject);
+        int numScrambles = object==null ? 0 : object.getNumScramble();
         mShouldReactToEndOfScrambling = false;
         act.getControl().scrambleObject(numScrambles);
         }
@@ -483,7 +472,12 @@ public class RubikScreenPlay extends RubikScreenBase
 
   public void savePreferences(SharedPreferences.Editor editor)
     {
-    editor.putString("statePlay_objName", mObject.name() );
+    RubikObject object = RubikObjectList.getObject(mObject);
+
+    if( object!=null )
+      {
+      editor.putString("statePlay_objName", object.getName() );
+      }
 
     if( mObjectPopup!=null )
       {
@@ -508,18 +502,21 @@ public class RubikScreenPlay extends RubikScreenBase
 
   public void restorePreferences(SharedPreferences preferences)
     {
-    String objName= preferences.getString("statePlay_objName", DEF_OBJECT.name() );
-    int ordinal = ObjectType.getOrdinal(objName);
-    mObject = ordinal>=0 && ordinal<NUM_OBJECTS ? ObjectType.values()[ordinal] : DEF_OBJECT;
+    RubikObject object = RubikObjectList.getObject(DEF_OBJECT);
+    String defName = object==null ? "CUBE_3" : object.getName();
+    String objName= preferences.getString("statePlay_objName",defName);
+    mObject = RubikObjectList.getOrdinal(objName);
+
+    if( mObject<0 || mObject>=RubikObjectList.getNumObjects() ) mObject = DEF_OBJECT;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public boolean setObject(RubikActivity act, ObjectType obj)
+  public boolean setObject(RubikActivity act, int ordinal)
     {
-    if( mObject!=obj )
+    if( mObject!=ordinal )
       {
-      mObject = obj;
+      mObject = ordinal;
       if( mPlayLayout!=null ) adjustLevels(act);
       return true;
       }
@@ -576,15 +573,15 @@ public class RubikScreenPlay extends RubikScreenBase
 
   public void adjustSolvedIcons()
     {
-    int dbLevel = getDBLevel(mObject);
-    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
+    int dbLevel = RubikObjectList.getDBLevel(mObject);
+    int numLevel= Math.min(dbLevel, LEVELS_SHOWN);
     RubikScores scores = RubikScores.getInstance();
 
     for(int i=0; i<numLevel; i++)
       {
       int level = i<numLevel-1 ? i+1 : dbLevel;
       Button button = (Button)mPlayLayout.getChildAt(i);
-      int icon = scores.isSolved(mObject.ordinal(), level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
+      int icon = scores.isSolved(mObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
       button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
       }
     }
@@ -593,8 +590,9 @@ public class RubikScreenPlay extends RubikScreenBase
 
   private void adjustLevels(final RubikActivity act)
     {
-    int dbLevel = getDBLevel(mObject);
-    int numScrambles = mObject.getNumScramble();
+    int dbLevel = RubikObjectList.getDBLevel(mObject);
+    RubikObject object = RubikObjectList.getObject(mObject);
+    int numScrambles = object==null ? 0 : object.getNumScramble();
     int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
     String[] levels = new String[numLevel];
 
@@ -641,7 +639,7 @@ public class RubikScreenPlay extends RubikScreenBase
       button.setText(levels[i]);
       button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
 
-      int icon = scores.isSolved(mObject.ordinal(), level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
+      int icon = scores.isSolved(mObject, level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
       button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
 
       button.setOnClickListener( new View.OnClickListener()
@@ -665,33 +663,6 @@ public class RubikScreenPlay extends RubikScreenBase
       }
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// historically older versions of the app had lower 'maxScrambles' in case of several objects and
-// those got remembered in the server-side DB already, so we need to keep using them. This function
-// provides a map between 'maxScramble' of an object and its 'dbLevel'. All new objects will have
-// those two values the same.
-
-  public static int getDBLevel(ObjectType object)
-    {
-    switch(object)
-      {
-      case CUBE_3: return 16;
-      case CUBE_4: return 20;
-      case CUBE_5: return 24;
-      case PYRA_4: return 15;
-      case PYRA_5: return 20;
-      case MEGA_5: return 35;
-      case DIAM_2: return 10;
-      case DIAM_3: return 18;
-      case REDI_3: return 14;
-      case HELI_3: return 18;
-      case SKEW_3: return 17;
-      case REX_3 : return 16;
-      case MIRR_3: return 16;
-      default    : return object.getNumScramble();
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public int getLevel()
@@ -708,7 +679,7 @@ public class RubikScreenPlay extends RubikScreenBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public ObjectType getObject()
+  public int getObject()
     {
     return mObject;
     }
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolver.java b/src/main/java/org/distorted/screens/RubikScreenSolver.java
index 97afc01d..653cfb16 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolver.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolver.java
@@ -35,7 +35,6 @@ import android.widget.LinearLayout;
 
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.TwistyObject;
-import org.distorted.objectlib.main.ObjectType;
 
 import org.distorted.dialogs.RubikDialogSolverError;
 import org.distorted.helpers.TransparentImageButton;
@@ -83,7 +82,7 @@ public class RubikScreenSolver extends RubikScreenAbstract
     mWeakAct = new WeakReference<>(act);
     mSolving = false;
 
-    ObjectType currentObject= ImplementedSolversList.getObject(0);
+    int currentObject= ImplementedSolversList.getObject(0);
     act.changeIfDifferent(currentObject,control);
     control.solveOnly();
 
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolving.java b/src/main/java/org/distorted/screens/RubikScreenSolving.java
index 2f26a081..5c64ea30 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolving.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolving.java
@@ -34,7 +34,6 @@ import org.distorted.helpers.TransparentImageButton;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.network.RubikScores;
-import org.distorted.objectlib.main.ObjectType;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -186,9 +185,9 @@ public class RubikScreenSolving extends RubikScreenBase
       mElapsed = System.currentTimeMillis()-mStartTime;
 
       RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-      ObjectType object = play.getObject();
+      int object = play.getObject();
       int level = play.getLevel();
-      boolean isNew = mScores.setRecord(object.ordinal(), level, mElapsed);
+      boolean isNew = mScores.setRecord(object, level, mElapsed);
 
       return isNew ? mElapsed : -mElapsed;
       }
diff --git a/src/main/java/org/distorted/solvers/ImplementedSolversList.java b/src/main/java/org/distorted/solvers/ImplementedSolversList.java
index a2dcb0c5..0e39bbd5 100644
--- a/src/main/java/org/distorted/solvers/ImplementedSolversList.java
+++ b/src/main/java/org/distorted/solvers/ImplementedSolversList.java
@@ -19,18 +19,18 @@
 
 package org.distorted.solvers;
 
-import org.distorted.objectlib.main.ObjectType;
+import org.distorted.objectlib.main.ObjectConstants;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public enum ImplementedSolversList
 {
-  CUBE3 ( ObjectType.CUBE_3),
+  CUBE3 (ObjectConstants.CUBE_3),
   ;
 
   public static final int NUM_OBJECTS = values().length;
 
-  private final ObjectType mObject;
+  private final int mObject;
 
   private static final ImplementedSolversList[] objects;
 
@@ -47,14 +47,14 @@ public enum ImplementedSolversList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static ObjectType getObject(int ordinal)
+  public static int getObject(int ordinal)
     {
     return objects[ordinal].mObject;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  ImplementedSolversList(ObjectType object)
+  ImplementedSolversList(int object)
     {
     mObject= object;
     }
diff --git a/src/main/java/org/distorted/solvers/SolverMain.java b/src/main/java/org/distorted/solvers/SolverMain.java
index 513e28cf..255fedf7 100644
--- a/src/main/java/org/distorted/solvers/SolverMain.java
+++ b/src/main/java/org/distorted/solvers/SolverMain.java
@@ -21,7 +21,7 @@ package org.distorted.solvers;
 
 import android.content.res.Resources;
 
-import org.distorted.objectlib.main.ObjectType;
+import org.distorted.objectlib.main.ObjectConstants;
 import org.distorted.objectlib.main.TwistyObject;
 
 import org.distorted.main.R;
@@ -34,6 +34,7 @@ public class SolverMain implements Runnable
 {
   private final Resources mRes;
   private final TwistyObject mObject;
+  private final int mOrdinal;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -41,6 +42,7 @@ public class SolverMain implements Runnable
     {
     mRes   = res;
     mObject= object;
+    mOrdinal = object.getObjectType().ordinal();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -49,9 +51,9 @@ public class SolverMain implements Runnable
 // If a certain cubit is locked, return the color (index into it's FACE_COLORS array) it
 // must have. Otherwise return -1.
 
-  public static int cubitIsLocked(ObjectType object, int cubit)
+  public static int cubitIsLocked(int object, int cubit)
     {
-    if( object == ObjectType.CUBE_3 )
+    if( object == ObjectConstants.CUBE_3 )
       {
       if( cubit==20 ) return 0; // center of the right  face
       if( cubit==21 ) return 1; // center of the left   face
@@ -209,7 +211,7 @@ public class SolverMain implements Runnable
     {
     RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
 
-    if( mObject!=null && mObject.getObjectType()==ObjectType.CUBE_3 )
+    if( mOrdinal==ObjectConstants.CUBE_3 )
       {
       solveCube3(solver);
       }
diff --git a/src/main/java/org/distorted/tutorials/TutorialActivity.java b/src/main/java/org/distorted/tutorials/TutorialActivity.java
index cea82e2e..530aae0a 100644
--- a/src/main/java/org/distorted/tutorials/TutorialActivity.java
+++ b/src/main/java/org/distorted/tutorials/TutorialActivity.java
@@ -39,10 +39,10 @@ import org.distorted.jsons.ObjectJson;
 import org.distorted.library.main.DistortedLibrary;
 
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectType;
 
 import org.distorted.main.R;
 import org.distorted.dialogs.RubikDialogError;
+import org.distorted.objects.RubikObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -197,10 +197,9 @@ public class TutorialActivity extends AppCompatActivity
 
       if( mWebView!=null ) mWebView.onResume();
 
-      if( mObjectOrdinal>=0 && mObjectOrdinal< ObjectType.NUM_OBJECTS )
+      if( mObjectOrdinal>=0 && mObjectOrdinal< RubikObjectList.getNumObjects() )
         {
-        ObjectType obj = ObjectType.getObject(mObjectOrdinal);
-        changeIfDifferent(obj,view.getObjectControl());
+        changeIfDifferent(mObjectOrdinal,view.getObjectControl());
         }
       }
 
@@ -223,11 +222,11 @@ public class TutorialActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    private void changeIfDifferent(ObjectType type,ObjectControl control)
+    private void changeIfDifferent(int objectOrdinal,ObjectControl control)
       {
-      InputStream jsonStream = ObjectJson.getStream(type,this);
-      InputStream meshStream = ObjectMesh.getStream(type,this);
-      control.changeIfDifferent(type.ordinal(),jsonStream,meshStream);
+      InputStream jsonStream = ObjectJson.getStream(this,objectOrdinal);
+      InputStream meshStream = ObjectMesh.getStream(this,objectOrdinal);
+      control.changeIfDifferent(objectOrdinal,jsonStream,meshStream);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/tutorials/TutorialList.java b/src/main/java/org/distorted/tutorials/TutorialList.java
index 7fee2d9d..2ddeeb88 100644
--- a/src/main/java/org/distorted/tutorials/TutorialList.java
+++ b/src/main/java/org/distorted/tutorials/TutorialList.java
@@ -19,14 +19,16 @@
 
 package org.distorted.tutorials;
 
-import org.distorted.objectlib.main.ObjectType;
 import org.distorted.main.RubikActivity;
+import org.distorted.objectlib.main.ObjectConstants;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public enum TutorialList
 {
-  CUBE2 ( ObjectType.CUBE_2,
+  CUBE2 ( ObjectConstants.CUBE_2,
           new String[][] {
                           {"gb","rJlh5p2wAKA","How to Solve a 2x2 Rubik's Cube","Z3"},
                           {"es","f85wqJTIDlw","Resolver cubo de Rubik 2X2","Cuby"},
@@ -39,7 +41,7 @@ public enum TutorialList
                          }
         ),
 
-  CUBE3 ( ObjectType.CUBE_3,
+  CUBE3 ( ObjectConstants.CUBE_3,
           new String[][] {
                           {"gb","-8ohoCKN0Zw","How to Solve a Rubik's Cube","Z3"},
                           {"es","GyY0OxDk5lI","Resolver cubo de Rubik 3x3","Cuby"},
@@ -54,7 +56,7 @@ public enum TutorialList
                          }
         ),
 
-  CUBE4 ( ObjectType.CUBE_4,
+  CUBE4 ( ObjectConstants.CUBE_4,
           new String[][] {
                           {"gb","RR77Md71Ymc","How to Solve the 4x4 Rubik's Cube","Z3"},
                           {"es","d_4xk1r9hxU","Resolver cubo de Rubik 4x4","Cuby"},
@@ -71,7 +73,7 @@ public enum TutorialList
                          }
         ),
 
-  CUBE5 ( ObjectType.CUBE_5,
+  CUBE5 ( ObjectConstants.CUBE_5,
           new String[][] {
                           {"gb","zMkNkXHzQts","How to Solve the 5x5 Rubik's Cube","Z3"},
                           {"es","6uaq-xfFs98","Resolver cubo de Rubik 5x5","Cuby"},
@@ -83,7 +85,7 @@ public enum TutorialList
                          }
         ),
 
-  CUBE6 ( ObjectType.CUBE_6,
+  CUBE6 ( ObjectConstants.CUBE_6,
           new String[][] {
                           {"gb","SkZ9UadAOvQ","How to Solve the 6x6 Rubik's Cube","JPerm"},
                           {"es","9X-mW6wbnQQ","Resolver cubo de Rubik 6x6","Cuby"},
@@ -95,7 +97,7 @@ public enum TutorialList
                          }
         ),
 
-  CUBE7 ( ObjectType.CUBE_7,
+  CUBE7 ( ObjectConstants.CUBE_7,
           new String[][] {
                           {"gb","xpI7jKs4bWQ","7x7 Centers (1/2)","CubeSkills"},
                           {"gb","xpI7jKs4bWQ","7x7 Edges & 3x3 Stage (2/2)","CubeSkills"},
@@ -108,7 +110,7 @@ public enum TutorialList
                          }
         ),
 
-  MIRR2 ( ObjectType.MIRR_2,
+  MIRR2 ( ObjectConstants.MIRR_2,
           new String[][] {
                           {"gb","rSH-ZEqTmxs","Solve 2x2 Mirror Blocks","King of Cubing"},
                           {"es","Ipz-Ajpd4Fg","Como resolver el mirror 2x2","RUBI CUBI"},
@@ -119,7 +121,7 @@ public enum TutorialList
                          }
        ),
 
-  MIRR3 ( ObjectType.MIRR_3,
+  MIRR3 ( ObjectConstants.MIRR_3,
           new String[][] {
                           {"gb","YkzXIWnqbSw","How to Solve the Mirror Cube","Z3"},
                           {"es","ZTkunMo51l0","Resolver cubo de Rubik MIRROR","Cuby"},
@@ -131,7 +133,7 @@ public enum TutorialList
                          }
        ),
 
-  JING  ( ObjectType.JING_2,
+  JING  ( ObjectConstants.JING_2,
           new String[][] {
                           {"gb","0T8Iw6aI2gA","Jing's Pyraminx Tutorial","SuperAntoniovivaldi"},
                           {"es","Na27_GUIzqY","Resolver Jing Pyraminx","Cuby"},
@@ -142,7 +144,7 @@ public enum TutorialList
                          }
         ),
 
-  PYRA3 ( ObjectType.PYRA_3,
+  PYRA3 ( ObjectConstants.PYRA_3,
           new String[][] {
                           {"gb","xIQtn2qazvg","Pyraminx Layer By Layer","Z3"},
                           {"es","4cJJe9RAzAU","Resolver Pyraminx","Cuby"},
@@ -155,7 +157,7 @@ public enum TutorialList
                          }
         ),
 
-  PYRA4 ( ObjectType.PYRA_4,
+  PYRA4 ( ObjectConstants.PYRA_4,
           new String[][] {
                           {"gb","tGQDqDcSa6U","How to Solve the Master Pyraminx","Z3"},
                           {"es","74PIPm9-uPg","Resolver Master Pyraminx 4x4","Cuby"},
@@ -167,7 +169,7 @@ public enum TutorialList
                          }
         ),
 
-  PYRA5 ( ObjectType.PYRA_5,
+  PYRA5 ( ObjectConstants.PYRA_5,
           new String[][] {
                           {"gb","2nsPEECDdN0","Professor Pyraminx Solve","RedKB"},
                           {"es","cSDj8OQK3TU","Tutorial del Professor Pyraminx","QBAndo"},
@@ -177,7 +179,7 @@ public enum TutorialList
                          }
         ),
 
-  KILO3( ObjectType.KILO_3,
+  KILO3( ObjectConstants.KILO_3,
           new String[][] {
                           {"gb","grgGgUSxiQg","How to Solve the Kilominx","Z3"},
                           {"es","g6WMYjkCLok","Resolver Kilominx","Cuby"},
@@ -189,7 +191,7 @@ public enum TutorialList
                          }
        ),
 
-  KILO5( ObjectType.KILO_5,
+  KILO5( ObjectConstants.KILO_5,
           new String[][] {
                           {"gb","VAnzC2SYVc4","How To Solve A Master Kilominx","Grizz Media"},
                           {"es","ozINTg-61Fs","Tutorial Master Kilominx","RubikArt"},
@@ -204,7 +206,7 @@ public enum TutorialList
                          }
        ),
 
-  MEGA3( ObjectType.MEGA_3,
+  MEGA3( ObjectConstants.MEGA_3,
           new String[][] {
                           {"gb","j4x61L5Onzk","How to Solve the Megaminx","Z3"},
                           {"es","xuKbT6Il0Ko","Resolver Megaminx","Cuby"},
@@ -216,7 +218,7 @@ public enum TutorialList
                          }
        ),
 
-  MEGA5( ObjectType.MEGA_5,
+  MEGA5( ObjectConstants.MEGA_5,
           new String[][] {
                           {"gb","MNBMm8BnHtQ","Solve the Gigaminx Part 1","BeardedCubing"},
                           {"gb","QrrP4GwqVMw","Solve the Gigaminx Part 2","BeardedCubing"},
@@ -234,7 +236,7 @@ public enum TutorialList
                          }
        ),
 
-  ULTI ( ObjectType.ULTI_2,
+  ULTI ( ObjectConstants.ULTI_2,
           new String[][] {
                           {"gb","n1ikPKZxGEo","Ultimate Skewb Tutorial","BeardedCubing"},
                           {"es","wNL1WJ_sCfs","Resolver Skewb ULTIMATE","Cuby"},
@@ -246,7 +248,7 @@ public enum TutorialList
                          }
         ),
 
-  DIAM2 ( ObjectType.DIAM_2,
+  DIAM2 ( ObjectConstants.DIAM_2,
           new String[][] {
                           {"gb","R2wrbJJ3izM","How to Solve a Skewb Diamond","Dr. Penguin^3"},
                           {"es","2RCusYQdYYE","Como resolver Skewb Diamond","Tutoriales Rubik"},
@@ -258,7 +260,7 @@ public enum TutorialList
                          }
        ),
 
-  DIAM3 ( ObjectType.DIAM_3,
+  DIAM3 ( ObjectConstants.DIAM_3,
           new String[][] {
                           {"gb","n_mBSUDLUZw","Face Turning Octahedron Tutorial","SuperAntoniovivaldi"},
                           {"es","ogf0t6fGxZI","FTO - Tutorial en español","Gadi Rubik"},
@@ -268,7 +270,7 @@ public enum TutorialList
                          }
        ),
 
-  DIAM4 ( ObjectType.DIAM_4,
+  DIAM4 ( ObjectConstants.DIAM_4,
           new String[][] {
                           {"gb","3GJkySk5zeQ","Master Face Turning Octahedron","SuperAntoniovivaldi"},
                           {"gb","zW_1htxy52k","Master FTO Tutorial","Michele Regano"},
@@ -277,7 +279,7 @@ public enum TutorialList
                          }
        ),
 
-  DINO3 ( ObjectType.DINO_3,
+  DINO3 ( ObjectConstants.DINO_3,
           new String[][] {
                           {"gb","puTJZqFBQwo","Dino Skewb Cube Tutorial","Bearded Cubing"},
                           {"es","6o1Yo5iCxvI","Resolver Cubo Dino","Cuby"},
@@ -289,7 +291,7 @@ public enum TutorialList
                          }
         ),
 
-  REDI3 ( ObjectType.REDI_3,
+  REDI3 ( ObjectConstants.REDI_3,
           new String[][] {
                           {"gb","Qn7TJED6O-4","How to Solve the MoYu Redi Cube","Z3"},
                           {"es","g0M38Aotgac","Resolver Redi Cube","Cuby"},
@@ -301,7 +303,7 @@ public enum TutorialList
                          }
         ),
 
-  HELI3 ( ObjectType.HELI_3,
+  HELI3 ( ObjectConstants.HELI_3,
           new String[][] {
                           {"gb","-suwJpd_PO8","Helicopter Cube Tutorial","Bearded Cubing"},
                           {"es","DWG9n_YyGPA","Resolver Helicopter Cube","Cuby"},
@@ -313,7 +315,7 @@ public enum TutorialList
                          }
         ),
 
-  SKEW2 ( ObjectType.SKEW_2,
+  SKEW2 ( ObjectConstants.SKEW_2,
           new String[][] {
                           {"gb","I6132yshkeU","How to Solve the Skewb","Z3"},
                           {"es","wxQX3HhPgds","Resolver Skewb (Principiantes)","Cuby"},
@@ -326,7 +328,7 @@ public enum TutorialList
                          }
         ),
 
-  SKEW3 ( ObjectType.SKEW_3,
+  SKEW3 ( ObjectConstants.SKEW_3,
           new String[][] {
                           {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
                           {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
@@ -341,7 +343,7 @@ public enum TutorialList
                          }
         ),
 
-  IVY2 ( ObjectType.IVY_2,
+  IVY2 ( ObjectConstants.IVY_2,
           new String[][] {
                           {"gb","QMzeJobSu1M","How to Solve the Ivy Cube","Z3"},
                           {"es","2-Gf2cmEJDs","Resolver Ivy Cube","Cuby"},
@@ -353,7 +355,7 @@ public enum TutorialList
                          }
         ),
 
-  REX3 ( ObjectType.REX_3,
+  REX3 ( ObjectConstants.REX_3,
           new String[][] {
                           {"gb","noAQfWqlMbk","Rex Cube Tutorial","CrazyBadCuber"},
                           {"es","Q90x9rjLJzw","Resolver Cubo Rex","Cuby"},
@@ -365,7 +367,7 @@ public enum TutorialList
                          }
         ),
 
-  BAN1( ObjectType.BAN1_3,
+  BAN1( ObjectConstants.BAN1_3,
           new String[][] {
                           {"gb","F_iJk_IvpVo","Bandaged Cube","CanChrisSolve"},
                           {"es","_lTgw5aEFOg","Tutorial 3x3 Fuse Cube","QBAndo"},
@@ -376,7 +378,7 @@ public enum TutorialList
                          }
        ),
 
-  BAN2( ObjectType.BAN2_3,
+  BAN2( ObjectConstants.BAN2_3,
           new String[][] {
                           {"ru","lS_EK0PMWI8","Как собрать 2-bar Cube","Алексей Ярыгин"},
                           {"pl","tX8ubTLh6p8","Bandaged 3x3 (Two bar)","MrUK"},
@@ -384,7 +386,7 @@ public enum TutorialList
                          }
        ),
 
-  BAN3( ObjectType.BAN3_3,
+  BAN3( ObjectConstants.BAN3_3,
           new String[][] {
                           {"gb","7UiCVGygUT4","Bandage Cube C Tutorial","PolyakB"},
                           {"ru","gXenRA92Wdc","Как собрать Bandaged 3x3 Type C","YG Cuber"},
@@ -393,7 +395,7 @@ public enum TutorialList
                          }
        ),
 
-  BAN4( ObjectType.BAN4_3,
+  BAN4( ObjectConstants.BAN4_3,
           new String[][] {
                           {"gb","AnpdIKICBpM","Trying to Solve a Bandaged Cube","RedKB"},
                           {"es","cUyo5fycrvI","Tutorial Bandaged Cube en español","Rafa Garcia Benacazon"},
@@ -405,7 +407,7 @@ public enum TutorialList
                          }
        ),
 
-  SQUA1 ( ObjectType.SQU1_3,
+  SQUA1 ( ObjectConstants.SQU1_3,
           new String[][] {
                           {"gb","0tX-f6RLgac","How to Solve the Square-1","Z3"},
                           {"es","mGtHDWj_i1o","Resolver SQUARE-1","Cuby"},
@@ -420,7 +422,7 @@ public enum TutorialList
                          }
        ),
 
-  SQUA2 ( ObjectType.SQU2_3,
+  SQUA2 ( ObjectConstants.SQU2_3,
           new String[][] {
                           {"gb","PPXojiFthEs","Square-2 Tutorial","SuperAntoniovivaldi"},
                           {"es","IiMwc51xKBQ","Cómo resolver Square-2","skieur cubb"},
@@ -431,7 +433,7 @@ public enum TutorialList
                          }
        ),
 
-  CU_323 ( ObjectType.CU_323,
+  CU_323 ( ObjectConstants.CU_323,
           new String[][] {
                           {"gb","pbv652cE1AU","How To Solve the 3x3x2 ","JRCuber"},
                           {"es","RtDbnDxXPrs","Cuboid 3x3x2 Tutorial","Cubo da Loucura"},
@@ -443,7 +445,7 @@ public enum TutorialList
                          }
        ),
 
-  CU_232 ( ObjectType.CU_232,
+  CU_232 ( ObjectConstants.CU_232,
           new String[][] {
                           {"gb","6dYOrUgFCsc","How to Solve the 2x2x3","Z3"},
                           {"es","5-ePFYnnY9k","Cuboid 2x2x3 Tutorial","Cubo da Loucura"},
@@ -455,7 +457,7 @@ public enum TutorialList
                          }
        ),
 
-  CU_343 ( ObjectType.CU_343,
+  CU_343 ( ObjectConstants.CU_343,
           new String[][] {
                           {"gb","nh8DqpMM3Ro","How to solve the 3x3x4","BeardedCubing"},
                           {"es","nfeJ1q_OoHU","Cuboid 3x3x4 Tutorial","Cubo da Loucura"},
@@ -469,7 +471,7 @@ public enum TutorialList
 
 
   public static final int NUM_OBJECTS = values().length;
-  private final ObjectType mObject;
+  private final int mObject;
   private final String[][] mTutorials;
   private final int mNumTutorials;
 
@@ -488,7 +490,7 @@ public enum TutorialList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  TutorialList(ObjectType object, String[][] tutorials)
+  TutorialList(int object, String[][] tutorials)
     {
     mObject       = object;
     mTutorials    = tutorials;
@@ -504,11 +506,11 @@ public enum TutorialList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static int getOrdinal(ObjectType object)
+  public static int getOrdinal(int object)
     {
-    if( object== ObjectType.DIN4_3 )
+    if( object==ObjectConstants.DIN4_3 )
       {
-      object= ObjectType.DINO_3;
+      object= ObjectConstants.DINO_3;
       }
 
     for(int i=0; i<NUM_OBJECTS; i++)
@@ -524,7 +526,7 @@ public enum TutorialList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public ObjectType getObject()
+  public int getObject()
     {
     return mObject;
     }
@@ -540,8 +542,9 @@ public enum TutorialList
 
   public int getIconID()
     {
+    RubikObject object = RubikObjectList.getObject(mObject);
     int iconSize = RubikActivity.getDrawableSize();
-    return mObject.getIconID(iconSize);
+    return object==null ? 0 : object.getIconID(iconSize);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/tutorials/TutorialScreen.java b/src/main/java/org/distorted/tutorials/TutorialScreen.java
index 41ed0b01..024ee5d7 100644
--- a/src/main/java/org/distorted/tutorials/TutorialScreen.java
+++ b/src/main/java/org/distorted/tutorials/TutorialScreen.java
@@ -29,6 +29,8 @@ import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.helpers.LockController;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
+import org.distorted.objects.RubikObject;
+import org.distorted.objects.RubikObjectList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.ScreenList;
 import org.distorted.helpers.TransparentImageButton;
@@ -74,7 +76,9 @@ public class TutorialScreen
       public void onClick(View v)
         {
         RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
-        int numScrambles = play.getObject().getNumScramble();
+        int object = play.getObject();
+        RubikObject obj = RubikObjectList.getObject(object);
+        int numScrambles = obj==null ? 0 : obj.getNumScramble();
         act.getControl().scrambleObject(numScrambles);
         }
       });
