Mondkalb's Addon Tutorial

From Bohemia Interactive Community
Revision as of 05:50, 29 December 2020 by Lou Montana (talk | contribs) (Text replacement - "{{SideTOC}}" to "{{TOC|side}}")
Jump to navigation Jump to search

In the following tutorial, I will explain to you in ten easy steps how you plan an addon, create the model, create the textures, put the textures on the model, how to get moving components into it (in this case, a working door), how to implement proper damage simulation, how you get this addon to Arma 2 and how you can release it.

Last Update: 21. October 2009 You can find a German Version of this tutorial here;

If something is not easily understandable, please help me to make it so :)

Step One: Plan the Addon

Before you start modelling anything for ArmA2, you should think of what you're going to do. This decision is not always as easy as it sounds. At first you should see, whether the project - the Addon - is useful and has a use in Arma 2. For this tutorial I've decided to create some Walls for a current project of Armed Tactics (20.10.2009). So I'm going to put up some criteria:


  • The wall segments should have compatible measurements so they fit together
  • The wall segments should provide good cover.
  • A door for the wall segments should be available.

Now we've set our goal, let's start.

Step Two: Work basis

Firstly, before you do anything in O2, you head for your work-in-progress directory (you do have one, don't you?) and create a new folder for your "Soon-To-be"-Addon. Umm, but how should it be named? Well, here we are at the first Addon-Artist Rule: The Nametag.

Certainly you've stumbled over these little Three-Letter tags infront of every addon-name. This nametag is very important to prevent conflicts between addons of the same name.

http://img94.imageshack.us/img94/7239/nametag.jpg The Nametag and the Addonname in their natural habitat inside of an "@AT"-Modfolder.

Example: You're releasing an addon named "cars.pbo" which increases the speed of all vehicles by 200km/h and someone else is also releasing an addon of the very same name, but his addon adds two new vehicles to the game. Thanks to Modfolders, these two totally different but same-named addons can be used in parallel, but the confusion stays.

As it to name? Since we want to make walls, I suggest to name a folder "ABC_Walls". The "ABC" is your own Addon-Nametag. If you don't have such an nametag, well, go ahead and create one. Three letters minimum, five letters maximum. If you have found one that suits you, jump over to here and check whether it is already taken by someone else (Again that fella...) or not. If your wanted nametag is already taken, well... you'll have to think of a new one. IF your nametag is free, go ahead and register it (Upper right corner: "Register a tag") Done. Now change the folder name and continue.

For tutorial purposes I chose the nametag „TUT“. So our folder will be called "TUT_Walls".

Step Three: Create the model

Start "Oxygen 2" (O2). If the Bulldozer won't open by itself, click this button: http://img237.imageshack.us/img237/594/bulldozer.gif. Save the project (click on the "floppy disk" symbol), head for the folder which you created and save the object as "TUT_Wall_3x3m.p3d". Make sure the path to your saved .p3d file doesn't contain any non-english characters, else the error will occur.

http://armtac.ar.funpic.de/O2Tut_EN/SpeichernDerDatei.jpg


Create wall

Wall segment will be a rectangular prism 3 m (long) x 3 m (wide) x 0.25 m (depth). Go to the "Front" viewport. Click menu "Create" > "Create Box". Enter the dimensions and click "OK".

http://img245.imageshack.us/img245/2451/createbox.jpg

Move your wall segment with the move-button (http://img237.imageshack.us/img237/360/move.jpg) by +1.5m on the Y-Axis, so it wont be stuck in the ground. Save the object.


Create wall with a door

Save the object again but this time go to "File" > "Save As...", and save it as "TUT_Door_3x3m.p3d".

Working with vertices in O2. Vertices are points allocated on intersection of edges of model. The wall-model in front of you should have eight vertices. You can check the amount of vertices that are currently in your model in the lower left corner of O2.

http://img94.imageshack.us/img94/6357/points.jpg

A model with around 2000 faces is Low-Poly.

Now you want to get an opening in this wall through which you can walk. And a door would be great. To accomplish this, you need to delete some Faces (Not vertices!)

Select the whole model with either using this button ( http://img245.imageshack.us/img245/2359/selectlinked.jpg )or hit "Ctrl+A". Now all lines should appear red.

To remove the faces, hit "D". The red lines vanished, but the vertices remain. Thats how it is supposed to be.

Now you need to create the "hole in the wall". Do make this an easy task, do the following: But, halt! How wide should be the door-hole? And how high? A witdh of 1.2 meters and a height of 2.2 meters should be appropriate dimensions. Now you have 90 cm left for the right and left rest of the wall, if you want it to be an 3x3m segment.

At first change your selection-mode to "Select Vertices": (http://img148.imageshack.us/img148/3333/selectvertices.jpg). Now select the lower left vertices in your "Front"-View. It seems like you have selected only one vertices, but in fact it are two, since you cannot see the 3rd Dimension in this viewport. The selected Vertices should now appear red. To check this, you can move around in your "3D"-View (Not Bulldozer!) - hold "ALT+LMB" while moving your mouse. Hold the "ALT+RMB" to change the camera's angle.

Hit "Ctrl + C" and then "Ctrl + V", to create a copy of the vertices. The copied vertices are now automatically selected. Move the copies with the "Move" button by 0.9 mters on the X-Axis. Copy and paste these two vertices again, and move them by 1.2 meters on the X-Axis. At last copy the four, new created vertices, paste and move them by 2.2 meters on the Y-Axis.

If nothing went wrong, it should look like this:

http://img245.imageshack.us/img245/69/3dpreview.jpg

The handy 3D-View

Now you have to assemble all the faces together by hand. To do so, select at least three, maximum four vertices and hit "F6" once. The "Top"-View is the most helpful view to do this. When handling complex models, the 3D-View should be your first choice. When you have created all Faces, check the model for unwanted holes. To do so, go to "Structure" -> "Topology" -> "Find Non-Closed". If nothing red appears, everything is fine. But if something does appear red (selected), you'll have to redo this section and their surrounding faces.

(Select the already red marked vertices, the next vertices around them. To add something to your selection, hit "Ctrl" while selecting. Now hit "D", and solve the problem with some "F6"-work.)

Hitting "Shift + Ctrl" while selecting will remove the vertices in your mousebox from the current selection. Try messing around with these hotkeys while selecting things, to see what I mean. If everything went well, it should look like this:

http://img405.imageshack.us/img405/5886/fertigfaces.jpg

3D-Window is the best for detecting errors.

Next: Have a look in Bulldozer. Click once with the LMB in any View to deselect the whole model, and switch to Bulldozer. While holding the RMB you can rotate the model in Bulldozer. Holding LMB will change the position of the camera. "W,A,D,S" will also change the camera's position, but I strongly recommend not to do this by keyboard, since some keys will trigger events in O2, which can be bad news when triggerd unintentionally. Especially the "W"-Key.

http://img237.imageshack.us/img237/1092/fertigbulldozer.jpg

Bulldozer: Solving problems since 2001...

But hey, what's that in bulldozer?

One face of the doorframe is missing! But you definately remember creating it... And the lighting is also a bit... unfortunate. Solve the issiues with the following:

Try to spot the missing face in your "3D-View". Those "Messy-Faces" are usually easy to spot while having the whole model selected. When you've found the bad three (or four) vertices, which add up to the missing face, select them (With the "Vertice Selection"-mode, and hit the Devil's Key No. 1: "W". This key Inverts the facing of this face. (odd sentence...) The "missing" face was always there, but facing simply in the wrong direction resulting in "nothing" to see. You can determine the facing of face by its blue lines coming form each vertice when having the face selected.

To fix the lighting, select the whole model and hit "U". See the result in Bulldozer. The exact opposite function of that key is performed by hitting "I".

http://img243.imageshack.us/img243/8138/finalobjekt.jpg

Nearly done!

Everything is as it should be? Save!

Now a door has to be created. So select the Doorframe (the eight "new" vertices), copy, paste and move them by 1m on the Z-Axis, to make it easy accessable in the viewports. Hit "W" once. Close all remaining empty faces with the "F6"-method. Now check for "Non-Closed". Select in the "Top"-View the upper two vertices (actuallyfour) and move them by -0.2 meters on the Z-Axis. To complete the Door, select it completely and move it by -0.9m on the Z-Axis and hit "U". Done and save! Important: The door has not to be connected with "F6" to the doorframe.

If you have understood this little excerpt of how to construct the door, you're capable of creating and modifying models. Single vertices can be created via the "Insert"-Key The're then created on the position of your mousecursor.

Step Four: Creating the UV-Map

A proper way of texturing the model is to do it with an "UV-Map". You'll soon be able to explain what an UV-map is, so stay tuned.

Start Photoshop and create a new file with the dimensions of 1024x1024 pixels. (Or 2048, if you're a Hi-Res Freak like me) „File“ > „New“.

Now fill this picture wiht blue.. „Edit“ > „Fill...“. The Blue color is an aid when working in the UV-Editor, you'll see what I mean.


Save this file as „TUT_Wall_CO.TGA“ to „TUT_Wall“ folder. Compression: 32Bit/Pixel.

Switch back to O2. Now press „A“ to get into the texture mode. Draw a box while holding LMB in any View. Click with the RMB into this box. Select „Load Texture“ and choose in your "TUT_Wall" folder your newly created .TGA file. O2 will convert it automatically to the .PAA file. If Oxygen2 leave loaded texture as .tga file, you should go to File/Options menu and tick the "Autoconvert GIF & TGA textures" checkbox.

When O2 has converted the texture, you'll be able to see it in your drawn, black surrounded box. Now fire up the UV-Editor by clicking on this symbol in the upper menu bar: (http://img27.imageshack.us/img27/1791/uvedit.jpg)

The following window should appear:

[1] The UV-Editor.

If this menu doesn't appear, it is stuck in the Taskbar. Simply clicking on it won't help. RMB on the Taskbar-entry and hit "Recreate"/"Recover".

Now load a texture to the UV-Editor. To do so, click on „Filter“ -> „Browse new texture...“. Select your „TUT_Wall1_CO.paa“. The screen should be filled with blue color. To change the zoom, use your mouse-wheel.

Back to O2: Select the whole model, single-click with the "Ctrl"-key and your LMB into the "Front"-View. Back to the UV-Editor.

Click on the following symbol: (http://img40.imageshack.us/img40/5067/planarmapping.jpg).

That's how it should look:

http://armtac.ar.funpic.de/O2Tut_EN/Planarmap1.jpg

Planar mapping does the trick.

And now remove the newly created selection in the UV-Editor by hitting your "Delete"-key. And yes, this is mandatory. :)


Switch back to O2, again... select using the „Vertice-Selection tool“ in your „Top“-view the upper side of the whole Doorframe (Excluding the door!). Now switch to the „Touch Faces modus“ (http://img18.imageshack.us/img18/204/touchfaces.jpg). Select the other side of your wallsegment (You've already selected the back of it, now the front has to be selected) while holding the "Ctrl"-key in the "3D"-View. If everything went well, it shoud look in the "Top"-view like this:

http://img63.imageshack.us/img63/6220/topviewr.jpg

Would you select the front of your wall by using the "Vertice-Selector", everything would be selected. And that is not wanted.

Only the horizontal lines are red! Click together with the "Ctrl"-Key into your "Front"-View and head back to the UV-Editor. Hit the Planar Mapping button. It seems there is no difference to the last time when you did this. But that is simply not true.

http://armtac.ar.funpic.de/O2Tut_EN/Planarmap1.jpg

Yep, it is the same picture from last time, but it simply DOES look like this, again.

Now hit the „Simple Unwrap“-Button (http://img63.imageshack.us/img63/2643/simpleunwrap.jpg) and it'll look like this:

http://armtac.ar.funpic.de/O2Tut_EN/Unwrapped.jpg

"When a problem comes along, You must wrap it Before the cream sits out too long, You must wrap it When somethings going wrong, You must wrap it"

Single click into the blue to deselect everything. Now your model is unwrapped. Bt some faces are inside of others, and usually not wanted.


Simply select the malplaced face:

http://armtac.ar.funpic.de/O2Tut_EN/neueAuswahl.jpg

And hit the „Break Selection“-Button (http://img96.imageshack.us/img96/8348/breakselection.jpg) to deselect isolated vertices. Now move the face up, so it'll align to the upper line of the doorframe-Faces. Now click on the „Snap to nearest point“-Button (http://img18.imageshack.us/img18/4782/snaptonearest.jpg) to snap it to it.

If needed, you can rotate faces. To do so, click on the „Rotate“-Button (http://img18.imageshack.us/img18/5772/rotates.jpg). In the appearing menu select „Rotation“ and enter the wanted angle. It's important to have „Pixels (Keep tex.aspect)“ selected.

http://img208.imageshack.us/img208/6508/rotatemenu.jpg

Anther handy, little thingy.

Repeat this with all malplaced faces, until it looks like this.

http://img40.imageshack.us/img40/1518/finishedunwrapping.jpg

Done!

Now move the whole thing into the lower left corner of one texutre-segment. Scale it up/down to make it taking approx. ¼ of the texture-area to leave some space for other faces/objects. Save in O2!

Unwrapping the door is much easier. Select the whole door, "Ctrl + LMB" into the "Front"-View, hit "Planar map". Delete the UV-Map. Then select only the front-face and the back face of the door, "Ctrl + LMB" into the Front-View. Hit "Planar Map" and then Simple unwrap. At last change it is position.

Now click in the menu-bar of the UV-Editor on „UV Editor“ -> „Export...“. In the following menu you adjust everything like the following picture. The "2048" is to be replaced by your chosen texture size. You have now created your very first EMF-file. You'll have to convert it with Irfan View to JPG. Or use the EmfToPng.exe in your Visitor-Folder, if you have installed it.

If your EMF file is not in a quadratic shape, you'll have to adjust the position of your Objects in the UV-Editor by the amount of texture-segements that the misaligment of the .emf suggests. Also, make sure tick checkboxes in UV Editor EMF export dialog to either keep ratio or directly specify file dimensions.

[2]

Fitting the UV-Map.

Do the same with the wall segmant without door, but save the EMF and the JPG under a different name. Align the wall to the upper left corner.

Load the converted EMF-Files into your Photoshop-project. The second EMF file may overlap the first one in the photoshop workspace, so you'll need to crop the second with this tool: (http://img42.imageshack.us/img42/9590/auswahlrechteck.jpg)

It should look something like this:

[3]

Now the fun begins: Creating the texure.

Step Five: Creating the texture

Im going to to explain two important ways of creating/mixing textures.

Get textures

Since we'd like to have something concrete like a concrete wall, we hop on over to www.cgtextures.com and look for fitting textures. For Tutorial-Purposes I'll use the following textures:

ConcreteBare0022_3_M.jpg

ConcreteBare0032_M.jpg

ConcreteNew0019_M.jpg

You can easily find them on www.cgtextures.com by clicking in the upper menu on „Textures“ -> „Advanced Search“.


At first I'll load all three textures into the photoshop-project.

Scale the „ConcreteBare0022_3_M“ so it will fill ¼ of the file. Hold the „Alt“-key and drag it to the right corner. A copy has been created. Repeat this until the file is covered in concrete. Select all copies and the original layer in the layer-menu and select "Reduce to one layer".

Now make the concrete layer seamless with the Repair-brush: (http://img237.imageshack.us/img237/3430/reperaturpinsel.jpg). Scale "ConcreteNew0019_M" up so it'll fill the complete file. Hide "ConcreteBare0032_M" with a click on the eye in the Layer-menu.

Drag the "ConcreteBare0022_3_M"-Layer (The seamless concrete) in your Layermenu to the uppermost place. Duplicate it. Hide the original. Doubleclick on the copy in the layermenu. The following window will appear.

http://armtac.ar.funpic.de/O2Tut_EN/F%fclloptionen.jpg

Trick 17... Oh, and excuse this picture being in german, jawohl?

Toy around with the "Colorarea"-Slider, until 50% of the layer are vanished. Click OK and create a new, empty layer underneath the one you edited right now. Merge these two (the 50%-one and the empty one) together. To do so, select them both and hit „Ctrl + E“.

Now click with the "Ctrl"-key on this new layer. It should look like this:

[4] Click to enlarge. And again: Ignore the german text.

Now hide these two layers, click on the layer with the "complete" concrete and click on the "Add layermask"-Symbol

http://armtac.ar.funpic.de/O2Tut/Ebenenmaske.jpg


Unhide this layer and duplicate it. Select the Layermask of the layer in your layermenu. (another odd sentence...) Click on „Filter“ -> „Blur“ ? „Gaussian blur“ and blur the whole thing by 4 px. Reduce fill and opacity of this layer to 60%. Remove the duplicate's layermask, hit it with your RMB (no, don't take this literally) and select "Remove layermask". Reduce opacity and fill of this layer to 40%.

Create below the "ConcreteNew0019_M" layer anew layer, which you'll fill with a 50%-Grey, (128,128,128)

Reduce the opacity and fill of the „ConcreteNew0019_M“-layer (Not the one from one sentence ago) to 90%.

If everything went well, it should look like this.

[5]

Guess what: It's nearly done.

Dirt layer

Hide all layers exept the EMF's. Now unhide "ConcreteBare0032_M", duplicate it, hide the original, reduce its color area so the cracks and dirt remain. Join this with a new, empty area. "Ctrl + LMB" on this area and create an layermask of the original layer of this texture. Blur it. Delete the duplicate and unhide the original.

To create a tile of this dirt, to make it seamless when more segments are placed together forming a wall, you'll need to duplicate this "Dirt"-Layer and mirror it horizontally.

Create a layermask to this duplicate and paint everything exept the lift corner of this layer with a black Grunge-brush on the layermask.

You can get grunge-brushes at this site: [6]

When finished, it should look like this.

[7]

Dirty, but realistic.

Now you can join these two dirt-layers to one. For safety-purposes duplicate and hide it.

The unhidden one can be moved by pressing "Ctrl + T". Move it in place so the dirt covers the top and the bottom of the wallsegments. You can enhance the whole thing with grunge-brushes on the layermask. But try to keep it tileable by only changing the middle part of this layer.

Same goes for the door. When finished, it should look like this. [8] Dirty stuff...

Now unhide all concrete-layers and save it as „TUT_Wall_CO.tga“. Backup this one by saving it as a .PSD-file!

Convert this texture in O2 to .paa and have a look in bulldozer.


When a face is displaying the texture with a wrong aligment, simply select it in O2, go over to the „UV-Editor“ and select it with the „Select Faces by Selection“-button: (http://armtac.ar.funpic.de/O2Tut/selectFacebySelection.jpg) Then mirror it the way it needs.

If everything worked, it should look like this:

http://armtac.ar.funpic.de/O2Tut/Texturiert.jpg

One could be satisfied with this, right? NO!?! Okay, let's spice up the whole thing.

_NOHQ

At first you need this nice plugin for photoshop: A good alternative to Photoshop and this plugin is a program called „xNormal“.

[9]

Save the current file „TUT_Wall_CO.psd“ as „TUT_Wall_NOHQ.psd“. Merge all layers into one and select in the upper menu-bar „Filter“ -> „Nvidia Tools“ -> „Normal Map Filter“.

When the tool has done doing it is magic, it should look like this:

[10]

Save this texture as „TUT_Wall_NOHQ.TGA“ and let O2 convert it to .paa.

_DT

Now open again the "TUT_Wall_CO.psd“-File and hide ALL layers except the „ConcreteNew0019_M“-layer. Try to turn it into a "Dirt-Layer" like the one before.

When you're ready, click with „Ctrl + LMB“ on this layer in the layer-menu, change to the "Channels" menu and click on the little symbol down there that says "Save selection as channel". Click where the eye symbol usually is to unhide this channel. A black/white image should be infront of you. Deselct the current selection by clicking with the "Wand"-Tool anywhere outside the image.

Now go to „Edit“ -> „Fill...“ and chose "White" as color and set the opacity to 75%. Confirm. The alpha-channel should now be darkened. Hit „Ctrl + I“ to invert the colors (White turns black, and black turns white...)

Go back to the layer-menu, select the "Background"-layer, unhide it and fill it with white color, 100% opacity.

It should look somewhat like this: [11]

If so, save it as „TUT_Wall_DT.TGA“.

Let O2 convert this one to .paa.

_SMDI

Now start TexVoew 2. Load „TUT_Wall_CO.paa“ and click on „Edit“ -> „Filter...“. A new menu should appear. Click on "Load" and load the „specularMapFinish.bitfilt“ file from your "/TexView2/Filters" directory. Hit Ok and let TexView work.

Converting 2048-textures can take up to five minutes.

http://armtac.ar.funpic.de/O2Tut/SMID_Vorher.jpg

comment "define specular power"
sp=10;
p = src pixel (u,v);
x = 1 - green p;
y = green p * ((sp * blue p + 1) / (sp = 1));
c = color(x,y,blue p,1);

When it is done, it should look like this:

http://armtac.ar.funpic.de/O2Tut/Smidi_Done.jpg

Go to „File“ -> „Save As“ and save it as „TUT_Wall_SMDI.paa“.

Step Six: RVMat

Now it't getting easy: Creating the the RVMat. The RVMat is the file, that tells a face what texture it has to use to create Bumpmaps, reflections, and so on.


And that's how it looks:

TUT_Wall.rvmat

surfaceInfo = "TUT_Wall\TUT_Concrete.bisurf"; //Definition od physical properties
ambient[]={1.000000,1.000000,1.000000,1.000000};
diffuse[]={1.000000,1.000000,1.000000,1.000000};
forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000};
emmisive[]={0.000000,0.000000,0.000000,1.000000};
specular[]= {0.536604, 0.600000, 0.480000, 1.000000};
specularPower=850; /// Glossiness; 1 = high, 64 = middle, 1000 = none
PixelShaderID = "NormalMapDetailSpecularDIMap"; // The pixelshader
// The pixelshader tells what stages (modes) the face should use.

VertexShaderID = "NormalMap";

class Stage1 {
	// The "NormalMap"
	texture="TUT_Wall\Tut_Wall_NOHQ.paa";
	uvSource="tex";
	class uvTransform
	{
		aside[]={1.000000,0.000000,0.000000};
		up[]={0.000000,1.000000,0.000000};
		dir[]={0.000000,0.000000,0.000000};
		pos[]={0.000000,0.000000,0.000000};
	};
};

class Stage2 {
	// The "Detail"
	texture="TUT_Wall\Tut_Wall_DT.paa";
	uvSource="tex";
	class uvTransform
	{
		aside[]={1.000000,0.000000,0.000000};
		up[]={0.000000,1.000000,0.000000};
		dir[]={0.000000,0.000000,0.000000};
		pos[]={0.000000,0.000000,0.000000};
	};
};

class Stage3 {
	// The "SpecularDIMap"
	texture="TUT_Wall\Tut_Wall_SMDI.paa";
	uvSource = "tex";

	class uvTransform {
		aside[] = {1.000000, 0.000000, 0.000000};
		up[] = {0.000000, 1.000000, 0.000000};
		dir[] = {0.000000, 0.000000, 0.000000};
		pos[] = {0.000000, 0.000000, 0.000000};
	};
};

Save this file as „TUT_Wall.rvmat“ to your project-folder.

You can find additional info about the rvmat's pixelshaders here.

As you may have noticed, right in the beginning of the .rvmat a certain "TUT_Concrete.Bisurf" file is called. This file tells Arma 2 details about the physical properties. It looks like this:

TUT_Concrete.bisurf

Density = 2000;
rough = 0.100000;
dust = 0;
bulletPenetrability = 20;
soundEnviron = "concrete_ext";
isWater = "false";
friction = 0.900000;
restitution = 0;
impact = "Hit_Concrete";
soundHit = "concrete";

the RVmat is finished. Now implement it to your model. Open your O2, hit "Ctrl + A" to select all and then hit "E".

http://armtac.ar.funpic.de/O2Tut_EN/Faceproperties.jpg


On the right side of the second input-field with the name "Material" click on the folder and select your „TUT_Wall.rvmat“.

Have look in bulldozer.

[12]

Tilt the object to make the bump-maps do something.

Step Seven: The LODs

Without any LODs (Level of Detail) is a model completely useless. But creating LODs isn't that hard. But first, to some lectureing: There are many different LODs, and a few main-types of LODs, which I'm going to explain:

Resolution LOD:

These LODs are used to save performance. ArmA2 drops a model's resolution-lod when you increase your distance to it. Each resolution-lod (0,000; 1,000, usw...) Contains fewer polygons to the next lower one.

To downsample/degeneerate a LOD, simply select the part you want to change, go to „Points“ -> „Merge near...“ and hit „Autodetect“. Then confirm. Done. But Resolutionlods are in our case quite useless, since this model is ultra-low-poly.

The both models you created are both in the 0.000 Resolution-LOD. The only one they currently have.

Geometry LOD:

The Geometry LOD („Geo-LOD“) is one of the most important LODs of a model. It provides the collision-information of all types.

To create it, click into the right window that already says "0.000" with your RMB and select "New".

http://armtac.ar.funpic.de/O2Tut/LOD_Fenster.jpg

Now a new, empty Resolution-LOD should've appeared. It is named "1.000". Select this one, click your RMB on it and chose "Properties". In the now appearing list select "Geometry" with a doubleclick.

Oh no, the model as turned yellow and isn't selectable anymore. That's half-right. The model still exists, but in the "0.000" lod. But you're working in the empty "Geometry" lod. Now you have to build the shape of this doorsegment with simple blocks.

The more precise the shape of the Geometry is to the shape of the 0.000 (Yellow lines), the better. The best is, to copy the content of the 0.000 LOD and paste it into the Geometry-Layer. Select everything (In the Geo-lod) and remove all faces ("D"), and create out of these vertices three single blocks.

And thats how it is done: Select the two vertices of the upper, left dooredge, copy them, insert them and hit "Shift + E". The following menu will appear.

http://armtac.ar.funpic.de/O2Tut/ShiftE.jpg

Change the Y-Axis from "2.200" to "3.0" and hit OK. Do the same to the upper right dooredge.

Turn these eight vertices into a box (F6, and so on...). Move this box by +2 meters on the Y-Axis. Delete the vertices of the door.

It should look like this:

http://armtac.ar.funpic.de/O2Tut/BlocknachOben.jpg

Now Move the vertices of the lower, outer Dooredges to 3.0 m on the Y-Axis. Link them to two Boxes with "F6". Move the first block back by -2 m on the Y-Axis.

Go to the "0.000" Lod and copy the Door. Insert it to the Geo-Lod. Select the Door, hit "E" and delete the paths to the .rvmat and .paa.

Check for "Non-Closed!" and save.

Select all. it should look like this:

[13]

As you may have noticed now, in the lower left corner a field namend "Mass" became active. If you can't see it, hit „Alt + M“. Here you can change the weight of this thing. 800 is a good value. Click "Apply" and it should now look like this:

[14]

Now each block needs an own selection, so ArmA2 will accept the Geolod. To make it easy, click on „Structure“ -> „Topology“ -> „Find Components“.

In one of the right windows four selections should appear.

http://armtac.ar.funpic.de/O2Tut/Selections.jpg

Selections.

If not, your geolod was not done correctly. You should create it again.

Fire Geometry LOD:

This LOD is nearly identically to the Geolod. This LOD is responsible for the simulation of projectile hits. If you don't create it, Arma 2 will use the Geolod for this, but no bulletholes will be displayed. Duplicate the geolod and turn it into a „Fire Geometry“.

Well, here is a goodie: Remember the .bisurf you created some time ago? This file is used now in a way. To enable material penetration, select the whole Fire Geometry, hit "E" and assign it the „TUT_Wall1.rvmat“. Done. Now the projectile of an Ak-74 will still not penetrate the walls, but the door the will surely turn into Swiss Cheese. And everyone taking conver behind.

[15]

Shadow Volume:

This LOD is responsible for proper shadowcalculating. Duplicate the 0.000 LOD and turn it into a „Shadow Volume“ LOD. make sure you enter the Value "1" in the list of the different LOD-Types when having selected the Shadow Volume.

Check this LOD for Non-closed. If nothing is marked red, feel free to be happy and continue. If not, well... you know the drill.

Select the whole model and hit "E" to remove all textures and materials from this LOD. Then click on „Structure“ -> „Triangulate“. Now all your squares have turned into triangles. This is very important. And now hit "U", which is also mandatory.

http://armtac.ar.funpic.de/O2Tut/Schadowlod.jpg


Roadway LOD:

The Roadway LOD is the area where you can walk on. A roadway in this wallsegments makes not really any sense, but since this is a tutorial, you go do it. Create a new LOD, turn it into "Roadway" and copy the lower four vertices of the doorframe form the 0.000 Lod into the roadway-lod and make a face out of them. If necessary, use "W".

http://armtac.ar.funpic.de/O2Tut/Roadway.jpg

Rodway-LOD

Well that's it. You're done. With modeling and texturing. :)


Step Eight: Configuration files

Well, the model is done. But Arma 2 has not a single clue what to do with it. To tell arma, what to do, we use the „Config.cpp“. I've underlined the .cpp on purpose, since I've written it wrong the first time I was dealing with these files and kept wondering, why OFP won't accept my config.cpp. So, one time more, in big:

'Config.cpp'

To get things like building-ruins and doors working, you'll have to do some things first:

A rubble model needs to be created. Surely you know them. Destroy a complete building in ArmA2, and the only thing remeaining is rubble and usually some dead, friendly AI bodies... This rubble is a model, like the door and wall, and has to be assigned to an object via in the config.cpp.

Some rubble with the dimensions of 3m x 3m x 0.25 are quick done.

The Door-selection: [16]

Somehow you need to tell Arma 2 what part of your model door is, and what not. So go into all lods, where your door is, select it, and create a new selection named "Door". To do so, simply klick into the window where the components are (Only in (Fire-) geometry LOD) and hit RMB. Select „New“. RMB on the new selection and Rename it to „Door“. Confirm with Enter.

Now you need to tell Arma 2 what axis the door should rotate around. For this purpose, create a „Memory“-LOD and copy two vertical vertices of the door into this LOD. Delete the crrent "Door"-selection in this lod. Select the two vertices and create a new selection named "Door_Axis". Create two additional vertices ("Inser"-key). One infront of, one behind the door (in the memory-lod). Put these two vertices into two selections. One named "Door", and one named "Door_Button". Move them up by 1m on the Y-Axis. The "Door_Button" will later carry the actionmenu entry.

[17]

The Memory-LOD

Now the model is prepared for everything. But still we're not going to do somethign about the config.cpp. Right now we need a „Model.cfg“ in your „TUT_Wall“-Folder.

This "Model.cfg" contains all information, that Arma 2 needs to determine what is door, hwo should it rotate, and so on. And here it comes:

I STRONGLY recommend to open and edit the following files (Model.cfg, Stringtable.csv, config.cpp) with Notepad ++. This forum provides a bad overview over these files.

Model.cfg

//The Class "CfgSkeletons" defines all moving objects.
 
class CfgSkeletons {
	//Always create class "default" first.
	//Your actual config-entry should be a derivate of this.
	class Default {
		isDiscrete = 1;
		skeletonInherit = "";
		skeletonBones[] = {};
	};
	//the derivate of your skeleton from claa "Default".
	class TUT_obj_skeleton : Default {
		isDiscrete=1;
		skeletonInherit="";
		
		// The moving objects are here defined
		// If two selections are linked together
		// they can be written next to each seperated by only a comma
		// if they are not linked, they need to be
		// seperated by  ,"", 
		skeletonBones[]= {
			"Door",""
		};
		// The last entry gets no comma
	};
};
 
 
// This class defines the actual moves
class CfgModels {
	//load some bases from which you can derivate
	class rotation;
	// And again: class default
	class Default {
	sectionsInherit="";
	sections[]={};
	skeleton="";
	 
	class Animations {};
	};
	
	// Your own "class default"
	class TUT_obj {
	sectionsInherit="";
	sections[]= {};

	skeletonName="TUT_obj_skeleton";	// same as in cfgskeletons
	};  
 
	// The name behind the class 
	// dhas to be the exact name of your .p3d
	// without .p3d
	class TUT_Door_3x3m : TUT_obj {
		sectionsInherit="TUT_obj";
		sections[]={};

		// the rotation animation
		class Animations {
			class Open_door : Rotation { // name of the animation
			

			type="rotation"; 	// Type of movement
			
			source="user"; // Trigger of the animation
			
			selection="Door"; // the thing that moves
			
			axis="Door_Achse"; // take a guess what this does...
			
			memory = 1; // can the axis be found in memory-lod? 1 = yes, 0 = no
			
			angle0=0; // initial angle of the door in radians
			
			angle1=1.6; // final position after playing the animation
			};
		};
	};
};

The comments in this file should help. When the „Model.cfg“ is finished, you can go into bulldozer and try out the animation. But first select the 0.000 lod, otherwise you'll see another Lod. Now go into bulldozer, hit the middle mose button and use your mousewheel.

" It's kinda magic, isn't it?

And now? Well... Close, but no config.cpp

At first you need a file that does the localization work. it is the so called "Stringtable.csv". This file is always to be opend with the standard texteditor or tools like Notepad ++. To get special letters like the "Ü" as in "Über" working, format the file to UTF-8. In Notepad ++ it is done under „Format“ -> „UTF-8“. Here's the file:

Stringtable.csv

LANGUAGE,English,German

str_TUT_Tur,"Wall (3x3m) with Door","Mauer (3x3m) mit Tür"
str_TUT_Wall,"Wall(3x3m)","Mauer (3x3m)"
str_TUT_OpenDoor,"Open Door","Tür öffnen"
str_TUT_CloseDoor,"Close Door","Tür schließen"

Now we're going to something about the config.cpp Everything else is explained by the comments. Learing from working config.cpps is IMHO the best way.

Config.cpp

/* Declaration as Addon-Content.*/
class CfgPatches 		{
	/* "Hey ArmA2, this is an addon and it is named "TUT_Wall"*/
	/* The name should be indentical to the folder's name*/
	class TUT_Wall	{
		units[] = {};
		weapons[] = {};
		requiredVersion = 0.1;
		requiredAddons[] = {};
	};
};

/* The category in the editor like "Objects" or "Cars".*/
class CfgVehicleClasses {

	class TUT_WallsVehicleClass {
		displayName = "TUT Walls";
	};
};

/* This is where arma gets the information about a new object. */
/* Donät be confused by the "vehicles" in CfgVehicles*/
class CfgVehicles {
	/* everything between here and "Class Land_ ..." is important for the animation to work properly without any "lags". */

	class All;

	class HouseBase;

	class Ruins: HouseBase {};
	
	/* Again your very own basic definition*/
	class TUT_Base_Object : All {
		scope = 0;
		side = 3;
		icon = "iconStaticObject";
		nameSound = "object";
		simulation = "house";
		picture = "pictureStaticObject";
		model="";
		sound = "Building";
		placement = "vertical";
		ladders[] = {};
		vehicleClass =  "";
		displayName = "";
		coefInside = 1;
		coefInsideHeur = 0.25;
		mapSize = 7.5;
		animated = true;
		armor = 200;
		destrType = "DestructBuilding";
		damageResistance = 0.004;

		class DestructionEffects {
			class Sound {
				simulation = "sound";
				type = "DestrHouse";
				position = "destructionEffect1";
				intensity = 1;
				interval = 1;
				lifeTime = 0.05;
			};

			class DestroyPhase1 {
				simulation = "destroy";
				type = "DelayedDestruction";
				lifeTime = 2.5;
				position = "";
				intensity = 1;
				interval = 1;
			};

			class DamageAround1 {
				simulation = "damageAround";
				type = "DamageAroundHouse";
				position = "";
				intensity = 1;
				interval = 1;
				lifeTime = 1;
			};
		};
	};

	/* Your very own base class for buildings*/
	class TUT_Housebase : TUT_Base_Object {
		scope = 1;
		model = "";
		icon = "";
		displayName = "";
		animated = true;
		vehicleClass = "TUT_WallsVehicleClass";
		nameSound = "house";
		accuracy = 0.2;
		typicalCargo[] = {};
		transportAmmo = 0;
		transportRepair = 0;
		transportFuel = 0;
		mapSize = 11;
		cost = 0;
		armor = 800;
		/*extern*/ class DestructionEffects;
	};
	/* Everything between here and "Class All" (above)  is important for the animation to work without any "lags". */
	/* The "Land_" infront of all buildings is important for the destructioneffects to work properly. After the "Land_" the name of the .p3d (without the .p3d ending) has to follow!*/

	class Land_TUT_Wall_3x3m: TUT_Housebase {
		model = "\TUT_Wall\TUT_Wall_3x3m.p3d";	/* path to the object */
		displayName =  "$STR_TUT_Wall"; 	/* entry in Stringtable.csv */
											/* Important are the $ and the capital STR_*/
		nameSound = "";						
		mapSize = 8;						/* Size of the icon */
		icon = "iconStaticObject";			/* Path to the picture shown in the editor. */
        accuracy = 1000;   
		armor = 450;						/* "Lifepoints", if you like to call it that way.*/
		destrType = "DestructBuilding";		/* type of destruction, when armor = 0 */
		scope = 2;							/* Display it in the editor? 1 = No, 2 = Yes */
		class DestructionEffects : DestructionEffects
		{
			
			class Ruin1
			{
			simulation = "ruin";
			type = "\TUT_Wall\TUT_Wall_3x3m_Ruin"; /* path to the object*/
				/* Warning, if you use a custom rubble model, it has to be defined in the cfgvehicles (see below)*/
			position = "";
			intensity = 1;
			interval = 1;
			lifeTime = 1;
			};
		};
	};
	
	/*  Same name as stated in the Class DestructionEffects, but an "Land_" added infront*/
	class Land_TUT_Wall_3x3m_Ruin : ruins	{
		scope = 1;
		model = "\TUT_Wall\TUT_Wall_3x3m_Ruin.p3d";
		displayName = "Wall ruins";
	};
	
	/* Your doorsegment is derivated from the normal wall.*/
	class Land_TUT_Tur_3x3m: Land_TUT_Wall_3x3m {
		model = "\TUT_Wall\TUT_Tur_3x3m.p3d";
		displayName =  "$STR_TUT_Tur";
	
		/* Arma needs to know, how the animation trigger is triggered*/
		class AnimationSources {
				/* name must be identical to the one given by the model.cfg ("Open_Door")" */
			class Open_door {
				source = "user";
				animPeriod = 4; /* duration in seconds */
				initPhase = 0; 
			};
		};
		
		/* The entry to the actionmenu */
		class UserActions
		{			
			class Open_Door
			{
				displayName="$STR_TUT_OpenDoor";
				onlyforplayer = true;
				position="Door_knopf";
				radius=2; /* visibility distance of the entry */
				condition="this animationPhase ""Open_door"" < 0.5";
				statement="this animate [""Open_door"", 1]";
			};
			class Close_Door : Open_Door
			{
				displayName="$STR_TUT_CloseDoor";
				condition="this animationPhase ""Open_door"" >= 0.5";
				statement="this animate [""Open_door"", 0]";
			};
		};
	};
};

Now the config.cpp is finished. The complete addon is just one step ahead.

Step Nine: Getting the addon into Arma 2

Before you pack ( = make a pbo) the addon, you'll need a signature first.

Addon signatures are these little files that usually come with each .pbo-file. They're named like this: „Nametag_NAME_OF_ADDON.Nametag.bisign“. These files are important for the multiplayer of Arma 2. This file contains information about the size of the signed addon. If the size of an addon isn't identical to the one saved in the bising, you'll be kicked from the server, since you either have an old version of the .pbo or you've simply modified something you shouldn't have.

This tool called „BinPBO“ does this job for you. But you need a signature to sign an addon. And here is how you get it:

DSCreateKey.exe

Download DSCreateKey.exe from the biki. [DSCreateKey] Unzip it, hit „Windows + R“ and enter the following.

http://armtac.ar.funpic.de/O2Tut/DSUtilsuse.jpg

Your path to the „DSCreateKey.exe“ may vary, but the „TUT“ should be identical. Now hit OK and look inside the folder that is containing your DSCreateKey.exe.

Two new files appeared there. The „TUT.bikey“ and the „TUT.biprivatekey“. The latter one has to remain on your PC. Never give it away. And store it in a safe place. Maybe even oben it with a HEX-Editor and print the file... The „.bikey “ should be always included to your addon-releases.

Now, since you have a „TUT.biprivatekey“, you may now start packing the addon, but first remove everything from your Project-folder, that doesn't belong there.

http://armtac.ar.funpic.de/O2Tut_EN/Ordnerinhalt.jpg

A clean project-folder

BinPbo.exe

Start BinPbo and configure it this way:

http://armtac.ar.funpic.de/O2Tut/EinstellungBInPBO.jpg

Please excuse the disturbing background. But am I not allowed to be lazy, sometimes...

Now hit "Pack" and let BinPBO work. If it displays in the lower left "Ready", and ow error messages appeared, you may now be happy. Your addon is complete.

Launch Arma 2, go into the editor, place the door, use it and then destroy it. [18] [19] [20]

Step Ten: Releasing the addon

Not much to say here, but if you want to release your addon, do it this way:

First, go to [www.armedassault.info] and make a readme with the help of the Readme-generator offered on this site.

Then create somewhere a Folder, that you name - since this is still an tutorial - „TUT_Wall_V1.0“ Copy to this folder your TUT_Wall_Readme.txt and create two new folders inside this one:

  • @TUT
  • Key

Into the "@TUT"-folder belongs another folder named „Addons“,in which you copy Readme, „Tut_Wall.pbo“ and „Tut_Wall.tut.bisign“.

Into the "Key"-folder goes your „TUT.Bikey“. (not the BIPRIVATEKEY!)


Now zip this folder. The Zip-File may be named now like this: „TUT_Wall_V1.0.zip“. Upload this file to a webspace (e.g. Rapidshare). And then go to THIS FORUM (A certain Placebo will probably thank you for not causing him work) and start a new thread with all information and pictures about your new addon. Don't forget to post the DL-Link.

Closing words

All this was originally written by Mondkalb, but feel free to add/improve this article the way you like it and makes sense.

Soon I'll probably retire from the OFP/ArmA/Arma 2-community, and I thought it would be a nice thing to provide you with a nice tutorial about everything I learned about creating addons in the past eight years.

I hope this tutorial will spawn many new addon artists and even more high quality addons to this great Arma 2 Community!

Ah, one last tip: Learning by doing! Always see how others have done it, but don't forget to credit them! Credits are the least you can do, and it doesn't cost anything. Uh, for example: I'd be glad if you thank me in your first released addon, if you've found this tutorial very helpful. Speaking of which: here we go:

Credits

My very first und biggest "Thanks, mate!" goes to „Brsseb“, the author of the first O2-Tutorial OFP which showed me how to do it and helped me with my first steps in Addon-creating.

My second best tahnks goes to „Sgt. Ace“, who showed me over the years many, many many many, tips and tricks. Also special thanks goes to „Scruffy“, who showed me, that "Config.cpp"-Files arent that bad as they seem to be.

So I remain with the following, last odd sentence: Name has no BAS and vote Quimby!

Aloha!

--Mondkalb 21:29, 22 October 2009 (CEST)