Preexisting score/lives after game ends?

MysticalMist

Well-known member
Something I noticed while working on projects in general that I haven't seem to find an exact solution for,

I don't know who else comes across this sometimes, but occasionally, if you complete a set of levels and even get past the hall of fame screen, you can still have your score/lives from your past playthrough for some odd reason, even if there's "end" within the set in the levels file. What is the cause of this, usually?
 
Something I noticed while working on projects in general that I haven't seem to find an exact solution for,

I don't know who else comes across this sometimes, but occasionally, if you complete a set of levels and even get past the hall of fame screen, you can still have your score/lives from your past playthrough for some odd reason, even if there's "end" within the set in the levels file. What is the cause of this, usually?
If I'm not wrong, it has a connection with the skipselect. In my case I fix it by manually resetting some data using scripts, you can choose the event that fits better for your game (updated, select screen, menu screen, etc).

Here's an example:

Code:
//DEFINE HERE THE DEFAULT SCORE, LIVES AND CREDITS. IT WILL BYPASS THE LEVELS.TXT CONFIG
int defaultScore = 0;
int defaultLives = 3;
int defaultCredits = 3;

changeplayerproperty(0, "score", defaultScore);
changeplayerproperty(1, "score", defaultScore);
changeplayerproperty(2, "score", defaultScore);
changeplayerproperty(3, "score", defaultScore);
changeplayerproperty(0, "lives", defaultLives);
changeplayerproperty(1, "lives", defaultLives);
changeplayerproperty(2, "lives", defaultLives);
changeplayerproperty(3, "lives", defaultLives);
changeplayerproperty(0, "credits", defaultCredits);
changeplayerproperty(1, "credits", defaultCredits);
changeplayerproperty(2, "credits", defaultCredits);
changeplayerproperty(3, "credits", defaultCredits);
 
Baffles me how much issues skipselect can cause.

I blame you all. No, seriously. :p

skipselect started as a bolted-on development feature by @Orochi_X during the Lavalit days around 2007. He later admitted he doesn't even remember adding it! There were actual flame wars over what it was supposed to mean. Whatever its exact original purpose, it was never designed as the clean, general-purpose, per-level character-forcing command people now assume it is.

Unfortunately, like several other development features from that era, the community immediately started using it in released games. OpenBOR's old, dogmatic backward-compatibility-at-all-costs community policy then made removing or properly redesigning it practically impossible.

Internally, skipselect is not a simple “do not display the selection screen” flag. It adds a pseudo-entry to the level order, stores a model name for each player slot, and runs the normal player-selection machinery without displaying the screen. Later revisions allowed multiple skipselect entries within one set and tied the whole thing into save-game restoration. Consequently, it intersects with models, player joining, lives, credits, score, saved games, and any scripts touching those systems.

For this specific report, @Kratus is correct. The current logic uses saved lives to guess whether skipselect is starting a new game or reselecting players during an existing game. The end command merely marks the preceding level as the end of the set. Completion handling resets the saved level and stage, yet leaves saved player lives and score intact.

When another new game starts, OpenBOR's internal selectplayer() function first saves the lingering player state, wipes the active player array, then finds saved lives greater than zero and treats the operation as a re-selection. It consequently restores the previous lives, score, and credits instead of initializing a new run. That is the direct cause of the behavior described here. @Kratus's reset script will work as a temporary workaround, though it should not run unconditionally from updated.c. Doing that would continuously reset those properties throughout the game. Gate the reset so it executes once when a genuinely new run begins, using whichever controlled startup event best fits the project.

Proper engine correction is to stop guessing from the player's remaining lives. Selection code needs an explicit context telling it whether the caller is starting a new game, re-selecting during the current game, or loading a saved game. That preserves the legitimate existing uses without treating leftover state as creator intent. I have tried to shore skipselect up for the upcoming release, though this particular path still needs that explicit cleanup. Even once this defect is corrected, forcing a specific model will never play perfectly with every script or feature someone might combine with it. The same is true of nearly anything in a creation toolbox. Some behaviors are simply oil and water, guys - that is how it is.

DC
 
Back
Top Bottom