Save/Load - Strange behaviour

I have written a basic save/load system, and it works just fine, except whenever I restart the game, the player’s level increases by one. Every other property is loaded just fine. I don’t have any explanation for this…

This is my code:

import System.IO;

static function save(slotNmbr) {
	var sPath : String = Application.persistentDataPath + "/savegame" + slotNmbr + ".txt";
	var sData : StreamWriter = new StreamWriter(sPath);
	sData.WriteLine(Application.loadedLevel);
	sData.WriteLine(PlayerStatus.level);
	sData.WriteLine(PlayerStatus.exp);
	sData.WriteLine(PlayerStatus.plHealth);
	sData.WriteLine(PlayerStatus.lives);
	sData.WriteLine(PlayerStatus.maxRange);
	sData.WriteLine(PlayerStatus.maxMelee);
	sData.WriteLine(PlayerStatus.pick[0]);
	sData.WriteLine(PlayerStatus.pick[1]);
	sData.WriteLine(PlayerStatus.pick[2]);
	sData.WriteLine(PlayerStatus.pick[3]);
	sData.Flush();
	sData.Close();
	
	PlayerPrefs.SetInt("Slot" + slotNmbr, 1);
}

static function load(slotNmbr) {
	var lPath : String = Application.persistentDataPath + "/savegame" + slotNmbr + ".txt";
	var lData : StreamReader = new StreamReader(lPath);
	var stage = parseInt(lData.ReadLine());
	var level =  parseInt(lData.ReadLine());
	var exp =  parseInt(lData.ReadLine());
	var plHealth =  parseInt(lData.ReadLine());
	var lives = parseInt(lData.ReadLine());
	var maxRange =  parseInt(lData.ReadLine());
	var maxMelee =  parseInt(lData.ReadLine());
	var shields =  parseInt(lData.ReadLine());
	var mines =  parseInt(lData.ReadLine());
	var bombs =  parseInt(lData.ReadLine());
	var turbo =  parseInt(lData.ReadLine());
	
	lData.Close();
	
	print(level);
	GameObject.FindWithTag("Player").SendMessage("freeWP");
	
	PlayerStatus.level = level;
	PlayerStatus.expToLevel = PlayerStatus.expToLevelArr[PlayerStatus.level - 1];
	PlayerStatus.exp = exp;
	PlayerStatus.plHealthMax = 10 * PlayerStatus.multArr[PlayerStatus.level-1];
	PlayerStatus.plHealth = plHealth;
	PlayerStatus.lives = lives;
	PlayerStatus.maxRange = maxRange;
	PlayerStatus.maxMelee = maxMelee;
	PlayerStatus.pick[0] = shields;
	PlayerStatus.pick[1] = mines;
	PlayerStatus.pick[2] = bombs;
	PlayerStatus.pick[3] = turbo;
	
	
	
	Application.LoadLevel(stage);
}

When I load a savegame from within the game, everything works as it should.

I have a Splash Screen Scene that automatically loads a ‘hub’ level. This in turn checks, if there is an autosave present and if so loads that, if not loads the first level. This hub scene has all important objects that are not destroyed on load (Player, Camera, Main Menu and the AutoLoader). When I delete the key for the autosave, the first level is loaded just fine. When I then close the game and restart (or restart it in the editor), the same level is loaded (since now there is an autosave there), but suddenly the player is at level 2. The print(level); line prints 1 to the console. When I repeat this, the pplayer is level 3, and the game prints 2.

The really strange thing is that values derived from the level (like max health and a damage multiplier) are calculated to level 2 although this should only happen an levelup, so it seems that the player somehow levels up, but that doesn’t make sense…just to be sure, here is the PlayerStatus script:

	//FX
var lvlUp : Transform;

//weapons
var weapons : Transform[] = new Transform[6];
static var maxRange : int = 0;
static var maxMelee : int = 3;
//health
static var lives: int = 3;
static var plHealth : int = 10;				//player health
static var plHealthMax : int = 10;			//maximum health

//power-ups
static var maxPowerUp : int = 5;			//max number per power up

static var pick : int[] = [5,5,5,5];			//availible powerups - shield, mines, bombs, turbo

//EXP
static var level : int = 1;
static var maxLevel : int = 10;
static var multiplier : float = 1.0;
static var multArr : float[] = new float[10];
static var exp : int = 0;
static var expToLevel : int = 1000;
static var expToLevelArr : int[] = new int[10];

//weapons
static var i : int = 0;
static var j : int = 3;

function Awake() {
	multArr = [1.0, 1.1, 1.3, 1.6, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0];
	expToLevelArr = [1000, 1500, 2500, 4000, 6000, 8000, 10000, 15000, 20000, 25000];
	
	switch(i) {
		case 0 : 
			gameObject.Find("Blaster").renderer.enabled = true;
			gameObject.Find("Laser").renderer.enabled = false;
			gameObject.Find("Plasma").renderer.enabled = false;
		break;
		
		case 1 : 
			gameObject.Find("Blaster").renderer.enabled = false;
			gameObject.Find("Laser").renderer.enabled = true;
			gameObject.Find("Plasma").renderer.enabled = false;
		break;
		
		case 2 : 
			gameObject.Find("Blaster").renderer.enabled = false;
			gameObject.Find("Laser").renderer.enabled = false;
			gameObject.Find("Plasma").renderer.enabled = true;
		break;
	}
	GameObject.FindGameObjectWithTag("Player").GetComponent(Player).primAtt = weapons*;*
  •   switch(j) {*
    
  •   	case 3 :* 
    
  •   		gameObject.Find("Blade").renderer.enabled = true;*
    
  •   		gameObject.Find("Mace").renderer.enabled = false;*
    
  •   		gameObject.Find("Lance").renderer.enabled = false;*
    
  •   	break;*
    
  •   	case 4 :* 
    
  •   		gameObject.Find("Blade").renderer.enabled = false;*
    
  •   		gameObject.Find("Mace").renderer.enabled = true;*
    
  •   		gameObject.Find("Lance").renderer.enabled = false;*
    
  •   	break;*
    
  •   	case 5 :* 
    
  •   		gameObject.Find("Blade").renderer.enabled = false;*
    
  •   		gameObject.Find("Mace").renderer.enabled = false;*
    
  •   		gameObject.Find("Lance").renderer.enabled = true;*
    
  •   	break;*
    
  •   }*
    
  •   GameObject.FindGameObjectWithTag("Player").GetComponent(Player).secAtt = weapons[j];*
    
  • }*

  • function Update() {*

  •   if(exp >= expToLevel) {*
    
  •   	if(level <= maxLevel){*
    
  •   		Instantiate(lvlUp, transform.position, Quaternion.identity);*
    
  •   		level++;*
    
  •   		exp -= expToLevel;*
    
  •   		multiplier = multArr[level - 1];*
    
  •   		expToLevel = expToLevelArr[level - 1];*
    

_ plHealthMax = 10 * multArr[level-1];_

  •   		plHealth = plHealthMax;*
    
  •   		transform.GetComponent("Player").marker.gameObject.renderer.material.SetFloat("_Cutoff", 1 - (parseFloat(PlayerStatus.plHealth) / parseFloat(PlayerStatus.plHealthMax)));*
    
  •   	}*
    
  •   }*
    
  •   if(statics.playerActive) {*
    
  •   	if(Input.GetKeyDown(KeyCode.R)) {*
    
  •   		i++;*
    
  •   		if(i > maxRange)*
    
  •   			i = 0;*
    
  •   		switch(i) {*
    
  •   			case 0 :* 
    
  •   				gameObject.Find("Blaster").renderer.enabled = true;*
    
  •   				gameObject.Find("Laser").renderer.enabled = false;*
    
  •   				gameObject.Find("Plasma").renderer.enabled = false;*
    
  •   			break;*
    
  •   			case 1 :* 
    
  •   				gameObject.Find("Blaster").renderer.enabled = false;*
    
  •   				gameObject.Find("Laser").renderer.enabled = true;*
    
  •   				gameObject.Find("Plasma").renderer.enabled = false;*
    
  •   			break;*
    
  •   			case 2 :* 
    
  •   				gameObject.Find("Blaster").renderer.enabled = false;*
    
  •   				gameObject.Find("Laser").renderer.enabled = false;*
    
  •   				gameObject.Find("Plasma").renderer.enabled = true;*
    
  •   			break;*
    
  •   		}*
    

_ GameObject.FindGameObjectWithTag(“Player”).GetComponent(Player).primAtt = weapons*;_
_
}_
_
if(Input.GetKeyDown(KeyCode.F)) {_
_
j++;_
_
if(j > maxMelee)_
_
j = 3;*_

* switch(j) {*
* case 3 :*
* gameObject.Find(“Blade”).renderer.enabled = true;*
* gameObject.Find(“Mace”).renderer.enabled = false;*
* gameObject.Find(“Lance”).renderer.enabled = false;*
* break;*

* case 4 :*
* gameObject.Find(“Blade”).renderer.enabled = false;*
* gameObject.Find(“Mace”).renderer.enabled = true;*
* gameObject.Find(“Lance”).renderer.enabled = false;*
* break;*

* case 5 :*
* gameObject.Find(“Blade”).renderer.enabled = false;*
* gameObject.Find(“Mace”).renderer.enabled = false;*
* gameObject.Find(“Lance”).renderer.enabled = true;*
* break;*
* } *

* GameObject.FindGameObjectWithTag(“Player”).GetComponent(Player).secAtt = weapons[j];*
* }*
* }*
* }*
And my AutoLoader:
* function Awake() {*
* Resources.UnloadUnusedAssets ();*
* if(PlayerPrefs.HasKey(“Slot0”))*
* SaveLoad.load(0);*
* else *
* Application.LoadLevel (“test2”);*
* }*

The autoload awake might be called before the PlayerStatus Awake, thus rendering the Playerload obsolete. The reason why it doesn’t give you an exeptcion is that you are initializing the exptolevel array when you are defining it and it gets initialized in constructor. Thus, if you change your PlayerStatus Update to this:

function Update() {
    if(expToLevel == 0)
    {
        expToLevel = expToLevelArr[level - 1];
    }
    else if(exp >= expToLevel) {
       if(level <= maxLevel){
         Instantiate(lvlUp, transform.position, Quaternion.identity);
         level++;
         exp -= expToLevel;
         multiplier = multArr[level - 1];
         expToLevel = expToLevelArr[level - 1];
         plHealthMax = 10 * multArr[level-1];
         plHealth = plHealthMax;
         transform.GetComponent("Player").marker.gameObject.renderer.material.SetFloat("_Cutoff", 1 - (parseFloat(PlayerStatus.plHealth) / parseFloat(PlayerStatus.plHealthMax)));
       }
    }

Then it should work.