Manual: BulletHell (Bullet Hell) Example Project

This tutorial will explain the overall structure and implementation mechanisms of the bullet hell system example game BulletHellSample.


◆ Game Overview

This is a game where the player defeats a Boss with 500 HP that fires bullet patterns using shooting and bombs. Since this is a sample project, the game ends immediately after the Boss is defeated.

Controls

  • Arrow keys: Move
  • Z key: Shoot
  • X key: Bomb

Common bullet hell mechanics such as Graze and Bomb Bullet Clearance are implemented.


Game Scene Structure

The game uses only one scene: test_scene.tscn. There is no scene switching.


Object Structure

Player

player.tscn is the scene for the player character.

Its child nodes include:

  • GrazeObject.tscn: Used for graze detection
  • player_hit_checker.tscn: Used for hit detection

Enemy

enemy.tscn is the scene for the enemy (Boss).

Its child nodes include:

  • damage_checker.tscn: Used for hit detection

Implementation Details of Each Feature

Enemy Bullet Patterns

The enemy uses a simple implementation: firing bullet patterns at fixed time intervals.

The bullet patterns include:

  1. Accelerating omnidirectional bullets
  2. Shotgun-style patterns combined with enemy movement
  3. Splitting bullets fired from the stage edges, targeting the player
  4. Flower-shaped patterns composed of omnidirectional bullets
  5. Simple geometric shapes drawn using homing bullets

Since bullet patterns require repeated sound effects, AnimationPlayer nodes trigger AudioStreamPlayer to play sounds.

Currently, due to the lack of suitable sound assets, this implementation is used. Ideally, each bullet pattern should have its own dedicated sound effect, played directly when the pattern is fired.

  • The current bullet system lacks a stop mechanism. Therefore, even after the enemy is defeated, already-generated bullet patterns continue firing. This issue is planned to be resolved in future updates by adding a bullet pattern stop feature. For now, it can be avoided by avoiding repeated processing and instead splitting states and manually implementing loop logic.

Player Standard Shooting Patterns

The player simultaneously fires four different bullet patterns within the same state.

Currently, rapid-fire bullet patterns cannot directly specify firing direction. Therefore, direction is simulated by firing toward very distant global coordinates.

  • Future updates plan to support direct direction specification for firing.

Graze Handling

Graze functionality is implemented by attaching GrazeObject.tscn as a child node of the player.

This object has a collision area larger than the player’s hit detection area. When it contacts enemy bullets:

  • Plays graze particle effects
  • Increases score

Damage Handling

Both player and enemy damage handling are implemented via separate child objects.

The main reasons are:

  1. Avoid interrupting the currently executing state due to damage
  2. Clearly distinguish between graze detection and hit detection
  • In ACTION GAME MAKER, HitArea2D detects collisions for all HitArea nodes under the root node, including child nodes. This issue can be avoided by generating the object as a child object rather than a child node. However, for easier visual confirmation of detection positions, this example uses child nodes.

Bullet Layer Structure

Layer settings are as follows:

  • Player: Layer 1
  • Enemy: Layer 2
  • Graze Detection: Layer 3

Bullet layers:

  • Enemy Bullets: Layers 1, 3
  • Player Bullets: Layer 2

Bomb Implementation

Bombs are not implemented as part of the bullet system but as regular projectiles.

bomb.tscn is the scene for bombs.

Features:

  • Sets a collision area covering the entire screen

  • Clears hit bullets

  • Converts cleared bullets into score items with a 10% probability

  • Simultaneously deals damage to the enemy

  • Converting bullets into score items involves object instantiation, which is a relatively heavy operation. Setting the conversion probability to 100% would cause performance degradation. Optimization solutions for this issue are under separate investigation.


Score Items

To reduce performance overhead from object instantiation, score items are implemented using GDScript.

  • Scene: score_test.tscn
  • Behavior:
    • Moves toward the player
    • Disappears when close enough
    • Modifies specified variable values

The following parameters can be customized in the Score node’s Inspector:

  • PickUpRadius: Pickup detection distance
  • PullSpeed: Movement speed
  • Group: Target group to approach
  • Project Variable: Name of the project variable to modify
  • Variable Add: Value to add