The HotWheels SDK indicators system provides real-time on-screen information display for movement tracking and feature status.
Overview
The indicators module (hacks/features/indicators/) implements:
- Velocity indicator with takeoff speed
- Color-coded velocity changes
- Optional fade effect based on speed
- Stamina indicator
- Keybind display
Architecture
The indicators system maintains state for each indicator type:
struct impl {
struct {
int last_vel = 0;
int tick_prev = 0;
int take_off = 0;
float take_off_time = 0.f;
bool last_on_ground = false;
} m_velocity_info;
struct {
int offset = 0;
} m_keybind_info;
void reset_data( );
void render( );
void velocity( );
void stamina( );
void keybinds( );
};
Source: hacks/features/indicators/indicators.h:5-23
Velocity Indicator
The velocity indicator shows current speed with color coding and optional takeoff speed:
Calculate Velocity
Get 2D velocity magnitude and round to integer
Track Takeoff
Detect ground-to-air transition and record takeoff speed
Apply Color Coding
Green for increasing, red for decreasing, orange for stable
Optional Fade
Apply alpha based on speed (0-310 units/sec)
Render Text
Display at screen center with current and takeoff speeds
Implementation
void indicators::impl::velocity( )
{
int corrected_velocity = static_cast< int >( ROUND_UP( g_ctx.local->velocity( ).length_2d( ) ) );
if ( m_velocity_info.last_on_ground && !g_ctx.local->flags( ).has( sdk::flags::ONGROUND ) ) {
m_velocity_info.take_off = corrected_velocity;
m_velocity_info.take_off_time = g_interfaces.globals->current_time + 2.f;
}
float text_alpha = g_config.find< bool >( HASH( "m_velocity_indicator_fade" ) )
? g_ctx.local->velocity( ).length_2d( ) >= 310.f ? 310.f : g_ctx.local->velocity( ).length_2d( ) / 310.f
: 1.f;
color velocity_color = corrected_velocity == m_velocity_info.last_vel ? color( 255, 199, 89, text_alpha * 255 )
: corrected_velocity < m_velocity_info.last_vel ? color( 255, 119, 119, text_alpha * 255 )
: color( 30, 255, 109, text_alpha * 255 );
const bool should_draw_pre =
( !g_ctx.local->flags( ).has( sdk::flags::ONGROUND ) || ( m_velocity_info.take_off_time > g_interfaces.globals->current_time ) );
const std::string str_pre = std::format( _("{}({})"), corrected_velocity, m_velocity_info.take_off ),
str = std::format( _("{}"), corrected_velocity );
g_render.render_text( g_ctx.screen_size.x / 2, g_ctx.screen_size.y / 2, font_alignment::AL_HORIZONTAL_CENTER, font_flags::FLAG_DROPSHADOW,
g_config.find< bool >( HASH( "m_velocity_indicator_show_pre" ) ) && should_draw_pre ? str_pre.c_str( ) : str.c_str( ),
g_fonts[ HASH( "indicator_verdana_font" ) ], velocity_color );
if ( m_velocity_info.tick_prev + 5 < g_interfaces.globals->tick_count ) {
m_velocity_info.last_vel = corrected_velocity;
m_velocity_info.tick_prev = g_interfaces.globals->tick_count;
}
m_velocity_info.last_on_ground = g_ctx.local->flags( ).has( sdk::flags::ONGROUND );
}
Source: hacks/features/indicators/indicators.cpp:28-60
Color Coding
The velocity indicator uses three colors to show speed changes:
color velocity_color = corrected_velocity == m_velocity_info.last_vel ? color( 255, 199, 89, text_alpha * 255 ) // Orange - No change
: corrected_velocity < m_velocity_info.last_vel ? color( 255, 119, 119, text_alpha * 255 ) // Red - Decreasing
: color( 30, 255, 109, text_alpha * 255 ); // Green - Increasing
Source: hacks/features/indicators/indicators.cpp:41-43
Velocity is sampled every 5 ticks to prevent excessive flickering from tick-to-tick variations.
Takeoff Speed Tracking
The system tracks when the player leaves the ground:
if ( m_velocity_info.last_on_ground && !g_ctx.local->flags( ).has( sdk::flags::ONGROUND ) ) {
m_velocity_info.take_off = corrected_velocity;
m_velocity_info.take_off_time = g_interfaces.globals->current_time + 2.f;
}
Source: hacks/features/indicators/indicators.cpp:32-35
The takeoff speed is displayed for:
- The entire duration of the jump
- 2 seconds after landing
const bool should_draw_pre = ( !g_ctx.local->flags( ).has( sdk::flags::ONGROUND ) ||
( m_velocity_info.take_off_time > g_interfaces.globals->current_time ) );
Source: hacks/features/indicators/indicators.cpp:44-45
Fade Effect
Optional alpha modulation based on velocity:
float text_alpha = g_config.find< bool >( HASH( "m_velocity_indicator_fade" ) )
? g_ctx.local->velocity( ).length_2d( ) >= 310.f ? 310.f : g_ctx.local->velocity( ).length_2d( ) / 310.f
: 1.f;
Source: hacks/features/indicators/indicators.cpp:37-39
The fade calculation:
- Velocity 0: Fully transparent (alpha = 0.0)
- Velocity 155: Half transparent (alpha = 0.5)
- Velocity 310+: Fully opaque (alpha = 1.0)
Fade effect caps at 310 units/sec to prevent over-brightness at high speeds.
The indicator uses C++20 std::format for string composition:
const std::string str_pre = std::format( _("{}({})"), corrected_velocity, m_velocity_info.take_off ),
str = std::format( _("{}"), corrected_velocity );
g_render.render_text( g_ctx.screen_size.x / 2, g_ctx.screen_size.y / 2,
font_alignment::AL_HORIZONTAL_CENTER,
font_flags::FLAG_DROPSHADOW,
g_config.find< bool >( HASH( "m_velocity_indicator_show_pre" ) ) && should_draw_pre ? str_pre.c_str( ) : str.c_str( ),
g_fonts[ HASH( "indicator_verdana_font" ) ],
velocity_color );
Source: hacks/features/indicators/indicators.cpp:47-52
- Standard:
285
- With takeoff:
285 (290) - Shows current speed and takeoff speed
Render Pipeline
The main render function coordinates all indicators:
void indicators::impl::render( )
{
if ( !g_interfaces.engine->is_fully_connected( ) || !g_ctx.local ) {
reset_data( );
return;
}
if ( g_config.find< bool >( HASH( "m_velocity_indicator" ) ) )
g_indicators.velocity( );
if ( g_config.find< bool >( HASH( "m_stamina_indicator" ) ) )
g_indicators.stamina( );
}
Source: hacks/features/indicators/indicators.cpp:14-26
Indicators automatically reset when disconnected or dead to prevent stale data.
State Management
The reset function clears all indicator state:
void indicators::impl::reset_data( )
{
m_velocity_info.last_vel = 0;
m_velocity_info.tick_prev = 0;
m_velocity_info.take_off = 0;
m_velocity_info.take_off_time = 0.f;
m_velocity_info.last_on_ground = false;
}
Source: hacks/features/indicators/indicators.cpp:5-12
Stamina Indicator
Placeholder for stamina tracking:
void indicators::impl::stamina( ) { }
Source: hacks/features/indicators/indicators.cpp:62
Stamina and keybinds indicators are not yet implemented.
Keybinds Display
Placeholder for active keybinds:
void indicators::impl::keybinds( ) { }
Source: hacks/features/indicators/indicators.cpp:64
Configuration Options
The indicators system supports several config options:
m_velocity_indicator - Enable/disable velocity display
m_velocity_indicator_fade - Enable fade based on speed
m_velocity_indicator_show_pre - Show takeoff speed in parentheses
m_stamina_indicator - Enable/disable stamina display
API Reference
render()
Main render function for all indicators. Call every frame.
velocity()
Renders the velocity indicator.
stamina()
Placeholder for stamina indicator.
keybinds()
Placeholder for keybind display.
reset_data()
Resets all indicator state. Called on disconnect/death.
Usage Example
// In your render callback
if ( g_ctx.local && g_ctx.local->is_alive( ) ) {
g_indicators.render( );
}
The velocity indicator renders at screen center by default. Ensure this doesn’t overlap with other UI elements.