-It is the year 3000 and the museum is in big trouble! The priceless artifacts are lost and scattered across timelines. Your team’s mission is to travel through time and bring them back into the museum.
+[Code for Life](https://www.codeforlife.education/) has been developed by Ocado Technology as a **free, open-source** project to inspire the next generation of computer scientists and to help teachers deliver the computing curriculum.
+
+**Kurono** is a [Code for Life](https://www.codeforlife.education/) project, aimed at teaching students and keen adults programming with Python. The game is designed to be played in a class or a group setting, as it simulates a multiplayer online game.
+
+We are open to contributors from anywhere around the world. Please read ahead if you'd like to get involved.
-## Quick Start
-1. **Fork** the repo.
-2. Take a look at our [usage guidelines](docs/usage.md) to see how to get started.
+## To get started
-## Documentation
-Take a look at our [documentation table of contents](docs/README.md).
+- [Developer Guide](https://docs.codeforlife.education/developer-guide)
-## How to contribute!
-__Want to help?__ You can read the [contributing guidelines][contrib-guidelines]. You can also contact us directly using this [contact form][c4l-contact-form] and we'll get in touch as soon as possible! Thanks a lot.
+- [Good First Issues](https://github.com/ocadotechnology/aimmo/contribute)
-[c4l-contact-form]: https://www.codeforlife.education/help/#contact
-[contrib-guidelines]: https://github.com/ocadotechnology/aimmo/blob/master/CONTRIBUTING.md
+- Setting up your work environment: [common setup](https://docs.codeforlife.education/git/common-setup) and [aimmo specific setup](https://docs.codeforlife.education/git/aimmo-setup)
+
+- [Testing](https://docs.codeforlife.education/git/testing)
+
+
diff --git a/docs/FAQ.md b/docs/FAQ.md
deleted file mode 100644
index 433876c49..000000000
--- a/docs/FAQ.md
+++ /dev/null
@@ -1,34 +0,0 @@
-[Documentation Table Of Contents](README.md)
-# Frequently Asked Questions
-- [What is Code For Life?](#what-is-code-for-life)
-- [I have an issue with the project, who do I contact, what do I do?](#i-have-an-issue-with-the-project-who-do-i-contact-what-do-i-do)
-- [I want to contribute... How?](#i-want-to-contribute-how)
-
----
-
-## What is Code For Life?
-- Ocado Technology's FREE Code for Life initiative has been developed to inspire the next generation of computer scientists and to help teachers deliver the computing curriculum.
-This repository hosts the source code of the [**Kurono game**](https://www.codeforlife.education/play/kurono/). Kurono is a follow-on from Rapid Router to teach computing to secondary-school age children.
-
-- It's ***FREE*** forever!
-
-- The other repos for Code For Life:
- - the main portal (as well as registration, dashboards, materials...), [Code For Life Portal](https://github.com/ocadotechnology/codeforlife-portal)
- - the first coding game of Code for Life for primary schools, [Rapid Router](https://github.com/ocadotechnology/rapid-router)
- - the [deployment code for Google App Engine](https://github.com/ocadotechnology/codeforlife-deploy-appengine)
-
-## I have an issue with the project, who do I contact, what do I do?
-The first step is to [**check the common/known issues**](common-issues.md) page to see if your issue is a common one and we know about
-the solution.
-
-Next step is to make sure you have set up the project correctly as per our instructions.
-
-Finally, you can contact the contributors and receive help by opening an issue in the project and tagging it
-appropriately (perhaps `bug` or `help-wanted`).
-
-## I want to contribute... How?
-
-First read our [contributing guidelines](https://github.com/ocadotechnology/codeforlife-portal/blob/master/CONTRIBUTING.md), thanks!
-
-Look for issues tagged with `help-wanted` to find some good starter issues you could start working on. If you need
-to contact us, look at the contact details. Thank you!
diff --git a/docs/README.md b/docs/README.md
deleted file mode 100644
index b62a35d91..000000000
--- a/docs/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Table Of Contents
-
----
-
-## Getting started
-The first required steps to get familiar with the project and run it locally.
-- [FAQ](FAQ.md) - Frequently asked questions with answers.
-- [Usage](usage.md) - How to get the project up and running.
-- [Common Issues](common-issues.md) - Common issues and their solutions.
-
-## Architecture
-
-Architecture of the project. How things are structured, what components exist, etc.
-
-- [Architecture](architecture/README.md)
- - [Game Creator](architecture/game-creator/README.md)
- - [Games](architecture/games/README.md)
- - [Workers](architecture/workers/README.md)
- - [UI](architecture/ui/README.md)
-
-### Babylon
-
-Babylon side of the project. Game engine and structure.
-- [Babylon](babylon/README.md)
-
-
-### Infrastucture
-
-We describe the technologies that are underlying to the project and support it
-- [Infrastructure](infrastructure/README.md)
-
-### Testing
-
-Levels of testing within Kurono.
-
-- [Testing](testing/README.md)
- - [Manual Test Plan](testing/test-plan.md)
- - [Automatic Test Plan](testing/automatic-testing.md)
-
-### Deployment
-
-The process of continuous integration and deployment of our project onto our cloud.
-
-- [Deployment](deployment/README.md)
- - [Sequence of Deployment Events](deployment/deployment-events.md)
- - [Admin NGINX & SSL setup on GCP](deployment/nginx-setup.md)
diff --git a/docs/analytics/google.md b/docs/analytics/google.md
deleted file mode 100644
index 9c0daf3c3..000000000
--- a/docs/analytics/google.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Analytics 2: Eletric Googaloo
-
-This document will show you how to create new google analytics events for Kurono.
-
-Google analytics events in React+Redux are done through the use of Epics. Epics are functions which take a stream of actions and return another stream of actions.
-
-This means that if you're looking to add new analytics event you will need to find what action relates to what you are measuring. Below is an example used to measure how often the "Run code" button is pressed in the code editor.
-
-```Javascript
-const postCodeAnalyticsEpic = action$ =>
- action$.pipe(
- ofType(types.POST_CODE_REQUEST),
- mapTo(analyticActions.sendAnalyticsEvent('Kurono', 'Click', 'Run Code'))
- )
-```
-
-Here, we can see that the function `postCodeAnalyticsEpic` takes in an action, checks that the action is the one we want, and if it is, maps the action to our analytics event action. Note, we must include `ofType(types.POST_CODE_REQUEST)` as in Redux actions are passed through to all of the epics, so we need to make sure we're only dealing with the ones we're interested in.
-
-Finally, there are a number of arguments passed into the `sendAnalyticsEvent()` action. These correspond to what the action will appear as on the Google analytics dashboard, so discussing with whoever relies on this the most (Most likely the PO [Product Owner]) to agree on how to catagorise the event would be advisable.
diff --git a/docs/architecture/README.md b/docs/architecture/README.md
deleted file mode 100644
index 1446cd2df..000000000
--- a/docs/architecture/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Architecture
-
-This section describes the whole game architecture and how things are structured. Kurono consists of five main components, split into their own directories.
-
-## Overview
-
-
-
-## Components
-
-[The Django API (`aimmo` directory)](ui/README.md)
-
-A Django app used to provide an api for game and code management.
-
-[Game Frontend (`game_frontend` directory)](../../game_frontend/README.md)
-
-A React app using [Babylon](https://www.babylonjs.com/) and [Pyodide](https://github.com/iodide-project/pyodide) to present the game state to the player, run their code and allow them to edit it.
-
-[Games (`aimmo-game` directory)](games/README.md)
-
-Holds and updates the game state (one per game).
-
-[Game Creator (`aimmo-game-creator` directory)](game-creator/README.md)
-
-Responsible for creating games (one globally).
-
-[Workers (`aimmo-game-worker` directory)](workers/README.md)
-
-Contains the avatar worker api used by the AvatarWorker in the frontend.
-
-## Terminology
-
-**Avatar:** a player's in-game representation. A player can have up to one per game.
-
-**Player:** an individual with an account.
diff --git a/docs/architecture/game-creator/README.md b/docs/architecture/game-creator/README.md
deleted file mode 100644
index 01d3db130..000000000
--- a/docs/architecture/game-creator/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Game Creator (`aimmo-game-creator` directory)
-
----
-
-The game creator consists only of a few classes. The service runs a worker manager daemon which periodically updates the games. The list of the games is exposed through the game API.
-
-The data is managed by a thread-safe class called WorkerManagerData. The synchronization is done using a lock over the set of the games. The set of games will change during each periodic update. The games that are no more present in the set of games exposed by the API are getting removed. The updates are made in parallel by multiple threads, thus the need for synchronization.
diff --git a/docs/architecture/games/README.md b/docs/architecture/games/README.md
deleted file mode 100644
index accd8d006..000000000
--- a/docs/architecture/games/README.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# Games (`aimmo-game` directory)
-
-## Game Components
-
-- [Game Runner](game-runner.md)
-- [Simulation Runner](simulation-runner.md)
-- [Map Generator](generators.md)
-- [World Map](world-map.md)
-- [Avatar](avatar.md)
-- [Actions](actions.md)
-- [Pickups](pickups.md)
-- [Interactables](interactable.md)
-
-## In Short
-
-- Maintains game state
-- Simulates environment events
-- Collects and runs player actions
-
-## General Overview
-
-The game (aimmo-game) is responsible for maintaining the game state,
-the worker avatars for the game, fetching the actions from
-each worker, and applying those actions, as well as fetching
-game metadata from the Django API.
-
-The game interacts with the rest of the components as follows:
-
-- It is created by the game creator.
-- Collects actions (see [turn_collector](../../../aimmo-game/turn_collector.py)) computed by the player's client (see [workers](../workers/README.md))
-- Send game states once per turn to the clients
-
-Once per turn it will:
-
-- Inform all workers of the current game state and gets their
- actions.
-- Perform conflict resolution on these actions and then apply
- them.
-- Update the world with any other changes to produce the next game state.
-
-Files for the game are stored in `aimmo-game`.
-
-[game-api]: https://github.com/ocadotechnology/aimmo/blob/master/aimmo-game/service.py
diff --git a/docs/architecture/games/actions.md b/docs/architecture/games/actions.md
deleted file mode 100644
index b97e2573e..000000000
--- a/docs/architecture/games/actions.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Actions
-
----
-
-An action is a pair (avatar, location). The action is registered onto the WorldMap by being appended to a cell.
-
-The action is processed by calling the apply function only if:
-- the action is legal (see below)
-- it's not rejected
-
-The exposed interface is:
-
-- **`apply`**
- - has to return true if event application succeeded
- - attaches an event to the avatar
-- **`is_legal`**
- - returns if an action is legal from the point of view of the map
- - the action gets applied or rejected accordingly
-- **`reject`**
- - attaches a (failed) event to the avatar
-
-Each of the 3 elements of the interface are implemented differently by different types of actions.
-
-The current types of actions as:
-- **`WaitAction`**
- - wait is always legal
- - no actions get attached to the avatar
-- **`MoveAction`**
- - *`is_legal`*
- - the responsibility is passed to world_map
- - *`apply`*
- - adds a move event to the avatar
- - change the avatar's world view
- - updates the map accordingly
- - *`reject`*
- - the failed event is added to the avatar
- - *overrides the processing of the action*
- - the action is chained in the action list of a cell
- - see World Map and Turn Manager for details
-- **`AttackAction`**
- - *`is_legal`*
- * attacking is legal is the avatar is attackable
- * *`attack`*
- * attaches the event to the attacker avatar
- * attaches the event to the attacked avatar
- * if the attacked avatar dies it is respawned
-
-
-
-### Legality of an Action
-A `WaitAction` is always legal. A `MoveAction` is legal if and only if:
- - The square the avatar attempts to move to is on the map
- - The square the avatar attempts to move to is not occupied (by e.g. another avatar or a wall)
- - Another avatar is not attempting to move to the same square.
-
- This means that, for example, given the following situation:
-
> _ <
- Where two avatars are trying to move horrizantally into the following square, we will get the following result:
-
x _ x
gi
- Where neither of the avatars have moved.
-
- This detection of collisions is done by registering actions with the cells where the avatars attempt to move and the `detect_cycles` method in the `MoveAction` class.
-
\ No newline at end of file
diff --git a/docs/architecture/games/avatar.md b/docs/architecture/games/avatar.md
deleted file mode 100644
index 6f8137fd6..000000000
--- a/docs/architecture/games/avatar.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Avatar
-
----
-
-This represents an avatar as part of the simulation.
-
-The avatar functionality is separated in several classes:
-
-- `AvatarWrapper` - the central avatar functionality, including the simulation properties such as health, score and so on
-- `AvatarView` - a personalized view of the worlds for each avatar
-- `AvatarAppearance` - a data class for customising the avatar's appearance
-- `AvatarManager` - a structure that maintains a mapping from player_id to `AvatarWrapper`s
-
-### `AvatarWrapper`
-The avatar wrapper represents the application's view of a character.
-The main functionality is:
-
-- decide action - given a serialised representation of an action, return a Python action object.
-- clear action
-- update effects - apply effects that come from getting a pickup
-- add event - attaches an event to the event setting -- not yet used
-
-*This functionality may not be fully implemented:*
-
-- die - dies and re-spawns at new location
-- damage - take damage
-
-
-### `AvatarManager`
-This is responsible for adding and removing avatars and managing the list of avatars that the main game simulation has a access to. It is kept in sync with the `Worker`s in [`WorkerManager`](worker-manager.md) by [`GameRunner`](game-runner.md).
diff --git a/docs/architecture/games/conditions.md b/docs/architecture/games/conditions.md
deleted file mode 100644
index 39a6993ef..000000000
--- a/docs/architecture/games/conditions.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Conditions
-
-Conditions are a component of an `Interactable`.
-
-A condition can be thought of as an function, any and all conditions must be something that can evaluate to either `True` or `False`. Each turn all of an Interactable's conditions are evaluated to see if its effects should trigger.
-
-Conditions will typically need some kind of data to check, conditions currently can only use information from the `WorldMap` for their checks.
diff --git a/docs/architecture/games/effects.md b/docs/architecture/games/effects.md
deleted file mode 100644
index 346dacd38..000000000
--- a/docs/architecture/games/effects.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Effects
-
-Effects are a component of an `Interactable`.
-
-An effect should have at least one target.
-
-When an Interactable's conditions are met, the targets are gathered, and the effects are then given to them. Targets for an effect must have a `effect` attribute with which to store its active effects.
-
-An effect can last 1 or many turns, and can impart a temporary or permanent change to its target, for example: restoring some of an Avatar's health, or giving an avatar a temporary damage boost.
diff --git a/docs/architecture/games/game-runner.md b/docs/architecture/games/game-runner.md
deleted file mode 100644
index 441e4d771..000000000
--- a/docs/architecture/games/game-runner.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Game Runner
-
----
-The code can be found [here](game runner update).
-
-The `GameRunner` class is responsible for initialising the
-games' components in order to spawn a new game. It holds a
-reference to these objects and has some getter functions
-defined in order to spawn or delete new users.
-
-More importantly, it contains the `update()` function which
-runs in a loop at `WORKER_UPDATE_SLEEP_TIME` intervals. This
-constantly uses the embedded communicator object to get
-the game metadata from our django API url.
-
-Once this information comes in it manages the changes in
-users that needs to happen (ie. finds users that need to
-be added or deleted). It then delegates the responsibility
-to the worker manager which handles the worker pods & their
-code. Finally the game state holds all new avatars for these
-users.
-
-The `GameRunner` should be the **only** class which has
-interactions with both *simulation logic* (avatar wrappers,
-game map etc) and *worker logic* (`WorkerManager`). This is
-an important decoupling.
-
-[game runner update]: https://github.com/ocadotechnology/aimmo/blob/d61c3f575f012fc6f99da9a99a4e5b3ac461d65c/aimmo-game/simulation/game_runner.py#L30
-
diff --git a/docs/architecture/games/generators.md b/docs/architecture/games/generators.md
deleted file mode 100644
index 2ebd89772..000000000
--- a/docs/architecture/games/generators.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Map Generators
-
----
-
-The generators are map creation services. The Django application is exposed
-to different map creation service classes. There is a map generation service
-as part of the Django application which uses the default map generator: the
-class Main in the map_generator file.
-
-A map generator is a class that inherits from BaseGenerator and has to
-implement the `get_map` method.
-
-#### The Main Map Generator
-
-The main map is supposed to be used for the generation of big worlds. This
-should be the only generator used at this time. The `Level1` generator and
-`BaseLevelGenerator` are legacy classes which eventually will be removed.
-The whole map is randomly generated, but the generation is regulated by the
-[World Map](world-map.md) settings.
-
-Obstacles are filled according to the obstacle ratio. Once an obstacle is
-added we ensure that each habitable cell can reach each other, thus the
-map will be connected and each generated avatar can reach others.
-
-#### Implementation details
-
-The `get_map` method builds the map gradually adding random obstacles
-until the obstacle ratio is reached.(see [World Map](world-map.md) settings)
-
-To ensure that the map is connected, we check that all the adjacent
-habitable cells can reach all the other cells. To check that neighbours
-reach each other efficiently we use A* for path
-finding.
-
-#### Serialisation to JSON
-We store our game information in `JSON` for the backend to be able to
-deserialize it. The below is a _**proposed**_ format which we are working
-towards.
-
-```Javascript
-{
- "id": 1,
- // each level is set in one era only
- "era": "future"
- "terrain": {
- "width": 10,
- "height": 10,
- }
- // we can figure out minX, minY, maxX, maxY and origin from these two corners.
- "south_west_corner": {
- "x": -2,
- "y": -2,
- },
- "north_east_corner": {
- "x": 2,
- "y": 2,
- },
- // the spawn location of the player
- "spawn_location": {
- "x": 0,
- "y": 1,
- },
- "obstacles": [
- {
- // the location here is the bottom left cell of the obstacle
- "location": {
- "x": 0,
- "y": 1,
- },
- "width": 2,
- "height": 1,
- "type": "van",
- "orientation": "east",
- }
- ],
- "pickups": [
- {
- "type": "damage",
- "value": 5,
- "location": {
- "x": 0,
- "y": 1,
- }
- }
- ]
-}
-```
-
diff --git a/docs/architecture/games/interactable.md b/docs/architecture/games/interactable.md
deleted file mode 100644
index 8f2c2ebe2..000000000
--- a/docs/architecture/games/interactable.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Interactable
-
-An `Interactable` is a dynamic object that exists in the `WorldMap`.
-
-All Interactables follow the same basic logic:
-CONDITIONS → EFFECTS → TARGETS
-
-This is to say that an `Interactable` has 1 or more [conditions](conditions.md) it's checking for. Once the conditions are met, it will apply any [effects](effects.md) it has to 1 or more specified targets. Currently the only compatible target is an avatar.
-
-## Implementation
-
-When implementing a new `Interactable` there is a number of criteria that need to be met:
-
-1. Any and all conditions should be specified in the `__init__()` method.
-
-2. Any and all effects should be specified in the `__init__()` method.
-
-3. The `get_targets()` method should be implemented to return a list of targets. Each effect will happen to **EVERY** target in the list.
-
-4. It should implement a `__repr__()` and `serialize()` method for informative purposes.
diff --git a/docs/architecture/games/pickups.md b/docs/architecture/games/pickups.md
deleted file mode 100644
index 0c17ff4da..000000000
--- a/docs/architecture/games/pickups.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Pickups
-
----
-
-A pickup is an object that is automatically grabbed by avatars in the same cell as the pickup. The pickup gets destroyed and generates an effect it is grabbed. An effect is an object that encapsulates a function that gets applied to an avatar on each turn. (see [Simulation Runner](simulation-runner.md))
-
-### Pickups
-
-A Pickup is attached to a cell. Getting a pickup should attach an effect to an avatar. Once the pickup is attached to the avatar, it gets deleted.
-
-The pickup references the cell and the cell references the pickup. The delete function is called once the pickup gets applied, removing both references. The Pickup class is an abstract one, each Pickup concrete class having to implement an `_apply` function.
-
-The different types of pickup supported are:
-* Health Pickup
- * restores health immediately, no **Effect** is used
-* Invulnerability Pickup
- * an **effect-based pickup**
- * applies an InvulnerabilityPickupEffect
-* Damage Pickup
- * an **effect-based pickup**
- * applies a DamagePickupEffect
-
-### Effects
-
-An Effect is a class that gets applied once per turn. The effect interface consists of the function `on_turn` which gets applied each turn.
-
-A Timed Effect is an Effect that gets removed after a number of turns. The Effect interface is extended with the `remove` function, that only removes the effect by default - this is overrided by different effects.
-
-There are 2 concrete effects implemented at the moment:
-* InvulnerabilityPickupEffect - increases the resistance of the avatar by a big offset
-* DamagePickupEffect - adds a damage boosts when initialized, removes the damage boost at effect removal
diff --git a/docs/architecture/games/simulation-runner.md b/docs/architecture/games/simulation-runner.md
deleted file mode 100644
index a11bbbc8a..000000000
--- a/docs/architecture/games/simulation-runner.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Simulation Runner
-
-The [`SimulationRunner`](simulation-runner-file) is responsible
-for running a turn in the simulation.
-
-The `run_turn` method is called from `GameRunner`, and it
-runs as follows:
-
-- Get the [`AvatarWrapper`'s](avatar-wrapper-file) to
- deserialize and register their actions.
-- Update the environment using the [World Map](world-map-doc)
-- Check if the level is complete (this is a somewhat deprecated feature)
-
-The alternatives for pooling each avatar for its decisions are:
-
-- SequentialTurnManager (used locally for testing) - get and
- apply each avatar's action in turn
-- ConcurrentTurnManager - concurrently get the intended
- actions from all avatars and register them on the world map;
- then apply actions in order of priority
-
-[simulation-runner-file]: /aimmo-game/simulation/simulation_runner.py
-[avatar-wrapper-file]: /aimmo-game/simulation/avatar/avatar_wrapper.py
-[world-map-doc]: world-map.md
diff --git a/docs/architecture/games/worker.md b/docs/architecture/games/worker.md
deleted file mode 100644
index 508472372..000000000
--- a/docs/architecture/games/worker.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Worker
-
-A worker is the part of the game client frontend that computes the user's `next_turn` for that turn. We use [pyodide](https://github.com/iodide-project/pyodide), a library that allows us to run Python in the browser, to do this.
diff --git a/docs/architecture/games/world-map.md b/docs/architecture/games/world-map.md
deleted file mode 100644
index a1085165f..000000000
--- a/docs/architecture/games/world-map.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# World Map
-
-The World Map is the central component of the simulation. The class itself consists of a grid and a set of JSON settings. The grid consists of a dictionary of type .
-
-### Cells
-
-A cell has the following components:
-
-- location - (x, y) pairs that can be added together, serialized, compared, etc.
-- avatars - see [Game Objects](game-objects) for more details
-- pickup - see [Game Objects](game-objects) for more details
-- cell content - the cell content can either be a score cell, an obstacle or a plain floor cell
-- actions - an array where the intended actions of different avatars are registered and, afterwards, applied
-
-### World Map basic functionality
-
-World Map has a lot of misc functionality, as multiple other objects communicate with it and need a simple API.
-
-Cell specific functionality:
-
-- get_cell
-- all_cells
-- score_cells
-- pickup_cells
-
-Map dimension functionality:
-
-- is_on_map
-- max_x
-- max_y
-- min_x
-- min_y
-- num_cols
-- num_rows
-- num_cells
-
-### The Update Cycle
-
-The most important responsibility of the world map class is the `self.update` after the intended character moves have been recorded by the Simulation Runner. The function `update` is called by the [Simulation Runner](simulation-runner).
-
-The update cycle is as follows:
-
-- update avatars
- - apply score: each avatar received a score
- - apply pickups: each avatar grabs a pickup if present
-- update map:
- - expand the map so that it fits the size of the avatars if more avatars arrive
- - reset score locations: new score locations are generated
- - add pickups: new pickups are generated
-
-All the map updates are regulated using the settings of a map. Some useful settings fields are:
-
-- TARGET_NUM_CELLS_PER_AVATAR - regulates the size of the map by number of avatars
-- TARGET_NUM_SCORE_LOCATIONS_PER_AVATAR - used to regulate the number of score locations; the new score locations are generated randomly and added to the map
-- SCORE_DESPAWN_CHANCE - another parameter to regulate the score cells generation; the game is more dynamic as some score cells are getting removed each turn and new ones are generated, giving the player the impressing of score cells moving around
-- TARGET_NUM_PICKUPS_PER_AVATAR - regulate the number of pickups similarly to how the number of score locations are regulated
-- PICKUP_SPAWN_CHANCE - a regulation parameter similar to SCORE_DESPAWN_CHANCE
-
-[simulation-runner]: simulation-runner.md
diff --git a/docs/architecture/overview.png b/docs/architecture/overview.png
deleted file mode 100644
index a378db442..000000000
Binary files a/docs/architecture/overview.png and /dev/null differ
diff --git a/docs/architecture/workers/README.md b/docs/architecture/workers/README.md
deleted file mode 100644
index f4e5da84c..000000000
--- a/docs/architecture/workers/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Workers
-
-The game worker is part of the [game_frontend](../../../game_frontend/README.md). Its responsibility is to run the player's code to get an action with any logs for a particular turn in the game.
-
-The code for the worker is split up in two places:
-
-- The [aimmo-game-worker](../../../aimmo-game-worker/) directory which holds the worker api source code for the player.
-- The corresponding [Pyodide runner](../../../game_frontend/src/pyodide) which uses the worker api to run the player's code.
-
-## How the Avatar Worker works
-
-
-
-The worker receives a game state of the current turn. It converts this into a representation of the world map and the avatar state (the classes for these can be found in the worker api package). These are then passed to the player's `next_turn` function. We collect the action returned from that function call along with any logs produced (via print statements or errors for example) to produce a `ComputedTurnResult` for the next turn.
-
-### Responding to player's code changes
-
-When the player changes the code for their avatar, we redefine the `next_turn` function in pyodide and then recompute their `next_turn` action with the new code. In the case of syntax errors with their code, we don't compute their `next_turn` and return a `WaitAction` with the errors they had in the logs.
diff --git a/docs/architecture/workers/avatar_worker_diagram.svg b/docs/architecture/workers/avatar_worker_diagram.svg
deleted file mode 100644
index a48bd2dc1..000000000
--- a/docs/architecture/workers/avatar_worker_diagram.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/babylon/README.md b/docs/babylon/README.md
deleted file mode 100644
index 8bba1c54f..000000000
--- a/docs/babylon/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Babylon
-
-This section describes the way Babylon is used as the game engine for Kurono.
-
----
-
-## Structure
-
-Here we will go into some detail on how Babylon is structured within our project, and how we've chosen to organise the files.
-
-First, we will look at the file structure for the babylon part of the game page:
-```
-babylon
-│
-├── assetPacks
-│ ├── assetPack.ts
-│ ├── future.ts
-│ ├── ...
-│ └── getAssetPackForEra.ts
-|
-├── entities
-│ ├── avatarManager.test.ts
-│ ├── avatarManager.ts
-│ ├── ...
-│ └── index.ts
-│
-├── environment
-│ ├── index.ts
-│ ├── light.test.ts
-│ ├── light.ts
-│ ├── ...
-│ ├── environment.ts
-│ └── environmentManager.ts
-│
-├── animation.ts
-├── diff.ts
-├── gameEngine.ts
-├── ...
-├── interfaces.ts
-└── orientation.ts
-```
-`interfaces.ts` contains the typing (interfaces) for objects specific to our project, such as `GameNode`.
-
-We split the remaining elements of the game into two folders:
-* **entities**: These populate the game world, and cover elements such as obstacles, avatars, and interactables.
-* **environment**: The elements of the game that make up the world, such as camera, light and terrain, as well as the renderer.
-
-The files inside **assetPacks** handle the loading and processing different 2D and 3D assets required for each different level, or *era*, of the game. *NOTE: the way this is currently written, each era has one only type of obstacle. However, as pointed out in the corresponding files, there are different textures and models ready to be loaded when the randomising functionality is implemented.*
-
-All classes in these folders implement the `GameNode` interface. Entities also implement the `DiffHandling` interface.
diff --git a/docs/common-issues.md b/docs/common-issues.md
deleted file mode 100644
index 3276039cd..000000000
--- a/docs/common-issues.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Common / Known Issues
-- [When running the game I get `no module named google.auth`](#when-running-the-game-i-get-`no-module-named-google.auth`)
-- [When deploying I get `error: Error -5 while decompressing data (...)`](#when-deploying-i-get-error-error--5-while-decompressing-data-)
-- [When running the game I get `ImportError: No module named django.conf`](#when-running-the-game-i-get-importerror-no-module-named-djangoconf)
-- [On Mac, when running the server with a fresh database, I get `django.db.utils.IntegrityError: The row in table ... with primary key '1' has an invalid foreign key: ... contains a value '1' that does not have a corresponding value in ...`](#on-mac-when-running-the-server-with-a-fresh-database-i-get-djangodbutilsintegrityerror-the-row-in-table--with-primary-key-1-has-an-invalid-foreign-key--contains-a-value-1-that-does-not-have-a-corresponding-value-in-)
----
-
-## When running the game I get `no module named google.auth`
-
-If you get an error when running the command `./run.py` or `./run.py -k` locally that states, somewhere in the
-traceback, `no module named google.auth`; then rerun the command again and the dependency should be
-detected. This is a [logged issue](https://github.com/ocadotechnology/aimmo/issues/449).
-
-## When deploying I get `error: Error -5 while decompressing data (...)`
-
-**This issue can only be solved by a repository admin.**
-
-When deploying with semaphoreCI, the cache may be old and corrupt one of the packages being installed by `pip`.
-
-The error you may get may look like this `error: Error -5 while decompressing data: incomplete or truncated stream`.
-
-You need to `ssh` into the appropriate server and delete the cache directory. Another solution is to `pip install` with the `--no-cache-dir` flag but we do not recommend this.
-
-## When running the game I get `ImportError: No module named django.conf`
-
-Run a pip install command to install django before running the project. Django should then resolve all the other dependencies specified in the setup file. To do this run: `pip install django=={version}`. You can find `version` from the `setup.py` file at the time.
-
-
-## On Mac, when running the server with a fresh database, I get `django.db.utils.IntegrityError: The row in table '...' with primary key '1' has an invalid foreign key: ... contains a value '1' that does not have a corresponding value in ...`
-
-This error is potentially caused by a wrong or incompatible sqlite3 version. You can check the sqlite3 version from a python shell with:
-
-```
-import sqlite3
-sqlite3.sqlite_version.
-```
-
-You need to install/update sqlite3 with brew: `brew install sqlite3`. Then follow the instructions in `brew info sqlite3` before installing a python version with `pyenv`.
-
-```
-If you need to have sqlite first in your PATH, run:
- echo 'export PATH="/usr/local/opt/sqlite/bin:$PATH"' >> ~/.zshrc
-
-For compilers to find sqlite you may need to set:
- export LDFLAGS="-L/usr/local/opt/sqlite/lib"
- export CPPFLAGS="-I/usr/local/opt/sqlite/include"
-```
-
-If you already installed a python version and a virtual environment, you need to clear them up:
-```
-pyenv versions
-pyenv uninstall
-pipenv --rm
-```
-
-Then reinstall pyenv with the right sqlite3 version (make sure `LDFLAGS` and `CPPFLAGS` are set as above):
-```
-pyenv install
-pipenv install --dev
-```
diff --git a/docs/deployment/README.md b/docs/deployment/README.md
deleted file mode 100644
index 489759627..000000000
--- a/docs/deployment/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Deployment
-
----
-- [Sequence of deployment events](deployment-events.md)
-- [One time **admin** nginx & SSL setup](nginx-setup.md)
-- [Monitoring the project](monitoring.md)
diff --git a/docs/deployment/cusotm-metrics.md b/docs/deployment/cusotm-metrics.md
deleted file mode 100644
index 618622121..000000000
--- a/docs/deployment/cusotm-metrics.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Custom Metrics
-
-This document outlines how to create custom metrics on our k8s clusters.
-
----
-
-There are a few things to be aware of before creating a custom metric:
-
-* For any metric you create, you must have a service that can expose the metric.
-* For any services exposing metrics, there must be a `ServiceMonitor` that targets this service.
-* Metrics must be unique (I know this seems obvious but it can be a source of some ambiguous errors).
-
-Okay, now we can look at creating our metric.
-
----
-
-1. Think carefully about what it is you want to measure, and what the most appropriate way to measure it would be. Metrics can be one of the 4 types outlined on the prometheus website [here](https://prometheus.io/docs/concepts/metric_types/).
-
-2. Give your metric a suitable name. Naming conventions for metrics can be found [here](https://prometheus.io/docs/practices/naming/). Don't worry too much about it sticking strictly to the convention, just as long as it's clear what you're measuring that is usually enough.
-
-3. Now it's time to create your metric. When implementing things we want to keep the metrics as unintrusive as possible from existing code, so when possible you should follow the example in `aimmo-game`.
-
- * Below is an example of a custom metric from the `metrics.py` file. The first snippet contains the metric itself, while the second snippet contains the function with how we want to use that metric.
- * This approach allows us to keep all our metrics in a single place so they're easy to find. Then you can simply import your metric where needed for use.
-
- ```python
- CUSTOM_BUCKET = [x/10 for x in range(10, 61)]
- GAME_TURN = Histogram('game_turn_time', 'Measures the time taken for the game to complete a single turn in seconds',
- buckets=CUSTOM_BUCKET)
- ```
-
- ```python
- def GAME_TURN_TIME():
- """ Used for measuring the time it games for the game to complete a turn.
- This is measured using the Histogram datatype. """
- return GAME_TURN.time()
- ```
-
- * If you're creating a metric not in aimmo game or game creator, you will need to create a service for the pod you're working with. Then add the exporter so a service monitor can find them. Follow the [Prometheus client](https://github.com/prometheus/client_python#exporting) section for exporting if this is needed (aimmo-game should already have this present).
-
-4. Now you should have a metric of your own, being exported to `/metrics` by default. You can check this by running the project locally in docker mode and going to that endpoint for the pod(s) you're interested in, if all is well you'll be greeted by a wall of text and numbers (this is normal).
-
-5. Last step is the `ServiceMonitor`. Below is the config for the service monitor we use for the games.
-
- ```yaml
- apiVersion: monitoring.coreos.com/v1
- kind: ServiceMonitor
- metadata:
- name: aimmo-game
- namespace: default
- spec:
- endpoints:
- - targetPort: 5000
- interval: 15s
- selector:
- matchLabels:
- app: aimmo-game
- ```
- * Service monitors only have two required fields in their spec: `endpoints` & `selector`. These fields specify how to find your service(s), and what to look for once they've found them. So in this example above we can see in the `endpoints` section we're looking for all services with a target port of 5000, which all of our games have. Then, just to make sure we are definitely getting the games, we specify that we are looking for services with a label `app`, that has the value `aimmo-game`. There are many other options and ways to configure your service monitor but the above example is sufficient for most basic use cases.
- * Give your service monitor a suitable name so it is easy to find if you need to create a new one (games already have a service monitor).
-
-6. You should now be able to see your custom metric in the Prometheus web UI. If not make sure your service monitor is configured correctly on the cluster and that you're custom metric is functioning properly.
diff --git a/docs/deployment/deployment-events.md b/docs/deployment/deployment-events.md
deleted file mode 100644
index 05b69e4de..000000000
--- a/docs/deployment/deployment-events.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Deployment Events
-
-**_We have moved to using Github actions for our CI. This sections needs updating._**
-
----
-
-We use Travis for contiguous integration. Travis CI is the first step in our integration pipeline. Each time a push is made Travis runs all our tests. We are currently in the process of migrating our coverage reports from [coveralls.io](https://coveralls.io/) to [codecov.io](https://codecov.io/).
-
-Our package Django app `aimmo` is deployed to [Pypi](https://pypi.python.org/pypi/aimmo) and we use [Versioneer](https://github.com/warner/python-versioneer) for package versioning.
-
-The rest of the components are Dockerised. Travis CI automatically recognises the **Dockerfiles** inside of each of the modules and pushes the newly created images to the **Docker Hub Registry**. Each of the components are then pulled automatically by the Google Cloud Container Engine.
-
-After all the Travis processes are finished, a curl request is made to SemaphoreCI. SemaphoreCI is responsible for orchestrating the deployment processes for all the Code For Life repositories. The Django application `aimmo` is installed directly from Pypi together with all the other modules. Due to the modularity of Django, the aimmo app can be just plugged inside the bigger Django project. _Currently, the pulled version in production will be the latest stable release._
-
-The application is then deployed to the Google Cloud. This finishes our build.
-
-Once the application is deployed to the Google Cloud, it needs to find the other services. The discovery of the game services provided is done using a hook that can be found in [this repository](https://github.com/ocadotechnology/codeforlife-deploy-appengine).
-
-```python
-AIMMO_GAME_SERVER_LOCATION_FUNCTION = lambda game: ('http://staging.aimmo.codeforlife.education', "/game/%s/socket.io" % game)
-```
-
-# Deploying to production
-
-Every time a new push is made to the development branch, the deployment process detailed above runs. This updates the `aimmo` project in our staging environment.
-
-To deploy to production, a pull request needs to be made from development into master. After the pull request is successfully reviewed and merged, the deployment process will run once more, with the small difference that the build tag will indicate that it is now a stable release, instead of a beta build.
-
-Monitoring the deployment process at this point is as important as always, if not more. Once the tests on Travis have passed, the Pypi package has been deployed and the Docker images have been built, the new version can then be deployed onto production from Semaphore CI. It is important to remember that this will also deploy the latest changes from Rapid Router and the Portal onto production.
diff --git a/docs/deployment/grafana-persistence.md b/docs/deployment/grafana-persistence.md
deleted file mode 100644
index e2fc267de..000000000
--- a/docs/deployment/grafana-persistence.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Grafana Persistence
-
-Here we will talk about how to connect our instances of Grafana to a database on Gcloud to ensure that data such as logins, permissions, and dashboards persist if the pod stops or is restarted for whatever reason.
-
-## Setup
-
-1. First, we need a database that Grafana will link to. To do this go to the [Google Cloud Console](https://console.cloud.google.com/home/dashboard?project=decent-digit-629) and in the menu go into the SQL section.
-
-2. Look for an instance named `aimmo-monitoring`, if this does not exist for whatever reason, one will need to be created by following the steps after clicking the `create instance` button (you can create either a MySQL or PostgreSQL instance, for simplicity we recommend choosing PostgreSQL).
-
-3. Now that you have an instance, go into it, then find the databases tab. You need 1 database per instance of Grafana (so one per cluster), the names of these databases are used later by the Grafana deployment so they are important. Recommended names are: `aimmo_monitoring_dev`, `aimmo_monitoring_staging`, `aimmo_monitoring_default`.
-
-4. You should now have a database for the cluster you're working with. Next, you need a user, there should already be a user called `grafana` that you can use, if not click `create user` and go through the steps there. You need to make sure the user will have access to the instance you created if you had to create a new one.
-
-5. Next, you should see 2 secrets on the cluster, one contains service account info, and the other has login details for Grafana. These are used in the `grafana-deployment.yaml`. If you need to recreate these secrects for whatever reason make sure the correct data is passed into this yaml. [Here](https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/blob/master/cloudsql/postgres_deployment.yaml) is an example deployment which makes a good reference for this step.
diff --git a/docs/deployment/monitoring.md b/docs/deployment/monitoring.md
deleted file mode 100644
index c0b520581..000000000
--- a/docs/deployment/monitoring.md
+++ /dev/null
@@ -1,141 +0,0 @@
-# Monitoring
-
-This document outlines the process we use to collect metrics from our clusters on Google Cloud Engine and how to restart the relevant pods in the event they break in some way.
-
-*Note: the monitoring setup is a one time event that should only be done again in the event of failure or breakage*
-
-## Monitoring with Prometheus
-
----
-
-Everything on our cluster is monitored via [Prometheus](https://prometheus.io/), and more specifically the [kube-prometheus](https://github.com/coreos/prometheus-operator/tree/master/contrib/kube-prometheus) setup used for kubernetes clusters.
-
-### Prometheus workflow
-
-Here is the official workflow for [Prometheus](https://prometheus.io/):  *[image source](https://itnext.io/kubernetes-monitoring-with-prometheus-in-15-minutes-8e54d1de2e13)*
-
-In the above picture there are a number of different components. In short, [Prometheus](https://prometheus.io/) uses service monitors to scrape metrics from all services on the cluster and holds them for a set amount of time. The operator is built on a framework used to package and deploy applications to kubernetes clusters, more information on operators can be found [here](https://coreos.com/operators/), but it's not required to understand how [Prometheus](https://prometheus.io/) interacts with the cluster.
-
-This gives us all we need to collect data and store it, but not a good way of making use of any of that data. That is handled via various Data vizualisation tools.
-
-### Data Visualisation
-
-There are a number of ways to view the data [Prometheus](https://prometheus.io/) collects, the ones we make use of are: the Prometheus web UI, and [Grafana](https://grafana.com/). The Prometheus web UI is a simple tool that allows you to create queries on various metrics, view results in simple graphs, and view things like data targets (which is where all your data comes from), rules, and alerts (alerts will be explained later).
-
-[Grafana](https://grafana.com/) is a tool that allows to create dashboards and organise our data, and gives a much wider range of options when it comes to creating graphs and charts. It uses the same query language as the Prometheus web UI for collecting data, making it much simpler to switch between the web UI and Grafana.
-
-# Setup
-
-In the `monitoring` folder in `cluster-setup` in the deploy app-engine repo. This folder contains all the configuration required to get [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) onto our clusters, but they will need to be exposed manually.
-
-1. To do this, first find thet file named `prometheus-prometheus.yaml` and change the following line:
-
-```yaml
- externalUrl: "https://{CLUSTER}-aimmo.codeforlife.education/prometheus"
-```
-
-by replacing the word `{CLUSTER}` with either dev/staging/default depending on which cluster you are applying the manifests to.
-
-2. Next we need to repeat this step for the `alertmanager-alertmanager.yaml` file, again finding the the line:
-
-```yaml
- externalUrl: "https://{CLUSTER}-aimmo.codeforlife.education/alertmanager"
-```
-
-and replacing `{CLUSTER}` with either dev/staging/default depending on which cluster you're workking with.
-
-3. Now we need to look for files named: `monitoring-ingress.yaml` & `grafana-ingress.yaml`. In both files there will be a line that looks like this:
-
-```yaml
- - host: "https://{CLUSTER}-aimmo.codeforlife.education"
-```
-
-Again you need to replace `{CLUSTER}` with either dev/staging/default depending on which cluster you're working on.
-
-4. After that, look for the `grafana-ini-configmap.yaml` file, this contains the main config file used to setup [Grafana](https://grafana.com/). inside the `[server]` header, look for the lines:
-
-```ini
-domain = {CLUSTER}-aimmo.codeforlife.education
-...
-root_url = https://{CLUSTER}-aimmo.codeforlife.education/grafana/
-```
-
-and once again replace `{CLUSTER}` with either dev/staging/default.
-
-5. Next, you need to go onto the Kubernetes Engine section of our [Google cloud console](https://console.cloud.google.com) dashboard, then go into services and look for the `aimmo-ingress` for the cluster you're working on. It should be near to, or at the top of the list of services.
-
-Click on the ingress to open up its details, then click "EDIT". You should see something like this:
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- annotations:
- kubernetes.io/ingress.class: nginx
- kubernetes.io/ingress.global-static-ip-name: dev-aimmo-ingress
- ...
-```
-
-Now add this line into the annotations section:
-
-```yaml
-nginx.org/mergeable-ingress-type: master
-```
-
-This is needed because we make use of multiple ingress files but you are only allowed a single ingress per host. For more information see the following example [here](https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/mergeable-ingress-types).
-
-6. Finally, should be able to apply these manifests to the cluster you're working with.
-
-To do this, run `kubectl create -f monitoring/ || true`, if prometheus does not exist on that cluster at all. If the manifests have already been applied before, use: `kubectl apply -f monitoring/ || true` and this will update the existing manifests and reset all the relevant components. You can use `kubectl delete -f monitoring/ || true` if you need to remove our monitoring for whatever reason (at present this will also destroy all data). You need to be in the same directory as the monitoring folder to run these commands.
-
-*Note: kubectl needs to be configured to work with the GCloud cluster for this method to work*
-
-## Potential setup issues
-
-Below are some issues you may encounter when setting up [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) on any of the clusters.
-
-### Grafana looks a bit empty
-
-If when you go to `https://CLUSTER_URL/grafana` all you see is a mostly blank page containing some text, this means the ingress isn't configured quite right so it's not exposing all the styles. Below are some examples for working configs for the `grafana-ingress.yaml`
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: grafana-ingress
- namespace: monitoring
- annotations:
- kubernetes.io/ingress.class: nginx
- nginx.ingress.kubernetes.io/rewrite-target: /$1
- nginx.org/mergeable-ingress-type: minion
-spec:
- rules:
- - host: staging-aimmo.codeforlife.education
- http:
- paths:
- - backend:
- serviceName: grafana
- servicePort: 3000
- path: /grafana/?(.*)
-```
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: grafana-ingress
- namespace: monitoring
- annotations:
- kubernetes.io/ingress.class: nginx
- nginx.ingress.kubernetes.io/rewrite-target: /
- nginx.org/mergeable-ingress-type: minion
-spec:
- rules:
- - host: staging-aimmo.codeforlife.education
- http:
- paths:
- - backend:
- serviceName: grafana
- servicePort: 3000
- path: /grafana
-```
\ No newline at end of file
diff --git a/docs/deployment/nginx-setup.md b/docs/deployment/nginx-setup.md
deleted file mode 100644
index 026cb86f3..000000000
--- a/docs/deployment/nginx-setup.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# NGINX Controller Ingress Setup
-
-**Note: This should only be done once only. The only time when a new setup might be required is when you reset the cluster to a fresh state or delete the relevant pods, services & deployments.**
-
----
-
-
-In order to deploy our ingress correctly with a specific nginx controller used in google cloud platform, we need to create several services. All of these up to date instructions can be found [**here**](https://github.com/kubernetes/ingress-nginx/blob/master/deploy/README.md).
-
-For the sake of correct version control, we have saved the yaml files at the time of setup in the repository `ocadotechnology/codeforlife-deploy-appengine` at the path `./clusters_setup/ingress_nginx`.
-
-To set up from scratch do the following:
-* Install gcloud locally. This is usually done by the following command: `pip install google-cloud`. At the time of writing the version is `0.32.0` and Google Cloud SDK of `189.0.0`.
-* Set the current project for this workspace by typing: `gcloud config set project decent-digit-629`.
-* Authenticate accordingly. You can read up on this [**here**](https://cloud.google.com/appengine/docs/standard/python/oauth/). Usually the following should work: `gcloud auth login`. This will open a web browser and will ask you to authenticate and give permissions to the google account. You should then (or only) run `gcloud auth application-default login` which will create the kubeconfig required for `kubectl` to work.
-* Get credentials to the appropriate cluster you want to work on by doing the following command: `gcloud container clusters get-credentials [dev/staging/default] --zone europe-west1-b`
-* `kubectl apply -f` should now be used on the following files (see path above to find these files):
- * `namespace.yaml`, `default-backend-service.yaml`, `default-backend-deployment.yaml`, `configmap.yaml`, `tcp-services-configmap.yaml`, `udp-services-configmap.yaml`.
-* Now install no RBAC roles by doing the same on `without-rbac.yaml`.
-* And finally GCE specific settings and patches:
- * Run `kubectl patch deployment -n ingress-nginx nginx-ingress-controller --type='json' --patch="$(curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/publish-service-patch.yaml)"`.
- * `kubectl apply -f` on `service.yaml` and `patch-service-without-rbac.yaml`
-
-***
-# Reserving a static external IP address for a cluster
-
-The load balancer IP needs to be static in order to be resolved to a single DNS address. The whole setup process won't have to be done again but for reference:
-* Go to **VPC Networks -> External IP addresses ** in the Google Cloud Platform UI and reserve a _**static**_ IP address with the name `[env]-aimmo-ingress`
-* In your appengine project, open the [`ingress.yaml`](https://github.com/ocadotechnology/codeforlife-deploy-appengine/blob/master/clusters_setup/ingress.yaml) file and make sure that the following complies:
- * In metadata:annotations `kubernetes.io/ingress.global-static-ip-name: [env]-aimmo-ingress` is set.
- * Ensure the spec:host entry is made for this domain in the ingress. For example `- host: default-aimmo.codeforlife.education`
-* Make a ANAME record in the DNS server to attatch it to that IP address that was reserved. Make sure this domain is `[env]-aimmo.codeforlife.education`.
-
-***
-# Securing the cluster with SSL.
-
-When settings the above DNS, you should generate/obtain appropriate CA, cert and key files. To now secure your domain you should:
-* In file [`ingress.yaml`](https://github.com/ocadotechnology/codeforlife-deploy-appengine/blob/master/clusters_setup/ingress.yaml) on the appengine project, the section _**spec:rules**_ should contain:
-```
-tls:
- - hosts:
- - [env]-aimmo.codeforlife.education
- secretName: ssl-cert-secret
-```
-* In your terminal, go to the directory that contains the above mentioned files and use the following to generate the secret: `kubectl create secret tls foo-secret --key=/tmp/tls.key --cert=/tmp/tls.crt`. This will require correct authentication which is described above.
-* The downtime between deleting the old `ssl-cert-secret` on a cluster and creating a new one will hang the game creator as it will not receive information since a certificate authority issue will occur. The solution for this is to delete the game creator **pod** which will reinstantiate all the games and workers from scratch.
diff --git a/docs/deployment/prometheus4k8s.png b/docs/deployment/prometheus4k8s.png
deleted file mode 100644
index c7924b774..000000000
Binary files a/docs/deployment/prometheus4k8s.png and /dev/null differ
diff --git a/docs/infrastructure/README.md b/docs/infrastructure/README.md
deleted file mode 100644
index 83f1105c7..000000000
--- a/docs/infrastructure/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Infrastructure
-
----
-
-## ...
diff --git a/docs/life-cycle-of-a-code-change.md b/docs/life-cycle-of-a-code-change.md
deleted file mode 100644
index f846815fb..000000000
--- a/docs/life-cycle-of-a-code-change.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Life cycle of a code change
-
-Once you're confident with the changes implemented in your local branch, you should push them and open a GitHub pull request that can be reviewed and approved. **Note that** this should be a `semantic` pull request.
-
-## Development to Staging
-
-The branch is ready to be merged into the `development` branch when all changes are reviewed and there are no conflicts or blocking errors.
-
-After the PR is merged in, a `development` build starts and a beta release may or may not be created depending on the semantic PR title (see [semantic release notes](https://github.com/semantic-release/semantic-release)). The version is updated and the following are built and pushed:
-
-- aimmo `PyPi` package (beta)
-- `Docker` images: aimmo-game, aimmo-game-creator and aimmo-game-worker (beta)
-
-Once the new beta version is released on PyPi and Docker Hub, Semaphore CI is notified and deploys it to our staging server, where the code changes will be tested further. See more details in our deploy app engine [documentation](https://github.com/ocadotechnology/codeforlife-deploy-appengine/blob/master/docs/life-cycle-of-a-code-change.md).
-
-## Staging to Production
-
-Once the changes on `development` are stable, this branch is merged into the `master` branch, updating it with the latest beta release. This triggers a `master` build and creates a release version. Deployment to production is manually triggered on Semaphore CI.
-
-After a successful deployment, the `master` branch has to be merged back into the `development` one to ensure that the latter is up-to-date and ready for the next release.
diff --git a/docs/testing/README.md b/docs/testing/README.md
deleted file mode 100644
index d439ecf56..000000000
--- a/docs/testing/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Testing
-
----
-
-- [Manual Test Plan](test-plan.md)
-- [Automatic Testing](automatic-testing.md)
diff --git a/docs/testing/automatic-testing.md b/docs/testing/automatic-testing.md
deleted file mode 100644
index 0560b08df..000000000
--- a/docs/testing/automatic-testing.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Automatic Testing
-- [Unit Tests](#unit-tests)
-- [Functional Tests](#functional-tests)
-- [Integration Tests](#integration-tests)
-- [Testing Tools](#testing-tools)
-- [Coverage Tools](#coverage-tools)
-
----
-
-
-## Unit Tests
-Currently our unit tests are located in `[module name]/tests/test_simulation`. They check that individual pieces of our code base work correctly, without integration of other functionality. They are all prefixed with `test_` and this is the requirement for it to be recognized when `all_tests.py` is ran.
-
-Every time you add a new piece of functionality; the bare minimum is to reflect this in the unit tests.
-
-## Functional Tests
-Our functional tests can be found in `[module name]/tests/functional`. They generally tend to mock all the logic of the game without actually integrating the surrounding server architectures.
-
-## Integration Tests
-TODO
-
-## Testing Tools
-[Hypothesis](https://hypothesis.works/) is a property based tool that can be used to run tests with a way wider range of scenario's than we could possibly design. It tends to find edge cases that we may have (and have already) missed various times. We encourage to convert current tests to make use of this framework as well as designing new ones with this.
-
-## Coverage Tools
-Our coverage tool right now is [coveralls](https://coveralls.io/). For the moment we do not count the coverage over the tests. This gives a closer to reality coverage, but it does not check if all the tests run.
\ No newline at end of file
diff --git a/docs/testing/test-plan.md b/docs/testing/test-plan.md
deleted file mode 100644
index 680799667..000000000
--- a/docs/testing/test-plan.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Manual Test Plan
-- [Level 1](#level-1)
-- [Custom Games](#custom-games)
-- [Out Of Testing Scope](#out-of-testing-scope)
----
-
-**Prerequisites**
-* Delete the database file in example_project/example_project/db.sqlite3.
-* First run the test using `./run.py` and then try `./run.py -k`.
-* Make sure to open your terminal to see for any messages. Some exceptions are expected but keep note.
-***
-
-
-## Level 1
-### Check the following:
-
-**Prior to playing the game:**
-* The level exists already. Check it by navigating to the Watch->Level.
-* If required, you can login using your details (admin:admin default).
-* You are at the correct URL (/kurono/watch_level/1/).
-* It consists of **_five_** square boxes lined horizontally. The leftmost is at (-2,0), the right most at (2,0).
-* There is no player on the screen. Nothing is happening.
-
-**Programming the game:**
-* Program the game (Program-> Level1) and end up in the correct URL (kurono/program_level/1/).
-* Ensure the code will be able to move the character to the right 4 times. Default code will suffice (see below to copy).
-* Click the save button. Now go to Watch->Level1 via the menu (or press the Watch hotlink above the editor).
-* See the character moving. It should stop when it gets to red box at (2,0).
-
-```
-class Avatar(object):
- def next_turn(self, world_view, events):
- from simulation.action import MoveAction
- from simulation.direction import ALL_DIRECTIONS
- import random
-
- return MoveAction(random.choice(ALL_DIRECTIONS))
-```
-
-***
-
-## Custom Games
-### Check the following:
-**Prior to playing the game:**
-* Ensure there are no custom games running (Watch menu).
-* Go to Program->Create a new game (/kurono/games/new). Select any name, select yourself in the 'Can Play' menu.
-* Ensure 'Generator' is set to "Open World". Save, watch.
-* A grid should show with an avatar moving around randomly.
-* The score location should move randomly from time to time (depending on settings).
-* Score of the avatar should increase as the avatar passes onto it.
-* Pickups (3 types) should spawn from time to time.
- 1. Any of the types should disappear after an avatar passes through the same cell.
- 2. Health pickup (white with red cross) should restore the avatar's health (the hp text).
- 3. The other two pickups (blue: invulnerability, red: damage boost) should appear, but have no visible effect on the avatar yet.
-* Health of an avatar should be able to decrease. On 0, the avatar should respawn.
-* Follow the instructions on the main homepage to see how you can add multiple avatars to a game at the same time.
-***
-
-## Out of testing scope
-### Check the following:
-* Reprogram the game to your own behavior. Check everything is done as expected.
-***
diff --git a/docs/usage.md b/docs/usage.md
deleted file mode 100644
index 595fde47a..000000000
--- a/docs/usage.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Usage
-
-This setup process will allow you to run Kurono locally via [docker](https://www.docker.com/) or a [kubernetes](https://kubernetes.io/) cluster, and to be able to contribute towards the project.
-
-- [Mac setup](#mac-setup)
-- [Ubuntu/Debian setup](#ubuntu-setup)
-- [Windows setup](#windows-setup)
-- [Testing locally](#testing-locally)
-- [Useful information](#useful-information)
-
-## Mac setup
-
-This can be done either manually or using the setup script.
-
-#### Install using the setup script:
-
-- Run `python aimmo_setup.py` in the Kurono root directory. Then:
-- Open Docker to finalise the install process. (This will install the [latest release](https://www.docker.com/get-started))
-- See [Useful information](#useful-information) for additional details about the script.
-
-#### Install manually:
-
-- First you get the [brew](https://brew.sh/) package manager. Then:
-- Follow the instructions at [game frontend documentation](https://github.com/ocadotechnology/aimmo/blob/master/game_frontend/README.md) in order to set up the frontend requirements, (you should be in the game_frontend folder for this step).
-- Follow the instructions for [installing pyenv](https://github.com/pyenv/pyenv#installation).
-- Run `brew install pipenv`, followed by `pipenv install --dev` (more information on [pipenv](https://pipenv.readthedocs.io/en/latest/)).
-- Install [Docker](https://www.docker.com/): `brew update && brew install --cask docker`.
-- Install Minikube: `brew install minikube`.
-- Check if you have `kubectl` installed (Kubernetes - it should come with Docker). If not, use: `curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.9.4/bin/darwin/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/`.
-- Install helm: `brew install helm`.
-- Add agones repo to helm: `helm repo add agones https://agones.dev/chart/stable && helm repo update`.
-- Create a minikube profile for agones: `minikube start -p agones --driver=hyperkit`.
-- Set the minikube profile to agones: `minikube profile agones`, then install agones using helm: `helm install aimmo --namespace agones-system --create-namespace agones/agones`.
-
-#### To run Kurono:
-
-- Ensure you are inside the python virtualenv, `pipenv shell`.
-- First start the agones cluster with: `minikube start -p agones --driver=hyperkit`.
-- Now use `python run.py` to run the project.
-
-## Ubuntu setup
-
-This can be done either manually or using the setup script.
-
-#### Install using the setup script:
-
-- Run `python aimmo_setup.py` in the AI:MMO root directory.
-- See [Useful information](#useful-information) for additional details about the script.
-
-#### Install manually:
-
-- First run `sudo apt-get update` to save having to do it later in the process.
-- Follow the instructions at [game frontend documentation](https://github.com/ocadotechnology/aimmo/blob/master/game_frontend/README.md) in order to set up the frontend requirements, (you should be in the `game_frontend` folder for this step).
-- Follow the instructions for [installing pyenv](https://github.com/pyenv/pyenv#installation).
-- Next run `sudo apt-get install python-pip`, followed by `pip install pipenv` to get the [pipenv](https://pipenv.readthedocs.io/en/latest/)) virtual environment.
-- Now use `pipenv install --dev` to get the requirements for the project.
-- Install [Snap](https://snapcraft.io/)) using `sudo apt install snapd`.
-- Now run `sudo snap install kubectl --classic` to install kubectl ([Kubernetes](https://kubernetes.io/)).
-- To install [Docker](https://www.docker.com/), either use `sudo apt-get install docker-ce` to install a fixed version of the latest release, or follow the Ubuntu install instructions on the [Docker website](https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-repository).
-- Install Minikube, running `curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64`, then `sudo install minikube-linux-amd64 /usr/local/bin/minikube`
-- Install helm: `sudo snap install helm --classic`
-- Add agones repo to helm: `helm repo add agones https://agones.dev/chart/stable && helm repo update`
-- Create a minikube profile for agones: `minikube start -p agones`.
-- Set the minikube profile to agones: `minikube profile agones`, then install agones using helm: `helm install aimmo --namespace agones-system --create-namespace agones/agones`
-
-#### To run Kurono:
-
-- Ensure you are inside the python virtualenv, `pipenv shell`.
-- First start the agones cluster with: `minikube start -p agones`.
-- Now use `python run.py` to run the project.
-
-## Windows setup
-
-#### Install Manually:
-
-- Contact a member of the Code for Life team via the [Code for Life contact form](https://www.codeforlife.education/help/#contact).
-
-The game should now be set up to run locally. If you wish to be able to run the project with [Kubernetes](https://kubernetes.io/) and containers, follow these next steps:
-
-- First, follow the instructions at [game frontend documentation](https://github.com/ocadotechnology/aimmo/blob/master/game_frontend/README.md) in order to set up the frontend requirements, (you should be in the `game_frontend` folder for this step).
-- Follow the instructions for [installing pyenv](https://github.com/pyenv/pyenv#installation).
-- Run `pip install pipenv`, followed by `pipenv install --dev` (more information on [pipenv](https://pipenv.readthedocs.io/en/latest/)).
-- Next, [download chocolatey](https://chocolatey.org/) and run `choco install kubernetes-cli`.
-- Follow the instructions for [installing pyenv](https://github.com/pyenv/pyenv#installation).
-- Then follow the [docker installation instructions for Windows](https://docs.docker.com/docker-for-windows/).
-- Install minikube: `choco install minikube`.
-- Install helm: `choco install kubernetes-helm`.
-- Add agones repo to helm: `helm repo add agones https://agones.dev/chart/stable && helm repo update`.
-- Create a minikube profile for agones: `minikube start -p agones`.
-- Set the minikube profile to agones: `minikube profile agones`, then install agones using helm: `helm install aimmo --namespace agones-system --create-namespace agones/agones`.
-
-#### To run Kurono:
-
-- Ensure you are inside the python virtualenv, `pipenv shell`.
-- First start the agones cluster with: `minikube start -p agones`.
-- Now use `python run.py` to run the project.
-
-## Useful information
-
-Here you can find some other useful information regarding the setup or usage of various aspects of the project.
-
-#### Setup script & other setup information.
-
-- It may be the case that the frontend does not load properly upon starting aimmo (when running the script). If this is the case then you may need to follow the [game frontend documentation](https://github.com/ocadotechnology/aimmo/blob/master/game_frontend/README.md) in order to resolve this (usually all the packages are there, it just requires you to set them up manually).
-- If the script fails when attempting to install Docker, it may be because you have an old version of docker currently installed. To fix this, run: `sudo apt-get remove docker docker-engine docker.io`, then re-run the script.
-- If there is an issue when using containers or the virtual enviroment. Then there small chance that VT-x/AMD-x virtualization has not been enabled on your machine. If this is the case the main way to solve this is to enable it through the BIOS settings.
-
-#### Testing locally
-
-- Use `./all_tests.py` to run all the tests (note that this is several pages of output).
-- The `--coverage` option will generate coverage data for the tests using `coverage.py`.
-
-#### Interacting with the cluster
-
-- `kubectl` and `minikube` can be used to interact with the cluster.
-- Running either command without any options will give the most useful commands.
-- Use `minikube dashboard` to open the [Kubernetes](https://kubernetes.io/) dashboard in your browser.
-
-#### Useful commands
-
-- To create an another admin account: `python example_project/manage.py createsuperuser`
- - By default, we create an admin account with credentials admin:admin when you start the project.
diff --git a/game_frontend/README.md b/game_frontend/README.md
deleted file mode 100644
index 95427fabb..000000000
--- a/game_frontend/README.md
+++ /dev/null
@@ -1,103 +0,0 @@
-[](https://github.com/standard/standard)
-
-
-
-# Kurono Frontend
-
-## Description
-
-This folder contains the frontend for the Kurono game. It is a single page application using [React](https://reactjs.org/). We use [Redux](https://redux.js.org/) for state management and [redux-observable](https://redux-observable.js.org/) for handling our side effects (e.g. asynchronous calls). To learn more about how we connect all of these together, feel free to check out our [How does it all work](#how-does-it-all-work) section.
-
-## Installation for Contributors
-
-### Requirements
-
-- [Node](https://nodejs.org/en/download/)
-- [Parcel](https://parceljs.org/)
-- [yarn](https://yarnpkg.com/en/)
-
-### Build dependencies
-
-Once you have cloned this repository, run the command below in this folder:
-
-```
-yarn
-```
-
-## Usage
-
-### Standalone
-
-It's possible to run the frontend by itself. To do so, run the command below in this folder.
-
-```
-parcel index.html
-```
-
-### With Django
-
-Our Django runner calls `djangoBundler.js` when running the project for you so nothing special needs to done! Run this command in the root of this repository (make sure you are in your virtualenv):
-
-```
-./run.py -k
-```
-
-`djangoBundler.js` is a custom `parcel-bundler` we use to make sure we generate a Django template as an entry point for the React code.
-
-### Running Tests
-
-```
-yarn test
-```
-
-## Contributing
-
-- tests
-- standard style guide (state exceptions)
-
-
-## How does it all work?
-
-### Prequisite Reading
-
-If you are new to React and Redux we recommend reading these resources:
-
-- [React tutorial](https://reactjs.org/tutorial/tutorial.html)
-- [Thinking in React](https://reactjs.org/docs/thinking-in-react.html)
-- [Redux and React tutorial](https://www.valentinog.com/blog/react-redux-tutorial-beginners/)
-
-In order to make sure our project structure is scalable we use [re-ducks](https://medium.freecodecamp.org/scaling-your-redux-app-with-ducks-6115955638be).
-
-### Optional reading
-
-The links here aren't necessary for helping you contribute straight away but they will help you out as you get more comfortable with our project:
-
-- [Jest testing cheatsheet](https://devhints.io/jest)
-- [Redux Observables](https://redux-observable.js.org/)
-- [RxJS Marble Testing](https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md)
-
-### How we integrate with Django
-
-Coming soon...
-
-### Technology Stack
-
-- React
-- Redux
-- redux-observable
-- styled-components
-
-#### For developers
-
-- Parcel
-- StandardJS
-- Babel
-
-#### For testing
-
-- Jest
-- Enzyme
-
-### Building for Production
-
-Coming soon...
diff --git a/docs/images/AIMMO-Logo-vertical-RGB.svg b/images/AIMMO-Logo-vertical-RGB.svg
similarity index 100%
rename from docs/images/AIMMO-Logo-vertical-RGB.svg
rename to images/AIMMO-Logo-vertical-RGB.svg
diff --git a/docs/images/kurono_game.png b/images/kurono_game.png
similarity index 100%
rename from docs/images/kurono_game.png
rename to images/kurono_game.png
diff --git a/docs/images/kurono_logo_mark.svg b/images/kurono_logo_mark.svg
similarity index 100%
rename from docs/images/kurono_logo_mark.svg
rename to images/kurono_logo_mark.svg
diff --git a/docs/images/kurono_logo_simple.svg b/images/kurono_logo_simple.svg
similarity index 100%
rename from docs/images/kurono_logo_simple.svg
rename to images/kurono_logo_simple.svg