Welcome Contributors!
Thank you for your interest in contributing to BeeHex! This guide will help you get started with contributing code, reporting issues, and improving documentation.
Getting Started
Set Up Development Environment
Explore the Codebase
Familiarize yourself with:
Project structure in src/app/ and src/components/
TypeScript interfaces in src/app/definitions.ts
WebSocket handling in src/app/game_mode/WebsocketHandler.ts
Find an Issue
Look for issues labeled:
good first issue - Great for newcomers
help wanted - Need community assistance
bug - Bug fixes needed
enhancement - New features
Start Contributing
Follow the workflow below to make your contribution.
Development Workflow
1. Fork and Clone
Fork the Repository
Click the Fork button on GitHub to create your copy of BeeHex.
Clone Your Fork
git clone https://github.com/YOUR_USERNAME/beehex_v2.git
cd beehex_v2
Add Upstream Remote
git remote add upstream https://github.com/ORIGINAL_OWNER/beehex_v2.git
2. Create a Branch
Create a descriptive branch name:
# For new features
git checkout -b feature/add-game-timer
3. Make Changes
Write clean, well-documented code:
// Good: Clear function with JSDoc comment
/**
* Validates a move on the Hex board
* @param x - X coordinate (0 to boardSize-1)
* @param y - Y coordinate (0 to boardSize-1)
* @param grid - Current game grid state
* @returns true if move is valid, false otherwise
*/
function validateMove ( x : number , y : number , grid : number [][]) : boolean {
// Check bounds
if ( x < 0 || y < 0 || x >= grid . length || y >= grid [ 0 ]. length ) {
return false ;
}
// Check if cell is empty
return grid [ y ][ x ] === 0 ;
}
4. Follow Code Standards
TypeScript Style Guide
BeeHex uses TypeScript with strict mode. Always define proper types!
// ✅ Good: Proper typing
interface GameState {
gameId : string ;
board : number [][];
currentPlayer : number ;
status : GameStatus ;
}
function updateGameState ( state : GameState ) : GameState {
return { ... state , currentPlayer: state . currentPlayer === 1 ? 2 : 1 };
}
// ❌ Bad: Using any
function updateGameState ( state : any ) : any {
return { ... state , currentPlayer: state . currentPlayer === 1 ? 2 : 1 };
}
React Component Best Practices
// ✅ Good: Functional component with proper types
import React from 'react' ;
interface GameBoardProps {
size : number ;
onCellClick : ( x : number , y : number ) => void ;
grid : number [][];
}
export default function GameBoard ({ size , onCellClick , grid } : GameBoardProps ) {
return (
< div className = "game-board" >
{ /* Component implementation */ }
</ div >
);
}
// ❌ Bad: No prop types
export default function GameBoard ( props ) {
return < div >{ /* Implementation */ } </ div > ;
}
Code Organization
Components : One component per file in src/components/
Pages : Use Next.js App Router structure in src/app/
Types : Define shared types in src/app/definitions.ts
Utilities : Helper functions in separate utility files
5. Test Your Changes
Run the Development Server
Check TypeScript
# Verify no type errors
npx tsc --noEmit
Test Different Scenarios
Test on different browsers (Chrome, Firefox, Safari)
Test different board sizes (5x5, 7x7, 9x9)
Test online and offline modes
Verify WebSocket reconnection handling
Build for Production
Ensure the build completes without errors.
6. Commit Your Changes
Follow conventional commit standards:
Feature
Bugfix
Documentation
Refactor
Style
git commit -m "feat: add game timer with countdown display"
Commit Message Guidelines
Type : feat, fix, docs, style, refactor, test, chore
Subject : Short description (max 72 characters)
Body (optional): Detailed explanation
Footer (optional): Breaking changes, issue references
Example:
feat: add move history replay feature
Implements a replay system that allows users to step through
previous moves in completed games. Adds navigation controls
and updates the board state for each move.
Closes #123
7. Push and Create Pull Request
Push Your Branch
git push origin feature/your-feature-name
Create Pull Request
Go to your fork on GitHub
Click “Compare & pull request”
Fill out the PR template (see below)
Click “Create pull request”
Pull Request Template
## Description
Brief description of what this PR does.
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Testing
Describe the tests you ran:
- [ ] Tested on Chrome, Firefox, Safari
- [ ] Tested different board sizes
- [ ] Tested online multiplayer
- [ ] Tested offline mode
- [ ] Verified no TypeScript errors
- [ ] Ran linter
## Screenshots (if applicable)
Add screenshots to demonstrate visual changes.
## Related Issues
Closes #issue_number
## Additional Notes
Any additional information reviewers should know.
Code Review Process
After submitting your PR:
Automated Checks : CI/CD runs linter and builds
Code Review : Maintainers review your code
Feedback : Address any requested changes
Approval : PR is approved by maintainers
Merge : Your contribution is merged!
Be patient and responsive to feedback. Reviews may take a few days.
Contribution Areas
🐛 Bug Fixes
Found a bug? Great!
Check Existing Issues
Search GitHub issues to see if it’s already reported.
Create Bug Report
If not reported, create a detailed issue:
Title : Clear, descriptive title
Description : What happened vs. what should happen
Steps to Reproduce : Detailed steps
Environment : Browser, OS, Node.js version
Screenshots : Visual evidence if applicable
Fix the Bug
Follow the workflow above to create a fix.
✨ New Features
Want to add a feature?
Discuss First : Open an issue to discuss the feature before implementing
Get Approval : Wait for maintainer feedback
Implement : Follow the development workflow
Document : Update documentation for your feature
📚 Documentation
Improve or add documentation:
Fix typos and grammatical errors
Add code examples
Improve existing explanations
Add new guides or tutorials
Update outdated information
🎨 UI/UX Improvements
Improve component styling
Enhance responsive design
Add animations and transitions
Improve accessibility (WCAG compliance)
Better color contrast and themes
Reduce bundle size
Optimize component rendering
Improve WebSocket efficiency
Add caching strategies
Optimize images and assets
Project Architecture
Key Files and Directories
definitions.ts src/app/definitions.tsCore TypeScript interfaces and enums for game logic, packets, and state management.
WebsocketHandler.ts src/app/game_mode/WebsocketHandler.tsWebSocket client for real-time communication with game server.
layout.tsx src/app/layout.tsxRoot layout component with metadata and global styles.
env.ts src/env/env.tsEnvironment configuration (gitignored).
Technology Stack
Technology Version Purpose Next.js 14.2.20 React framework with App Router React 18.x UI library TypeScript 5.x Type safety Styled Components 6.1.13 CSS-in-JS styling Socket.IO Client 4.7.5 Real-time communication ECharts 5.6.0 Data visualization Axios 1.7.2 HTTP client SweetAlert 2.1.2 Modal dialogs
WebSocket Protocol
BeeHex uses custom WebSocket packets defined in definitions.ts:
Client-Bound Packets (Server → Client)
enum ClientBoundPacketType {
ERROR_MESSAGE = 0 , // Error notifications
GAME_SEARCH = 1 , // Game search status
GAME_FOUND = 2 , // Game found notification
JOIN_GAME = 3 , // Join game with initial state
MOVE_PLAYED = 4 , // Move update
GAME_END = 5 // Game end with result
}
Server-Bound Packets (Client → Server)
enum ServerBoundPacketType {
GAME_SEARCH = 0 , // Start searching for game
CANCEL_GAME_SEARCH = 1 , // Cancel search
JOIN_GAME = 2 , // Join specific game
JOIN_ROOM = 3 , // Join room
PLAY_MOVE = 4 , // Play a move
FORFEIT_GAME = 5 // Forfeit the game
}
Game State Management
interface Game {
game_id : string ;
game_parameters : GameParameters ;
grid : Array < Array < number >>; // 0 = empty, 1 = player1, 2 = player2
first_player_id : string ;
second_player_id : string ;
turn : number ; // Current turn number
}
interface GameParameters {
ranked : boolean ; // Is this a ranked game?
board_size : number ; // 5, 7, or 9
time_limit : number ; // Time limit in seconds (0 = unlimited)
}
Common Tasks
Adding a New Component
Create Component Directory
mkdir src/components/my_component
Create Component Files
src/components/my_component/my_component.tsx
import React from 'react' ;
import styles from './my_component.module.css' ;
interface MyComponentProps {
title : string ;
onClick ?: () => void ;
}
export default function MyComponent ({ title , onClick } : MyComponentProps ) {
return (
< div className = {styles. container } onClick = { onClick } >
< h2 >{ title } </ h2 >
</ div >
);
}
src/components/my_component/my_component.module.css
.container {
padding : 1 rem ;
background : #f5f5f5 ;
border-radius : 8 px ;
}
.container:hover {
background : #e0e0e0 ;
}
Use Component
import MyComponent from '@/components/my_component/my_component' ;
export default function Home () {
return (
< MyComponent
title = "Hello BeeHex"
onClick = {() => console.log( 'Clicked!' )}
/>
);
}
Adding a New Page Route
Create Page Component
src/app/new_page/page.tsx
import type { Metadata } from 'next' ;
export const metadata : Metadata = {
title: 'New Page - BeeHex' ,
description: 'Description of the new page' ,
};
export default function NewPage () {
return (
< div >
< h1 > New Page </ h1 >
< p > Content goes here </ p >
</ div >
);
}
Add Styling
src/app/new_page/page.module.css
.container {
max-width : 1200 px ;
margin : 0 auto ;
padding : 2 rem ;
}
Handling WebSocket Events
import { WebsocketHandler } from '@/app/game_mode/WebsocketHandler' ;
import * as packets from '@/app/definitions' ;
// Create WebSocket handler with callbacks
const ws = new WebsocketHandler ({
errorCallback : ( message ) => {
console . error ( 'Error:' , message );
// Show error to user
},
gameSearchCallback : ( params , playerCount , eloRange ) => {
console . log ( `Searching: ${ playerCount } players` );
// Update UI with search status
},
gameFoundCallback : ( gameId ) => {
console . log ( 'Game found:' , gameId );
// Navigate to game page
},
joinGameCallback : ( game ) => {
console . log ( 'Joined game:' , game );
// Initialize game board
},
movePlayedCallback : ( x , y , turn , grid ) => {
console . log ( `Move played at ( ${ x } , ${ y } )` );
// Update game board
},
connectionEndedCallback : () => {
console . log ( 'Connection lost' );
// Show reconnection UI
}
});
// Send packet to server
const searchPacket : packets . ServerBoundGameSearchPacket = {
type: packets . ServerBoundPacketType . GAME_SEARCH ,
game_parameters: {
ranked: true ,
board_size: 7 ,
time_limit: 0
}
};
ws . sendPacket ( searchPacket );
Style Guide
Component Structure
// 1. Imports
import React , { useState , useEffect } from 'react' ;
import styles from './component.module.css' ;
import { Game } from '@/app/definitions' ;
// 2. Interface definitions
interface ComponentProps {
game : Game ;
onMove : ( x : number , y : number ) => void ;
}
// 3. Component definition
export default function Component ({ game , onMove } : ComponentProps ) {
// 4. State and hooks
const [ selectedCell , setSelectedCell ] = useState <[ number , number ] | null >( null );
// 5. Effects
useEffect (() => {
// Effect logic
}, [ game ]);
// 6. Event handlers
const handleCellClick = ( x : number , y : number ) => {
setSelectedCell ([ x , y ]);
onMove ( x , y );
};
// 7. Render
return (
< div className = {styles. container } >
{ /* JSX */ }
</ div >
);
}
Naming Conventions
Components : PascalCase (GameBoard, PlayerCard)
Files : snake_case for directories, PascalCase for React components
Functions : camelCase (handleMove, validateInput)
Constants : UPPER_SNAKE_CASE (BOARD_SIZES, TIME_LIMITS)
Types/Interfaces : PascalCase (GameState, PlayerInfo)
Getting Help
Need assistance?
GitHub Issues : Ask questions in issues
Discussions : Use GitHub Discussions for general questions
Documentation : Check technical documentation
Code Examples : Look at existing components for patterns
Recognition
Contributors are recognized in:
GitHub contributors page
Project README
Release notes for significant contributions
Thank you for contributing to BeeHex! 🐝
Next Steps
Setup Guide Set up your development environment
Architecture Overview Understand the system architecture
Deployment Learn about deployment processes
WebSocket Protocol Explore the WebSocket communication protocol