Skip to main content

Overview

The ProjectM mode is specifically designed for Project M and Project+ with coordinates optimized for their physics engines. It features wider analog stick ranges (28-228 vs 48-208), adjusted modifier values, and a configurable Z-button behavior.

Constructor

ProjectM()
Creates a new ProjectM mode instance with default settings.
return
ProjectM
A new mode instance ready for configuration

Configuration

SetConfig

void SetConfig(GameModeConfig &config, const ProjectMOptions options)
Configures the mode with game-specific settings and options.
config
GameModeConfig&
required
Base configuration including SOCD pairs and button remapping
options
ProjectMOptions
required
Project M-specific configuration options

ProjectMOptions

The ProjectMOptions struct configures mode-specific behavior:
true_z_press
bool
default:"false"
When true, RF3 sends true Z (R button). When false, RF3 sends lightshield + A macro (except when Mod X is held).
disable_ledgedash_socd_override
bool
default:"false"
Disable horizontal SOCD override for ledgedash maximum jump trajectory
has_custom_airdodge
bool
default:"false"
Enable custom airdodge angle instead of default (82, 35)
custom_airdodge.x
uint8_t
Custom X-axis coordinate for MX + diagonal + R (0-100)
custom_airdodge.y
uint8_t
Custom Y-axis coordinate for MX + diagonal + R (0-100)

Button Layout

Digital Outputs

Action Buttons

  • A: RT1 (or RT1 + RF3 if Z macro enabled)
  • B: RF1
  • X: RF2
  • Y: RF6
  • L: LF4 (or Nunchuk Z when connected)
  • R: RF5 (or RF3 if true_z_press enabled)
  • Z: RF3 (behavior depends on configuration)
  • Start: MB1
  • D-Up: RF8 (or via MX+MY layer)
RF3 behavior is configurable:
  • true_z_press = false (default): Lightshield (49) + A button macro
  • true_z_press = true: True Z press (R button)
  • With Mod X held: Always sends true Z regardless of setting

Directional Inputs

Movement

  • Left: LF3
  • Right: LF1
  • Down: LF2
  • Up: RF4

C-Stick

  • C-Left: RT3
  • C-Right: RT5
  • C-Down: RT2
  • C-Up: RT4

Modifiers

Modifier Buttons

  • Mod X: LT1
  • Mod Y: LT2
  • Lightshield: RF7 (49 analog)

D-Pad Layer

Activate by holding Mod X + Mod Y or Nunchuk C:
  • D-Up: RT4 (also available as RF8 standalone)
  • D-Down: RT2
  • D-Left: RT3 (or MB3)
  • D-Right: RT5 (or MB2)
When the D-Pad layer is active, C-stick inputs are disabled.

Analog Stick Range

Extended Range

Project M uses wider analog stick ranges than Melee:
  • Minimum: 28 (vs 48 in Melee)
  • Neutral: 128 (same)
  • Maximum: 228 (vs 208 in Melee)
This provides 100 units of travel in each direction, matching PM/P+ expectations.

Modifier Coordinates

Mod X (LT1)

InputCoordinatesOffsetUsage
MX + Left/Right128 ± 7070Horizontal tilt
MX + Up/Down128 ± 6060Vertical positioning

Mod Y (LT2)

InputCoordinatesOffsetUsage
MY + Left/Right128 ± 3535Slow walk
MY + Up/Down128 ± 7070High vertical

Default Coordinates

No Modifiers

InputCoordinatesOffsetUsage
Cardinal128 ± 100100Full range
Q1/Q2 Diagonal(83, 93)83, 93Upper quadrants

Special Features

SOCD Configuration

ProjectM requires 2IP No Reactivation for all directional pairs:
  • Left/Right (LF3/LF1)
  • Down/Up (LF2/RF4)
  • C-Left/C-Right (RT3/RT5)
  • C-Down/C-Up (RT2/RT4)

Z-Button Macro System

The Z-button (RF3) has flexible behavior:
When true_z_press = false:
  • Sends A button + lightshield (49 analog) simultaneously
  • Useful for Z-canceling and lightshield techniques
  • Override: Hold Mod X to send true Z instead

Ledgedash SOCD Override

When horizontal SOCD is detected and:
  • No vertical direction is held
  • No shield button is pressed (LF4 or RF7)
  • disable_ledgedash_socd_override is false
Then X coordinate is set to 128 ± 100 for maximum ledgedash trajectory.

C-Stick ASDI Slideoff

With C-Left/Right + C-Down (but not C-Up + C-Left/Right):
  • Coordinates: (35, 98) = 3000, 9875
  • Optimized for PM/P+ slideoff mechanics
  • Preserves C-stick nair possibility with up+horizontal

D-Pad Up Standalone

Unique to ProjectM: RF8 always maps to D-Pad Up, even outside the MX+MY layer. This is combined with any existing D-Pad Up input from the layer.

Nunchuk Support

When a Wii Nunchuk is connected:
  • Z button → L trigger
  • C button → D-Pad layer activation
  • Analog stick → Overrides left stick completely

Example Usage

#include "modes/ProjectM.hpp"

// Create mode instance
ProjectM pm_mode;

// Configure with options
GameModeConfig config = {
    .mode_id = MODE_PROJECT_M,
    .socd_pairs_count = 4,
    .socd_pairs = {
        SocdPair { .button_dir1 = BTN_LF3, .button_dir2 = BTN_LF1, .socd_type = SOCD_2IP_NO_REAC },
        SocdPair { .button_dir1 = BTN_LF2, .button_dir2 = BTN_RF4, .socd_type = SOCD_2IP_NO_REAC },
        SocdPair { .button_dir1 = BTN_RT3, .button_dir2 = BTN_RT5, .socd_type = SOCD_2IP_NO_REAC },
        SocdPair { .button_dir1 = BTN_RT2, .button_dir2 = BTN_RT4, .socd_type = SOCD_2IP_NO_REAC },
    },
};

ProjectMOptions options = {
    .true_z_press = false,  // Use lightshield + A macro
    .disable_ledgedash_socd_override = false,
    .has_custom_airdodge = true,
    .custom_airdodge = { .x = 80, .y = 40 }
};

pm_mode.SetConfig(config, options);

Differences from Melee Modes

Key Differences

FeatureProjectMMelee20Button
Analog range28-228 (±100)48-208 (±80)
Z-buttonConfigurable macroDirect Z
D-Up buttonRF8 standaloneVia layer only
Default diagonal(83, 93) Q1/Q2(56, 56) all
MX horizontal±70±53
MY vertical±70±59

Source Code

  • Header: include/modes/ProjectM.hpp
  • Implementation: src/modes/ProjectM.cpp

Build docs developers (and LLMs) love