Rhythm Game Prototype
Introduction
As part of my vocational training's final project, I embarked on developing a multiplayer online rhythm game. While the circumstances required scalling down the project, the resulting prototype showcases, technical skills in game development, audio programming, and project management.
Note: Due to school ownership of the project, source code and documentation cannot be disclosed unless officially published. This article focuses on the technical approach and learnings from the development process.
Project Overview
Why a Rhythm Game?
The choice of developing a rhythm game was delibate choice, as it combines multiple areas of interest and technical challenges:
- Practical application of audio programming knowledge
- Integration of musical elements with gameplay mechanics
- Opportunity to explore the challenges of a game developer
- Foundation for future exploration of game, graphics and audio programming
Key Features
The prototype successfully implements:
- Core gameplay mechanics similar to Groove Coaster
- Custom note event system using
MIDIJSON files - Precise audio-gameplay synchronization
- Scoring and note judgment system
- User interface with instructions
- Note object pooling for performance optimization
Here's a preview of the prototype:
Technical Decisions and Challenges
Choosing Godot Engine
The decision to use Godot Engine was driven by several factors:
- Resource efficiency, it works well in machines with limited RAM
- Recent improvements in Godot 4.0
- Open-source nature aligning with my personal preferences and allowing deep understanding of the tool
- Rapid prototyping capabilities
- String documentation and community support
While I Initally considered using frameworks like Raylib, project time constraints made Godot the practical choice for initial development.
Component Design
The game architecture takes advantage of Godot's node-based system, emphasizing modularity and maintainability:
- GameManager (Node2D)
- Acts as the central coordinator for all game systems
- Manages game state and interactions between other components
- Handles rhythm synchronization and audio playback
- Processes JSON data for song and note information
- AudioManager (Node)
- Manages audio playback
- Provides precise timing information for synchronization
- NoteManager (Node)
- Parses and manages note data from JSON files
- Controls the spawning and movement of note objects
- Processes notes based on current playback position
- BeatManager (Node)
- Synchronizes game events with the song's rhythm
- Emits signals for beats and measures
- HUDManager (Node)
- Updates the user interface elements
- Manages progress bars, beat indicators, and countdown displays
Data Flow and Processing
- Song data is loaded from JSON files, parsed by GameManager, and distributed to relevant components.
- AudioManager starts playback and continuously provides timing information.
- NoteManager processes notes based on the current time, spawning and moving note objects.
- BeatManager tracks the song's rhythm and emits beat/measure signals.
- GameManager processes player input and checks for note hits/misses.
- HUDManager updates the UI based on game state and player performance.
Overcoming Technical Hurdles
Audio Synchronization
One of the most critical challenges was achieving precise synchronization between audio and gameplay events. After studying various approaches:
- Initial Research
- Explored solutions from osu-framework and StepMania
- Investigated custom timing systems
- Final Implementation
- Leveraged Godot's built-in audio synchronization
- Solved the desynchronization over time problem
- Reduced timing variance from ~30ms to ~4ms
- Demonstrated the importance of understanding and utilizing engine capabilities effectively
MIDI Integration
One of the most significant challenges was working with MIDI files for note events. While Godot doesn't natively support MIDI, I explored various solutions:
- Initial Approach
- Studied MIDI file format specification
- Attempted custom MIDI parsing module development
- Practical Solution
- Implemented MIDI to JSON conversion as an interim solution
- Maintained project timeline while ensuring functionality
- Identified area for future improvement without compromising current development
Development Process
Project Management
Despite shifting to a solo project, professional development practices were maintained:
- Git version control for code management
- Trello board implementation using Kanban methodology
- Discord integration for automated progress tracking
- Regular documentation updates
This setup, while not fully utilized due to the project's shift to a solo effort, demonstrated foresight in project management and collaboration tools.
Technical Implementation Highlights
- Implemented object pooling for efficient note management
- Designed extensible systems for future feature addition
- Created modular components for easy testing and maintenance
- Utilized Godot's node system for clean architecture
Achievements and Learnings
Technical Accomplishments
- Successfully implemented core rhythm game mechanics
- Achieved precise audio synchronization
- Developed efficient note management system
- Created extensible architecture for future development
Personal Growth
- Enhanced problem-solving skills, particularly in dealing with complex file formats (MIDI)
- Improved ability to adapt to changing project requirements and scope
- Gained experience in rapid prototyping and prioritizing features under time constraints
- Improved technical documentation skills
- Developed debugging and optimization techniques
- Gained valuable experience working with game engines
Future Directions
- Core Features
- Custom MIDI parsing system implementation
- Enhanced visual feedback system
- Multiplayer functionality integration
- Technical Improvements
- Custom level editor development
- Performance optimization for larger song libraries
- Additional gameplay mechanics implementation
Conclusion
This project, despite its challenges, has been a significant learning experience. It has not only improved my technical skills in game development but also the ability to make informed decisions about tools and architecture, enhanced my ability to manage complex projects, adapt to unforeseen circumstances, and find creative solutions to technical challenges.
The resulting prototype, while not the originally envisioned multiplayer game, serves as a solid foundation for future development and is a proof of my resilience as I managed to create something albeit of the major setbacks that the project had been through.