If I call a function from within itself, will it return to its original place when the recursive call is finished?

I have a turn based game system where after calling the NextTurn function, the current unit is deactivated and the next unit in the initiative order is made active. If there are no more units in the turn order list, StartTurn is called and a new round begun.

I’ve added a timed buff system, and the current spell effects on a unit should tick at the start of the units action, in case damage over time effects etc kill it before it has a chance to act. However this leaves my current function broken when killed by a spell effect and then referenced by the remaining part of the function where it should be taking its action.

I want to include a sanity check to make sure the unit is still active, and if not advance to the next unit in the turn order but I’m not sure where it should go. If I tick spell effects, then test if the active unit is null and then call NextTurn again if so, is this like calling a break on my current iteration through the function, or will it return to the exact same spot after executing and the problem is still there? I thought about encapsulating all the unit selection part in a while selectedUnit != null loop, but not quite sure how to structure this with the else condition that calls StartTurn at the end of the initiative list, since if there’s no other valid unit in the turn order that loop will continue forever? Any idea how i should structure this? Thank you!

edit: I’m also removing the unit from the initiative liston its Death() function but it might be more sensible to just not remove it there, allow that index to be null and rebuild it at the top of the turn? Since if it’s triggering death off a spell effect and removing itself from the list this seems like it might screw with the indices

	public void StartTurn(){
		//reset the target highlights
		foreach (GameObject tile in map.tileArray)
			tile.GetComponent<SpriteRenderer> ().color = Color.white;
		
		//reset initiative order and advance round counter
		currentInitIndex = 0;
		roundCounter += 1;

		//reset hero's ability to cast
		playerHero.hasCast = false;
		playerHero.GetComponent<SpriteRenderer> ().color = Color.white;

		map.GetComponent<CombatLog> ().NewMessage ("ROUND " + roundCounter +" BEGINS");
		map.selectedUnit = map.initiativeOrder [currentInitIndex];
		map.selectedUnit.GetComponent<Unit> ().isActive = true;

		foreach (TimedBuff buff in map.selectedUnit.GetComponent<Unit>().currentBuffs.ToArray()) {
			buff.Tick (1);
		}

		if (map.selectedUnit.GetComponent<Enemy> ()) {
			map.selectedUnit.GetComponent<Enemy> ().TakeTurn ();
		}
	}

	public void NextTurn(){
		//reset the target highlights
		foreach (GameObject tile in map.tileArray)
			tile.GetComponent<SpriteRenderer> ().color = Color.white;

		//null path and reset movement points
		map.selectedUnit.GetComponent<Unit> ().currentPath = null;
		map.selectedUnit.GetComponent<Unit> ().remainingMovement = map.selectedUnit.GetComponent<Unit> ().moveSpeed;

		//remove any expired buffs from the current unit before advancing turn, this is separate from the tick logic which should apply at start of turn

		foreach (TimedBuff buff in map.selectedUnit.GetComponent<Unit>().currentBuffs.ToArray()) {
	
			if (buff.IsFinished) {
				map.selectedUnit.GetComponent<Unit> ().currentBuffs.Remove (buff);
			}
		}
			

		//advance the next unit in the initiative order array as the active unit and deactive the previous unit
		if (currentInitIndex < map.initiativeOrder.Count-1) {
			map.selectedUnit.GetComponent<Unit> ().isActive = false;
			currentInitIndex += 1;
			map.selectedUnit = map.initiativeOrder [currentInitIndex];
			map.selectedUnit.GetComponent<Unit> ().isActive = true;

			//advance all times buffs by one tick, we want to advance after selecting the new unit but before it acts, in case it is killed by a spell effect
			foreach (TimedBuff buff in map.selectedUnit.GetComponent<Unit>().currentBuffs.ToArray()) {
				//all buffs currently decrement by one tick per turn
				buff.Tick (1);

			}
			//TODO sanity check in case a fatal debuff has killed the unit before taking its turn

			
			//if the next unit to act is an enemy, take its turn
			if (map.selectedUnit.GetComponent<Enemy> ()) {
				map.selectedUnit.GetComponent<Enemy> ().TakeTurn ();
			}

		} else {
			//we have reached the end of the initiative order list, begin a new combat round
			map.selectedUnit.GetComponent<Unit>().isActive = false;
			map.selectedUnit = null;
			StartTurn();
		}

	}

Tl;dr - yes, recusions work perfectly fine in C#, without recursions the language would obviously be Turing incomplete and then it would never come into use, let alone be a language for Unity.

Thanks TheSOULDev (tried to submit this as a comment on your reply but it doesnt seem to work)

I thought that was the case so I guess just recurring the function before doing the action doesn’t quite work since it will eventually return and either execute a double action or act on a null object… could I encapsulate it like this example below? I’d also have to null-check the lines at the top of NextTurn and StartTurn since I can no longer guarantee a valid unit exists at that point to be acted on but this check seems like it should work - at the point it is recurring NextTurn if needed, there is no further code to execute in the root function call.

The if statement checking the next index in preparation to recur it might need to be tweaked - if I’m calling List.Remove on that object as part of its death, do all the indices after it in the list get decremented by one? If so I should be checking the same index… but then when I recur the function it’s going to then increment the counter and shoot past a valid index. In that case should I just destroy the object but not remove it from the list, iterate through the indices recursively as normal and then remove all nulls from the list as part of my start turn cleanup procedure?

      //*select units and tick through buffs*
    
                   if(map.selectedUnit != null){
        
                  	  //if the next unit to act is an enemy, take its turn (otherwise done, wait for player input)
                  	  if (map.selectedUnit.GetComponent<Enemy> ()) {
                   	      map.selectedUnit.GetComponent<Enemy> ().TakeTurn ();
                   	   }
        		} else{
        
        		//selected unit is null, so it has died from a spell effect before acting
        		//check if there is another unit in the turn order list, if so recur NextTurn otherwise call the next round
        		
        
        		   if(currentInitIndex+1 < map.initiativeOrder.Count-1){
        			NextTurn();
        		   }else{
        			StartTurn();
        			}
        
        		}