dan

modularize version of phaser

Recommended Posts

I am new to Phaser and really excited about the posibilities it opens to game developers.
There is one issue I like to talk about - modularity. Phaser is 45,000 lines of JS. the code seems to be well written and domuented but it's still a lot of code to reason with and to maintain.

I am coming from a Node.js mindset and in the Node world everything is modular. The idea is to constract your app using small NPM modules.
This modular approach is one of the reason for the popularity of the Node echosystem.
Node itself has small core and the community adds more functionality by publishing their libraries to NPM.

How cool it would be if we could have something like this;

var gameLoop = require('game-loop');
var keyboard = require('keyboard');
var entity = require('entity');
var physiqueEngine = require('engine');

etc..

Now if something new comes up, we don't need to wait for anyone to add this new hotness into our framework since there is no big framework.
we just replace whatever we want. In addition it will be easier to contribute to the different libraries since each of them is small and is doing only 1 thing (the unix philosophy).

In the 3d game development there is a good example to this approach - http://voxeljs.com/
In the DB world there is levelDB which also based on this - https://github.com/rvagg/node-levelup/wiki/Modules

There is an interesting project for 2d games that is trying this approach - http://crtrdg.com/
And here is a recent blog post by Seth, the developer of this project - http://learnjs.io/blog/2014/03/04/gameloop-load-images-sprite-2d/

I don't know what is the effort and viability for breaking up Phaser into small modules, but at least let's have a discussion about it!
 

Share this post


Link to post
Share on other sites

I'm afraid this isn't something I'll be doing in a hurry, although its open source, so anyone is welcome to take a stab at it!

 

There are several reasons why, but the biggest three for me:

 

1) There are deep dependencies between lots of what would be the core modules. Refactoring the code around that is non-trivial to say the least.

 

2) Module version hell. In terms of looking after so many different modules, cross checking a change to one doesn't break a version of another, explaining to end users why maybe their Sprite doesn't do X because they've only got module version Y installed. That's a whole other level of support I really don't fancy entering! Not to mention the increased dev time for me maintaining so many independent packages.

 

3) Node / npm packages / requireJS are inherently non-beginner friendly, and more importantly are web developer technologies. Most game devs I know don't care or want to be web developers, they just want to download a JS file and get hacking. I know this approach doesn't stop me from releasing single JS builds, but it does add to the effort I'd have to employ making them.

 

I'm well aware the size of Phaser is quite large. With all 3 bundled in physics engines it's 2.07MB raw, 559KB minified but a mercifully moderate 124KB gzipped. That's probably smaller than most title page graphics, or a few seconds of audio. Take out the external libs and it's 76KB gzipped. I know the benefit of being modular isn't just filesize, but it's a big part of it.

 

I will be looking at allowing for more controlled builds, i.e. excluding TIlemaps if you don't need them, or Keyboard/Gamepad support if you know you're building for mobile. So going sort of modular in a way via more fine-grained build scripts.

 

But I have to ruthlessly stick to my number one aim beyond all: It has to be easy to use. Every aspect of it. The second I lose sight of that, I've lost sight of who I'm building it for and it's just become a pet computer science project :)

Share this post


Link to post
Share on other sites

I use Phaser as module with require.js, so i know the module pattern is great, but it's a hard and strict approach. 

Not to mention with modular approach Rich would depend on another 3.rd party library(browserify or require.js), because there is no native support for it.(Until ES6, which will have classes and import)

Share this post


Link to post
Share on other sites

Great insights. thanks.

The problem i see with frameworks is they are short-lived. New framework is created, with cleaner codebase that is a better fit for the new shiny technology and developers will jump to the new thing.

By using small modules that works together we create an eco-system that is more flexible and adapt to changes.

 

Just my 2 cents.

Share this post


Link to post
Share on other sites

Surely your modules have to upgrade and adapt to whatever shiny new thing the devs want? Otherwise they'll drop your modules for others in the same way they'd drop a framework?

 

I believe a framework should be a living organic thing. They should (and indeed must) change over time. Now I fully admit I've been a bit rash in the sweeping changes I've made along the 1.x path, and that's something I will lock down tightly when 2.0 ships. I will fix the API in place and significant modifications to it will be carefully thought out and community approved.

 

Post 2.0 I see the next steps being plugins. So leaving the core alone as much as possible, and releasing plugins instead.

 

But I don't intend to hold on to legacy baggage either. If a feature is no longer relevant for web browsers then I'll drop it.

 

If the framework stops being updated altogether, then that surely just shows a lack of love / investment from me, and I deserve for devs to look elsewhere.

 

I agree with you though - devs are a fickle bunch, and will happily jump ship. But I don't believe its out of malice, it's not like supporting a sports team - they tend to just pick what works for them, at that moment in time, and lots are open to 'coming back again' as well. Providing you've made something worth coming back for :)

Share this post


Link to post
Share on other sites

 

Surely your modules have to upgrade and adapt

but it's not my modules. it's everyones. the community will create many small modules. they will fork my modules and create different ones.

just like in nature - the fittest survives. it require more 'plumbing' from the developers' side but that's the way to be innovative, fast and flexible.

 

When I use node.js, everytime I start a new project I uses similar modules but many of them are a bit different than my previous project, different ones or upgraded version.

The same goes with levelDB. leveDB is the DB that is used by the chrome browser. it's an embedded DB. if i want to be able to access it from another process, i'll expose it over http using another module (multilevel). If I want to have replication I'll use it with level-replicate module etc. Here is a nice diagram of levelDB echo-system.

 

That way you, Rich, don't need to work so hard on every release. the community will take a lot of the burden.

Share this post


Link to post
Share on other sites

This kind of community driven module making system requires a lot of active developers, which node.js has, because you can use it for work and it is a tool for modern web development.

Phaser(or Html5 Game Developing) community is much smaller(i think), because it's more specialized than web development.

With Phaser you can make games, but node.js has much more usage.

Share this post


Link to post
Share on other sites

valid point about the community size.

 

But let's imagine that we have a modular approach. So instead of 45k lines of JS, we will have 15 separate github repositories, each with 1k-5k lines of code.

I am sure you'll see a lot of forks and many developers will be able to contribute since the complexity is reduced and more devs will be able to wrap their heads around the code.

Right now the barrier to entry is pretty high due to the monolith design and the tight coupling between components.

Share this post


Link to post
Share on other sites

I don't really understand why you keep talking about the total number of lines in the JS file - surely that's irrelevant? No-one debugs the one single JS file! The actual source is all neatly split up into, dare I say it, modules. If you want to work on the Loader, you open up the Loader and deal with just 1400 lines of code (lots of which is comments). Want to tweak the bitmapFont parser? Open the LoaderParser and it's all there in < 80 lines of code.

 

Very few of the classes are especially big and I'd say for anyone even moderately skilled at JavaScript it's pretty easy to play around with. Which is probably why we've nearly 800 forks and I've closed close to 200 pull requests, because people do grok it.

 

I'm still sure that now we've finally stabilised the core at 2.0 that we'll see quite a few plugins start appearing, I know it's where I'll be focusing my attentions.

Share this post


Link to post
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...

  • Recently Browsing   0 members

    No registered users viewing this page.