diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp
index 70c72ef5..45510763 100644
--- a/src/CBot/CBotClass.cpp
+++ b/src/CBot/CBotClass.cpp
@@ -504,16 +504,25 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
         classe->Purge();                            // empty the old definitions // TODO: Doesn't this remove all classes of the current program?
         classe->m_IsDef = false;                    // current definition
 
+        classe->m_pOpenblk = p;
+
         if ( !IsOfType( p, ID_OPBLK) )
         {
             pStack->SetError(CBotErrOpenBlock, p);
             return nullptr;
         }
 
-        while ( pStack->IsOk() && !IsOfType( p, ID_CLBLK ) )
+        int level = 1;
+        do                                          // skip over the definition
         {
-            classe->CompileDefItem(p, pStack, false);
+            int type = p->GetType();
+            p = p->GetNext();
+            if (type == ID_OPBLK) level++;
+            if (type == ID_CLBLK) level--;
         }
+        while (level > 0 && p != nullptr);
+
+        if (level > 0) pStack->SetError(CBotErrCloseBlock, classe->m_pOpenblk);
 
         if (pStack->IsOk()) return classe;
     }
@@ -521,6 +530,26 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
     return nullptr;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+void CBotClass::DefineClasses(CBotClass* pClass, CBotCStack* pStack)
+{
+    while (pClass != nullptr)
+    {
+        CBotClass* pParent = pClass->m_parent;
+        pClass->m_nbVar = (pParent == nullptr) ? 0 : pParent->m_nbVar;
+        CBotToken* p = pClass->m_pOpenblk->GetNext();
+
+        while (pStack->IsOk() && !IsOfType(p, ID_CLBLK))
+        {
+            pClass->CompileDefItem(p, pStack, false);
+        }
+
+        if (!pStack->IsOk()) return;
+
+        pClass = pClass->GetNext();
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
 {
diff --git a/src/CBot/CBotClass.h b/src/CBot/CBotClass.h
index 234f5786..2fc494dc 100644
--- a/src/CBot/CBotClass.h
+++ b/src/CBot/CBotClass.h
@@ -291,6 +291,14 @@ public:
     static CBotClass* Compile1(CBotToken* &p,
                                CBotCStack* pStack);
 
+    /*!
+     * \brief DefineClasses Calls CompileDefItem for each class in a list
+     * of classes, defining fields and pre-compiling methods.
+     * \param pClass List of classes
+     * \param pStack
+     */
+    static void DefineClasses(CBotClass* pClass, CBotCStack* pStack);
+
     /*!
      * \brief CompileDefItem
      * \param p
@@ -385,6 +393,8 @@ private:
     CBotFunction* m_pMethod;
     void (*m_rUpdate)(CBotVar* thisVar, void* user);
 
+    CBotToken* m_pOpenblk;
+
     //! How many times the program currently holding the lock called Lock()
     int m_lockCurrentCount = 0;
     //! Programs waiting for lock. m_lockProg[0] is the program currently holding the lock, if any
diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index d0284ea2..77dac399 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -99,6 +99,10 @@ bool CBotProgram::Compile(const std::string& program, std::vector<std::string>&
             else m_functions->AddNext(next);
         }
     }
+
+    // Define fields and pre-compile methods for each class in this program
+    if (pStack->IsOk()) CBotClass::DefineClasses(m_classes, pStack.get());
+
     if ( !pStack->IsOk() )
     {
         m_error = pStack->GetError(m_errorStart, m_errorEnd);