pumpkin 10 Posted November 26, 2013 As I come from Operation Flashpoint/Arma series, I was surprise not to find a scripting language in Take On Mars (as SQS/SQF), even with very few commands. a (small) scripting language could eventualy relieve to the missing of functionnalities and/or permits to easily insert random in user's missions. Did you plane to add a scripting language (I saw a sub-forum on Steam "Scripting & Configs") ? Or may I suggest you to add one ? Share this post Link to post Share on other sites
dram 14 Posted November 26, 2013 Hi, actually the scripting language in Take On Mars is extremely powerful. It is very low-level though, which can scare off potential modders, but it is very similar to C++, and actually the entire game is written in script. The scripts are packed in .pak files but can be unpacked. We'll hopefully release some videos showing how to unpack and mod the files soon. The reason there are no SQF or SQS files is that it supports any text format. If you have a look at the example addon we released on steam workshop, you can unpack it straight from the main menu, and then you can have a look at its contents in: C:\Program Files (x86)\Steam\userdata\YOUR STEAM ID\244030\local\addonpacks\ADDON NAME\ Here's an example of a controller script for the basic probe: /**************************************************************************** * PROBE CONTROLLER ***************************************************************************/ const float PRB_LANDSPEED = 64; // 2m/s const float PRB_LANDSPEED_SPACE = 32; // 1m/s const float PRB_HEIGHTTHRUST = 3200; // 100m const float PRB_HEIGHTTHRUST_SPACE = 4800; // 150m const float PRB_HEIGHTLAND = 16; // 0.5m const float PRB_ANGPUSHMAX = 10; const float PRB_ANGPUSHMULT = 0.5; const float PRB_ANGPUSHLATSPEEDMAX = 800; // 2m/s float sinInc; int probeBody; int part_thrusters; void Controller_Init(Vehicle_Controller controller) { Vehicle_Handler vehicle = controller.ownerVehicle; vehicle.EmergencyMode = false; probeBody = -1; part_thrusters = -1; sinInc = 0; for (int i = 0; i < vehicle.storage.parts_num; i++) { if (vehicle.storage.parts_types[i] == "ProbeBody") probeBody = i; if (vehicle.storage.parts_types[i] == "Antenna" && vehicle.storage.parts_subtypes[i] == "ProbeDish") part_thrusters = i; } } void Controller_OnSim(Vehicle_Controller controller) { Vehicle_Handler vehicle = controller.ownerVehicle; bool inSpace = false; if (vehicle.storage.owner && vehicle.storage.owner.IsSpaceLocation()) inSpace = true; int i2 = 0; bool b1 = false; bool b2 = false; float f2 = 0; vector v2 = ZeroVec; vector mat1[4]; Vehicle_FX fxEnt = NULL; if (vehicle.parts_ents[vehicle.storage.CurrentPriPart] && vehicle.storage.parts_types[vehicle.storage.CurrentPriPart] == "ProbeBody") b1 = true; if (vehicle.parts_ents[vehicle.storage.CurrentSecPart] && vehicle.storage.parts_types[vehicle.storage.CurrentSecPart] == "ProbeBody") b2 = true; /*float inputV = 0; float inputH = 0; float inputT = 0; if (b1 && b2) { inputV = vehicle.input_arc_pri0; inputH = vehicle.input_arc_pri1; inputT = vehicle.input_arc_pri2; }*/ // Increment vehicle landing time and manual landing time if (!vehicle.storage.SystemsActivated && vehicle.storage.LandingActivated) { vehicle.storage.landing_totaltime += phys_FixedTick; } float curHeight = 0; float curLatVel = 0; vector curVelocity = ZeroVec; vector curLatVelocity = ZeroVec; sinInc += phys_FixedTick * frand(0.9, 1.1) * 360; Vehicle_Part partBody = vehicle.parts_ents[probeBody]; if (partBody) { GetMatrix4(partBody, mat1); v2 = mat1[3]; curVelocity = GetVelocity(partBody); curLatVelocity = curVelocity; curLatVelocity[2] = 0; curLatVel = VectorLength(curLatVelocity); curHeight = vehicle.GetSolidGroundDist(NULL, mat1[2] * -1); /*if (VectorLength(curVelocity) <= PRB_LANDINGVEL && manCtrlTime <= 0 && curHeight < PRB_HEIGHTLAND) { if (lndNoHUDSwitchTime >= PRB_NOHUDSWITCHTIME) { lndNoHUDSwitchTime = 0; partBody.GenVec2[0] = 1; lndCountUp += phys_FixedTick; if (lndCountUp > PRB_LANDINGTIME || manCtrlTime <= 0) { lndCountUp = 0; if (!vehicle.storage.SystemsActivated) { vehicle.storage.LandingZone = ZeroVec; vehicle.storage.SystemsActivated = true; vehicle.storage.AddLogEntry("#tkom_log_landed"); if (g_Campaign) g_Campaign.VehicleLanded(); } } } }*/ } if (part_thrusters == -1) return; Vehicle_Part thrusterPart = vehicle.parts_ents[part_thrusters]; // Check if part is connected to the lander if (partBody && thrusterPart && vehicle.CheckPartConnect(part_thrusters, probeBody) && vehicle.storage.LandingActivated) { if (partBody.GenVec2[0] == 0) { float linDamp = AirFriction_Global * 1.8; clamp linDamp<0, 1>; dBodySetDamping(thrusterPart, linDamp, AirFriction_Global); } fxEnt = NULL; if (thrusterPart.FXIndex != -1) fxEnt = Vehicle_FXList[thrusterPart.FXIndex]; float hgtThrust = PRB_HEIGHTTHRUST; float lndSpeed = PRB_LANDSPEED; if (inSpace) { hgtThrust = PRB_HEIGHTTHRUST_SPACE; lndSpeed = PRB_LANDSPEED_SPACE; } if (partBody.GenVec2[0] < 2) { // Not Landed yet float thrustLevel = 0; if (partBody.GenVec2[0] == 0 && curHeight < hgtThrust) partBody.GenVec2[0] = 1; if (partBody.GenVec2[0] == 1 && curHeight < PRB_HEIGHTLAND) partBody.GenVec2[0] = 2; // Work out thrust etc if (partBody.GenVec2[0] == 1 && curVelocity[2] < -lndSpeed) thrustLevel = 1; // End landing sequence if in space and travelling slowly enough if (inSpace && curVelocity[2] >= -lndSpeed) partBody.GenVec2[0] = 2; /** For vehicle log: GenVec3[0] - if 1, logged a minor malfunction GenVec3[0] - if 2, logged a major malfunction **/ // Now work out failure float malfVal = thrusterPart.GenVec3[0]; thrusterPart.GenVec3[1] = thrusterPart.GenVec3[1] + phys_FixedTick; if (thrusterPart.GenVec3[1] >= 0.5 && vehicle.storage.parts_damage[part_thrusters] > 0.25) { // Only check once per 1/2 second and only if damaged thrusterPart.GenVec3[1] = 0; if (thrustLevel > 0) { // Only check if the thruster intends to thrust float rndChc = frand(0, 1); // If not jammed, % chance of jamming relative to the damage if (malfVal < 1 && rndChc <= vehicle.storage.parts_damage[part_thrusters] - 0.25 / 0.75) malfVal = 1; else { // If jammed, % chance of jamming permanently relative to the damage, and only above 0.6 damage if (malfVal == 1 && vehicle.storage.parts_damage[part_thrusters] > 0.6 && rndChc <= vehicle.storage.parts_damage[part_thrusters] - 0.6 / 0.4) malfVal = 2; // If jammed, % chance of unjamming relative to the damage if (malfVal == 1 && rndChc >= vehicle.storage.parts_damage[part_thrusters] - 0.25 / 0.75) malfVal = 0; } if (malfVal == 0 && thrusterPart.GenVec3[0] > 0) thrusterPart.GenVec3[0] = 0; if (malfVal == 1 && thrusterPart.GenVec3[0] == 0) { thrusterPart.GenVec3[0] = 1; vehicle.storage.AddLogEntry("#tkom_log_malfmin " + vehicle.storage.parts_title[part_thrusters] + " " + itoa(vehicle.PartSubTypeGetNum(part_thrusters, vehicle.storage.parts_subtypes[part_thrusters]))); } if (malfVal == 2 && thrusterPart.GenVec3[0] != 2) { thrusterPart.GenVec3[0] = 2; vehicle.storage.AddLogEntry("#tkom_log_malfmaj " + vehicle.storage.parts_title[part_thrusters] + " " + itoa(vehicle.PartSubTypeGetNum(part_thrusters, vehicle.storage.parts_subtypes[part_thrusters]))); } thrusterPart.GenVec3[0] = malfVal; } } if (malfVal > 0) { vehicle.EmergencyMode = true; // Thusters stuck thrusterPart.DeletePTC(); thrusterPart.StopSnd(PART_SOUNDS_EXTCHNL1); thrusterPart.StopSnd(PART_SOUNDS_EXTCHNL2); } else { if (thrustLevel > 0) { GetMatrix4(thrusterPart, mat1); // Give thrust impulse /*v2 = VectorMatrixMultiply3(mat1, "0 0 1") * thrusterPart.GenVec[0] * phys_FixedTick * thrusterPart.GenVec2[0]; dBodyApplyForce(thrusterPart, v2);*/ v2 = GetVelocity(thrusterPart); float velScale = 1 - fsum(phys_FixedTick * 4); SetVelocity(thrusterPart, v2 * velScale); // If tilted in wrong direction, try to level out /*vector angs = GetAngles(thrusterPart); vector torque = ZeroVec; torque[0] = fsum(cos(angs[0] * DEG2RAD) * -angs[2]) + fsum(sin(angs[0] * DEG2RAD) * angs[1]) * PRB_ANGPUSHMULT; torque[1] = fsum(sin(angs[0] * DEG2RAD) * -angs[2]) + fsum(cos(angs[0] * DEG2RAD) * -angs[1]) * PRB_ANGPUSHMULT; for (int a = 0; a < 3; a++) { if (torque[a] < -PRB_ANGPUSHMAX) torque[a] = -PRB_ANGPUSHMAX; if (torque[a] > PRB_ANGPUSHMAX) torque[a] = PRB_ANGPUSHMAX; } dBodyApplyTorque(thrusterPart, torque);*/ if (!inSpace) dBodyApplyTorque(thrusterPart, Vector(sin(sinInc * DEG2RAD) * 3 * thrusterPart.GenVec2[0], cos(sinInc * DEG2RAD) * 4 * thrusterPart.GenVec2[0], sin(sinInc * DEG2RAD) * thrusterPart.GenVec2[0])); if (fxEnt && fxEnt.FX_Ptc_Thruster != "") thrusterPart.PlayPTC(fxEnt.FX_Ptc_Thruster); thrusterPart.GenVec2[0] = phys_FixedTick * thrustLevel * 4 + thrusterPart.GenVec2[0]; if (thrusterPart.GenVec2[0] > thrustLevel) thrusterPart.GenVec2[0] = thrustLevel; thrusterPart.LerpPTC(thrusterPart.GenVec2[0] * 0.5 + 0.5, EP_VELOCITY); thrusterPart.LerpPTC(thrusterPart.GenVec2[0], EP_SIZE); thrusterPart.LerpPTC(thrusterPart.GenVec2[0], EP_BIRTH_RATE); } else { thrusterPart.GenVec2[0] = -phys_FixedTick * 0.75 + thrusterPart.GenVec2[0]; if (thrusterPart.GenVec2[0] < 0) thrusterPart.GenVec2[0] = 0; thrusterPart.LerpPTC(thrusterPart.GenVec2[0] * 0.5 + 0.5, EP_VELOCITY); thrusterPart.LerpPTC(thrusterPart.GenVec2[0], EP_SIZE); thrusterPart.LerpPTC(thrusterPart.GenVec2[0], EP_BIRTH_RATE); } } } else { if (thrusterPart.ptc_emit) { thrusterPart.GenVec2[0] = -phys_FixedTick * 1.5 + thrusterPart.GenVec2[0]; if (thrusterPart.GenVec2[0] < 0 && GetParticleCount(thrusterPart.ptc_emit) == 0) { thrusterPart.GenVec2[0] = 0; thrusterPart.DeletePTC(); } else { thrusterPart.LerpPTC(thrusterPart.GenVec2[0] * 0.5 + 0.5, EP_VELOCITY); thrusterPart.LerpPTC(thrusterPart.GenVec2[0], EP_SIZE); thrusterPart.LerpPTC(thrusterPart.GenVec2[0], EP_BIRTH_RATE); } } } if (thrusterPart.GenVec2[0] != 0) { float sndVar = sin(part_thrusters) * 0.2 + 1; float sndFreq = 1.2; if (vehicle.storage.parts_subtypes[part_thrusters] == "T_Attitude") sndFreq = 1.6; if (fxEnt && fxEnt.FX_Snd_Thruster != "") thrusterPart.PlaySnd(PART_SOUNDS_EXTCHNL1, fxEnt.FX_Snd_Thruster, SFX_3D, fxEnt.FX_Vol_Thruster * fabs(thrusterPart.GenVec2[0]), 0.2 * fabs(thrusterPart.GenVec2[0]) + sndFreq * sndVar); if (fxEnt && fxEnt.FX_Snd_Thruster_Far != "") thrusterPart.PlaySnd(PART_SOUNDS_EXTCHNL2, fxEnt.FX_Snd_Thruster_Far, SFX_3D, fxEnt.FX_Vol_Thruster_Far * fabs(thrusterPart.GenVec2[0]), 0.2 * fabs(thrusterPart.GenVec2[0]) + sndFreq * sndVar); } else { thrusterPart.StopSnd(PART_SOUNDS_EXTCHNL1); thrusterPart.StopSnd(PART_SOUNDS_EXTCHNL2); } } else { // Delete particle effects if thruster is detached if (thrusterPart) { thrusterPart.DeletePTC(); thrusterPart.StopSnd(PART_SOUNDS_EXTCHNL1); thrusterPart.StopSnd(PART_SOUNDS_EXTCHNL2); } } } /**************************************************************************** ***************************************************************************/ Share this post Link to post Share on other sites
pumpkin 10 Posted November 27, 2013 Hi, actually the scripting language in Take On Mars is extremely powerful. It is very low-level though, which can scare off potential modders, but it is very similar to C++, and actually the entire game is written in script.Happy to know a scripting language exists, even(mostly!) if "very low-level". The greatest difficulty will be to find the syntax of the language; did you plane to create any documentation or a wiki ?The scripts are packed in .pak files but can be unpacked. We'll hopefully release some videos showing how to unpack and mod the files soon.The reason there are no SQF or SQS files is that it supports any text format. If you have a look at the example addon we released on steam workshop, you can unpack it straight from the main menu, and then you can have a look at its contents in:C:\Program Files (x86)\Steam\userdata\YOUR STEAM ID\244030\local\addonpacks\ADDON NAME\ Got it : Addon > pack and unpack (without videos), and test it, and read some ".h" files. During the test, I'm afraid to have discovered a little bug (see feedback tracker ID 0000376: Tech-Tree blocked when unpack addon). I have a suggestion too about... well, just look at the summary : ID 0000377: presence of addon's items in tech-tree. Share this post Link to post Share on other sites
Hugo_Stiglitz 10 Posted February 6, 2015 I have been playing Arma 3 for a while now so of course I would ask this, will we be able to do the same things with ToM as we do with Arma 3 like mods, addon, textures, etc.. Share this post Link to post Share on other sites
felthat 1 Posted February 7, 2015 yes, u can mod tkom etc, u even have workshop, although tkom uses different engine so expect thing to not be excatly the same Share this post Link to post Share on other sites
dram 14 Posted February 9, 2015 Hi Hugo, as FeltHat mentioned, TKOM is very moddable, in fact, the entire game is written in script, and may thus be edited in its entirety. This includes the human controller, spawning of vehicles, creating/dissecting packets, etc. Take On Mars also comes with its own editing suite called Workbench, which allows the creation of terrain, particle effects, materials, and so on. Share this post Link to post Share on other sites
kazesim 2 Posted April 1, 2015 That's too bad, all these years of scripting for Arma 2 and I think I've finally mastered that language, now I gotta learn another. It looks more like C#/Java, which is much better than C++. At least we'll finally have classes and not have to 'select' things out of arrays. I just hope we get some good documentation. Share this post Link to post Share on other sites
bardosy 158 Posted June 15, 2015 I play TKOM in single and manned missions are really busy. I would be great if the player could print rover parts and build together to a non-science, but working rover and then program it: eg a rover check the marsdust container in the transformer machine and if it's empty, the rover can take it and bring to the dustmaker and fill it. Just a suggestion to the future. And yes, my idea was inspirated by Colobot. ;) Share this post Link to post Share on other sites
T-1000 0 Posted August 22, 2015 Hello, After spending a day in game I noticed the gameplay could be improved by adding user space scripts for managing rovers navigation, etc if that would become as optional part of gameplay. There are basic commands already so why not to expand on this? :) So the long hours spent for just driving rover or similar thing could be exchanged with something else in background while that small rover moves 2km+ between two exploration sites using gamer made script in rovers 'console'. If anyone is familar with Ceebot(Colobot) old game - http://www.ceebot.com/ceebot/index-e.php it had that functionality and was really fun to play with. Cheers! Share this post Link to post Share on other sites
shadeemry 0 Posted January 17, 2016 So, not to sound rude, but has anyone found the name of this scripting language? Share this post Link to post Share on other sites
noubernou 77 Posted February 9, 2016 So, not to sound rude, but has anyone found the name of this scripting language? It looks like C++/CLI. It is basically a CLI (the .NET bytecode) version of C++. It is pretty nice, though it is not _standard_ C++ (and I believe it lacks a lot of features from C++/11 and C++/14 [and nothing from C++/17]). Share this post Link to post Share on other sites