# Software Development Process

## Auto routing

To achieve the auto routing, we first use Expo's location module to retrieve the user's current location as the point of origin, then another module from npmjs library which allows us to pick a random point on the perimeter of a circle of a pre-defined radius (we use the distance defined by the user for this radius).&#x20;

We use this module to find 2 points, and together with the origin as the starting and ending point, we are able to request a route from Google Directions API to generate the route for us.

Thus the array in request to be sent to Google API will look like this: \
\[Origin, Random Pt 1, Random Pt 2, Origin].

Why only 2 random points?

With only 2 random points, the route generated on a 2D map will result in a proper loop, whereas with 3 or more random points, the route generated may not give us a loop (as illustrated below).

![](/files/-MenGCuvFllS3FGDNHXA)

The distance of the generated route will never exactly be the distance desired by the user. We chose a distance margin of 250m as the distance slider is set to increments of 500m.&#x20;

Therefore, we recursively do the following to get a route:

1. Check the distance of the route (using another module)
2. If it is within 250m of the desired distance, we show the user the route
3. Otherwise, we request from Google Directions API again for another route

Once the user is satisfied with the route shown, they may start the run with the generated route displayed on their device and begin running the route.

## Tracking the run

When the run starts and at every position change, the app records down the user's new location and appends the information into the back of an array. These array stores elements containing the latitude and longitude values of the user during their run, thus allowing us to dynamically plot a line on the map as the user moves. A timer is implemented by simply incrementing a variable by 1 at every 1s intervals. The tricky part to implement is when the app is backgrounded but we still want it to continue tracking.

When the app is backgrounded, we want to track only 2 things, the timer and location.

1. For the timer, a timestamp is recorded the moment the app goes into the "background" and into the "active" state respectively. By taking the time between these 2 timestamps, we will then have the duration the device spent in the background. All that is left is to add this duration to the timer variable once the app returns to the “active” state.<br>
2. For the location, we will have to request both foreground and background location services permissions on the user's phone. With the background location services granted, the application will be able to constantly update the locations array and hence continue tracking the user. Once the app state changes back into "active", the background tracking stops while the foreground tracking resumes.

![Summary of completed run](/files/-MenGCuwd4XB2BV5G-yn)

When the user ends the run, they will be able to see their progress to the next level, time taken, average pace, distance travelled, estimated calories burned, and an interactive map for them to view their completed run.

This information will be logged into our database, thus allowing users to review their run in their running logs.

## Firebase Usage

We use Firebase to keep track of all the data such as the user's stats, past runs (statistics + array of user locations), which user is friends with who, and to implement the leaderboard and PVP functions. One of the main reasons for choosing firebase would be its simplicity and user-friendly UI. The query methods are also really suitable for our mobile app implementation.

For the leaderboard and running logs, firebase helps to maintain all of our users’ run records. For both features, we made use of queries to firebase to retrieve the necessary data for the UI.

As for the friends feature, when a user searches for another user through the UID, it sends a firebase query to help retrieve that specific user’s information.

Last but not least is the PVP feature. We made use of a lot of firebase queries to help handle the PVP logic and the real-time aspect of the battle. The main method used here to listen for changes would be the on() method from firebase. This method helped us to maintain the real-time aspect of our PVP feature by listening to changes and updating the UI accordingly.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://run-mania.gitbook.io/run-mania/software-development-process.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
