1st Step: Preparing YOUR MIND! | ||
So one day you wake up and think: "Hey, I wish I could make some new cool 2D fighter for my favorite console!".
Of course, in order to accomplish that, you will need some kickass characters to do the fighting. Whether you create
your own sprites or download an existing spritesheet somewhere on the interwebz*, this guide will teach you how to
turn them into the bestest characters to have ever walked the virtual landscape! *Josh Tari Games/Dogma/Whatever my game company is called cannot encourage the use of illegally acquired copyrighted material. But just so that we're clear, they are awesomely easy to use with D-Engine and look pretty darn awesome. |
This is serious business. | |
2nd Step: Preparing the sprites | ||
Unlike other moddable engines, the D-Engine does not use spritesheets, but rather one pic per sprite. The name of each
pic consists of the animation name, which must be exactly eight letters long, and the frame. So if you wanted to name
the third frame of an animation which is called "STANDING", it would be: STANDING3.png An important limit here is the fact that the width and height of every sprite has to be a power of two in pixels. Additionally, the height and width have to be the same. Possible sizes are (128x128) and (256x256). Impossible sizes are (127x150) or (128x256). Engine test have revealed the upper limit to be a size of (256x256) pixels, although there are two restrictions: 1. Complex backgrounds paired with (256x256) characters may negatively affect the framerate. 2. (256x256) characters do not support the 24bpp TrueColor and have to be encoded with a palette. Such a smooth transition to... not the palettes, we are first going to deal with TrueColor sprites. |
A folder containing TrueColor PNGs. |
|
2.1 TrueColor ... Is just a fancy name for normal images. Not sure whether there is much to explain here, just save your image as a (128x128) png. You are free to use the jpg format, but I highly recommend the lossless png format. Either way, they have to be converted. Twice. If you are lucky, you can find a tool called Omni Converter at the Downloads section of this site, immediately converting the image to the D-Engine format (.pkg), the Crash Layer bitmap (.bmp) and the good ol' KMG format. Should it not be available, I'm afraid you have to do a little more legwork: First you will need a program called kmgenc, which is short for KallistiOS image encoder. It is part of KallistiOS and can be downloaded here, until I have figured out the legal stuff and uploaded precompiled binaries. Use it with a command line along with the option -a4 in a style similar to the picture to the right. This tool will automatically convert all images, no matter which file type, to the KMG format. Don't delete the PNG files though, they will serve another purpose later. Now, to compress the converted KMG files, you need one of my babies, the Kompressinator, or KOMPRESSOR for short (available at the Download section). No command line here, just drag 'n drop all the files on the tool and BAZINGA: Perfect PKG files. In case you know a program which converts image files to the bitmap format, you can use another one of my programs available here, called 2CRA (There is a pun. A very subtle Tupac reference!). Just change the 2CRA.cfg to include the command line necessary and do the Drag and Drop stuff to convert the images to the bmp format. The 2CRA tool will then proceed to turn these Bitmaps into (128x128) black and white representation of the sprite. Keep them for the next chapter below, appropriately named "The Crash Layer". |
Linux. Execute this command line in the folder KMGENC is located. Windows. Notice the big difference. This is what 2CRA outputs. Feel free to ignore the diagonal line in the middle. |
|
2.2 Palettes These may be used for a variety of reasons: Either you want to save some memory (pretty useless if you ask me, the Engine is able to deal with more than a thousand 128x128 TrueColor sprites already), you wish to have an alternate set of colors for the second character in case of a mirror-match, or you create a (256x256) character. The highest set of colors the D-Engine palette may have is 256. There is a little trick to it though: To make up for the fact that the D-Engine palettes do not support transparency, the first color in the palette serves as a transparentinator, meaning it is not displayed within the game, but replaced with transparency. | ||
Look right for an example character with a palette and how to apply the palette properly! |
These examples use GIMP. Free software FTW. | |
...And finally the saving stuff. |
Don't tell this around, but the filename doesn't have to be ".p8b". Any three-letter combination will work. | |
Now you should have a folder filled with these unviewable, paletted images, probably having the file extension (.p8b),
which brings us to the various conversions: KMGENC does not support paletted textures, so you will need one of them fancy tools from the downloads section to get those KMG files, a tool called PALENC (What a lame name, not even a pun!). Just drag and drop all the files on the executable to have a whole load of pseudo-KMG files (the normal KallistiOS KMG functions do not support paletted textures). To get the D-Engine's PKG files, download the KOMPRESSOR tool in the Download section in order to -you guessed it- compress the KMGs. Just drag and drop the files, no command line required. Now you will need to prepare a little something for the hit detection (or "Crash Layer" as it is usually called). For that reason, check out a sweet 'lil something called P8B2CRA. This wondrous piece of craftmanship will take your P8B-files as Input and spit out black and white BMP-files which are immediately usable for the stuff to be done in the next paragraph, which deals with the Crash Layer. |
This is what P8B2CRA outputs. Feel free to still ignore the diagonal line in the middle. | |
3rd step: The Crash Layer | ||
A fancy name for the hit detection. If you followed the second step you are now the proud owner of a folder filled
with black and white (128x128) BMP-files. Now it's your job to recolor parts of it: These bitmaps can have four different colors. Black (0x000000) - Black only means that there is something to hit. White (0xffffff) - White means nothing. No, not that nothing, that other nothing, you know? Nothing nothing. Red (0xff0000) - Red parts of the BMP stand for the parts of the animation which attacks. Blue (0x0000ff) - Blue stands for blocking. Yeah, sometimes it's as simple as that. The tool which creates those Black and White BMPs you look at now was a great invention, because there are only a few things you need to do before pumping these beauties into the Crash Layer Converter: Remove all black parts from animations which happen after your character got it. If you do not remove it, your character might be hit multiple times in a row. Them again, that could be a great basis for a combo system. Gotta think flexible! After you have done that, recolor the "attack" parts of the attack animations red and color the blocking animations blue. See, you are already done and that was was way easier and more exact than those oh-so popular hitboxes. Yeay, it's converting time again! This time, there is a single tool called CRA which converts these BMP files you can drag and drop on it into CLA- and more importantly, CRA-files. The CLA files are for debugging only, so feel free to remove or keep them. Just put all CRA-files into an extra folder and keep them for the finalization process. |
Pure existentialism. A normal attack. Well, normal in a weird kind of way. Blocking is essential. |
|
The 4th step: The first Finalization | ||
Kind of an Oxymoron there, but we are now going to create the first two files to be actually used with the
engine. Well, actually YOU are going to create them, I am just a voice in your head. Do I sound like Sean Connery?
I wanna sound like Sean Connery! *A-hem*, what you need here is genromfs. If I am not totally mistaken it is included in Linux, comes bundled with KallistiOS, and can be downloaded here. Now, after you have set it up use those two command lines in the genromfs folder: Linux: ./genromfs -d YOUR_PKG_DIRECTORY_HERE -f CHARACTERNAME_PKG.img Windows: genromfs -d YOUR_PKG_DIRECTORY_HERE -f CHARACTERNAME_PKG.img Linux: ./genromfs -d YOUR_CRA_DIRECTORY_HERE -f CHARACTERNAME_CRA.img Windows: genromfs -d YOUR_CRA_DIRECTORY_HERE -f CHARACTERNAME_CRA.img Keep in mind that your character's name must be exactly eight letters and/or numbers long. So if you want to create a character named "STICKLER" on Linux, your PKG directory is "/home/captaindc/PKG" and your CRA directory is subsequently "/home/captaindc/CRA", check this out: ./genromfs -d /home/captaindc/PKG -f STICKLER_PKG.img ./genromfs -d /home/captaindc/CRA -f STICKLER_CRA.img This will create STICKLER_PKG.img and STICKLER_CRA.img (or whatever your character is called) in the genromfs directory. Put these two files somewhere safe, they will be needed in the final step. Woot, the easy part is over! Err, of course I meant the hard part, hehe. Or was it really the hard part and the other half was easy? Only one way to find out. | ||
The 5th step: A new beginning | ||
The practical part is over, so let's get scratching with the DOLMEXILERS (Dolmexica-Compilers)! Download the
one used to create characters, and create a new .txt/.nfo document. It is very important that you edit these files with
a simple editor, such as, well, the Windows editor or Mousepad on Linux. Of course, if you are a snazzy hipster like
the DEPR0GRAMMER, you might as well try nfopad for Windows. Recommended by gangstas. Either way, it has to be an ASCII editor. Got one ready? Cool! The Dolmexiler reads values by using a very simple method, all lines look like that somehow: SUPERCOOLVALUE = [42] The spaces before and after the equals sign are very important, so are the brackets encasing the value. These brackets may contain an array, a number, or something else. Check out the corresponding sections below for more info about each value. | ||
5.1 Header Stuff | ||
This is more of a list of the various identifiers and the values they accept. All values here are compulsory. Heh,
this IS the header after all. --- CHARACTERNAME = [YOURCHAR] Please note that the Character Name must be exactly eight characters long. The real character name, to be displayed in the game, will be declared later. This one here is just for filenames and other things. --- TEXTURESIZE = [128] Remember that the width and height of the image must be the same. That is why there is only one value to be entered. --- OFFSET = [35] Usually characters are not at the left side of the image. Should you wish to place your character a little more to the right, check this value out. Don't feel bad if the value isn't that exact, it is mainly used by the artificial intelligence. On a completely unrelated side note, this value can be seen as a lead-up to the next value... --- WIDTH = [40] Well, the character's width. Like the offset, this value does not have to be that exact. It is used in conjuncture with the Offset, for example in this scenario here, the characters right side would be at 75 pixels. --- HEIGHT = [40] Use the Y-Value of the image here. The Y-Axis of the image runs from the top to the bottom so this may be a tad confusing at first. Just point your pointer at the point (Triple Combo!!) in the image with whichever Paint editing tool you prefer. --- WALKING SPEED = [3] The unit is pixels per frame. Remember that this value is "upscaled": If your character is drawn as a 256x256 character on the screen, but really is a 128x128 character like here, the character's walking speed will be doubled (6 in this case). This is because the size the character is drawn as depends on the stage, not the character. It may sound annoying to you now, but once you've finished the char, you will see how cool it could potentially be. Or not, lol, I dunno. --- DEFENSE = [0] The Maximum Health is a fixed value. Defensive characters may have a defense which is substracted from every attack. Should be used with caution though, as it throws off the balancing real quick... --- JUMP IDLE UP STRENGTH = [10] This value determines how high a character jumps in the air if it neither jumps forward nor back. As you know, the character deaccelerates one pixel per frame instead of just going up ad infinitum, so it is a real tricky value. It is also scaled and changes depending on how large the character is drawn on the screen. --- JUMP FORWARD STRENGTH = [11] The same as above, just for jumping forward. --- JUMP BACK STRENGTH = [9] The same as the one above the one above, just for jumping back. --- JUMP FORWARD SPEED = [3] Just how fast does the character jump forward. This value is scaled as well. --- JUMP BACK SPEED = [3] Pure mystery. --- PALETTE = [NO] Does the character use a palette. This is a YES/NO answer type. Write your answer between the brackets in friendly capital letters and you're good to go! --- BACK BLOCKING = [YES] You know, Street Fighter and co's characters defend when the players presses back while the enemy attacks. Mortal Kombat's characters on the other hand don't do that. This is the value to deal with that, yup! --- REALCHARNAME = [CAPTAIN DC] This name is displayed within the game (somewhere along the lifebar). It must not be longer than 16 characters. --- | ||
5.1.1 Sound Effects | ||
Excuse the triple number, this addition is relatively new. For adding a sound effect, use the following line right
after the header stuff: SOUND EFFECT NAME = [HIT_WKPN] Repeat until every sound effect is declared. Keep in mind every sound effect's name needs to consist of exactly eight letters. Now that you have named all the Sound Effects, you should already create the Sound Effect Archive using genromfs: Linux: ./genromfs -d YOUR_SOUNDEFFECT_DIRECTORY_HERE -f CHARACTERNAME.sfa Windows: genromfs -d YOUR_SOUNDEFFECT_DIRECTORY_HERE -f CHARACTERNAME.sfa There you go! Keep the SFA file for the final step and read on: | ||
5.2 Compulsory Animations | ||
There are a few animations every fighter needs, like Walking or Blocking. This first section is initiated by the
words #1 COMPULSORY ANIMATIONS and has to end with three of these number thingies: ### Now for the single animations, every new animation that is put between these two identifiers above is started by three minuses: --- Only put those three minuses at the start of the animation, not the end. Putting them at the end as well will cause the Dolmexiler to go nuts. Let's go through the different identifiers for compulsory animations: --- TYPE = [IDLE] There are 14 different compulsory animations, so here are their identifiers: [IDLE] = The normal standing animation. [WALKINGFORWARD] = Walking forward. Yeah. [WALKINGBACK] = Would be weird if you couldn't do that. [INTOCROUCH] = The animation which shows a character going from the stance into the crouch animation. [CROUCH] = The normal standing animation... while you're crouching. [HIGHDAMAGE] = This plays when you get hit by a high attack. [HIGHRECOVERY] = After you get hit by a high attack and have stopped flying all over the place, this happens. [KNOCKEDDOWN] = This animation plays when you get knocked off your feet. [GETTINGUP] = Recovering from getting knocked down. [CROUCHDAMAGE] = If you get hit... while crouching. [CROUCHRECOVERY] = Recovering from getting hit... while crouching. [BLOCK] = The normal blocking animation when standing. [CROUCHBLOCK] = Yeah. Crouching fighters can block as well. [VICTORY] = Well, once you win, most fighters freak out and celebrate. As of version 1.0.0, all animations have to be included. Not including them might lead to unexpected bugs and freezing. --- NAME = [STANDING] The name of the animation. Please remember that it has to be exactly eight characters long. --- FRAMEAMOUNT = [8] Just how many frames does the animation have? --- SPEED = [6] This value determines how fast the frames of the animation change. Keep in mind that the value runs at 60 fps, so a value of 6 means there is a new frame every tenth of a second. --- | ||
5.3 All the cool Jumping stuff | ||
There are three types of Jumps: Jumping forward, jumping back and just jumping up. Each of these Jump Types has its own
section, each one starting with a unique identifier and ending with the three number thingies (###) again. So you have three sections looking like that: #2 JUST JUMPING UP ### #3 JUMPING FORWARD ### #4 JUMPING BACK ### Just like in the "Compulsory Animations" section, the space between the identifiers and the number thingies(seriously, what are they called?) is filled with the different animations. It pretty much works like above, but now there are new types and a new Identifier. Either way, here is the complete list: --- --- Animations start with three minuses again. --- TYPE = [JUMPSTART] There are different types now. Complex analysis of human jumping has revealed that jumps can be split up into five parts: [JUMPSTART] = The animation before the actual Jumping takes place. This type is compulsory. [JUMPIDLEUP] = If the LOOP identifier is set to [YES], this animation plays until the character is near the Jumping peak, else it plays 'till it's done. [JUMPPEAK] = If set to loop, it plays during the jump's peak. [JUMPLOOP] = It is the Jump's "fallback" animation and is the only compulsory animation beside the JUMPSTART one. [JUMPRECOVERY] = Like JUMPSTART, just after the jump. It's not compulsory, though. --- LOOP = [NO] A typical YES/NO type. It should always be set to NO for JUMPSTART and JUMPRECOVERY. Otherwise, if set to NO, it will usually pass control to the next animation. Should JUMPLOOP get the NO treatment, it will simply display the final frame of the animation 'till the Jump is over. --- NAME = [JUMPING1] See section "Compulsory Animations" for an explanation. --- FRAMEAMOUNT = [1] "Vide supra", it's latin for "see above"! See, this is totally not wasted space. --- SPEED = [5] "Eesay Boveaay", it's Pig-Latin for "see above". Okay, okay, this IS wasted space. --- | ||
5.4 Normal Attacks/Animations | ||
NOW we are getting to the interesting things: This is where everything playable goes. Nothing unusual here though, the starting identifier is: #5 NORMAL ANIMATIONS ...the ending identifier are three... number signs. Yeah, that's what they are called: ### Like before, animations start with three minuses: --- This time around, there are more identifiers for each animation. Check these out: --- TYPE = [ATTACK] Hey, another list of possible types! Let's give 'em a swirl. [BLOCK] = Certain game series, like Mortal Kombat, feature characters which block attacks by pressing a button. This type makes it possible. The animation loops as long as the button is pressed. [ATTACK] = A normal attack. This animation takes place, and that is it. [THROW] = If the animation hits, the D-Engine passes control to the Throw Animation you will later define with SPECIAL ID. [SPECIALATTACK] = Immediately passes control to the SPECIALATTACK defined in SPECIAL ID later. [SPECIALEFFECT] = For throwing fireballs 'n stuff. It is used in conjunction with the SPECIALEFFECT named in SPECIAL ID. [COMBO] = Passes control to the COMBO later named in SPECIAL ID. --- BUTTONS = [A] This defines with which button(s) the animation is initiated. It may consist of up to two parts, the Basis-Button and the AddOn. The Basis-Button is compulsory and may stand alone, like in the example above. Additionally, it may be enhanced with the Add-On and a plus. Here are the examples: [A+X] = Another button. Pretty straightforward. [A+DOWN-DOWNFORWARD-FORWARD] = The typical Hadouken move. It may seem weird because it is in the wrong order, but it is the very move. [A+DOWN-DOWNBACK-BACK] = The same thing, but different! [A+FORWARD] = You have to hold forward at the same time. [A+BACK] = Hold back, but still give it all you've got. Watch out for future updates, there will be more Add-Ons. Awesomesaucetacular Add-Ons. Oh, and just in case, the six Dreamcast buttons are: A, B, X, Y, L and R. --- NAME = [KICKWEAK] Yup, the name again. Exactly eight letters, watch out for that! --- FRAMEAMOUNT = [5] Check the "Compulsory Animations" section if you need a few pointers. --- SPEED = [6] Check the "Compulsory Animations" section if you need a few pointers. This is an automated message, so please do not respond to it. --- LOOP = [NO] Does the Animation Loop? Mostly useless these days, the only good reason to set it to YES would be a blocking animation. --- LEVEL = [GROUND] There are three positions a character can have: Airborne [AIR], Crouching [CROUCH] and just doozing around normally [GROUND]. --- ENEMY ACCELERATION X-AXIS = [10] The strength with which the enemy is pushed back. Keep in mind that this is one of them deaccelerating values, making them very tricky to get right. On top of that, it is also scaled, depending on how much the char is enlarged. --- ENEMY ACCELERATION Y-AXIS = [8] The same thing as above, just for kicking the enemy up in the sky. It also deaccelerates, but usually less than the X-AXIS value. Scaled 'n everything. --- RANGE X-AXIS = [88] This value is only used by the artificial intelligence. Basically, it declares when exactly a CPU-controlled character attempts this attack. --- RANGE Y-AXIS = [78] This value is only used by the artificial intelligence. Basically, it declares when exactly a CPU-controlled character attempts this attack... Y-AXIS. --- STRENGTH = [50] The damage this animation deals. Really nothing to take care of here. A character's maximum health is 1000. --- SOUND EFFECT - MISS = [MISSWKPN] The sound effect that plays when a certain frame declared in SOUND EFFECT FRAME - MISS is displayed. Don't include this line if you don't want a sound effect. This value takes the name of the sound effect without the .wav extension in the brackets. --- SOUND EFFECT FRAME - MISS = [3] Only include this if you also include SOUND EFFECT - MISS. Pretty straightforward, when does the sound effect play? --- SOUND EFFECT - HIT = [HIT_WKPN] This sound effect plays when your hit connects. There's no need to declare a frame for this one, eh? --- SPECIAL ID = [0] Declare this value if the type of this animation makes it necessary (Check TYPE for more info). Otherwise you can set it to zero or delete the line. The Special IDs will be declared later, in their respective sections. --- ADDON = [SWEEP] This is an optional line. There are multiple different ADDONs for an animation (Yeah, another list!): [OVERHEAD] = This addon basically gives GROUND animations AIR attributes. Crouching enemies don't stand a chance. [SWEEP] = This one turns GROUND moves into CROUCH types. [OMNI] = Pass control to the Omni Move declared in SPECIAL ID, but only if your animation hits. --- SPECIAL NEEDED = [0] In case your mod has a special bar and this animation uses it up, use this line. Otherwise you can set it to Zero or just delete the line. --- | ||
5.5 Throwing | ||
Before we continue, let me state that from now on every addition to the text file is no longer compulsory. So if
you feel like you are done with the char already, fast forward to the next step. The throwing section doesn't hold that many surprises, like all other sections, it starts with an identifier: #6 THROW ANIMATIONS and ends with three number thingies: ### Inbetween, every animation starts with three minuses (---), but now there is a catch: First you declare stuff which counts for the entire animation and afterwards you declare values for each single frame. Each frame data is started with three pluses (+++). If that's too theoretical, we are going through another one of them identifier lists. Maybe that will clear things up. Or overcomplicate things again, I dunno. Before you start with the animations, you need to tell the Dolmexiler just how many animations there will be: THROWAMOUNT = [1] ...And you're good to go. --- --- Every animation starts with three minuses. Right after that you should declare the header data: --- SPECIAL ID = [1] This is the same SPECIAL ID used to refer to this animation. Check the section above for more info. Just one more hint: Please declare the IDs in order. The first Animation has SPECIAL ID = [1], the second one has SPECIAL ID = [2], and so on and so on. *A-hem*, of course that's not a shortcoming of the Dolmexiler, you should rather consider it a feature. --- THROWNAME = [OVERTROW] This is the name of the actual throwing animation that plays if the initiating animation from the "Normal Animations" section hits. Exactly. Eight. Letters. --- THROWFRAMEAMOUNT = [10] Just what you would expect it to be. Unless you don't expect it to be the amount of frames this animation has. --- +++ So much for the header stuff, now you need to declare the following set of variables for each frame. Every frame is started with the three pluses you see above. It's just like with the minuses, just a lot more plus...sy. --- THROWSTAGE = [BEFORE] This here declares just where the frame fits in: [BEFORE] the actual throw is taking place, [DURING] the actual throw (the frame during which the enemy is sent flying) and [AFTER] the throwing took place. --- ENEMYALIGNMENT = [PARALYZED_STANDING] With this you choose whether the enemy is standing [PARALYZED_STANDING], or lying [PARALYZED_LYING]. Not much else to it. --- FRAMESPEED = [10] How long is this frame displayed? Well, it's not really a question, y'know, it's obvious this example lasts one sixth of a second. --- CHARPOSITIONCHANGEX = [-12] This value declares how much the character moves, once, as soon as the frame is loaded. --- CHARPOSITIONCHANGEY = [-24] This value declares how much the character moves, once, as soon as the frame is loaded... Y. --- ENEMYPOSITIONCHANGEX = [33] This value declares how much the enemy moves, once, as soon as the frame is loaded. --- ENEMYPOSITIONCHANGEY = [-10] This value declares how much the enemy moves, once, as soon as the frame is loaded... Y. --- ENEMYACCELERATIONX = [33] This line is only important for the frame DURING which the actual throwing takes place. It is the same as the value ENEMY ACCELERATION X-AXIS from the "Normal Animations" section. --- ENEMYACCELERATIONY = [11] This line is only important for the frame DURING which the actual throwing takes place. It is the same as the value ENEMY ACCELERATION Y-AXIS from the "Normal Animations" section. --- STRENGTH = [96] This line is only important for the frame DURING which the actual throwing takes place. It is the same as the value STRENGTH from the "Normal Animations" section. Maximum Health of a char: 1000. --- | ||
5.6 All the cool stuff | ||
An identifier: #7 COOLER ANIMATIONS ...and three number thingies... ### These animations are cooler than the normal ones, hence the name. Like with throws, it consists of header information and of information for each single frame, with each animation staring with three minuses (---) and each frame data starting with three pluses (+++). Unlike throws, cool moves don't give you control over the enemy, but only serve as an enhancement for normal moves. Anyway, now for the list: Before anything happens, you need to declare the amount of Animations: ANIMATIONAMOUNT = [1] Now for the actual animations: --- --- Every animation starts with three minuses. Don't take it too "negative" though... C'mon, that was comedy gold! --- SPECIAL ID = [1] Please refer to the Throwing section for more info. You know, I'm saving space here. The less I type, the more interwebz trees do not have to be turned into interwebz paper. --- NAME = [COOLKICK] Exactly eight letters. EIGHT. LETTERS. --- FRAMEAMOUNT = [4] Like with throws. Or, anything else. It's really self-explaining, isn't it? --- +++ Yup, if you have read the throwing section this will seem familiar: These three pluses have to be put in front of every frame. --- FRAMESPEED = [3] Tells the good ol' engine how long the frame is displayed. --- CHARPOSITIONCHANGEX = [12] Exactly the same value as the one from the throwing section. The character's position changes only once, just when the frame is drawn for the first time. --- CHARPOSITIONCHANGEY = [-12] Exactly the same value as the one from the throwing section. The character's position changes only once, just when the frame is drawn for the first time... Y. --- CHARCOMBOMOVEMENTX = [3] Now the main difference between this value and the CHARPOSITIONCHANGE type is that this value is continuously added to the character's position. For every frame the sprite is displayed, the char's position changes by that exact value up there. --- CHARCOMBOMOVEMENTY = [-5] Now the main difference between this value and the CHARPOSITIONCHANGE type is that this value is continuously added to the character's position. For every frame the sprite is displayed, the char's position changes by that exact value up there... Y. --- STRENGTH = [77] This animation's strength. A character's max health is 1000. --- | ||
5.7 Special Effects | ||
Fireballs, tornadoes, pure energy, even compact discs: Special Effects are the kind of moves for which the character's
sprite just doesn't suffice. Remember the Hadouken from Capcom's Street Fighter? That's a brilliant example for what
this section attempts to achieve. Just bigger, better and all-around-more-128-bit-blast-processing-er. So much for the
explanation, let's get to the dry theoretical stuff.
...NOT. See, you have probably already added all of the character's animations in the first half of the section. But
what about the Textures used for the Special Effect? This pretty much works like with normal sprites, but like always,
there is a catch to consider: Every Special Effect consists of four different animations: The first one, playing
directly after the Special Effect is initiated [PRELOOP], plays once and passes control over to the second
animation, which simply loops [LOOP] until either the Special Effect has reached its limit and vanishes (the
third animation/[VANISH]) or until the animation hits the enemy (the fourth animation/[HIT]). Each of them
has to be given a different eight-letter name, just like with normal animations. Of course this means they also
have to be a power of two, 16/32/64/++. Paletted characters can either have Special Effects sharing the character's
palette or have Special Effects use the "normal" TrueColor mode. Use PALENC for the former and KMGENC for the latter.
Now here is the catch making things so difficult around Special Effects: They are not compressed. Don't send the KMGs
through the compressor, just pump them into the PKG folder of your character as KMGs. See the problem here? Special
Effects can increase the PKG file size of your character dramatically. As if that wasn't enough drama, they also need their own collision detection. While there is (theoretically) no size limit for Special Effects (Engulf the entire screen in a tornado? Be my guest!), the hit detection portion is never bigger than the size of a character. Basically that means that if your image is smaller than the character texture size, the canvas has to be increased to match it (with the animation retaining its original size and remaining in the upper left corner), before you can go through the whole Crash Layer process with it. On the other hand, if the Special Effect is bigger than the original texture size, you need to downsize it. You can declare an Offset to the Hit detection just to adapt to that, both for the X-and the Y-AXIS respectively, more on that later. But hey, stop digressing, we are still not done with the whole Crash Layer thing. Now you should have versions of your sprites which are perfectly compatible with one of the 2CRA tools. Now, the BMPs again. Black and White, real glorious. Instead of remodeling them to red and white, just use the SPECIAL_CRA converter, downloadable in the downloads section. It will convert the black 'n white BMPs to the special effect version of the crash layer format. Hammer them into your character's CRA folder and you are one big winner. Promise! Man, what a crackdown on technobabble. Could we now please get back to the equally awesome Dolmexiling part? Like each section, the Special Effect part starts with an identifier: #8 SPECIAL EFFECTS Guess what it ends with: Three number signs! ### Yup, inbetween, every new Special Effect begins with three minuses (---). As has been stated before, there are four different animations each Special Effect is split up into. Each of these animations starts with three pluses (+++). So now let's go through this step by step: --- EFFECTAMOUNT = [1] Before declaring a special Effect, tell the Dolmexiler just how many Special Effects there are going to be. --- --- Every new Special Effect starts with three minuses. After the minuses, the header stuff gets declared: --- SPECIAL ID = [1] This is the same SPECIAL ID used to refer to this animation. Check the "Normal Animations" section above for more info. Just one more hint: Please declare the IDs in order. The first Animation has SPECIAL ID = [1], the second one has SPECIAL ID = [2], and so on and so on. --- SIZE X-AXIS = [32] The X-Texture-Size of each Special Effect Sprite. --- SIZE Y-AXIS = [32] The Y-Texture-Size of each Special Effect Sprite. Yay! --- RELATIVE TO CHAR = [YES] Einstein would be proud: The next values, POSITION X-AXIS and POSITION Y-AXIS, may either be fixed values, in which case the current line would be NO, or relative to your character's position. Epic = Mega Cool squared. --- POSITION X-AXIS = [69] The Effect's position. RELATIVE TO CHAR influences this value. --- POSITION Y-AXIS = [71] The Effect's position. RELATIVE TO CHAR influences this value... Y-AXIS. --- WHICH FRAME INITIATES = [4] This neat little line here declares when all the Special Effect stuff starts taking place. Remember that all the things you write here only deal with the additional Special Effect. The character's actual throwing animation is declared in the "Normal Animations" section. --- RANGE = [200] The Special Effect's Range, X-AXIS only. Please note that this is another scaled value. --- SPEED X-AXIS = [3] This time it doesn't deal with the amount of time anything is displayed. Just the Special Effect moving all over the place. --- SPEED Y-AXIS = [0] This time it doesn't deal with the amount of time anything is displayed. Just the Special Effect moving all over the place... Y-AXIS. --- EFFECT = [FREEZE] This optional line adds an additional pain in the neck for your enemy, IF the Special Effect hits. Currently, there are those possible options: [FREEZE] = The enemy can no longer move and is what we professionals like to call: "Frozen". Make sure to further define how long the enemy is frozen with EFFECT DURATION. Please note that hitting the enemy will unfreeze the enemy. [OMNI] = Pass control to the Omni-portion of the D-Engine and have your enemies say their final prayers. If you select this EFFECT, you have to include the line OMNI MOVE ID, but more on that later. --- EFFECT DURATION = [60] Only include this line if you have included the EFFECT line and if the EFFECT line's value is not [OMNI]. --- OMNI MOVE ID = [1] Only include this line if you have included the EFFECT line and if the EFFECT line's value is [OMNI]. This ID links to the OMNI move it is supposed to load once the Special Effect hits. --- SOUND EFFECT - HIT = [HIT_STPN] Weird enough, this line is not compulsory. Just like its "Normal Animations" namesake, it is used to define the sound effect that plays when the Special Effect hits. Cool, eh? --- COLLISION OFFSET X-AXIS = [0] Not compulsory. This is the offset for the hit detection mentioned above! --- COLLISION OFFSET Y-AXIS = [0] Not compulsory. This is the offset for the hit detection mentioned above... Y-AXIS! --- +++ As mentioned in this sections's intro, every Special Effect consists of four seperate animations. The data for each animation starts with three pluses. Please note that each of these four parts is compulsory. --- STAGE = [PRELOOP] Just like the intro said, there are four compulsory Special Effect Animations: [PRELOOP] = The animation playing once after the Special Effect starts. [LOOP] = This one just loops forever, until the animation's range is reached or 'till it deals some damage. Word. [VANISH] = Once the range has been reached, this animation takes place ONCE. [HIT] = Oh yeah, this plays when you hit the enemy. Each one of these stages is compulsory and must be included. --- NAME = [HADO_PRE] Each of these four animations must have a unique eight letter name. The naming stuff works just like with normal animations. --- SPEED = [5] The amount of frames each single sprite is displayed. By now, you should have seen this value once or twice. --- FRAMEAMOUNT = [2] How many frames exist for this animation? How many? Yeah, not really groundbreakingly new. --- | ||
5.8 C-C-C-C-Combo Maker! | ||
The main kicker this time around is the fact that the animation can be continued by instantly loading the next attack
animation. This is triggered by pressing a user-specified button. There is just one thing you should keep in mind:
The SPECIAL ID declared in the "Normal Animations" section immediately passes control to the Combo section. This
means that instead of loading all the things you have named in the "Normal Animations" section, but replaces it
immediately with the Combo stuff with that SPECIAL ID. That being said, let's rock: This part of the text file should start with the identifier #9 COMBO ANIMATIONS and end with (drumroll): +++ In this section, there is no more messing with header and frame things. In fact, most of the things are borrowed from the "Normal Animations" section. Here are the identifiers which you know already: --- Every animation starts with three minuses. NAME, FRAMEAMOUNT, SPEED, TYPE, LOOP, ENEMY ACCELERATION X-AXIS, ENEMY ACCELERATION Y-AXIS, SOUND EFFECT - HIT, SOUND EFFECT - MISS, SOUND EFFECT FRAME - MISS and STRENGTH still work the same. --- SPECIAL ID = [1] This is not the SPECIAL ID from the "Normal Animations" section, but rather the one used in the other Special Attack sections: It is used to refer to this animation. Check the "Normal Animations" section above for more info. Just one more hint: Please declare the IDs in order. The first Animation has SPECIAL ID = [1], the second one has SPECIAL ID = [2], and so on and so on. --- GO TO SPECIAL = [1] Now THIS is the SPECIAL ID from the Normal Animations section, it just has a different name. --- GO TO BUTTONS = [A] The button which must be pressed to load the next animation. Only use single buttons here, Add-On identifiers like with the BUTTONS identifier from the "Normal Animations" sections are ignored. --- CHAR POSITION CHANGE X-AXIS = [-12] This value declares how much the character moves, once, as soon as the frame is loaded. --- CHAR POSITION CHANGE Y-AXIS = [-24] This value declares how much the character moves, once, as soon as the frame is loaded... Y-AXIS. --- | ||
5.9 Omni Moves | ||
This section, boldly named OMNI MOVES (probably a freudian slip related to Cloud's Omnislash), is meant to combine
everything from all the sections and gives you full control over every aspect of the D-Engine. It can either be
initiated by a normal move that hits the enemy or a Special Effect that connects. Unlike with other Special Moves, stuff
isn't declared for every single frame, but rather for so-called "actions". Since you have control of both the character
and a Special Effect texture, you can change both in both go, and the status lasts for as long as you define it in
DURATION. We'll go through it step by step again, so that should clear things up a bit: The initiator this time around is... #10 OMNI ATTACKS and the end-inator consists of... three... ### So much fun. Like always, every animation starts with three minuses (---) and every "action" with three pluses (+++). But hey, before the real important stuff begins, declare how many animations exist: ANIMATION AMOUNT = [1] Now, the usual list: --- --- Every animation starts with three minuses. --- SPECIAL ID = [1] The SPECIAL ID is used to refer to this animation. Check the "Normal Animations" section above for more info. Just one more hint: Please declare the IDs in order. The first Animation has SPECIAL ID = [1], the second one has SPECIAL ID = [2], and so on and so on. This is the only header value, the rest is declared within "actions", starting with... --- +++ ...three pluses! Now for the interesting part, declaring "actions" is a tad more difficult than the previous fun stuff: --- ENEMYALIGNMENT = [PARALYZED_STANDING] With this you choose whether the enemy is standing [PARALYZED_STANDING], or lying [PARALYZED_LYING]. Not much else to it. Deja vu? --- CHARACTER ANIMATION NAME = [STAIRWAY] Only include this line if you wish to change something about the character's animation. If you choose to include this line, you need to/are able to to include the following lines as well. --- CHARACTER FRAME AMOUNT = [10] How many frames does the animation have? This line depends on CHARACTER ANIMATION NAME. --- CHARACTER ANIMATION SPEED = [4] Declares how long each frame is displayed. This line depends on CHARACTER ANIMATION NAME. --- CHARACTER WHICH FRAME = [1] This one tells the engine which frame is supposed to be portrayed right after the "action" has finished loading. It depends on CHARACTER ANIMATION NAME. --- SPECIAL EFFECT ANIMATION NAME = [TOHEAVEN] The name of the Special Effect to be displayed. By including this optional eight-characters-long value, you also enable/force the use of the following lines as well. --- SPECIAL EFFECT FRAME AMOUNT = [4] The amount of frames this Special Effect has. Depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT ANIMATION SPEED = [4] The time (in frames) each single sprite is displayed. Depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT WHICH FRAME = [1] This one tells the engine which Special Effect frame is supposed to be portrayed right after the "action" has finished loading. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT SIZE X-AXIS = [512] The texture size of the Special Effect. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT SIZE Y-AXIS = [512] The texture size of the Special Effect... Y-AXIS. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT RELATIVE TO POSITION? = [NO] If the Special Effect's position is a fixed position somewhere on the screen, set it to NO. If the POSITION declared later is added to the character's position, use YES instead. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT POSITION X-AXIS = [0] Well, just the position. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT POSITION Y-AXIS = [0] Well, just the position... Y-AXIS. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT SPEED X-AXIS = [0] Declares how fast the animation moves. It depends on SPECIAL EFFECT ANIMATION NAME. --- SPECIAL EFFECT SPEED Y-AXIS = [0] Declares how fast the animation moves... Y-AXIS. It depends on SPECIAL EFFECT ANIMATION NAME. --- CHARACTER POSITION CHANGE X-AXIS = [0] Exactly the same value as the one from the throwing section. The character's position changes only once, just when the action is loaded. --- CHARACTER POSITION CHANGE Y-AXIS = [0] Exactly the same value as the one from the throwing section. The character's position changes only once, just when the action is loaded... Y-AXIS. --- ENEMY POSITION CHANGE X-AXIS = [0] The enemy's position changes only once, just when the action is loaded. --- ENEMY POSITION CHANGE Y-AXIS = [0] The enemy's position changes only once, just when the action is loaded... Y-AXIS. --- CHARACTER MOVEMENT X-AXIS = [0] Now the main difference between this value and the CHARACTER POSITION CHANGE type is that this value is continuously added to the character's position. For every frame the sprite is displayed, the char's position changes by that exact value up there. --- CHARACTER MOVEMENT Y-AXIS = [-3] Now the main difference between this value and the CHARACTER POSITION CHANGE type is that this value is continuously added to the character's position. For every frame the sprite is displayed, the char's position changes by that exact value up there... Y-AXIS. --- ENEMY MOVEMENT X-AXIS = [0] Now the main difference between this value and the ENEMY POSITION CHANGE type is that this value is continuously added to the enemy's position. For every frame the sprite is displayed, the enemy's position changes by that exact value up there. --- ENEMY MOVEMENT Y-AXIS = [0] Now the main difference between this value and the ENEMY POSITION CHANGE type is that this value is continuously added to the enemy's position. For every frame the sprite is displayed, the enemy's position changes by that exact value up there... Y-AXIS. --- CHAR POSITION RELATIVE TO POSITION? = [NO] This optional line allows you to declare a fixed position on the screen to which your character moves instantly. Interesting enough, if you set this value to YES, the POSITION FIXED type values work just the same as the POSITION CHANGE type ones. Curious, isn't it? --- CHARACTER POSITION FIXED X-AXIS = [320] The character's new position. Depends on "CHAR POSITION RELATIVE TO POSITION?". --- CHARACTER POSITION FIXED Y-AXIS = [0] The character's new position... Y-AXIS. Depends on "CHAR POSITION RELATIVE TO POSITION?". --- ENEMY POSITION RELATIVE TO POSITION? = [NO] This optional line allows you to declare a fixed position on the screen to which your enemy moves instantly. Interesting enough, if you set this value to YES, the POSITION FIXED type values work just the same as the POSITION CHANGE type ones. Still curious, isn't it? --- ENEMY POSITION FIXED X-AXIS = [32] The enemy's new position. Depends on "ENEMY POSITION RELATIVE TO POSITION?". --- ENEMY POSITION FIXED Y-AXIS = [0] The enemy's new position...Y-AXIS. Depends on "ENEMY POSITION RELATIVE TO POSITION?". --- ENEMY ACCELERATION X-AXIS = [10] The strength with which the enemy is pushed back. Keep in mind that this is one of them deaccelerating values, making them very tricky to get right. On top of that, it is also scaled, depending on how much the char is enlarged. For Omni Moves, this value is usually used to end them. --- ENEMY ACCELERATION Y-AXIS = [8] The same thing as above, just for kicking the enemy up in the sky. It also deaccelerates, but usually less than the X-AXIS value. Scaled 'n everything. For Omni Moves, this value is usually used to end them. --- ANIMATION STRENGTH = [0] If you want the enemy to lose health immediately, use this optional line. (A character's max health is 1000). --- DURATION = [60] Probably the most important value, this one defines how long (in frames) it takes 'till the next "action" is loaded. --- | ||
6th step: Using the Dolmexiler | ||
Now, save your input text file and open the command line in your DOLMEXILER directory. Activate the program with the
following parameters: -i This option is used just before the input text file. -o Used just before the output directory. So if your input file is "/home/captaindc/STICKLER.txt" and your output directory is "/home/captaindc/OUTPUT" it would be on Linux: ./DOLMEXILER -i /home/captaindc/STICKLER.txt -d /home/captaindc/OUTPUT This will create your character's STA, _HUMAN.mvt and SFX files. Keep them around for the final step. | ||
7th step: Artificial Intelligence | ||
You know, the problem with the CPU is that he (or she?) doesn't give a damn about buttons, the thing people use
to tell the engine which attack the engine is supposed to use. Rather, the sexually ambivalent blast processor tends to
care about situations. After these words of introduction, close (and save!) the text file you used for the 5th
step and open a new one. Defining the artificial intelligence is a lot easier than the whole stuff before, since the DolmexicAI (cool name, eh?) uses the original MVT file as input. On the upside that means no more declarations of animations. On the downside, that means that Computer-controlled enemies cannot have attacks human players do not have. Like before, there are identifiers. This time around they deal with situations though. After using the situation identifier, you can add a new animation to be used in that situation by using one minus and the animation name in brackets. Too theoretical? Let's look at an example: --- CHARACTERNAME = [STICKLER] Before you do anything, declare the character's name. --- ---STANDARD GROUND MOVES Before adding animations, you need to declare a situation. Here is a list of all current identifiers: ---STANDARD GROUND MOVES = The fallback animation. Consider it a strong ground move to be used when fighting an enemy that is also standing. ---GROUND INTERCEPTOR = Should both you and the enemy be standing and the enemy is very close to you, these animations are used. This is where the quick jabs go. ---GROUND AGAINST AIR MOVES = Jumping enemies can be a real threat. ---GROUND AGAINST CROUCH MOVES = Sometimes these happen, sometimes the AI goes crouching as well. ---CROUCH AGAINST GROUND MOVES = These clear identifiers make me unemployed. ---CROUCH AGAINST AIR MOVES = The enemy jumps, the AI is busy crouching, these animations play. ---AIR AGAINST AIR MOVES = Dogfight! ---AIR AGAINST GROUND MOVES = Rumor has it these moves concern Air moves which are used against enemies on the ground. --- -[KICKWEAK] You can add as many animations as you feel necessary. They will be copied over from the _HUMAN.mvt, so don't go inventing new things here! Note: All Special Moves are copied over, there's not even a check whether they are used or not. You still need to declare their "starters" though! "Starters" are the animations from the "Normal Animations" section that started the Special Move. --- | ||
8th step: Another tool, another story | ||
Now we create the final file, the _CPU.mvt. For this, we use a tool called DolmexicAI: It is used like the
Dolmexiler, with a command line. This time around, there are three option flags though: -i The TXT file you just made. -o The output directory. -m The _HUMAN.mvt created in the 6th step. So if your text file's filedir is "/home/captaindc/STICKLER_AI.txt", your output directory is "/home/captaindc/OUTPUT" and your _HUMAN.mvt is located at "/home/captaindc/STICKLER_HUMAN.mvt", use this command under Linux: ./DOLMEXICAI -i /home/captaindc/STICKLER_AI.txt -o /home/captaindc/OUTPUT -m /home/captaindc/STICKLER_HUMAN.mvt This will create the _CPU.mvt, the final compulsory file necessary for your character to kick butt. | ||
The final step: Restarting from scratch | ||
The title scared you, didn't it? Of course you don't have to restart from scratch, you're finished bro! Keep
the files, you will need to put them in the game later on. That's another story for another manual (Creating a new
Dolmexica Engine CD) though, so for now, let me be the first to congratulate you for your new character! I hope you
had a good time putting together that piece of fighting history, it may have been hard, but it will all be worth it
once you see that creation of yours waltzing over the screen. Enjoy your victory, guess we'll meet again when you want
to create a new background, hehe. 'Till then! -J.T. |