diff --git a/Makefile b/Makefile
index 4b3bed8f0d7d4fd0ba7c0387eb701323d746a3b5..35704d190e0f0fc1de0dd219f79bf462e7d8bda6 100644
--- a/Makefile
+++ b/Makefile
@@ -61,10 +61,7 @@ test-all: ## run tests on every Python version with tox
 	tox
 
 coverage: ## check code coverage quickly with the default Python
-	coverage run --source flatland -m pytest
-	coverage report -m
-	coverage html
-	$(BROWSER) htmlcov/index.html
+	python make_coverage.py
 
 docs: ## generate Sphinx HTML documentation, including API docs
 	python make_docs.py
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index eb44e95ecbb9bc4079613db7f5d1e95ed4359691..0000000000000000000000000000000000000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-# TODO fix sphinx warnings instead of suppressing them...
-SPHINXOPTS    = -Q
-SPHINXBUILD   = python -msphinx
-SPHINXPROJ    = flatland
-SOURCEDIR     = .
-BUILDDIR      = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
-	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
-	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/make.bat b/docs/make.bat
deleted file mode 100644
index 40b4f60ada7eb91f7153d03787084019bf219fb9..0000000000000000000000000000000000000000
--- a/docs/make.bat
+++ /dev/null
@@ -1,36 +0,0 @@
-@ECHO OFF
-
-pushd %~dp0
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
-	set SPHINXBUILD=python -msphinx
-)
-set SOURCEDIR=.
-set BUILDDIR=_build
-set SPHINXPROJ=flatland
-
-if "%1" == "" goto help
-
-%SPHINXBUILD% >NUL 2>NUL
-if errorlevel 9009 (
-	echo.
-	echo.The Sphinx module was not found. Make sure you have Sphinx installed,
-	echo.then set the SPHINXBUILD environment variable to point to the full
-	echo.path of the 'sphinx-build' executable. Alternatively you may add the
-	echo.Sphinx directory to PATH.
-	echo.
-	echo.If you don't have Sphinx installed, grab it from
-	echo.http://sphinx-doc.org/
-	exit /b 1
-)
-
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
-goto end
-
-:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
-
-:end
-popd
diff --git a/flatland/core/env.py b/flatland/core/env.py
index 1bc5b6f3eba4ee4713bd3c8d6b88440006c215a5..3b17b53141f43e0c775c96b3018e219dfffa9229 100644
--- a/flatland/core/env.py
+++ b/flatland/core/env.py
@@ -66,7 +66,7 @@ class Environment:
         The returns are dicts mapping from agent_id strings to values.
 
         Parameters
-        -------
+        ----------
         action_dict : dict
             Dictionary of actions to execute, indexed by agent id.
 
diff --git a/flatland/core/env_observation_builder.py b/flatland/core/env_observation_builder.py
index 4acdf16f292a1b3ef5b78620e588dea8c3ff27e3..c7f18e2df6f2ca3f2c1942f6d1f0a859e07eb31b 100644
--- a/flatland/core/env_observation_builder.py
+++ b/flatland/core/env_observation_builder.py
@@ -36,8 +36,8 @@ class ObservationBuilder:
         in the `handles' list.
 
         Parameters
-        -------
-        handles : list of handles (optional)
+        ----------
+        handles : list of handles, optional
             List with the handles of the agents for which to compute the observation vector.
 
         Returns
@@ -57,8 +57,8 @@ class ObservationBuilder:
         for each agent independently (agent id `handle').
 
         Parameters
-        -------
-        handle : int (optional)
+        ----------
+        handle : int, optional
             Handle of the agent for which to compute the observation vector.
 
         Returns
diff --git a/flatland/core/env_prediction_builder.py b/flatland/core/env_prediction_builder.py
index 5ce69a8110236128b9a982e2540bc79357c1ba2d..86deebe54bd0248eead6716cb5a599cbb34f4d0c 100644
--- a/flatland/core/env_prediction_builder.py
+++ b/flatland/core/env_prediction_builder.py
@@ -33,11 +33,11 @@ class PredictionBuilder:
         Called whenever get_many in the observation build is called.
 
         Parameters
-        -------
+        ----------
         custom_args: dict
             Implementation-dependent custom arguments, see the sub-classes.
 
-        handle : int (optional)
+        handle : int, optional
             Handle of the agent for which to compute the observation vector.
 
         Returns
diff --git a/flatland/envs/predictions.py b/flatland/envs/predictions.py
index 4718ad9906db9b479123b53e9e9df0ff4db3b462..4eac97cbc25c18dd372618fdf16b80ec09ccad1a 100644
--- a/flatland/envs/predictions.py
+++ b/flatland/envs/predictions.py
@@ -22,10 +22,10 @@ class DummyPredictorForRailEnv(PredictionBuilder):
         Called whenever get_many in the observation build is called.
 
         Parameters
-        -------
+        ----------
         custom_args: dict
             Not used in this dummy implementation.
-        handle : int (optional)
+        handle : int, optional
             Handle of the agent for which to compute the observation vector.
 
         Returns
@@ -96,10 +96,10 @@ class ShortestPathPredictorForRailEnv(PredictionBuilder):
         Requires distance_map to extract the shortest path.
 
         Parameters
-        -------
+        ----------
         custom_args: dict
             - distance_map : dict
-        handle : int (optional)
+        handle : int, optional
             Handle of the agent for which to compute the observation vector.
 
         Returns
diff --git a/flatland/envs/rail_env.py b/flatland/envs/rail_env.py
index e4d693065aec0307bee8eaf3acd1c9e9e9df0e93..dc715abd84420c950be63181925bf858a5648f9c 100644
--- a/flatland/envs/rail_env.py
+++ b/flatland/envs/rail_env.py
@@ -114,7 +114,7 @@ class RailEnv(Environment):
         Environment init.
 
         Parameters
-        -------
+        ----------
         rail_generator : function
             The rail_generator function is a function that takes the width,
             height and agents handles of a  rail environment, along with the number of times
diff --git a/flatland/envs/rail_generators.py b/flatland/envs/rail_generators.py
index a16fb6018a6354665a44c1b44cafd6975bb4e680..7e718eb3888b8fec916905c29dbacc1d5b225402 100644
--- a/flatland/envs/rail_generators.py
+++ b/flatland/envs/rail_generators.py
@@ -38,8 +38,10 @@ def complex_rail_generator(nr_start_goal=1,
                            max_dist=99999,
                            seed=0) -> RailGenerator:
     """
+    complex_rail_generator
+
     Parameters
-    -------
+    ----------
     width : int
         The width (number of cells) of the grid to generate.
     height : int
@@ -165,7 +167,7 @@ def rail_from_manual_specifications_generator(rail_spec):
     transitions specifications.
 
     Parameters
-    -------
+    ----------
     rail_spec : list of list of tuples
         List (rows) of lists (columns) of tuples, each specifying a rail_spec_of_cell for
         the RailEnv environment as (cell_type, rotation), with rotation being
@@ -207,7 +209,7 @@ def rail_from_file(filename) -> RailGenerator:
     Utility to load pickle file
 
     Parameters
-    -------
+    ----------
     filename : Pickle file generated by env.save() or editor
 
     Returns
@@ -241,7 +243,7 @@ def rail_from_grid_transition_map(rail_map) -> RailGenerator:
     16-bit transitions specifications.
 
     Parameters
-    -------
+    ----------
     rail_map : GridTransitionMap object
         GridTransitionMap object to return when the generator is called.
 
@@ -277,7 +279,7 @@ def random_rail_generator(cell_type_relative_proportion=[1.0] * 11) -> RailGener
     found to turn most un-genereatable levels into valid ones.
 
     Parameters
-    -------
+    ----------
     width : int
         The width (number of cells) of the grid to generate.
     height : int
@@ -527,11 +529,12 @@ def random_rail_generator(cell_type_relative_proportion=[1.0] * 11) -> RailGener
 
 
 def sparse_rail_generator(num_cities=5, num_intersections=4, num_trainstations=2, min_node_dist=20, node_radius=2,
-                          num_neighb=3, grid_mode=False, enhance_intersection=False, seed=0):
+                          num_neighb=3, grid_mode=False, enhance_intersection=False, seed=0) -> RailGenerator:
     """
     This is a level generator which generates complex sparse rail configurations
 
     :param num_cities: Number of city node (can hold trainstations)
+    :type num_cities: int
     :param num_intersections: Number of intersection that city nodes can connect to
     :param num_trainstations: Total number of trainstations in env
     :param min_node_dist: Minimal distance between nodes
@@ -540,13 +543,10 @@ def sparse_rail_generator(num_cities=5, num_intersections=4, num_trainstations=2
     :param grid_mode: True -> NOdes evenly distirbuted in env, False-> Random distribution of nodes
     :param enhance_intersection: True -> Extra rail elements added at intersections
     :param seed: Random Seed
-    :return:
-        -------
-    numpy.ndarray of type numpy.uint16
-        The matrix with the correct 16-bit bitmaps for each cell.
+    :return: numpy.ndarray of type numpy.uint16 -- The matrix with the correct 16-bit bitmaps for each cell.
     """
 
-    def generator(width, height, num_agents, num_resets=0):
+    def generator(width, height, num_agents, num_resets=0) -> RailGeneratorProduct:
 
         if num_agents > num_trainstations:
             num_agents = num_trainstations
diff --git a/flatland/envs/schedule_generators.py b/flatland/envs/schedule_generators.py
index e81da924d1157fa9d5deef56306643c6a356cc8d..ba65ffec819814f899c9d66143029524f4c35841 100644
--- a/flatland/envs/schedule_generators.py
+++ b/flatland/envs/schedule_generators.py
@@ -17,7 +17,7 @@ ScheduleGenerator = Callable[[GridTransitionMap, int, Optional[Any]], ScheduleGe
 def speed_initialization_helper(nb_agents: int, speed_ratio_map: Mapping[float, float] = None) -> List[float]:
     """
     Parameters
-    -------
+    ----------
     nb_agents : int
         The number of agents to generate a speed for
     speed_ratio_map : Mapping[float,float]
@@ -120,7 +120,7 @@ def random_schedule_generator(speed_ratio_map: Mapping[float, float] = None) ->
     Given a `rail' GridTransitionMap, return a random placement of agents (initial position, direction and target).
 
     Parameters
-    -------
+    ----------
         rail : GridTransitionMap
             The railway to place agents on.
         num_agents : int
@@ -213,7 +213,7 @@ def schedule_from_file(filename) -> ScheduleGenerator:
     Utility to load pickle file
 
     Parameters
-    -------
+    ----------
     input_file : Pickle file generated by env.save() or editor
 
     Returns
diff --git a/make_docs.py b/make_docs.py
index 47588be7a7dd4134fd55deda46fae410454a5282..54fa84b3324f36769072b2b3f7da33ed8aa666bb 100644
--- a/make_docs.py
+++ b/make_docs.py
@@ -5,7 +5,7 @@ import shutil
 import subprocess
 import webbrowser
 from urllib.request import pathname2url
-from shutil import copyfile
+
 
 def browser(pathname):
     webbrowser.open("file:" + pathname2url(os.path.abspath(pathname)))
@@ -22,17 +22,21 @@ def remove_exists(filename):
 remove_exists('docs/flatland*.rst')
 remove_exists('docs/modules.rst')
 
-subprocess.call(['sphinx-apidoc', '--force', '-a', '-e', '-o', 'docs/', 'flatland', '-H', '"Flatland Reference"'])
-
+# copy md files from root folder into docs folder
 for file in glob.glob(r'./*.md'):
     print(file)
     shutil.copy(file, 'docs/')
 
+subprocess.call(['sphinx-apidoc', '--force', '-a', '-e', '-o', 'docs/', 'flatland', '-H', '"Flatland Reference"'])
+
 os.environ["SPHINXPROJ"] = "flatland"
 os.chdir('docs')
 subprocess.call(['python', '-msphinx', '-M', 'clean', '.', '_build'])
 # TODO fix sphinx warnings instead of suppressing them...
-subprocess.call(['python', '-msphinx', '-M', 'html', '.', '_build', '-Q'])
-subprocess.call(['python', '-mpydeps', '../flatland', '-o', '_build/html/flatland.svg', '--no-config', '--noshow'])
+subprocess.call(['python', '-msphinx', '-M', 'html', '.', '_build'])
+#subprocess.call(['python', '-msphinx', '-M', 'html', '.', '_build', '-Q'])
+
+# we do not currrently use pydeps, commented out https://gitlab.aicrowd.com/flatland/flatland/issues/149
+# subprocess.call(['python', '-mpydeps', '../flatland', '-o', '_build/html/flatland.svg', '--no-config', '--noshow'])
 
 browser('_build/html/index.html')
diff --git a/requirements_continuous_integration.txt b/requirements_continuous_integration.txt
index 9a523cc136f3857fd6f8359ea6f278f581c3dacb..0054fec1724765b8ffa8be620c5d4c1ac4cfd6b3 100644
--- a/requirements_continuous_integration.txt
+++ b/requirements_continuous_integration.txt
@@ -4,9 +4,10 @@ wheel>=0.32.1
 watchdog>=0.9.0
 benchmarker>=4.0.1
 coverage>=4.5.1
-Sphinx>=1.8.1
+# pin sphinx to <2.0 because of https://github.com/readthedocs/sphinx_rtd_theme/issues/746
+Sphinx>=1.8.1,<2.0
 sphinx-rtd-theme>=0.4.3
-numpydoc
+numpydoc>=0.9.1
 docutils>=0.15.2
 flake8>=3.7.7
 flake8-eradicate>=0.2.0
diff --git a/tox.ini b/tox.ini
index 0b445e902454376b22ef95cd31d11800f659f3a8..282d83888de34042ebad21278867b040b3663c79 100644
--- a/tox.ini
+++ b/tox.ini
@@ -68,7 +68,7 @@ deps =
     -r{toxinidir}/requirements_continuous_integration.txt
 changedir = {toxinidir}
 commands =
-    make coverage
+    python make_coverage.py
 
 [testenv:benchmarks]
 ; use python3.6 because of incompatibility under Windows of the pycairo installed through conda for py37