Jump to content

Postmortem: Medieval Defense Z


Bikas
 Share

Recommended Posts

Hello everyone, 

Recently i finished my first medium-sized HTML5 game - Medieval Defense Z.

I came from flash background and developing for HTML5 presented with some new challenges. So i would like to share what worked and what didn't.

This is more like review/tutorial type of thing, so hopefully someone will find something useful.

hvpUaCd.png 

• Goals:
    • 60fps.
    • Smooth gameplay and animations.
    • Quality comparable to flash games.

• Tools:
    • Language: Haxe. Strictly typed programming language, similar to ActionScript 3.0. Compiles to all major languages, including javascript.
    • Editing: HaxeDevelop IDE. Freeware, great code completion and very fast compared to everything i tried.
    • Debugging: Chrome. Has console, debugger and profiler.
    • Rendering library: Pixi.js. Uses display list concept like flash. Works well.
    • Sound library: Howler. Good enough, the id system is a bit weird though.
    • Bitmap font exporter: http://kvazars.com/littera/. Free and web-based.
    • Sprite Sheet Packer: https://spritesheetpacker.codeplex.com/. Freeware and very simple.
    
• Graphics:
    • Scaling will look ugly if you use many small png files for textures.
    • If you want nice scaling, fast load times and fast rendering - pack everything to 2048x2048 spritesheets (include bitmap fonts too).
    • Resolution of assets: 1024x768, background can extend to 1382x768, so it covers most aspect ratios in horizontal orientation.
    • To get proper native resolution in mobile browsers i scaled up renderer and scaled down canvas by window.devicePixelRatio.

0pvs1Qx.png
    
• Sounds:
    • Library: Howler.
    • Sound formats: ogg for Chrome and Firefox, m4a for Safari and Internet Explorer (note: mp3 has licensing issues with play count).
    • ffmpeg: because of licensing issues and whatnot can't convert to m4a, unless you recompile ffmpeg with m4a, which is a pain to setup.
    • I used MediaHuman Audio Converter (freeware) to convert from wav to ogg and m4a (64 bit).
    • iOS Safari: keep in mind that before any sound could be played, user must first tap on the screen.
    
• Mouse Events:
    • Used pixi.js API to open links.
    • iOS Safari: window.open under "touchstart" event won't open links in new tabs, use "tap" event instead.
    • sprite.on("mousedown", callback) for desktop.
    • sprite.on("tap", callback) for mobile.
    
• Performance:
    • Reuse frequently used sprites.
    • Avoid creating too many objects every frame.
    • I would recommend looking up data-oriented programming to get more juice out of Javascript.
    • Record timeline with Chrome profiler to find performance bottlenecks.
    • Masks are slow. Use trim if you only need a simple cut.
    • Very large functions may cause lag spikes. My best guess is that browser is trying to optimize the function. Splitting big function into several smaller ones solved my problem.
    
• Game Debugging:
    • Simple CSS + DOM side menu.
    • Basic field view/edit.
    • Simple buttons with callbacks.
    
zLk3MGG.png
    
• How to debug html5 game on android (mobile) with desktop chrome (PC):
    1. Upload game to your website.
    2. Go to (desktop) chrome: chrome://inspect
    3. Connect Android device with USB and run your game on android chrome (your android device must be enabled for development).
    4. Open Command Prompt and enter: adb devices (must have Android Debug Bridge installed).
    5. To quit debugging enter: adb kill-server
    
• Conclusions:
    • Programming in Haxe instead of pure Javascript probably saved hours and hours of debugging.
    • Would have liked more automated solution for spritesheet and sound stuff.
    • Poor performance bites sooner or later, so be prepared to do extensive profiling.
    • Stable 60fps is very hard to achieve, even if you keep your code below 1-2ms per frame.
    • Overall i am happy with the results, however it took longer than expected to make this game.
    

Any feedback is appreciated.

Game Link: http://html5games.vooxe.com/a90bd3f1fba643828ccfb0109b41a252/index.html

Trailer:

GIRa2EG.gif

Link to comment
Share on other sites

Hi,

game looks very nice and animations are smooth, but I have a question about your conclusion with pixi.js.

Quote

Pixi.js is great, but i wouldn't recommend doing very complex scenes.

Can you explain this more?

Also I was wondering, if you put this on app store, what will you use to wrap it? (Intel XDK, ludei etc.) Do you have a preference?

Thanks.

Link to comment
Share on other sites

23 hours ago, asyncrobot said:

Hi,

game looks very nice and animations are smooth, but I have a question about your conclusion with pixi.js.

Can you explain this more?

Also I was wondering, if you put this on app store, what will you use to wrap it? (Intel XDK, ludei etc.) Do you have a preference?

Thanks.

Hi,

I am not an expert on Pixi, however i noticed that scenes with lots of nested containers and sprites causes more of internal Pixi updates (transformations and probably WebGL related stuff) which may eat few milliseconds of CPU time. As far as i am aware, adding/removing stuff is most expensive. That's why re-used arrows and zombies in this game.

As far as app store, i have not tried any of these wrappers. However i did look into Intel XDK and it seems pretty good choice. I would expect that they value performance and have good profiler and debugger.

Link to comment
Share on other sites

On 9/2/2017 at 2:06 PM, Bikas said:

• How to debug html5 game on android (mobile) with desktop chrome (PC):
    1. Upload game to your website.
    2. Go to (desktop) chrome: chrome://inspect
    3. Connect Android device with USB and run your game on android chrome (your android device must be enabled for development).
    4. Open Command Prompt and enter: adb devices (must have Android Debug Bridge installed).
    5. To quit debugging enter: adb kill-server

didnt know about this, tyvm!

when it will be released?

Link to comment
Share on other sites

With regards to the performance issues in PIXI. What you are saying is correct, however there are ways around this. You can actually run two instances of PIXI (background / foreground) and you can set the fps on the background to lower of the foreground. You can also set things like 'clearBeforeRender' to false and preserveDrawingBuffer to true. These I found were some performance gains. You can also create fresh textures out of nested containers and set the cache as bitmap as true until they need to be redrawn and their transformation matrix updated. I hope any of this is help to you :)

Link to comment
Share on other sites

13 hours ago, megmut said:

With regards to the performance issues in PIXI. What you are saying is correct, however there are ways around this. You can actually run two instances of PIXI (background / foreground) and you can set the fps on the background to lower of the foreground. You can also set things like 'clearBeforeRender' to false and preserveDrawingBuffer to true. These I found were some performance gains. You can also create fresh textures out of nested containers and set the cache as bitmap as true until they need to be redrawn and their transformation matrix updated. I hope any of this is help to you :)

Thanks for the tips!

I was not aware of "clearBeforeRender" and "preserveDrawingBuffer", i will have to try it out.

In my game, background has very few bitmaps while foreground has tons. Do you find worth splitting in that case? Wouldn't that increase GPU calls or cost in some other way?

Regarding cache as bitmap, wouldn't that spam GPU memory? Which could be a problem in older devices.

Link to comment
Share on other sites

Yes and no.. it wouldn't really increase GPU calls because everything gets called from the GPU anyway. your issue is taking up GPU memory, and on older devices it is an issue. I think it's more a game by game basis where you need to decide what your target devices are and having 60fps on 85% of modern devices, is better than having 50fps on all devices and clunky unscalable code. End of the day, in 18 months time, tech will have roughly doubled in performance and cpu / gpu power.. so unless you're ready to release your game today, then that should be factored in anyway.

I don't know if you are, but you can create a texture map cache in the boot / preload phaser of your game. For things like arrows and zombies, you can add a reference flag to the texture in the preloaded resources obejct, and store it either as a hashed map or a data dictionary. This means you won't have to do lookups in the cache which speeds things up. you just grab an instance of that texture and use it directly. When you use the from image, the baseTexture will go through all of the caches searching for the texture, before making an xhr request to a web server for it.

Link to comment
Share on other sites

Thanks for the response.

Yeah, i get your point about trade-offs regarding devices. I want to make more complicated games, so i would like to get the right approach from the start.

With arrows/zombies i already use texture instances and pre-generate sprites to avoid lag spikes in the actual game. Adding/removing was the main issue.

Link to comment
Share on other sites

  • 2 weeks later...
14 hours ago, Matt_MyAppIncome said:

Thank you for posting your experience. 

The game looks fantastic. Do you have any marketing and monetization plans?

Thanks.

Monetization plan was the usual - selling exclusive or non-exclusives to websites.

Always wanted to make a moving defense game with zombies and to try out HTML5 market - hence this game. :) 

Link to comment
Share on other sites

  • 3 weeks later...

This is a really great post, spectacular detail and cover so many great points to help others too. Used the android debugger before, it's good. I personally try to make it 'perfect' on desktop first then usually mobile is easier to figure out. Might have to take a few tips from your dev methods.

The game itself is great :D  went quite the distance with a few archers.. Get's tough toward the end. I'd like an end of level bonus type thing too.. Need more cash haha.
 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...