Devlog #End
Welp, I apologize, but I no longer want to continue programming for this game. I'm going to relax a bit, learn and most likely move onto Unity. Goodluck guys, and again, sorry for leaving.

Okay so this is my first time making a dev log. I didn't want to start this off with a meh post but I needed to at least start the dev log...so a meh post it is!

-----

I'm Mit's programmer for a game called Mfgg TKO. It's a 2D brawler platformer based around the members of MFGG. I'll try to post about progress whenever I feel I need some feedback, have done anything log worthy, or to just keep you guys in the loop.

Instead of writing of everything I've done so far in single post, I'll try to spread it out over a few days so it's not too overwhelming. For now, I'll just make a general post about what I've done so far.

Here are a few gifs of the game so far. The levels aren't apart of the final game, they're just for testing purposes. (which some have seen in the WIP thread)

The tool supports palettes, skeletal animation, and normal frame-based animation. You can also animate tinting, rotation, scaling, translating, skewing visibility, and palette fading/changing/animating among other things. I also added subanimations which I had fun implementing. You can basically use and animate multiple subanimations within an animation. However, you can only animate the subanimation from a higher level. You can indirectly affect it's timeline so you can play it at arbitrary times or even speed it up or slow it down. It was originally made for Ridge Troopa's and Phaze's game which unfortunately went on hiatus before I could get any good progress done on the tool. I've made a few animation tools, and this one along with the sprite engine is my favorite so far, thanks Ridge.
The game itself is still in very early development. I'm still just laying down the core engine stuff.

In the engine, attacks have "scripts"(subactions) attached. The script is called once per animation frame. I love this system which I based off of how PSA's are done over at kc-mm. I can create offensive collisions, graphics effects, play sounds, whatever, etc within the script in order to create the move. -I gotta move the code out of C# later and into Lua so Mit and the others can code their own moves without needing to rebuild the game or directly need me. An idea we have is to have online multiplayer where your friend's custom characters will be loaded and can be selected by eachother. That should be fun to code when we get there.

Yeah of course. Since movesets are going to be done in lua, they're easily editable. By then, there should be support for custom movesets. When you play with a friend online, you can download/use each other's custom characters. That's the idea so far. 0% of progress done on that part networking side though. The moveset "engine" is pretty much done (the actual fighting isn't), we just need to make content for it.

Came in not expecting much (not intended as being offensive) but I'm pretty blown away; this looks really impressive. I could see this being used for something substantial.

I'd love to see a game like this be worked into a Metroidvania style RPG - I would love to get involved in such a project. It looks supremely awesome. Very smooth, really interesting. Do you have any sort of super basic demo? Does the whole thing allow for a larger scale? It's relatively low-res right now, which is absolutely fine, but it'd be interesting to see a more extended view, or for other projects using the same engine, larger graphics.

Tsunami Bomb - The Simple TruthWe could run away
Leave behind anything paper
Not knowing where we're going to stay
When there's no Mondays

You're part of me, it's so easy to see the simple truth
When I'm in your arms, I feel safe from harm and sorrow too
You're part of me, it's so easy to see the simple truth
But most of all, nothing couldn't be solved when I'm with you

(01-10-2014, 07:10 PM)TheShyGuy Wrote: An idea we have is to have online multiplayer where your friend's custom characters will be loaded and can be selected by eachother. That should be fun to code when we get there.

I'd be careful with this and try to place ingame engine limits. This idea won't be fun when That Guy makes a character with a kick that fills the whole screen and OHKOs you ):

If possible (and I'm not a programming sort) I'd try to hardcode maximums for each usable stat and probably hardcode a maximum sprite-size too (though it would suck having to fight that guy with a 2px hitbox) so you dont have The Most L33T Characters Alive

(01-11-2014, 10:43 AM)Dazz Wrote: Came in not expecting much (not intended as being offensive)

None taken, that's a bit understandable.

Quote: Do you have any sort of super basic demo? Does the whole thing allow for a larger scale? It's relatively low-res right now, which is absolutely fine, but it'd be interesting to see a more extended view, or for other projects using the same engine, larger graphics.

Right now, there isn't a public demo out, sorry.

The moveset engine is pretty simple and subactions/attacks should be pretty cheap since they run throughout the animation, once per animation frame. I'm unsure about the animation system though. Right now the animations for mit are very simple since it's just frame-based. But theres support to make it a lot more interesting. I designed the animation system to be a bit generic (not literally) which allows flexibility at the cost of a bit of performance. Previous and Fluttershy over at the chat helped me out when I had questions or issues with making it generic - thanks guys. With my zero experience of big projects, I can only hope it scales fine.

cross post from Mit over at MFGG about the graphics. (answer at the bottom)

however, more members will be represented as enemies and Membits, the latter being similar to Options from Gradius. they follow you around and help you in certain aspects. here's the current list of Membits-

Genogenesis7
Roushi
Yoshbert
Mario
Luigi

the Mario and Luigi Membits obviously aren't members of MFGG, but they're in there for reasons that will become apparent eventually.

I tried to come up with a roster of characters that were involved in the previous incarnations of Super MFGG Bros., an also are well known around MFGG in general. it's mostly final, but assuming the animation tool TheShyGuy's working on becomes public, it will 100% be possible for people to make their own characters, and the team could make DLC characters if the demand is high enough.

Jaden1291 the Toad Wrote:(if you include me, use my sprite sheet from the dA MFGG Gallery and add a few new poses...)

all officially made characters are gonna follow the same style, which is most likely going to retain the Bews-esque style that you see now. HOWEVER, I made the style a bit differently for this, and I made the animations a bit simpler with the intent that people could make their own characters/themselves if they so choose.

Kosheh Wrote:This idea won't be fun when That Guy makes a character with a kick that fills the whole screen and OHKOs you ):

The idea hasn't been fully though out yet. In my mind, I figured it be more of a peer to peer/ friend to friend type of deal. If your friend decides to piss you off by making a cheap character then beat his ass in real life...or y'kno -rage quit. If it does become a big issue, then I'll try to look into ways to put limitations in.

You could always have set maximums for individual things and have a maximum overall that each different type of thing consumes weighted amounts from the budget. This would be very complex and difficult to balance effectively, though. It's up to you!

@Phaze and Kosheh:
The game is really only going to be released here and on mfgg. If someone makes a cheap character, then don't play with them. I think that's a easier solution than putting in fake limits. It just doesn't feel right and would probably be more trouble to tweak than it's worth.

Devlog #1

I spent the day moving the character Mit's subaction data over to lua. Everything works fine which is awesome. Moving the movesets out to lua allows so much more ease especially since lua has coroutines. Which basically means I can run a function over time instead of doing it all in one go. It's easier to do in lua than c#. In c#, I just used a behavior tree which basically does something similar. It's also bit uglier when trying to use general variables between 'events'/functions within even the same subaction which wasn't even possible the way I had it set up at first. A few months ago, I even went as far making a cache and wrappers of primitive types for custom variable use. It worked...but it was so ugly..... Anyways, lua allows people to create and use custom variables to do whatever they want and share them between other subactions and throughout the subaction itself without any weird code or ugliness (run on?? heh). I still gotta move all the events out to lua to which is easy, but annoying.

Lua shouldn't be too hard to learn. Really, if you don't plan on doing anything fancy, all you'd have to know in order to make a custom moveset is the list of events that I coded.

---------------------------------------------------

I also made a very simple string file format a few days ago since I needed a quick and easy format to export data from blender to (has nothing to do with this) It's very easy to read in and write out. For those who need a simple save file format, here it is:

Code:

Description
* each block begins with "{", "}" (on a lone line)
* a block's properties follow (without quotes, separate line) : "PropName=PropVal"
* note* the properties just have to be in the same '{','}' block,
* they don't have to be in any order
*
* block interpretation:
*
* each block has atleast "BlockTag" property to easily ID it
* nested blocks are children of the parent block

//keep reading until I hit the closing bracket
while (!line.Equals("}"))
{
//If I hit an opening bracket, then the following lines
//are of a new nested child block
if (line.Equals("{"))
result.ChildBlocks.Add(ReadBlock(reader));
else if(!string.IsNullOrWhiteSpace(line))
{
//or else the following line is a property.
string[] split = line.Split('=');
string key = split[0];
string val = split[1];

And there we go. The format is simple to write to and read from especially since it's recursive. The block intermediate format allows you to easily parse the properties into your game object properties. People can use this if they want, no credit needed but it would be appreciated if you notify me that you used it.

I finished moving all events over to lua. I also moved mit's actions and subactions over too. He's no longer hardcoded into the game and is now easily editable. There wasn't much that happened in the last few days other than that.

However, today, I realized that one somewhat important moveset feature doesn't actually work.... I'll explain how actions and subactions work really quick. Actions decide and set the current subaction. Actions get called every game step. They do not call or execute subactions. Subactions are coupled with an animation and gets executed once per animation frame. When an action changes the subaction, the new subaction will get executed from start to finish over the animation's time. Subactions can also change the current subaction to whatever they want which will also be executed from start to finish. This is how i did the punch combo. But... what if I have a subaction that needs to be "passFramed". PassFraming basically means to skip to an arbitrary frame in the next subaction. Visually, the animation and it's timeline is skipped correctly. But the code/script/subaction won't. I just realized now that the feature doesn't work =( ... I have ideas about how to go about doing it right, but I've found issues with all of them... I don't know how to "pass frame" correctly. Now, this isn't that big of a deal if I never have to passframe of course... But in this case, I do.

*they all play at the same framerate. All animations have the same frame lengths. Ignore the fact that they're not synced.

Mit is shooting while walking. Each gif is a separate subaction.

....*deleted paragraph of explanation of issue*...

I don't even know how to explain the issue with lua code without things getting too confusing. I'm just having trouble explaining this. Basically, this group of subactions all have to be pass framed to. As you can see, each subaction shoots a projectile at a specific frame. It is important then to use pass frame in order to skip to the correct location within the subaction script so that any event before hand doesn't get called. If i pass frame past the shooting frame, then I shouldn't shoot at all. The issue is that every event prior to the wanted pass frame will execute.... Meaning that if I played the 4 subactions above, passframing from one to the other, then it would shoot 4 times instead of once...............

...*another deleted paragraph of brainstormed solutions*....

I don't know how to fix this issue. I can go around it by covering blocks of events within conditions like

... but that's seriously ugly. I can do that, but I wouldn't expect anyone else to do it....

Again, this isn't a feature that's required to make a moveset. Although, it would be nice to have the feature supported in a nice way. I'll stop whining now, thanks for reading. If anyone has any ideas, please share.

*Note: that there is an idle animation of the same shooting. So I couldn't go from the idle shot to walking shot without passframe. I also couldn't do the reverse of walking while shooting then going idle.

-----------------------------------------------------

Edit:

I've been thinking of creating a queue-like system for subactions. Events are added to the queue and then processed as they're added to the queue. The queue will have a "Queue Frame". The only way to change the queue frame is by Asynchronous and Synchronous timers. As events are processed, they are timestamped with the queue frame. Their timestamp/framestamp will be compared with the passframe value. If it fails, then the event isn't executed. If it succeeds, then the event is executed. This means no more lua for subactions. Actions don't execute with an animation, so they're fine. People can still make their own custom movesets, but the programming might become inconsistent for you guys. I'd have to make a small tool similar to PSA. This might be overkill, especially for a single feature. In the long run, I feel this is necessary. If I ever move to a 3D brawler like smash bros, then pass framing might become really important for unique moves or transitions. In smash bros brawl, if you do land on the ground while doing an air attack, then the subaction passframes to another subaction. This is so there isn't an abrupt change from the aerial attack to standing idle when you land. If I try to do the above in 3D, then I'd probably try to split animations and subactions based on body part. The legs would run the walk subaction and animation while the upper body runs the shooting subaction and animation. That would be overkill in a 2D game - and in a 3D smashbros-like game where fighting happens on a 2d plane.... This is all just brainstorming and I like this idea so far. What do you guys think?

*strike-outs* hmmm. Atm, events are "direct". When they're called, they directly affect the game and or character. If I decide to wrap every event into a "Queue item", then it might work fine as is - no need for a tool. Events will be wrapped at a lower level, so you guys won't have to worry about it. Loops and conditions would all work the same in lua. However, the way variables are used might have to change or be explicitly wrapped into a queue item somehow. If anyone makes new events, they'd have to manually wrap them. This feels like an improved idea since there's no need to make a custom tool and you can still use lua which keeps coding actions and subactions constistent. Thoughts?

I found a nice solution to the above. I kinda went with the queue...but at the same time the "if( (passFrame && frame == #) || !passframe)"...? Basically, I just made an EventQueue which events "respect" (?). The queue basically gives them permission about whether they're allowed to execute, are suspended and thus should skip a frame, or should be ignored and not do what they wanted to do. I made a small wrapper function in lua which referenced the queue and passframing works as it should now =p. I only wrapped functions that made a change to the game or character. I didn't wrap conditional events or events that returned information. Lua can be used like lua so there was very little loss and headache over supporting passframing which surprised me a bit (and at the same time didn't?)

If you have a subaction that you would like to pass frame to, then there is a little bit you have to do to ensure it passframe right. However, it's no big deal and very minor. In the end, I'm happy with the solution.

It took me a few days to go through all my code and clean it up. Someone wanted to help out on the coding side. I hope the code is easier for him to get into now. -I have not heard of him since.....Sorry lol.

My animation tool has been giving me headaches with bugs too. Lots of bugfixes there, I won't go into detail.

I also had to work on a new collision system to replace the Farseer Physics Engine. Farseer is great and all, but it's very much overkill. I find it a bit difficult to do nonrealistic physics.....with the realistic physics engine hehe.

For those interested, the collision test is the Separating Axis Theorem (SAT). I also use a broadphase called Persistent Sweep and Prune (SAP). It was pretty fun and rewarding to learn. I went from only being able to do about 200 polygons brute force (every polygon against every other polygon so about 40,000 test per frame) to about 1500 polygons with persistent SAP until the framerate starts to die.

Also note that the above collision resolution isn't some seriously complicated physics thinger majiggly thing...ger... All it's doing is pushing the shapes out of intersection by changing the velocity instead of position. In the game, I'll probably just change the position directly instead since all that "extra" stuff is unnecessary.

The green circles are the defensive collision circles. The red circles are the offensive collision circles. The fighting system collisions are separate from the level collisions so def/off collisions don't interact at all with the level collisions. The two are separate collision system instances.

I had this debug level done when I still had Farseer, but it ran pretty slow when I started to destroy blocks. It's nice to know that my own collision system is a step up in this case.

I'm still fixing bugs and whatever from the integration. One big thing that I'm having trouble with is rotating based on the ground slope =/. Hopefully I can fix it soon[Fixed]

The particle system now supports a BaseAlpha (starting Alpha), scale and offset "simulation?". Just like how position is affected by velocity which is affected by acceleration, scale and offset (and rotation) also have their own velocity and acceleration. In the gif below, you should now be able to see the brick pieces shrink as they fade. The smoke puff now offsets as it rotates which creates a subtle swirl effect.

for i=0,2 do
if(events.onGround(context)) then
//this is the "smoke" gfx at the feet
events.addParticleRelative_1(context,12,pVector2(0,5,0,0,0,0),pFloat(0),pVector2(.5,.5,-.5/1,-.5/1,0,0),pVector2.Zero,.5,true,false,-1)
//these are the particles that create the "V"
events.addParticleRelative_1(context,4,pVector2(0,10,-30,-30,0,0),pFloat(0,0,0),pVector2(0,0,1/.5,1/.5,0,0),pVector2.Zero,.5,true,true,1,20)
events.addParticleRelative_1(context,4,pVector2(0,10,30,-30,0,0),pFloat(0,0,0),pVector2(0,0,1/.5,1/.5,0,0),pVector2.Zero,.5,true,true,1,20)
end
events.synchronous(context,5)
end
end,
sfx = function()
local context = _coArgs.values[0]
coroutine.yield()

events.playSound(context,27,.1)

if(events.onGround(context)) then
events.playSound(context,20,.01)
end
end
}

I also spent a good day or two doing some memory optimizing. Not much to say here. I just used a good ol profiler and looked for memory leaks and garbage and got rid of most of em. Animation datas are preloaded once, cached, and then deep copied (animations are shallow copied) when asked for. That means that I'll no longer load the same 900+ block animation datas for that block debug level somewhere above but instead just create copies for it which means faster loading and less garbage....