SUPER Cute Alien - 1-4 players platformer about friendship, love and what it means to be human.
-
Thanks to @Gama11 and @starry-abyss the HTML5 is now working!
The performance is great :blue_heart: , although tons of effects are disabled. But is okay, since is for web, would be some sort of fancy preview of the full version.
Also been creating a neat boss battle, that would add some interesting gameplay, since it breaks tiles and the player would need to avoid the gaps :)
Here's a gif of it:
HD version here: https://gfycat.com/ConfusedDependentIslandcanary
More news soon!
-
Nothing much, polishing here and there, here's how the PAUSE section is looking:
But there's another cool thing that I did, which is some sort of online news feed. Basically it fetchs the content from a file of my desire. Pretty cool, since it will allow us to inject live content, to let players know about upcoming stuff.
Here's how it looks:
Code is suuuuper simple, if anyone is interested... just whistle.
More news later!
-
I'm pretty interested by the code :p
Do you have something like a repo?
-
Hey, sorry, not public repo, I wasn't planning to make it open source, plus the source is a bit messy (performs super well, but messy indeed), not an example or learning material at all :P
Anyhow, here's the code for anyone interested on reading things from da webs:
public static var newsFeed:String; static public function getNews():Void { trace( "Utils.getNews" ); var _Loader:URLLoader = new URLLoader( ); _Loader.addEventListener( Event.COMPLETE, _onLoaded); _Loader.load(new URLRequest("https://dl.dropboxusercontent.com/u/10323577/sca_news.txt")); } static private function _onLoaded(e:Event):Void { newsFeed = Std.string(e.target.data); trace( newsFeed ); }
Then, you can use it in your FlxText, by simply doing superMessage.text = newsFeed;
As far as teh game goes, been crippling a few bugs here and there, nothing super important, but nothing to show at the moment.
I will, probably, give away 5 free versions of the game here, to get some sort of feedback. I will do this later, but if anyone is interested, just whistle!
EDIT: oh, remember to call getNews(), but wait a few seconds before using the newsFeed string (might take a few seconds to get the response back from da internets), otherwise you'd get a null string.
-
Well, after what I would consider, the worst flu I experienced in my life, we are back to bussiness :)
Been polishing more things here and there, we added bosses intros :dark_sunglasses:
Is a bit inspired on the ones from Nuclear Throne
Used the waifu2x image upscaler to increase the resolution of the original boss sprite, and it did wonders! If you haven't heard of it, take a look!
Also, happy to announce that the final level is completed:
A video about the polished guns is coming soon!
-
Well, as it seems this topic gaining some traction, I guess it wouldn't hurt to give away some tips on the HTML5 version that we are creating. Hey, is a forum for HaxeFlixel users, after all!
First of all, while some maps did run actually fine, others did not, because optimization was missing. A quick compile from the normal version (the one that had all effects) to HTML5, produced 14 unplayable maps. Yay.
Now after lots of optimizations, 19 maps, from 20 works! 60/60 fps, with occasional tiny and acceptable drops on heavy moments. For those that wonder, the map that I still can't get to work is the one that needs the Tester thingy to draw lines between objects. Those lines are way too expensive, and the optimizations I made aren't enough.
Here's the tips I found successful while optimizing the HTML5 version:
-
HTML5 really really hates things such as alpha, rotations, scaling and coloring. If you are using some of them, and you are suffering from performance issues, consider using less and less of these. Do not understimate this tip!
There was a map that had 40 fps max. For the love of me, couldn't figure out what was causing that. Ended up being the colored sprites that I had. The solution was simple: use already colored buttons. -
Use
loadRotatedGraphic()
whenever possible. I had particles and lots of effects that basically crippled the performance. Reducing the amount of these and by using baked rotations, made these effects possible. -
Mind your assets. By default, you might ending up just loading all the assets in your folders (
<assets path="assets" />
). That's is a no no, mainly because everything will be loaded. Not only because this will increase loading times, because increases memory usage as well.
Consider excluding things that you don't need and reduce the quality and size of your assets whenever you can. In my case, I useexclude
and I changed the paths on game.XML to use different sound folders (with lower quality) for the HTML5 version, while preserving high quality sounds for the Windows version. Here's a good article on how to handle this matter. -
Not everything must be done 60 times per second! Is often a handy way to throw things that needs to always run, in your
update()
function. It could be aif(alive)
check, or perhaps, anisOnScreen()
check, it doesn't matter. The question is, do you really need to? If the answer is no, then what it comes handy, first and foremost, areFlxTimers
. How so? You can create a (what I call) heart beat function, that you run aprox, once per second. In there you can check if your player is dead, or change the properties of all the members in a group, or you could update the text in your UI... anything really.
A case study: I've got lasers in my game. Those needed to always callmakeGraphic()
and check for overlaps with elements in screen, such as props. I changed the frequency of those instructions, by removing them fromupdate()
and placing them on a function that was called 10 times per second or so. The performance gain was inmediate with any side-effects.
-
super.update(elapsed) can be a life saver. The new option of update lets you specifically, change the update speed. I found it extremly useful, as I had some NPCs that had some heavy code. Reducing the update rate of these resulted in a performance gain I didn't thought it could be possible. And was by simply doing
super.update(elapsed/2)
. I combined it with a distance check, so the objects that were far from my main character, were updated less. This saved CPU cycles and the performance increased. -
Be memory friendly. Use
destroy()
for things that you won't ever ever need. In my case, I had permanent bodies. In some maps, the body count was way too high. You surely can useexists = false
, but if you have no plans to reuse them, usedestroy()
This will free some memory, and that is always good :) -
Use
recycle() - revive()
and try to create everything you are going to need, at the start of your state. Creating new objects at runtime is not always a good idea. You couldrecycle
bullets, instead of creating new ones. You couldrevive
NPCs you previously killed, instead of creating a new one. -
Common sense is your friend. Why to do a complex
collision
oroverlap
check, when you just can simple check the.y
of two objects? In my case, on the latest picture, I had some acid that did rise. Touching it of course, would kill the player. While overlap/collide was acceptable, I found out that just checking the Y position of the character and the Y of the acid, was 10x times better! This of course can't be applied on all your games, but if you are suferring from performance issues, you might find some answers by thinking outside the box! -
You are human, you will miss out things, this is why you need profilers. Chrome bundles up a great profiler you can quickly use, by opening the console (F12) and going to the Profiles tab:
You can use the
Take Heap Snapshot
option. This will show memory distribution in your game. You can sort the values, to see which functions are the most memory consuming ones. In my case, I've got 311 particle objects that I'm not even using. I will need to decrease a bit themaxSize
of my FlxEmitters :stuck_out_tongue_closed_eyes: - Also, I've memory allocated for things that I didn't add, but were created anyways (such as the character's cape).Well, that's it for now. I hope someone else will find this tips useful! If something else pops up in my mind, I will be sure to edit this post. Laters! :heart_decoration:
EDIT: added the profiler tip.
-
-
Very interesting Dev Log! The game looks interesting.
Is there a chance to test a Demo?
-
@Agustín-Pérez-Fernández hey, thanks mate! The HTML5 will be free, so, yes, I will sign you up for the next batch, latest version, as soon as it is done :)
And, speaking of which, been polishing the UI. Idea is to have a quite clean interface, with the less amount of objects as possible. Most of the UI elements come and go exactly when you need them. Is a much more time consuming process, but more inmersive.
Here's how it looks so far, also here's the logo, which is WIP, of course:
Sadly, most of this UI won't be available for the Windows version. This is like... a simple UI, mobile/web oriented, with gigantic, and readable content (ugh! :sick:). The Windows version will have a different menu, with different options, and considerably smaller UI. For PC people, ya know :upside_down:
-
Wonder what this might be...
-
Development of SCA resumed and soon releasing on Steam Early Access! Here's some mayor points:
- Added Spine skeletal animation for masks support, and well, incredible character customization and movement. Also created some cool clases to easily customize colors and attachments. This is something probably I will write in more detail later, since, well, this is a HaxeFlixel forum!
- Added local multiplayer, plus a few coop and versus maps.
- Added joystick support. Works beautifully.
- Support for HTML5 and Flash dropped, we will only target Windows for now.
(lol)
Last stop is the dynamic lighting and guess we are good to go. More media super soon!
-
Beware of portals!
-
Well, I guess since we about to reach 5000 views (!!)... I sense there might be a person or two that is still tracking this dev log! So, quick update!
SINGLE PLAYER MODE:
- Added GOOD/EVIL system. Basically, good actions give you rewards, and being a bad boy makes you evil. Being good or bad unlocks different content.
- Added antenna that controls enemies for advanced gameplay. You can break the antenna, fight its drones and pick loot or save the controlled enemies individually and get coins or walk past by and ignore everything or kill everything in sight!
- New enemies!
- Added shader based meta balls ( this is to spawn realistic blood, like a liquid!)
VERSUS MODE:
- Added player selection
- Added zoom in, zoom out
- Tons of cool weapons (with lasers, silencers and cool stuff)
- Vendetta mode (challenge and punish other players)
- Aaaaaaaaaaaaand added ragdolls! CHECK IT OUT (heads are placeholders!) -> https://my.mixtape.moe/jlbanz.webm
Here's how it looks so far (there's someone cloacked there!):
And all of this stuff supports joystick. And 4 players. In coop as well.
There's more stuff, but I can't remember everything. So, here's the changelog from repo.
That's it for now! Thanks, bye
-
Survival mode in coop :)
I also found the way to, finally, replace custom FlxSpine sprites, programatically. This would be incredible useful to support things like.. custom user heads!
They, of course, support ragdoll. The implementation reads directly from the FlxSpine body parts and creates bodies and sprites accordingly. Also, I extended the system to support a few unnecessary things (but cool) such as dismemberment, freezing of bodies (for the ice gun) and a burning mode, which uses a procedural 'running on fire' animation driven by physics. It really looks organic and brutal, which was the intention :)
This involves hacking
FlxSpine::GetSprite
function:if (regionAttachment.name.indexOf("alien/masks/custom") >=0) { trace("mask detected, replacing"); var wrapper2:FlxSprite = new FlxSprite("assets/custom heads/custom1.png"); if (regionAttachment.name.indexOf("alien/masks/custom1") >=0) wrapper2.loadGraphic("assets/custom heads/custom1.png"); if (regionAttachment.name.indexOf("alien/masks/custom2") >=0) wrapper2.loadGraphic("assets/custom heads/custom2.png"); if (regionAttachment.name.indexOf("alien/masks/custom3") >=0) wrapper2.loadGraphic("assets/custom heads/custom3.png"); if (regionAttachment.name.indexOf("alien/masks/custom4") >=0) wrapper2.loadGraphic("assets/custom heads/custom4.png"); imageFrame = FlxImageFrame.fromGraphic(wrapper2.graphic); }
Luckily I found out the way to do, 100%, everything I wished for the Spine implementation. If anybody has a question about it, I will super happy to help!
Here's the inventory that won't make the cut for the upcoming public version, but will be finished at some point:
In the last couple of months an insane amount of changes were done. Most of them, probably, boring, so a video is coming up soon!
EDIT: added speech bubbles!
Did a fancy, super easy class to manage a simple speech bubble. You feed a large string containing '\n" for line breaks, then displays each line in sequence (which you can speed up and skip). Anyone interested, just whistle!
-
Took me longer than expected! But put together a quick reveal video with a few features in. Hope you guys like!
When the real trailers comes out, I was wondering if would be cool to support HaxeFlixel and put a logo at the start of video. Is the least that I can do. Can I do that?
-
Aaaaaaaand finished some sort of demo. Anyone interested, just whistle and I'll be sending a copy!
EDIT:
I've been asked on now to make these fancy buttons. Most of it comes from the great 9 slice tutorial from here: http://coinflipstudios.com/devblog/?p=243 But I extended it a bit to support fancy labels. And that's the trick. Here's the steps I took.
Somewhere in your class:
var btn_versus:FlxUITypedButton<FlxSprite>;
In your
create()
;var _slice:Array<Int> = [10, 10, 40, 40]; var _sliceArray:Array<Array<Int>> = [_slice, _slice, _slice]; // all 3 buttons have same slicing var _graphic_sheet:String = "assets/img/ui/9slice/sheet_button.png"; buttonsWidth = 170; var buttonsHeight:Int = 50; var labelHeight:Int = 35; btn_versus = new FlxUITypedButton(0, 0,YOUR_FANCY_FUNCTION_HERE); btn_versus.loadGraphicSlice9([_graphic_sheet], buttonsWidth, buttonsHeight, _sliceArray, FlxUI9SliceSprite.TILE_NONE, -1, false, 49, 49); btn_versus.label = createLabel(); cast(btn_versus.label,FlxBitmapText).text = "Versus";
Here's the sprite I created:
Now, on the label. I used a custom bitmap font, with effects already on the letters. You need this kick ass site to generate your font: http://kvazars.com/littera/ -- nothing complicated, just pick Preset: Basic and export as it comes by default (XML .fnt)
Grab the exported files and put them in your assets folder.
If you noticed, I used
createLabel()
, here's the function (feel free to tweak it as you wish ie scale):private function createLabel():FlxBitmapText { var textBytes = Assets.getText("assets/font/font.fnt"); var XMLData = Xml.parse(textBytes); var fontAngelCode:FlxBitmapFont = FlxBitmapFont.fromAngelCode("assets/font/font.png", XMLData); var fancy_text:FlxBitmapText = new FlxBitmapText(fontAngelCode); fancy_text.text = "change_me"; fancy_text.blend = BlendMode.MULTIPLY; fancy_text.alignment = FlxTextAlign.CENTER; fancy_text.multiLine = true; fancy_text.wordWrap = false; fancy_text.scale.set(0.5, 0.5); fancy_text.antialiasing = true; fancy_text.autoSize = true; return fancy_text; }
Now, the labels won't be centered. That's a bit tricky since is now a label of a button, and the latest will control its position. We need to offset it automagically, like this:
btn_versus.label.offset.x -= (buttonsWidth - cast(btn_versus.label, FlxBitmapText).width) / 2; btn_versus.label.offset.y -= (buttonsHeight - cast(btn_versus.label, FlxBitmapText).height ) / 2;
Well, off I go. Hope that comes useful for someone else!
-
This post is deleted!
-
@Claudio-Ficara hello I've been following your development of this game for months I've learned so many great tricks and tips from optimization to the cool Dropbox text loader to now really nice flx Bitmap text. I'd love a copy of the game if that's still available. Also the Continued updates of this dev log is really helpful to so many devs as well as myself and I really appreciate it.
-
@PXshadow Hey mate, thanks for following the project and I'm super glad I helped someone with these tips and such.
I do recognize that I should be writting more about some concepts, ideas and implementations, specially because the HaxeFlixel/OpenFL/Spine/Tiled combo is quite powerful, and there are some libraries, (ie Spine) that could use some explaining.As a related Dropbox text loader / copy of the game, I implemented this other thing yesterday, looks like this:
Basically, is a very simple activator online, that will fetch from a server what copy should and shouldn't be playable. Also, there are two methods of activating it, as a developer or beta tester.
I do understand that is not a perfect solution and could be easily cracked, but it would stop most of the people without that knowledge.
While the final version of the game won't have DRM (perhaps a default common one handled by the distribution platform) this whole thing is important for a few reasons: 1- Kill switch for versions that got leaked. 2- Kill switch for versions that are waaay too old. 3- Developer mode can be easily set for any person I wish.
But in short: yeah, I'm gonna wrap this up and prepare a copy!
-
This post is deleted!
-
Moar GFX progress!
PS: Preparing a playable copy soon. Is just that this thing took priority.