Skip to content

Commit

Permalink
Full project review
Browse files Browse the repository at this point in the history
  • Loading branch information
gruvw committed Jan 6, 2024
1 parent 6f3a56f commit 63c47c4
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 27 deletions.
52 changes: 28 additions & 24 deletions project/tic-tac-tile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ To install the game, you will need to obtain the `tic-tac-tile.nds` game file.
Use one of the following method:

- Download it online from the GitHub releases: [`tic-tac-tile.nds`](https://) <!-- TODO -->
- Build it from source by running `make build` in the same directory as this README (requires [`devkitpro-pacman`](https://apt.devkitpro.org/install-devkitpro-pacman)).
- Build it from source: clone this repository and run `make build` in the same directory as this README (requires [`devkitpro-pacman`](https://apt.devkitpro.org/install-devkitpro-pacman)). The game file `tic-tac-tile.nds` will be generated in that directory.

Place the `tic-tac-tile.nds` file inside the micro SD card of an [R4 cartridge](https://en.wikipedia.org/wiki/R4_cartridge).

Expand All @@ -46,22 +46,22 @@ It features 3 **game modes**:
* Two player mode, single NDS
* Two player mode, two NDS over Wi-Fi

Select among the 3 **speeds** and adjust the game's difficulty:
Select among the 3 **speeds** to adjust the game's difficulty:

* Slow (green)
* Medium (orange)
* Fast (red)

#### Play

1. Select the settings that you want by using the bottom touch screen. (see below for Wi-Fi two player mode setup)
1. Select the settings that you want by using the bottom touch screen. (see below for [Wi-Fi Two Player Mode Setup](#wi-fi-two-player-mode-setup))
2. Press on the `START` button to launch a game.
* In Wi-Fi two player mode, the first player to press start will start the game for both players and will play first.
* In Wi-Fi two player mode, the first player to press `START` will go first and starts the game for both players.
3. Select the square where you want to place your piece using the `LEFT`, `RIGHT`, `UP`, `DOWN` arrow buttons.
4. Press on the `A` button to confirm your choice and place your piece. Be carefull about the progress bar, you need to play before you run out of time to win!
5. Wait for the other side to play.
* In single player mode, the bot will play instantly after your turn.
* In (local) two player mode, you need to hand out the Nintendo DS to the other player so they can play.
* In (local) two player mode, you need to hand out the Nintendo DS to the other player so they can play on the same device.
* In Wi-Fi two player mode, simply wait for your opponent to play on their Nintendo DS.
6. Carry on till you reach the Game Over screen. Alternatively you can also press the `START` button at any moment to put an end to the current game and go directly to the Game Over screen.
* If one of the side won, their 3 winning pieces will be highlighted on the board. Additionally, the winning side will be crowned on the bottom screen.
Expand All @@ -87,36 +87,36 @@ NDS setup:
2. Click on the "Two Player Wi-Fi" game mode. Keep the NDS very close to the AP.
3. You will see the Wi-Fi icon show up while trying to connect to the AP: <p align="center"><img src="docs/wifi.png" alt="Wi-Fi icon" width="60px"></p>
* If the connection is successful, the "Two Player Wi-Fi" mode will now be selected.
* Otherwise it will stop trying to connect after a few seconds, hide the Wi-Fi icon and stay in your current game mode.
* Otherwise (fails to connect to AP) it will stop trying to connect after a few seconds, hide the Wi-Fi icon and leave you in your current game mode.
4. Once the "Two Player Wi-Fi" mode is selected (successfully connected to AP), the search icon will indicate that your NDS is ready to pair with another NDS: <p align="center"><img src="docs/search.png" alt="Search icon" width="60px"></p>
5. After two NDS are searching to connect at the same time, they will find each other automatically and pair. The paired/success icon will be displayed on the two NDS once the connection is fully established: <p align="center"><img src="docs/paired.png" alt="Paired icon" width="60px"></p>
5. When two NDS are looking to connect together, they will find each other automatically and pair. The paired/success icon will be displayed on the two NDS once the connection is fully established: <p align="center"><img src="docs/paired.png" alt="Paired icon" width="60px"></p>
6. Each player can chose their own speed difficulty independently. You can now start a game!
7. At the end of the game, each player needs to press the `START` button to go back to the main menu. The search process will start again (back to point 4). It allows to change opponents between games if other NDS are also searching (more than 2 NDS), otherwise just wait a few seconds to connect back to your opponent.
7. At the end of the game, each player needs to press the `START` button to go back to the main menu. The search process will start again (back to point 4). It allows to change opponent between games if another NDS is also searching (more than 2 NDS connected on AP). Otherwise just wait a few seconds to connect back to your opponent.

**Note 1**: on the main menu, you can restart the pairing process by pressing the `SELECT` button (e.g. if you want to pair to someone else).

**Note 2**: you can play with more than 2 NDS on the same Wi-Fi network! You can have multiple games running simultaneously (e.g. with 4 NDS).

##### Troubleshoot

You should not expect many issues with the game but as it went under extended testing before release.
You should not expect many issues with the game, as it went through extended testing before release.

However, if you happen to run into an issue, there is a good chance that you will find the solution below:

* **Problem 1** - You are stuck in a game. Simply press the `START` button once to bring up the Game Over screen, and then a second time to get back to the main menu.
* **Problem 2** - Wi-Fi connection is momentary interrupted: this can take the form of longer time in search mode trying to pair to opponent or a move played that was not reflected on the other NDS during a game. This is normal and can happen, make sure to keep the phone AP very close to the NDS and wait for the messages to arrive.
* **Problem 3** - If one or more NDS is blocked in search mode and can't find the other NDS to connect:
* **Problem 2** - Wi-Fi connection is momentary interrupted: this can take the form of longer time in search mode trying to pair to your opponent or a move played during a game that is not reflected on the other NDS during a game. This is normal and can happen, make sure to keep the phone AP very close to the NDS and wait for the messages to arrive.
* **Problem 3** - If one or more NDS is blocked in search mode and cannot find the other NDS to connect to:
1. First, try to press the `SELECT` button on all affected NDS to reset the connection process and see if it helps.
2. If that did not work, it means the Wi-Fi connection is permanently lost (see Problem 4 below).
* **Problem 4** - Wi-Fi connection is permanently lost: this can take the form of NDS blocked in search mode (even after pressing the `SELECT` button) or not being able to select the "Two Player Wi-Fi" mode. You can simply shutdown all the NDS and the smartphone Wi-Fi Access Point, and then restart the Wi-Fi setup (full systems reboot). Everything should be working normally after that.

**Note**: there are no security features builtin the Tic-Tac-Tile game. Games can be rigged by hackers on the same (public) local network.
**Note**: there are no security features built into the Tic-Tac-Tile game. Games can be rigged by hackers on the same (public) local network.

## Development

This project was less about creating a great game to play than it was about controlling peripherals and embedded programming.
I chose a simple game but utilized a lot of peripherals and NDS functionalities.
The focus was on **code quality** and **documentation** and **Wi-Fi communication reliability**.
The focus was on **code quality**, writing a good **documentation**, and **Wi-Fi communication reliability**.

### Presentation

Expand Down Expand Up @@ -148,7 +148,7 @@ Keypad:

Touchscreen:

* Select the game settings in the beginning menu, 6 different touch areas used, select game difficulty (speed) and game mode.
* Select the game settings in the game menu, 6 different touch areas used, select game difficulty (speed) and game mode.
* Reading touchscreen by polling.

Sound:
Expand All @@ -159,7 +159,7 @@ Sound:

Sprites:

* 7 sprites in the project: 4 sprites are used to display the outcome of the game on the Game Over screen: (1) crown for the winner, each side (2) has their sprite, (1) clock to indicate losing because of timer 3 sprites indicate the status of the NDS connection/pairing (Wi-Fi).
* 7 sprites in the project: 4 sprites are used to display the outcome of the game on the Game Over screen: (1) crown for the winner, each side (2) has their sprite, (1) clock to indicate losing because of timer; 3 sprites indicate the status of the NDS connection/pairing (Wi-Fi).

Wi-Fi:

Expand All @@ -171,12 +171,12 @@ Wi-Fi:
#### NDS improvements

* Implemented a bot/AI for single player mode that plays perfectly: using a minimax algorithm to find the best move + hard coded every first move response as it was to slow (~2 seconds) to compute.
* Added button debounce procedure (using timer) to avoid double trigger of NDS buttons.
* Modified WiFi_minilib: implemented Wi-Fi AP connection timeout (do not stuck the game if can’t connect to AP, still can play other game modes)
* Added button debounce procedure (using a timer) to avoid double trigger of NDS physical buttons.
* Modified WiFi_minilib: implemented Wi-Fi AP connection timeout (do not stuck the game if can’t connect to AP, can still play other game modes even after connection failure).
* If both players press START at the same time (in Wi-Fi mode) it will launch a conflict resolution process and still work as expected.
* Wi-Fi stack implementation stands very strongly against packet loss thanks to the ACK and Message Queue system.

**Note**: see code for more details!
**Note**: see source code for more details!

### Project structure

Expand All @@ -197,15 +197,15 @@ Here is the project structure:

* `art` - The folder with the [Aseprite](https://en.wikipedia.org/wiki/Aseprite) pixel "art" files for the game. There are 17 art files done entirely by me. Note that the colors in those files (and in `data`) might not be accurate as they are in fact redefined by the two color palettes in the game.
* `audio` - The music and sound effect files. I did not create those myself, but I found them on sites that reference public and free to use sounds.
* `data` - Arts exports to images, later processed by [GRIT](https://www.coranac.com/man/grit/html/grit.htm).
* `docs` - Contains images in this README.
* `data` - Arts export to images, later processed by [GRIT](https://www.coranac.com/man/grit/html/grit.htm).
* `docs` - Contains the images used in this README.
* `source` - The source code for the game. Follows a strict [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) code architecture.
* `controller` - Puts together the view and model and orchestrates the game's logic. It also contains the audio components.
* `controller` - Puts together the view and model, and orchestrates the game's logic. It also contains the audio components.
* `wifi` - Implementation of the fully custom Wi-Fi stack and protocols (P2P-BOP and Message Queue ACK system).
* `model` - [Bit Field Vector](https://en.wikipedia.org/wiki/Bit_array) modelling of the Tic-Tac-Toe game. It also contains the implementation of the bot/AI used in single player mode.
* `view` - Contains the screen/graphics components and sprites control.

**Note**: I wrote about 1900 lines of C code for this project in the `source` folder. This is without counting debugging time, artwork, system design, testing and documentation.
**Note**: I wrote close to 2000 lines of C code for this project in the `source` folder. This does not account for debugging time, artwork, system design, testing and documentation.

### Wi-Fi Connectivity Stack

Expand All @@ -225,10 +225,13 @@ Here is a simplified diagram of how it works:

<img src="docs/Message_Queue_FSM.png" alt="Message Queue FSM" width="700px">

Additionally the system will first check for the correct unique game identifier and match the sender and receiver of the packet before processing it.
Additionally the system will first check for the correct unique game identifier and match the sender and receiver IDs of the packet before processing it.
That allows for more than two simultaneous players on the same AP Wi-Fi network.

**Note**: if you want to further understand the implementation of this protocol, check the `source/controller/wifi/packet.c` file.
I also implemented a "simultaneous message action recovery mechanism" to fix the problem of two NDS sending the same message to each other at the same time and being stuck in a dead state.
Essentially the connection leader will keep its state and inform the other NDS to reset their state when it detects a simultaneous message event (conflict resolution process).

**Note**: if you want to further understand the implementation of those mechanisms, check the `source/controller/wifi/packet.c` file.

### Roadmap

Expand Down Expand Up @@ -261,5 +264,6 @@ That allows for more than two simultaneous players on the same AP Wi-Fi network.
- [X] Update presentation
- [X] Go back to 16 bits network identifiers
- [X] README full documentation + code structure + BOP protocol explain
- [X] Last full project review (code, README, presentation, game test)
- [ ] GitHub release (add to README)
- [ ] GitHub reorganize repo (project and others)
6 changes: 4 additions & 2 deletions project/tic-tac-tile/source/controller/wifi/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ PacketData receive_packet_data() {
data[2], // packet id
ID_FROM(data[3], data[4]), // sender
ID_FROM(data[5], data[6]), // receiver
data[7], // content type
data[8], // content arg
{ // Message
data[7], // content type
data[8], // content arg
},
};
}

Expand Down
2 changes: 1 addition & 1 deletion project/tic-tac-tile/source/controller/wifi/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ typedef struct {

#endif

#define EMPTY_QUEUE (Queue) {{0}, 0, 0};
#define EMPTY_QUEUE ((Queue) { { 0 }, 0, 0 })

// === Queue Interface ===

Expand Down

0 comments on commit 63c47c4

Please sign in to comment.