ARRRType is an open source typing trainer, made by pirates for pirates
. It will help you improve your typing speed and accuracy while embarking on a swashbuckling adventure.
Practice your typing skills against computer opponents, challenge other players, and track your progress with detailed statistics.
A live version is currently at https://arrrtype.com.
- Campaign Mode: Battle through progressive levels against computer opponents with increasing difficulty
- Training Modes:
- Regular training against computer opponents
- Single word practice
- Custom text practice
- Learn from your mistakes with targeted practice
- Multiplayer: Challenge other players in real-time typing battles
- Detailed Statistics:
- Track your WPM (Words Per Minute)
- Monitor accuracy
- View typing consistency
- Analyze problem characters with heatmaps
- Identify slow words and mistypes
- Customization:
- Choose your avatar
- Select your flag
- Adjust opponent difficulty
- Toggle forced correction mode
- Customize text length
- Node.js (v14.17.0 or higher, download at https://nodejs.org/)
- npm (Node Package Manager)
- Git (see installation instructions)
- A Supabase account (see below) or, alternatively, Supabase CLI / Docker for local deployment (not tested)
- Clone the Repository
git clone https://github.com/omegarhovega/ARRRType.git
cd ARRRType- Install Dependencies
npm install- Supabase Setup
a. Create a new Supabase project:
- Go to Supabase
- Sign up/Login and create a new project
- Note down your project URL and anon key
b. Set up the required tables in Supabase by pasting the below code into the Supabase SQL console and running it:
-- Create profiles table
CREATE TABLE profiles (
id UUID PRIMARY KEY REFERENCES auth.users(id),
coins INTEGER DEFAULT 0,
last_unlocked_level INTEGER DEFAULT 1,
games_played INTEGER DEFAULT 0,
time_played INTEGER DEFAULT 0,
last_round_wpm INTEGER[],
last_round_gross_wpm INTEGER[],
wpm_buckets INTEGER[],
accuracy_buckets INTEGER[],
"100_slow_words" JSONB,
"last_slow_words" JSONB
);
-- Create user_stats table
CREATE TABLE user_stats (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES auth.users(id),
wpm INTEGER,
grossWPM INTEGER,
accuracy FLOAT,
wpmPerSecond INTEGER[],
grossWpmPerSecond INTEGER[],
created_at TIMESTAMPTZ DEFAULT NOW(),
errors JSONB,
totalOccurrences JSONB,
mistakesMade JSONB,
consistency FLOAT
);
-- Create texts table
CREATE TABLE texts (
id SERIAL PRIMARY KEY,
text TEXT NOT NULL
);
-- Create words table
CREATE TABLE words (
id SERIAL PRIMARY KEY,
"3_letters" TEXT NOT NULL
);
-- Create games table
CREATE TABLE games (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
text_id INTEGER REFERENCES texts(id),
start_time TIMESTAMPTZ,
players UUID[],
finishing_times JSONB,
heartbeat JSONB
);
-- Create total_games table
CREATE TABLE total_games (
id SERIAL PRIMARY KEY,
total_time BIGINT DEFAULT 0,
total_count INTEGER DEFAULT 0,
wpmbuckets INTEGER[],
accuracybuckets INTEGER[],
grosswpmbuckets INTEGER[]
);c. Set up the required functions in Supabase by pasting the below code into the Supabase SQL console and running it:
-- Create update_heartbeat function
CREATE OR REPLACE FUNCTION update_heartbeat(game_id UUID, user_id UUID)
RETURNS VOID AS $$
DECLARE
current_heartbeat JSONB;
curr_timestamp TIMESTAMPTZ;
BEGIN
-- Get current timestamp
curr_timestamp := NOW();
-- Get current heartbeat data
SELECT heartbeat INTO current_heartbeat FROM games WHERE id = game_id;
-- If heartbeat is null, initialize it as an empty array
IF current_heartbeat IS NULL THEN
current_heartbeat := '[]'::JSONB;
END IF;
-- Remove old entry for this user if it exists
current_heartbeat := current_heartbeat - (
SELECT ordinality - 1
FROM jsonb_array_elements(current_heartbeat) WITH ORDINALITY
WHERE (value->>'user_id')::UUID = user_id
);
-- Add new heartbeat entry
current_heartbeat := current_heartbeat || jsonb_build_array(
jsonb_build_object(
'user_id', user_id,
'timestamp', curr_timestamp
)
);
-- Update the games table
UPDATE games
SET heartbeat = current_heartbeat
WHERE id = game_id;
END;
$$ LANGUAGE plpgsql;Please note that the security settings for the Supabase tables in production need to be set to your requirements.
d. (Optional and not tested) If you want to run the application locally, without linking to an online Supabase account, you need to install the Supabase CLI and Docker. Follow these instructions for Supabase local deployment. Note that this will require additional modifications to include the local server address when you run the application.
- Database Population
You can populate the database with sample texts and words using the provided CSV files:
-
Import words_rows.csv:
- Navigate to your Supabase project dashboard
- Go to Table Editor > words
- Click on "Insert" dropdown and select "Import data from CSV"
- Upload the
words_rows.csvfile - The importer should correctly match to the '3_letters' column automatically
- Click "Import Data"
-
Import texts_rows.csv:
- Navigate to Table Editor > texts
- Click on "Insert" dropdown and select "Import data from CSV"
- Upload the
texts_rows.csvfile - The importer should correctly match to the 'text' column automatically
- Click "Import Data"
- The CSV files are located in the
/table datadirectory of the project words_rows.csv: Contains sample words for typing exercisestexts_rows.csv: Contains sample texts for typing challenges
You can of course add to/change/replace the content to your liking.
Note: If you encounter any encoding issues during import, ensure your CSV files are UTF-8 encoded.
- Environment Setup
Rename the env.example file in the root directory to .env:
VITE_APP_SUPABASE_URL=your_supabase_project_url
VITE_APP_SUPABASE_ANON_KEY=your_supabase_anon_keyReplace "your_supabase_project_url" and "your_supabase_anon_key" with your Supabase project url and your Supabase anonymous key, respectively.
- Run the Development Server
npm run devPaste the local url shown into your browser to run the application.
- Building for Production
npm run build- Testing
npm run test:unitCommon issues and solutions:
-
Database Connection Issues
- Verify your environment variables are correct
- Check if your IP is allowlisted in Supabase
- Ensure your database tables are properly set up
-
Build Errors
- Clear your node_modules and package-lock.json
- Run
npm installagain - Ensure you're using a compatible Node.js version
-
Authentication Issues
- Check your Supabase authentication settings
- Verify your API keys and URLs
- Clear local storage and try again
- Fork the repository
- Create a new branch for your feature
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the GNU General Public License v3.0 (GPL-3.0).
The full license text can be found in the LICENSE file in the repository.
For more details about the GPL-3.0 license, visit: https://www.gnu.org/licenses/gpl-3.0.en.html
For support, please create an issue in the GitHub repository.
Start your typing adventure today and become the fastest typist in the seven seas! 🌊