Author Topic: ship save/load script  (Read 31725 times)

0 Members and 1 Guest are viewing this topic.

Goober5000 made a much improved (and backwards compatible) version of the script:

https://www.hard-light.net/forums/index.php?topic=96939

----------------

Ship save/load script for checkpoints and red-alert like missions.
Instructions how to use it can be found in the readme.

Download:
http://www.mediafire.com/file/6dclueqkc4yxuol/Ship_SaveLoad_script.zip

Use 3.7.2 or newer (probably works on 3.6.16 upwards).

----------------

While working on a campaign I remembered reading that red-alert is not always doing what it should, especially with branching missions and several red-alert missions in a row. So I thought that a script might be a solution and because I wanted to learn how scripting works (haven't done much programming up to now, nothing object oriented) I started creating a script that saves all important (shipclass, hitpoints, ammo left,...) and some not so important (energy, shields, ...) shipdata into a file and loads the data into the game from the file.

The script is working as it should and gets called via script-eval with the shipname in FRED. It manages data for several ships in one file and does ship-vanish when a ship that was dead or absent while saving gets loaded. That way it can be used for red-alert like missions while playing them in the simulator or when a ship is not present in the next mission but is used again in the mission afterwards without repairs.

That said I have a few questions:

Does a script like this already exist and I just didn't find it?
Does it make sense at all to make a script for something the game engine should be able to do?

Is anyone interested in such a script and wants to see some feature in it? I'm still thinking about what else can be added or what options for loading may be of use...

The script needs a place to save shipdata and possibly a configuration file. Do you know what filetype may be the best choice and where to save it?

At the moment everything is in one file and all functions are in
Code: [Select]
#Global Hooks
$Global:
[
...
]
#end
I'm not exactly sure if this is the right place or if the functions should be better somewhere else.

So if there is any interest in the script I'll put in some changes, clean it, try to follow some of the advise in http://www.hard-light.net/forums/index.php?topic=72312.0 and release it. At the moment it's more or less the result of me learning lua the hard way with a target and without starting with easy examples like 'Hello World'  :D
« Last Edit: October 21, 2020, 06:44:26 am by Admiral MS »
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
the thing i like about scripting is its not fred. im not really sure what can and cant be pulled off with existing features in the mission editor, im not sure what bugs affect red alert missions. but having a way to log stats for ships and reload them in the next mission with exactly the same stats sounds impressive. not sure if that is out of fred's capabilities or not.

it sounds like your'e using fred to call functions defined globally with scripting. of course i would use the $game_init: hook because i dont think global hooks work with modular tables, so if you stacked your script onto another mod wih scripting, only one of those mods would get its global hook scripts used which could lead to things you defined being nil when you go to use them. instead use:
Code: [Select]
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
--script goes here
]
#end
you should also kind of keep the use of globals to the minimum. using locals in functions is sufficient so long as you use descriptive enough names on your functions. you can further reduce the number of globals by sticking functions in tables such as:
Code: [Select]
pongFuncs = {}
function pongFuncs.initPong()
of course this kinda thing is somewhat overkill in most cases and even i dont do this. you could also make things easier and just use a prefix specific to your script on all your global names. this is also somewhat overkill because there just arent enough people using scripting for people to have clashing variables.

i probibly dont have much use for such a script, of course im not really a mission designer so i wouldnt know. getting non-scripters (especially moders who are primarily graphics people, and to a lesser degree freders) to use scripts no matter how well packaged and well written scripts are is all but impossible. there are exceptions, such as mega-mods and tcs who would jump at the possibility to have a full time scripter on their team. my scripting interest pretty much revolves around graphics, game play and physics. i do have a concept for a mod which revolves around being able to "collect" supplies from one mission add them to an inventory of sorts and use them to "collect" more supplies in the next mission, and where failing to "collect" them results in a very hard game, and will end the game for you when the inventory reaches zero. but its a bridge i cross if i ever get there.
« Last Edit: February 20, 2011, 01:11:36 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Quote
the thing i like about scripting is its not fred. im not really sure what can and cant be pulled off with existing features in the mission editor, im not sure what bugs affect red alert missions. but having a way to log stats for ships and reload them in the next mission with exactly the same stats sounds impressive. not sure if that is out of fred's capabilities or not.
You can do some saving in fred using player-persistent variables but for a lot of ships you need tons of variables and so on. I think changing the class of a ship to something else and loading all other stats is impossible in fred.

Quote
it sounds like your'e using fred to call functions defined globally with scripting. of course i would use the $game_init: hook because i dont think global hooks work with modular tables, so if you stacked your script onto another mod wih scripting, only one of those mods would get its global hook scripts used which could lead to things you defined being nil when you go to use them. instead use:
Code: [Select]
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
--script goes here
]
#end
The script is used in fred like a sexp with the shipname as argument. For a number of uses you should be able to call it everytime (so save and load in the same mission). $On Game Init: doesn't seem to enable this.

Quote
you should also kind of keep the use of globals to the minimum. using locals in functions is sufficient so long as you use descriptive enough names on your functions. you can further reduce the number of globals by sticking functions in tables such as:
Code: [Select]
pongFuncs = {}
function pongFuncs.initPong()
of course this kinda thing is somewhat overkill in most cases and even i dont do this. you could also make things easier and just use a prefix specific to your script on all your global names. this is also somewhat overkill because there just arent enough people using scripting for people to have clashing variables.
I already did most of this because i got a number of problems when using globals. There are only local variables and the complete shipdata is stored in one table with a lot of integrated tables. The data is transferred via function calls anyway.


I expected that only a few people will ever look into the scripting section but I'll finish the script for use in my campaign and propably release it in a few days. Some campaigns already have in-mission savepoints and i may try to extend the script to be used at reloading to a given point in a mission or you can do quite some funny things with it in a parody campaign.
Scripting really needs some advertising outside this part of forum...

Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
This would be a much better way to do this stuff than the system used in War in Heaven. If I can figure out how to use it I'd definitely consider it as a replacement. Nice job.

 
While trying to implement the last feature into the script i sort of hit a wall.
I tried to use
Code: [Select]
if (mn.evaluateSEXP("is-destroyed-delay !0! !"..shipname.."!")) thenand the game dumps me to desktop with a stupid error message:

Can't find operator s-destroyed-delay in operator list
.
ntdll.dll! KiFastSystemCallRet
kernel32.dll! WaitForSingleObjectEx + 67 bytes
kernel32.dll! WaitForSingleObject + 18 bytes
fs2_open_3_6_12r_INF_SSE2.exe! <no symbol>
fs2_open_3_6_12r_INF_SSE2.exe! <no symbol>
fs2_open_3_6_12r_INF_SSE2.exe! <no symbol>

Debug gives an assertion at that point :confused::

Assert: *Mp == '('
File: sexp.cpp
Line: 18613

It does this with the same error message no matter what is actually written inside evaluateSEXP(" ... ") and the debug log doesn't contain any more information with the standart settings.

Am i using it the wrong way or what's the problem with it?
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
this is not familiar territory for me. the only mission integration i have done is using the script-eval sexp (this is used by the atmospheric flight script to tell it what planetary/atmospheric profile to use for the mission).

does the sexp expect some kind of termination on the string, like a \0 or \r\n or some such?

*edited because im a moron*
« Last Edit: February 22, 2011, 02:28:47 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Code: [Select]
(mn:runSEXP("is-destroyed-delay !0! !"..shipname.."!"))
This returns a true (for running that sexp succesfully) so unless evaluateSEXP ist totally different it should be right. And as i already said, it doesn't matter if i use evaluateSEXP("") or evaluateSEXP("stuff"), the error message is the same.

It feels more like something is buggy. I never got an assertion in debug up to now, not even a crash at all no matter what i did in my script. And one time the game freezed without error message when getting to the evaluateSEXP part...
« Last Edit: February 22, 2011, 02:36:42 pm by Admiral MS »
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
The error message makes it look like the initial 'i'  in 'is' is somehow being chopped off and the SEXP thus cannot be recognized. That's weird.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
i dont see any reason in the source why that should happen, did you try padding it with whitespace?

though there is this amusing little snippet:
Code: [Select]

// HACK: ! -> "
for (i = 0; i < (int)strlen(buf); i++)
if (buf[i] == '!')
buf[i]='\"';

« Last Edit: February 22, 2011, 02:45:26 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Adding spaces in front of it changes nothing, adding an "i" in front of it freezes the normal game but debug keeps producing the same assertion. So i guess the normal game just crashes because it ignores that assertion or whatever and tryes to go on somehow.

Quote
Code: [Select]

// HACK: ! -> "
for (i = 0; i < (int)strlen(buf); i++)
if (buf[i] == '!')
buf[i]='\"';


Uh what's that?
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
just an amusing piece of code from run_sexp() in sexp.cpp.

but i followed the calls and run_sexp(), does some string magic (namely the hack above) to process the string and dump it into a buffer. then set a pointer to the buffer. this pointer seems to be a global. at some point in get_sexp(), a call is made to get_sexp_main(), which makes use of that same global pointer (*Mp). and in that function there is this code:

Code: [Select]
savep = Mp;
if (!strncmp(Mp, "( )", 3))
savep++;

Assert(*Mp == '(');

and theres yer problem. seems it expected to see a ( character, but saw an 'i' instead. thus the assert. i think your sexp needs to be in a set of (). that is assuming my understanding of how asserts work is correct.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Adding some () so it looks like:
Code: [Select]
if (mn.evaluateSEXP("(is-destroyed-delay !0! !"..shipname.."!)")) thenseems to work. I get no error and there are the right results in the savefile.  :)

That much about the documentation of scripting  :rolleyes: and error messages telling the user what's wrong :wtf: Why is the syntax of evaluateSEXP() different than that of runSEXP()?

Thanks for looking for it in the code, would've been stuck without your help!
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
seems the only difference between evaluateSexp() and runSexp() is this line:

Code: [Select]
snprintf(buf, 8191, "( when ( true ) ( %s ) )", s);
which is present in runSexp() but not evaluateSexp(). to make the syntax more uniform, i could just add it to evaluateSexp but use:

Code: [Select]
snprintf(buf, 8191, "( %s )", s);
which would essentially put anything in your sting in parenthesis for you, but this feels kinda like yet another hack in an already hackish system. im gonna ask the coders if this is a good idea to do this or not or not. it also kind of makes me question why we need both functions.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Quote
it also kind of makes me question why we need both functions.

I need both evaluateSEXP() and runSEXP() because what they return is completely different. Evaluate does return whether the statement is true, false or whatever and run just tells me if the game could process the sexp or not.
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
in that case i may just add more info to the description strings so scripters aren't at a total loss about syntax.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Finally finished the script.

There are 4 functions usable with script-eval in fred:

saveship('shipname')
saves the data of a ship to the savefile

deleteship('shipname')
deletes the data of a ship out of the savefile

deleteshipsavefile()
obvious

loadship('shipname')
loads the saved data of a ship into the game, has a number of optional arguments besides the standard use which tell the script what data and how to load the data.
For shipnames too long for the characterlimit in script-eval there is an option to load the shipname from a variable defined in fred.

An explanation of the features is in the readme.txt or you can just ask me here if it's hard to understand. I was trying to make the use really simple but somehow after reading my readme it feels complicated.

Download:
http://www.mediafire.com/?3bc31gfn2c2k9vw

The .zip contains two missions as example, the script and a readme. It is now in a .tbm enabling the modular use everyone likes ;) and no more parts of the script are in #Global Hooks.

I tested everything I could think of in 3.6.12 but if you encounter any problems just report it in this thread.
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
It feels like my era is over as soon as it came. What place is there for a FREDder with these brilliant new minds and their 'scripts'?

 
It feels like my era is over as soon as it came. What place is there for a FREDder with these brilliant new minds and their 'scripts'?

A lot of places after all... Considering that I'm working on my campaign for many years and the only things of it i actually finished are 5 missions which are of no use unless i finish the others and this script that may never see the light of the day inside the campaign i made it for   :sigh:
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
there still needs to be mission designers. this script really just means they have new toys to play with. this is one of the reasons ive always tried to push for mission-embedded scripts so that missions could include scripting without needing any other external tables or scripts, and that scripted missions may be validated for multi and not require mods to run.

also a note for functions that are to be called from sexp, i helps to keep arguments and function names as short as possible, because, iirc, you are limited to 32 byte strings. i usually just use a proxie function to allow a shorthand version that can be used if you need a lot of arguments or long arguments (some ships have really long names), it might call for a series of functions or globals to be set before calling the function to do the job. but in this case i think it should be enough space.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
Yeah I am pretty much joking cats