Skip to content

Call onComplete if _sound is null #3614

Open

Description

@SimonArs

If _sound is null then return is simply called

function startSound(st:Float):Void {
	if (_sound == null) return;

	_time = st;
	_paused = false;
	_channel = _sound.play(_time, 0, _transform);

	if(_channel != null) {
		pitch = _pitch;
		_channel.addEventListener(Event.SOUND_COMPLETE, stopped);
		active = true;
	} else exists = active = false;
}

Because of this some necessary functions aren't called
I suggest just calling these functions and I think it will be enough

if (_sound == null) {
	if (onComplete != null) onComplete();
	cleanup(autoDestroy);
	return;
}

Activity

  1. Geokureli commented on Jun 11, 2026

    @Geokureli
    Member

    Can I get a practical code example that illustrates the issue with the old code? also can you link to the code lines you're trying to change?

  2. SimonArs commented on Jun 11, 2026

    @SimonArs
    ContributorAuthor

    Can I get a practical code example that illustrates the issue with the old code? also can you link to the code lines you're trying to change?

    Yes, right here
    https://github.com/HaxeFlixel/flixel/blob/dev/flixel/sound/FlxSound.hx#L769-L790

    Imagine situation when at end of a certain sound we need to switch to another state for example:

    import flixel.FlxG;
    import flixel.FlxState;
    
    class TestStateA extends FlxState
    {
    	override function create():Void {
    		FlxG.camera.bgColor = 0xFF81FFA4;
    		super.create();
    	}
    
    	override function update(elapsed:Float):Void {
    		if (FlxG.keys.justPressed.ENTER)
    			FlxG.sound.play(null, 1, false, null, true, () -> FlxG.switchState(TestStateB.new));
    
    		super.update(elapsed);
    	}
    }
    
    class TestStateB extends FlxState
    {
    	override function create():Void {
    		FlxG.camera.bgColor = 0xFFFF8181;
    		super.create();
    	}
    }

    And if sound is null for some reason, nothing will happen and onComplete isnt called, so I think it'd be better to add

    if (_sound == null) {
    	if (onComplete != null) onComplete();
    	cleanup(autoDestroy);
    	return;
    }

    in startSound function if sound is null

  3. Geokureli commented on Jun 12, 2026

    @Geokureli
    Member

    In the above case I would rather FlxG.sound.play throw an error saying you're trying to play a null sound, rather than silently continuing and assuming this is something the dev wanted to happen

  4. SimonArs commented on Jun 12, 2026

    @SimonArs
    ContributorAuthor

    Well I agree here too but in this case you'll have to rewrite a lot. Is it possible to regulate this somehow, like if the developer wants onComplete to be called even if there's no sound? Of course, you can do something like that

    FlxG.sound.play(null, 1, false, null, true, () -> FlxG.switchState(TestStateB.new)) ?? FlxG.switchState(TestStateB.new);

    But for me itsa waste of time
    Well I leave decision to you

  5. Geokureli commented on Jun 12, 2026

    @Geokureli
    Member

    Can you tell me more about the actual case you came across that needed this change?

  6. SimonArs commented on Jun 12, 2026

    @SimonArs
    ContributorAuthor

    I made Easter eggs in Main Menu of my game, and when you click on certain object, sound is played and at end of sound, transition to PlayState occurs

    if(controls.inputCheck(smnk, JUST_RELEASED))
    	secret('freedom_dive', 'tag_simona');
    
    if(controls.inputCheck(cup, JUST_RELEASED))
    	secret('sosatbl', 'cup');
    
    function secret(n:String, s:String):Void {
    	secretT = 0;
    	selSmth = doSecret = true; //blockers
    	secretName = n;
    	secretSound = s;
    }
    
    //update
    if(doSecret) {
    	secretT += elapsed;
    	final trans:Float = Math.min(secretT / 0.6, 1);
    
    	if(Fei.prf.musicVol != 0) {
    		FlxG.sound.music.volume = FlxMath.lerp(Fei.prf.musicVol, 0, trans);
    		FlxG.sound.music.pitch = FlxMath.lerp(1, 9, trans);
    	}
    
    	if(trans >= 1) {
    		doSecret = false;
    
    		FlxG.sound.play(Paths.sound('sounds/$secretSound'), Fei.prf.soundVol, false, null, true, () -> {
    			PlayState.SONG = backend.Song.loadSong(secretName, 3);
    			PlayState.isStoryMode = false;
    			PlayState.storyDifficulty = 3;
    			new Loading().load();
    		});
    	}
    }

    And when I was testing builds by deleting assets and checking game's operation (so that it didn't break down due to lack of pictures, sounds) and when I clicked on items in the menu, game just stopped and because of this, menu hung because input blockers were triggered and only restarting helped
    And thats why I created issue

  7. Geokureli commented on Jun 12, 2026

    @Geokureli
    Member

    Did flixel warn that you tried to load/play a missing sound?

  8. SimonArs commented on Jun 12, 2026

    @SimonArs
    ContributorAuthor

    Yes of course

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions