Jump to content
Sign in to follow this  
[frl]myke

ArmA 2 Scripting lessons for beginners

Recommended Posts

Introduction:

Often i see threads that roughly looks like follows: "Hi all, i would like to create <description of very complex mission idea> but i have absolutely no scripting kills. What do i do now?"

First of all, of course it's nothing wrong with having high-level plans. But, it is better to start off with simple things in scripting since directly trying to create very complex systems, fail is preprogrammed already. One need to understand how scripting works at basics and then, based on that knowledge, refine scripting techniques and gather even more knowledge.

Just as an example, myself i've started scripting ~5 years ago but i guess i've just mastered maybe 50% of whats possible and doable. But i'm also a slow-learner aswell.

So, creating complex scripting systems is a time consuming and more than often a frustrating process. Be aware of this before you start. If you're not patient or not so willing to just sit down and read pages of (often boring but nonetheless important) tutorials and forum threads, then maybe rethink your plans for something more simple is better.

Ok, you're still here, fine. I will give you some problems to solve, beginning with some rather simple things, goin for more complex as we proceed. If this threads evolves, you might find code snippets from other forum members that already might have solved a problem you're actually working on. You might copy/paste these snippets but you just will fool yourself as you didn't understand how to solve the problem itself.

Problem 1:

Create a infantry unit on position A and make him move to position B.

Use only scripting. Don't use triggers at all (exception: radio trigger to start the script)

Possible extensions:

Create a empty vehicle of your choice inbetween point A and point B and make the unit use this vehicle to reach point B. Also make him disembark vehicle at point B. Still no triggers allowed.

Problem 2:

Create a group of enemy units at position A. Make them hunt you down. Add some randomness so they don't move to your exact location but nearby. Do not use triggers except for starting script.

Possible extensions:

As soon they know you're in the area, make them split and trying to flank your position. You might also include a vehicle as you see fit.

:EDITH:

Ok, for those who already solved the first two problems, here another one, altough a more simple this time. To solve it, reading configs from within the script is necessary:

Problem 3:

Create a unit of class A (you're free to chose) but with the weapon loadout of a unit of class B (also free to chose, can also be from another side/faction). Define both classes from the scriptcall:

_nul = ["classNameA", "classNameB"] execVM "yourScript.sqf"

Possible extension:

Include a spellchecker that checks if classnames are valid and throws out a proper hint if not.

...more to come depending on feedback...

Useful links:

ArmA 2 command reference

Notepad++

Notepad++ plugin: .sqf synthax highlight

Squint sqf editor

Edited by [FRL]Myke

Share this post


Link to post
Share on other sites

My problem is thinking way to big. I try to make the most complex and difficult to make ones... when I should focus on basic stuff for now.

I consider myself a beginner to scripting. But it is the one thing I really want to learn (besides island making, but I know better than to try that) so that's where most of my attention is on these forums. I really would like to put out some quality missions along the lines of W0lle, Celery, Zipper5, etc (not to disrespect anyone else of course).

So, this will help me. As simple as these problems are I simply can't do it without using references. I've been avoiding cut and pasting and even try to comment my own scripts just for the repetition. But I'm a slow learner with this as well. I'll keep trying though.

Thanks again, you and everyone else who teaches and corrects us, I'd be a lot further behind without the help. :)

Share this post


Link to post
Share on other sites
I try to make the most complex and difficult to make ones... when I should focus on basic stuff for now.

We ran into this kind of issue with a mission the other night. The beginning of the mission was meant to be a HALO insertion from a C-130J at a specific point, then you fly towards an LZ.

Problem was, the Receiving... screen blacked out the whole first 30-40 seconds of the mission. That was than followed by a blackout intro screen. By the time players had any control they were about 200m from the tree tops. By the time they knew this they were dead.

Then came the problem where the plane people dropped from... was a real plane! So anyone that JIP'd in ended up jumping from the plane wherever it happened to be circling at the moment, waaaay far away from the AO.

So as cool as "jumping from a C-130J" can be, they implemented it in a very sloppy manner. Instead they should have either virtualized it (start people in the air automatically and skip the whole "you're in a plane, now get out!" thing or use the static model of it, so if you joined in later you'd start from the correct location.

So come up with ideas, then try to make them as simple and effective as you can. :) That's the real challenge.

Share this post


Link to post
Share on other sites

As far as i can tell, people tend to choose the most complicated things to start with. Everyone started as complete noob, no one was born with all knowledge that is required. The ArmA 2 script engine is pretty powerful but this also has the effect that things can't be achieved in simple manners (mostly) just because it is so open for everything.

So, start small. First walk, then drive and as last, fly.

Share this post


Link to post
Share on other sites

Good idea for a thread. :)

IMHO, Problem 2 is a bit of a jump from Problem 1, though.

I'll see if I can think of some things, too. Maybe have something to help people start exploring the init.sqf mission start?

Edit(s):

Perhaps lesson 2 could focus more on the position array - manipulate the parameters to change where things are in relation to each other? (Works getPos and setPos.)

Maybe for problem 4 or 5 (or later), but the Waypoint array is somewhat unique. Maybe an exercise in changing where the waypoints are, and which one is active.

Oh, and hint, using hint with structured text (format ["blah %1", _testvar]), and diag_log for reporting. That would be HUGELY valuable for bug squashing later.

Edited by TRexian

Share this post


Link to post
Share on other sites

Very good thread indeed, Myke. Maybe you should explain to the unexperienced crowd what a script really is. For years people complain about "not using too many" scripts. However they don't get the idea that the whole editor is just a basic scripting portal and outsourcing editor code into separate files is for easier usage. Of course that's one of some reasons.

Share this post


Link to post
Share on other sites

Myke, I love this idea. I also think way too big, but I do have patience....well, sometimes...but would like to see more problems or codes to try out.

Share this post


Link to post
Share on other sites
Myke;1807298'][

Problem 1:

Create a infantry unit on position A and make him move to position B.

Use only scripting. Don't use triggers at all (exception: radio trigger to start the script)

Possible extensions:

Create a empty vehicle of your choice inbetween point A and point B and make the unit use this vehicle to reach point B. Also make him disembark vehicle at point B. Still no triggers allowed.

if (isServer) then {GroupBF = CreateGroup East};

BFCAS = createVehicle "I44_Plane_G_Bf109F2_SC50_WL";

[(getMarkerPos ""BFSpawn"") select 0' date=(getMarkerPos ""BFSpawn"") select 1,100], [], 0, ""FLY""];

BFPilot = GroupBF createUnit [""I44_Man_G_WL_Pilot_P38"", [0,0,1], [], 0, ""CAN_COLLIDE""];

BFPilot moveInDriver BFCAS; BFPilot setSkill 1;

wp1 = GroupBF addWaypoint [(getmarkerpos ""BFTarget""), 0];

wp1 setWaypointCombatMode ""RED"";

wp1 setWaypointSpeed ""FULL"";

wp1 setWaypointType ""GETOUT";

not sure if that will work for the first problem. Requires a pre-placed trigger activated by radio, and 2x markers which could be scripted on activation before calling the BFCAS scripty.

Edited by Ebolavirus
activated by anyone becomes radio activation

Share this post


Link to post
Share on other sites

Ive been playing with execFSM for fsm scripting and found things that it can do things that sqf just cant, my BattleField 3 is 80% FSM code , if you would like some input into FSM i will be glad to help, Yes it is no harder than sqf in fact i find it easier in most cases it just does thing differently and can get around some probs .

Share this post


Link to post
Share on other sites
Ive been playing with execFSM for fsm scripting and found things that it can do things that sqf just cant, my BattleField 3 is 80% FSM code , if you would like some input into FSM i will be glad to help, Yes it is no harder than sqf in fact i find it easier in most cases it just does thing differently and can get around some probs .

I haven't looked too deeply into FSM other than some examples for conversations with npc's.. I've always thought FSM was predominantly used give the perception of AI reacting more organically, rather than mechanically. I'd be interested to know how easy it is to debug an FSM vs sqf routines.

Share this post


Link to post
Share on other sites

Myke this is a great idea.

im putting this in here as i think learning to use FSM aswell as SQF is a good way to go

bistudio's FSM_Editor

using execFSM is the same code as sqf debugged in the same way.

Main difference is the speed of the code , you create 2 scripts 1 in sqf and the same code in FSM , the FSM will create vehicles and units much quicker,

you cant use waituntil or sleep, but there are very simple ways around that.

(time > _timeout + 10)

Im no expert and still learning even some of what it can do

the code cant have errors or undefined values, it will complain.

except if you dont have a }; where you should , the code just stops without an error message.

From how it looks to me is, it is snippets of sqf code put into case statements

when you get used to using the editor "which is not hard" if an error is in your script

because of the way its written as a bunch of case statements and is very visual its easy to work out where the error is. without having to search through lines of code.

To debug BF3 i just used a titletext in each section to make sure the right values were

getting to where they should be.

if i had the same script running in several objects i would just name one and put

if(_name == whatever) then

{

titletext blah blah;

};

in the FSM script

then you would only see the debug info from one script not 100

i also found the breaking up a large FSM scripts into several smaller ones to be more efficient. seemed to use less memory and cpu while the speed of the code didnt change.

For camera scripts and scripts that loop or where you may have alot of different options depending on what may happen, FSM is excellent. say you had a point where if one of 5 things happened it did something, SQF can do that but if by some 1 in 1000 chance all 5 things happened at once "dont laugh it does happen" with FSM you can give each of the options priority "which one to do first" so just by putting in a number saves writing alot of code,

IE:

if (damage > .2) then {hint "ouch"}; set to priority 0

if (damage > .7) then {hint "f%$^ ouch"}; set to priority 1

first it will check to see if damage is > .7 is so it will do whatever for .7 if not it will do whatever for .2

it will not do both.

if (damage == 1) then {hint "dead again"}; set to priority 2

and if you add more set the priority to importance

you can do the same with SQF in this case you just need more code

but in some cases you can only achieve what you need to do with FSM

In BF3 i use it for all of the server sided scripts as well as the respawn scripts which are client sided.

it cant be used for everything , but where you can you will find it more stable.

Edited by Zonekiller

Share this post


Link to post
Share on other sites

The real strongpoint of using fsm is visualized branching. This is fully possible to do using normal scripts, even a single one, but I wouldn't recommend it. When you come to the point where using fsms to get a handle on branching, I think you've passed the point where it is meant for beginners.

Beginners should be made aware of the basic concept of fsms, but no need to go at it in depth. I think getting around the basics of sqf, it's syntax, how to make good looking code etc should be the main goal. Make projects that aren't overly complex to solve, that doesn't require you to be an expert on all the specialized keywords (this scripting language has plenty). I think even basic c++ assignments should be a good start to get an idea on flow.

One of the most annoying things I see here are requests for help without using the code tags to get the code properly indented. When I see code in quote tags, especially with plenty of blocks, I just ignore the request. I've asked moderators if it's possible to have the code tag available in the quick reply field, but they suggested need to hack it so I'm not sure if it's easily possible.

Edit: A great source of learning, at least has been for me, is to hack other missions. BIS own missions have a style and MP considerations that make them hard to understand, that I wouldn't recommend for a complete beginner. Other than sporadic scripts for OFP, I started out modding Evo for Arma1, but found it too hard to read and understand. So I switched to Domination which was very well written and commented. Domination today (or upcoming D4) are no longer written for the beginner to understand, but I'm not sure what would be a good mission to start from.

Slightly off topic, but... One thing worth mentioning though regarding fsms, not so much for scripting as for mission making in general, is to take a look at BIS own missionflow.fsm stuff, where debugging and cheat codes are used to advance the mission to a certain point. People not only wants to create overly complex scripts, but also overly complex missions for their skill. All you need is an fsm editor, and what's in it becomes pretty obvious.

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites

@Zonekiller & CarlGustaffa

i hate to stop people, especially when they put up such excellent posts. The intention of this thread is to throw some easy problems to solve for absolute beginners so they can have a start to get used with scripting, making the really first steps. The problems given in my OP gives a start and once a "Newbie" has solved these, he might expand them for more functionality or clean them up for faster execution.

Just a point to start small and then grow with the arising problems step by step.

Ok, for those who already solved the first two problems, here another one, altough a more simple this time. To solve it, reading configs from within the script is necessary:

Problem 3:

Create a unit of class A (you're free to chose) but with the weapon loadout of a unit of class B (also free to chose, can also be from another side/faction). Define both classes from the scriptcall:

_nul = ["classNameA", "classNameB"] execVM "yourScript.sqf"

Possible extension:

Include a spellchecker that checks if classnames are valid and throws out a proper hint if not.

Edited by [FRL]Myke

Share this post


Link to post
Share on other sites

Professor Myke is expecting high scores on his assignments. :cool:

But yea I agree with your first post. For some reason I see a lot of people trying to accomplish things that are way too ambitious to start with.

Edited by Big Dawg KS

Share this post


Link to post
Share on other sites

Peeps, don't get me wrong, it is ok to have high ambitions...as long you know you have to start a bit smaller for the first steps. ;)

Share this post


Link to post
Share on other sites

An absolute beginner should be given hints as to what is classnames (what's their job), where does he find them (by de-pbo'ing addons), how does he extract them (using a linked tool), and how does he convert it into something readable (using CfgConvert in BITools2).

Without knowing the structure of what he's looking for, he might find himself into a lot of grief. I don't consider myself a beginner, and I read config values all the time, but I still have to look up the syntax :p

Not to criticize, but I think the goal is a bit high on this one, for a complete beginner at least. Unless there are some methods I don't know about, making me the complete beginner :D

Share this post


Link to post
Share on other sites

might i suggest for the next problem, to use arrays and set variables to their proper scope? as you could tell from my other thread i just go braindead when trying to read scoped variables and manipulating multidimensional arrays (your script you showed me has me even more stumped about how to just use unit1 in the script and not all of the units.)

i dont know why, but when it comes to understanding the code when having multidimensional arrays and script in script, i just cant comprehend whats being executed

Share this post


Link to post
Share on other sites

@Myke: Good thread idea!

Anyways, here's my solution to the first one for you scripting masters to critisize:

 Private ["_posA", "_posB", "_posVehicle", "_grp", "_s1", "_wpVehicle", "_wpEnd", "_eastCentre"];

// In case side centre has not yet been created (do I need to check to see if it exists?)
_eastCentre = createCenter east;
_grp = createGroup east;
_posA = getMarkerPos "A";
_posB = getMarkerPos "B";
_posVehicle = getMarkerPos "Vehicle";

_s1 = "Ins_Soldier_1" createUnit [_posA, _grp];
_Vehicle1 = "car_sedan" createVehicle _posVehicle;
sleep 0.5;

_WpVehicle = _grp addWaypoint [_posVehicle, 0, 0];
[_grp, 0] setWaypointType "GETIN";

waitUntil {_s1 in _vehicle1};
_WpEnd = _grp addWaypoint [_posB, 0, 1];
[_grp, 1] setWaypointType "GETOUT";

waitUntil {!(_s1 in _Vehicle1)};
hint "Task Complete";
_s1 setDammage 1;
_vehicle1 setDammage 1;
titleCut ["Because I felt like it", "Plain"]; titleFadeOut 4;

Let's see what mark Prof. Myke gives me :bounce3:

Ok, now I'm going to start working on number two...

Edited by kyfohatl

Share this post


Link to post
Share on other sites

@kyfohatl

Your script looks good and i guess you also tested it to see if it works. Only thing i would change (but rather because of personal preference than urge) is to not hardcode several things like classnames and markernames to be passed with scriptcall. Makes the script better reusable for different purposes.

Share this post


Link to post
Share on other sites

@Myke: Good point. I changed the script to include your advise. However, the original script does not work :o as I just found out by testing. The soldier and the car are created, however the waypoint command does not seem to work, because the soldier just stands there. This variation however does work (I've tested it):

Private ["_posA", "_posB", "_posVehicle", "_grp", "_s1", "_eastCentre", "_vehicle1"]; 

// In case side centre has not yet been created (do I need to check to see if it exists?) 
_eastCentre = createCenter east; 
_grp = createGroup east; 
_posA = getMarkerPos (_this select 0); 
_posB = getMarkerPos (_this select 1); 
_posVehicle = getMarkerPos (_this select 2); 

_s1 = (_this select 3) createUnit [_posA, _grp, "myUnit = this"]; 
_Vehicle1 = (_this select 4) createVehicle _posVehicle; 
sleep 0.5; 

_grp move _posVehicle; 
waitUntil {(myUnit distance _vehicle1) < 8};
myUnit moveInDriver _vehicle1; 
sleep 0.5;

_grp move _posB; 
waitUntil {(myUnit distance _posB) < 2};
sleep 2;
moveOut myUnit;
sleep 3;
hint "Task Complete"; 
myUnit setDammage 1; 
_vehicle1 setDammage 1; 
titleCut ["Because I felt like it", "Plain"]; titleFadeOut 4;  

It is called by: 0 = ["A", "B", "Vehicle", "Ins_Soldier_1", "car_sedan"] execVM "Challenge1.sqf"

The downside to this new version is that the "moInDriver" and "moveOut" commands do not display animation of the unit getting in/out of the car. So they look a bit awkward, which is why I was trying to use "addWaypoint" instead, but it doesn't work. Any comments?

Share this post


Link to post
Share on other sites

@kyfohatl

Take a closer look to assignAsDriver and orderGetIn, maybe this will get you the desired result instead of moveInDriver. ;)

Besides that, i don't want check your script. It is for yourself to encounter some (as i see it) very basic problems and find ways to solve them. Obviously you achieved this goal since your first attempt wasn't working while your second does. So you surely learned a few things while writing this script.

That's how this thread is supposed to work: the more experienced scripters (not only me, any help is welcome) pointing the newcomers some valuable stuff to learn, especially for a start-off.

So, basically i don't want to see your code, although everyone's free to post theyr approaches. And surely i (may i say "we"?) will try to help to fill the gaps.

Share this post


Link to post
Share on other sites

kyfohatl,

Can you post the fixed version of the challenge script? I just want to see the working script so I can learn how to do it. Great info here guys!

Myke,

These "instruction" threads you've started here are fantastic! Thank you to all that helped.

Share this post


Link to post
Share on other sites

Myke,

These "instruction" threads you've started here are fantastic! Thank you to all that helped.

Just giving back what i received from the community in the past. ;)

Share this post


Link to post
Share on other sites

I'm digging up this thread, it needs to be further built upon. Maybe a sticky? Also, maybe some other simple things could be added to the OP list. ammo check,fuel check, distance check etc etc.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×