Thread Rating:
  • 5 Vote(s) - 3.8 Average
  • 1
  • 2
  • 3
  • 4
  • 5
The A-Engine: A new Beat 'em Up game engine
#1
[Image: 33w3.png]

Hey LF2 fellas!
So I have been working on this little project of mine, the A-Engine. Inspired by the ability of LF2 to be fully modded, I started writing a beat 'em engine (written with C++ using SDL loading imgs, sounds and input and OpenGL for rendering) which you guys won't face any limitations in your developing. The scripting syntax is very similar to that of LF2's data changing, but with more syntactic sugars to make the scripting way easier for you. All that mentioned, the A-Engine literally supports mostly everything you will need. The menus interface is customizable, and so are game mechanics; the gravity, the friction and even the FPS can be changed to suit your needs. Not to forget to mention how you're given control over allocating the number of frames in your .a file (the .dat file) or even the number of images you can load. You also have the support to do some inline sprite editing including filtering, changing transparency, transformations and some other even greater stuff. PNGs, BMPs, JPGs, non animated GIFs and hopefully animated GIFs and APNGs are to be supported too. As for controls, you are given the choice to have a 4th button for whatever purpose, and the key combinations are limitless as long as you keep it down to 6 key presses max. This also includes Holding buttons or clicking them. The time interval between each key press can be set as well. Dynamic stages ranging from windy platformed mountains to icey slippery surroundings are supported. A 3rd meter bar was also implemented for those whom are interested in having an additional one for stamina or whatlike.A lot of other features were implemented, but the one that I am most fond of is the Variables, Registers and Functions systems. Consider the following basic frame example:


Code:
#this is a comment
[f=20]  #Frame start. This is frame 20.
|STANDING|NOSHADOW|             #These are the "Switches". Does the job of "state:" in LF2
img=0 delay=3 center=39, 99     #img=->pic: delay=->wait: center=->centerx:centery:
vel_x=0 vel_y=3-3 vel_z=0       #vel_x=->dvx:.note the 3-3;will be evaluated at runtime to 0
c<a>=30 c<d>=30 c<j>=30 c<s>=30 #hit_a, hit_d, hit_j, hit_s; s being the 4rth button
h<a>=30 h<d>=30 h<j>=30 h<s>=30 #thats for holding the 4 buttons
[/f]    #Frame end


Now this is pretty basic right? Notice the switches I used. Instead of having a single state, we can now have more than a state by using multiple switches. The object in that frame will be considered standing (will go to walking frames if any arrow button is clicked) and will have no shadow.Now lets try to do something different. Something that is considered hard to do wiht LF2. Suppose you would like to have clicking attack take you to a frame based on a condition. For instance, you would like to have clicking attack while your HP is lower than 250 take you to frame 25;else, you would like to got to frame 30. You will have to use the "conditional operator ("?")" for it. C programmers will find this familiar XD:
Code:
somevar= myhp<250?iftrue:iffalse;
In the A-Engne script though, you will have to start that with a "~" and end with a ";" for parsing's sake:
Code:
c<a>=~@curr_hp@<250?25:30; #if current hp is less than 250, goto 25;else, to 30
Now that same syntax can be used for the "delay=", "center=" or any other tag as well. Now notice how "curr_hp" was surrounded by a pair of "@"s. It just means that this is a "variable"; it varies according to game. You can't change or edit that. There are other variables as well storing your object's velocity, id, position in x,y and z..etc. Now to get even more flexible, you can store data in "registers". For every object, you have got 52 registers for you to manipulate and even share with other follower objects. The registers can be accessed by surrounding any alphabet, capital or small, with a pair of "$" (horraay PHP developers XD). To store data in any register, you use a special tag: "set_reg=" taking 2 parameters:
Code:
[f=3]
img=0 center=30,30 delay=1
set_reg=$a$, 30             #store the value 30 in the reg a.It's a bit of ASM's "MOV" here XD
alpha=125                   #a simple tag for changing the transparency of this sprite to 125/255
[/f]

[f=4]                       #notice how I didn't have any "goto=" tag in frame 3.
                           #I ignored it because I didnt' have to. In case you leave
                          #a goto of a frame, it will automatically goto the frame
                           #with the number that comes after its' number.
img=2 center=30,30 delay=1 goto=0
set_reg=$a$, $a$+1          #I increment the value of $a$ by 1.
[/f]
Sweet, right? Now you are even given 100 more GLOBAL variable which are just shared between everything. These registers are basically from 1 to 99 ($0$, $1$...$99$). Third, we've got oursevles some "functions" to do cool stuff for us. A function is surrounded with a pair of "&"s. Suppose you would like to launch your opponent upwards with an angle 30 degrees and velocity of 10 px/frm (pixels per a (1/FPS)th of a second):
Code:
[f=222] #knock opponent
img=123 goto=0 delay=2 center=0,0
set_rect[               #and here is our itr!!  
|FALL|                  #"switch"; will have the opponent fall now matter what
x=0 y=0 z=-8            #the x,y,z coords for where the rect starts
w=10 h=30 d=16          #the width,height and depth of the rect
rect_density=2          #arest/vrest; the no. of objects the rect can hit at once
hit_interval=30         #how many delay units will it take for the rect to hit again
x_impact=10*&COS{30}&   #dvx of the rect.We multiply by cos(angle) to get x-component
y_impact=-10*&sin{30}&  #dvy of the rect.We multiply by sin(angle) to get y-component
damage=20
]
[/f]


Now lets try to make use of the vars, regs and the functions to do something cool. Suppose you would like to have some cool physics stuff in your game. You would like your forward-up uppercut to knock the enemy away, or to be more accurate, transfer your momentum in x and y to him, and then heal your HP with a random value between 0 and 100. To do this, you will have to store his current velocity in a register (the mass in the calculation is handled by the engine itself). Then you will be doing some momentum physics to find your new velocity and his new velocity.:
Code:
[f=532] #uppercut
img=421 center=(30+30)/2,(5+5)*3  #evaluates to center=30,30
delay=$b$-2                       #supposing b is 3; it evaluates to 1              
vel_x=10 vel_y=-12
set_rect[                                
x=0 y=0 z=-8 w=10 h=30 d=16                    
damage=40
copy_target_reg=@x_vel@|@y_vel@,$x$|$y$      
#copy target's x,y velocity to your regs $x$, $y$
x_impact=@x_vel@ y_impact=@y_vel@
success=533                       #if this rect successfully hit, goto 533
]                                              
[/f]

[f=533] #Recoil frame
f_x=$x$*-1 f_y=$y$*-1    #f_x,y,z sets force on you equal to the value to make you accelerate
center=0,0
img=999 delay=1
goto=0 hit_ground=44     #hit_ground is the frame you will goto if you reach the ground
add_hp=&randint{0, 100}& #the randint function returns a random int between its 2 arguments
[/f]

There are still a loooooot of tags you can use, but I will just list them down later.
Lets see what frame components do we have for the A-Engine. In LF2, the only think you could use in an object's dat file are frames. This isn't true for the A-Engine though!. In addition to having frames in your .a files, you can pack frames together in a sequence. For that to work though, the frames must have consequtive img numbers, same delay and center values.

Consider the following example:

Code:
[f=4]
img=0 center=30, 30 delay=1 #the goto is automatically set to )4+1)
[/f]
[f=5]
img=1 center=30, 30 delay=1 #goto=5+1
[/f]
[f=6]
img=2 center=30, 30 delay=1 #goto=6+1
[/f]
[f=7]
img=3 center=30, 30 delay=1 #goto=7+1
[/f]
[f=8]
img=4 center=30, 30 delay=1 #goto=8+1
[/f]
[f=9]
img=5 center=30, 30 delay=1 #goto=9+1
[/f]
[f=10]
img=6 center=30, 30 delay=1 #goto=10+1
[/f]
[f=11]
img=7 center=30, 30 delay=1 goto=1000 #delete object
[/f]
Now using sequences (), that can be:
Code:
[s=4->11]
img=0                   #will be incremented for every frame in the seq
center=30, 30 delay=1   #these will be common for all frames in the seq
goto=1000               #this goto will be executed at frame 11
[/s]

Note that it is possible to change a frame in the sequence if that particular frame was rewrote down:
Code:
[f=4]
img=0 center=30, 30 delay=1 #the goto is automatically set to )4+1)
[/f]
[f=5]
img=1 center=30, 30 delay=1 #goto=5+1
[/f]
[f=6]
img=2 center=30, 30 delay=1 #goto=6+1
[/f]
[f=7]
img=3 center=123, 440 delay=433 #hey look! my tags are different!
[/f]
[f=8]
img=4 center=30, 30 delay=1 #goto=8+1
[/f]
[f=9]
img=5 center=30, 30 delay=1 #goto=9+1
[/f]
[f=10]
img=6 center=30, 30 delay=1 #goto=10+1
[/f]
[f=11]
img=7 center=30, 30 delay=1 goto=1000 #delete object
[/f]
with sequences you can do
Code:
[s=4->11]
img=0 center=30, 30 delay=1 goto=1000              
[/s]
[f=7] #this frame will rewrite frame 7 in the sequence
img=3 center=123, 440 delay=433
[/f]


Oh and here is a list I rushed with, HOPEFULLY, all the in-frame tags you can use:
[Image: ylJPmCAeSRc196XIRQtw+table1.png]
Frame Components:
In LF2, we had itrs and bdys for hits and damage related stuff, wpoints to set a position of a weapon if any is hold, cpoints for

catching, and opoints for spawning objects. In the A-Engine, these stuff are covered quite differently. The wpoints and the

cpoints were omitted. You've been given only 7 components that will hopefully cover all your needs:
1-The "set_rect[ ]" component (itr); for hits, platforming, catching or any other stuff that directly affects the target player.
2-The "set_bdy[ ]" component (bdy); for invulnerability areas, defending..etc.
3-The "call_object[ ]" component (opoint); for spawning new objects into the screen and controlling them around.
4-The "set_combination[ ]" component; for advanced keys input and combinations.
5-The "draw_shape[ ]" component; for drawing simple colored circles, rectangles, ellipses...etc.
6-The "set_transformation[ ]" component; for skewing, cutting, translating, stretching..etc of the sprites.
7-The "set_media[ ]" component (not implemented yet); for playing and simple editing of sounds and video clips.
Now lets try to do something with inputs. We will create a key combination that works just like Super Smash Brother's. To do this, we are going to be using the "set_combination" component. Here is a list of all the tags that can be used inside "set_combination[]":
[Image: lgbuS99SMyTJMCyMTteh+table2.png]
Now lets start with a simple example first; Davis's Dragon punch combination (D^A):
Code:
set_combination[   #here is our combination component
sequence=(c<d>,c<u_a>,c<a>)
time_interval=4321   #we don't consider the delays b/w the presses
goto=250             #we goto the dragon punch frame
]  #the rest of the tags are unnecessary in this case

Now lets try to have dragon punch work in Smash Bros'  style. Having it as a smash Up attack would've been been clicking "Up" followed by "Attack" with a small time interval between the presses:
Code:
set_combination[   #here is our combination component
sequence=(c<u>,c<a>) #Up followed by attack
time_interval=100    #100 milliseconds being a 10th of a second is the interval b/w the 2 presses
goto=250             #we goto the dragon punch frame
]  #the rest of the tags are unnecessary in this case

As a light Up attack, it would've been holding Up and clicking attack while Up is held:
Code:
set_combination[   #here is our combination component
sequence=(h<u_a>,c<a>)#hold Up and then click Attack
time_interval=0   #no time interval at all. Up must be held when Attack is pressed
goto=250             #we goto the dragon punch frame
]  #the rest of the tags are unnecessary in this case

~To be continued


Oh and about the progress; the Engine is pretty much done as I've been working on it for sometime now (almost 7 months until now). The engine's game logic is pretty much done. Still have a little bit of work to do with the A-Engine's user interface then I am going to try to redo some LF2 characters using it XD. Its gonna be 2 or 3 more months I guess..

Any questions, suggestions or anything are very welcome.


Current projects using the A-Engine:
-One Piece A-Edition
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
#2
Woah, that looks pretty darn impressive. I'll definitely have to tinker with that :p

And now I see why you asked about the tables, haha :D

As I see it, the engine supports everything the regular LF2 can do. Would be cool if you could write up a little script that converts the original dat's to this format. That'd at least give some more chars to play with. But I definitely like where this is going. If there was the chance to thank this post twice, I'd certainly do this. Wait a min...

Ramond edited this post 09-15-2014 10:05 AM because:
LFE WARS EPISODE V: TESTUSER STRIKES BACK

» Gallery | » Sprites | » devArt

  [Image: style5,Blue-spc-Phoenix.png]
» Want your project on the Mainsite? Just follow the instructions in this thread!
Reply
#3
I also wanted to create my own engine but i didn't know much about C++ (only some basics I learned in school) and I have no time to learn it now.
I didn't read the whole text now, probably i wouldn't understand all...

A-Man Wrote:Inspired by the ability of LF2 to be fully modded, I started writing a beat 'em engine (written with C++ using SDL loading imgs, sounds and input and OpenGL for rendering) which you guys won't face any limitations in your developing.
So what i would like to see, don't know if it is already possible in the normal LF2 engine:
Will it be able to make id dependent effects, I mean if object id:1 and id:2 hit each other something different happend as when id:1 and id:3 hit each other and id:1 and id:4.
Better working cooldown system i know there is something already possible in the normal LF2 engine.
Summoring more than one opoints at once in a singel frame.

Would be cool if this is possible.
[Image: ZHkICNr.png][Image: adGT3Xm.png]
Reply
Thanks given by: A-Man
#4
damnit, i hope you wont be able to export to android :p id have that advantage then at least
great work, as i am making a lf2 clone too i can relate to the amount of work (and i recycle a lot of lf2 code actually).
big thumbs up!
Reply
Thanks given by: A-Man
#5
Lol finally you decided to post! :P amazing job, that's needless to say.. with the possibilities, I really expect some bigass DCers to create magic characters using the A-engine :P
Also, why dont you link to the A-engine demo and a bit of screenies here?
Keep it up bro :D

PS : IM ALREADY CALLING DIBS FOR CREATING A DBZ MOD IN THIS, DONT STEAL IDEA (jk)

@joho : indeed I believe everything is possible, however i'd only answer about the id dependent effects since im sure of that, all the effects that you can imagine, can be easily adjusted inside the .A (.dat) files. Like armor and stuff along with no shadows etc
Reply
Thanks given by: A-Man
#6
@Blue Phoenix: Thank you very much. A converter is the plan XD.

@JoHo:
Quote:So what i would like to see, don't know if it is already possible in the normal LF2 engine:
Will it be able to make id dependent effects, I mean if object id:1 and id:2 hit each other something different happend as when id:1 and id:3 hit each other and id:1 and id:4.
Possible and less complex than you might think. Give me a while until I update that tutorial with stuff about rects (equivalent to itrs) and bdys. Put in mind that there won't be any "id-dependent" stuff. Whereas Marti and Starsky built a game that was exploited to be modable engine, I am actually building an engine, and stuff properties should be equal for every id.

Quote:Better working cooldown system i know there is something already possible in the normal LF2 engine.
I am not sure I understood what you meant by a cool down system. Do you mean something like a move which when performed needs some time before you can do it again? If that's it, then yes. All you need to do is set a Register with the time it would take to "cool down" when the move starts. The combination that takes to that move would then have a condition which only makes it work if that register is 0. That register can then be made to decrement every frame until it reaches 0. Here is how you're going to do it:
    C-Code:
{info}  #will be explained in detail later
etc etc etc
{/info}
 
{initialregs} #will be explained in detail later
etc etc etc
{/initialregs} 
 
{mainloop} #set_regs here will be activated once every frame
set_reg=$c$, ~$c$==0?0:$c$-1;
{/mainloop}
 
#Now we start with our frames
 
[f=0] #standing
img=0 delay=1 center=39,79 
set_combination[ 
sequence=(c<d>, c<f>, c<a>) time_interval=4321 goto=210 
condition=~$c$==0?1:0; #this combination would only work if this returns 1
]
[/f]
 
[f=210] #the move
set_reg=$c$, 330  #supposing the FPS is 30, it would take 10 seconds for the move to cool down
img=90 delay=1 center=39,79 goto=whatever  
[/f]


Quote:Summoring more than one opoints at once in a singel frame.
Yes, possible and can even work when the frame didn't start with a next. (I really can't understand why LF2 had opoints only work with frames that started from a next. If someone knows why, I am all ears.)

@Bamboori: Lol I don't think I am gonna be having android support. At least not any time soon XD. Thanks!

@Freaky: I don't want to link to that since its 4 months old and uses Ripped non-Lf2 sprites. I am preparing something LF2ish though; Don't know what screenies either. All I can say is soon :P
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by: JoHo15 , Nyamaiku
#7
I just have one question: Will players be able to mash buttons to speed up an animation or through set of moves? If you want a clear example, imagine when you get dizzy in a fighting game... the player has to mash buttons to get out of dizzy faster. Will something like that be able to be programmed in? It's the only thing I am curious about that hasn't been brought up yet.
To live a life of power, you must have faith that what you believe is right, even if others tell you you're wrong.
The first thing you must do to live a life of power is to find courage. You must reach beyond the boundaries of time itself.
And to do that, all you need is the will to take that first step...
Ask not what others can do for you, but what you can do for others.
Reply
Thanks given by:
#8
(06-02-2014, 03:25 AM)Bat Tamer Wrote:  I just have one question: Will players be able to mash buttons to speed up an animation or through set of moves? If you want a clear example, imagine when you get dizzy in a fighting game... the player has to mash buttons to get out of dizzy faster. Will something like that be able to be programmed in? It's the only thing I am curious about that hasn't been brought up yet.
Yes, definitely. This is how you're going to do it:
    C++-Code:
[f=9] #dizzy start
img=233 delay=3
set_reg=$d$,6   #6 clicks should get you out of the stun
[/f] #goto=9+1
 
[f=10] #dizzy
|FLUSHCOMBINATION|  #this switch clears the input buffer. We need to do this every time we have a combination of only one key.
img=234 delay=5 loop=10, 11, 0 #after ten loops, go to frame 0 if and only the previous frame was 11.
set_combination[
seq=(c<a>) set_reg=$d$, ~$d$>0?($d$-1):0; #decrement d every time attack is clicked until it reaches 0
goto=4321    #4321 is a magic number as I've said before. It basically means go to nowhere if Attack is clicked.
]
[/f] #goto=10+1
 
[f=11] #dizzy
|FLUSHCOMBINATION|
img=235 delay=5 
goto=~$d$==0?0:10;     #check if $d$ is equal to 0. if true, get done with the stun. else, continue until the loops gets you out instead 
set_combination[
seq=(c<a>) set_reg=$d$, ~$d$>0?($d$-1):0; #decrement d every time attack is clicked until it reaches 0
goto=4321    #4321 is a magic number as I've said before. It basically means go to nowhere.
]
[/f]

More elaborated explanation:
The original dizzy state is basically 10 loops going between 10 and 11. You can, however, get out of it by pressing Attack five times. We first start by defining the register $d$ (or any other register) and set it to 6. At the loop itself, we're gonna make a "set_combination[]" tag that takes you nowhere (its goto is 4321), but just decrement the value of $d$ whenever the combination happens. The problem of using a combination component with only one key is that the time interval between the click and itself is always 0; therefore we make sure we clear the key clicks buffer every frame.
You can also see that the goto in frame 11 got a conditional statement: "~$d$==0?0:10;"; if 6 clicks where done and $d$ was down to 0, escape the dizziness and goto frame 0. Else, continue with the loop.
I know it looks a bit complicated now, but it really isn't as complex as what you guys do with the ik8 stuff lol. Remember that you don't have to go through these stuff if you want to do anything within LF2's scope. Once you get used to this, you will see how the A-Engine can be a real beast XD.

I am planning to do a little project here where I am going to work on an A-Engine character and an interactive stage and walk with you guys step by step in the process. I am quite busy nowadays, but I will try my best to start that ASAP.


Also, I was thinking of changing the "set_rect[]" (itr) component and renaming it into set_box[]. After that, I can do some other identical components, "set_ellipsoid[]" and "set_cylinder[]", which instead of having the collision detection range rectangular, can have it in and egg shape or a cylinder. This can get really convenient when tracing platforms which have curved shapes; a hill for example. Ideas? Suggestions?
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by: Rhino.Freak
#9
Something which I quite did not understood properly[as I have no time to read that all and I don't understand it too :p ] but I can see things from the image in your profile. Great effort A, which turned out very very well. This is hell IMPRESSIVE!!!!!!
...............
Reply
Thanks given by:
#10
Thanks you very very much! If you anything turns out unclear, let me know and I will see if I can rewrite that part so it becomes more clear.
So I decided the demo is going to be DBZ style; since that the the theme I can most show off with XP. So me and Rhino.Freak are working on this character called "Sayaplate". The name says it all; a Sayan template :P. Visuals aren't all that great, I am sorry. I couldn't find better assets.
Sayaplate flying around (Click to View)
To start flying, press jump in air after jumping. Hold forward to fly forward, Up or down to move in the Z-axis. Holding Up or Down together with Jump will fly Up or Down in the y-axis.

Planned attacks:
All in all, the new fourth key, special, will cover all the energy ball attacks. Attack will cover the directional melee attacks; smash bros style.
Special: Ki blast. The faster you tap the key the faster you will shoot. Holding Special should charge the Ki blast for a bigger stronger one. I am also planning to have it chase to a very low extent.
Forward+Special: Kamehameha. The more you charge the stronger it is.
Attack: A right kick,left kick,left punch or right punch at random. You can tap Attack to barrage your opponent with hits.
Forward+Attack(immediately; SSB style): A tackle the launches the opponent forward.
Up+Attack(immediately): An uppercut the launches the opponent upward.

While flying:
The above attacks plus:
Down+Attack: A hammer fist with both hands to knock your opponent downward.
Down+Forward+Attack: A thrust kick in that direction.
"Running" in air should be a boost in speed with some aura going around you. Should cost Ki.

P.S: If anyone is interested in helping me with the assets, PM me. I have been looking for some HDish Ki balls as well.
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by: bashscrazy , Hate




Users browsing this thread: 1 Guest(s)