-
Notifications
You must be signed in to change notification settings - Fork 557
Ideas
Sorting: an easy way to make sure different groups of objects are always positioned correctly on z-axis. Grouping: Perform operations on the layer (think css transforms on a div). We could even have a .each() method to perform normal operations on all the entities. Properties: make it possible to define certain properties on a per layer basis. FX, set the render system to DOM/canvas
- Create a new abstraction in Crafty for creating layers and manage a three-like hierarchy.
- Create a Layer component that somehow takes care of the z-index.
The idea is to have a way to describe AI in a composable way. A behavior is something that an entity is doing until that behavior decides it is done. Two behaviors could be “follow mouse until collision” and “eat mouse”. An action list contains a list of behaviors that the entity will perform in sequence (think pipelining a set of commands in an RTS). Behaviors can be added to front or back of the list, so if the cat sees a dog it can add a behavior to the front “run and hide until the dog is gone”. Similarly if the mouse shoots the cat with a paralyzing poison you would add a “do nothing for x seconds” behavior This idea could be really powerful if combined with a Crafty editor.
The Action list could be implemented as a component that entities would require. Behaviors could be implemented as components. These components would then not be required by the entity, but consumed by the action list component. Alternatively a separate notion of a Behavior could be introduced in Crafty say, Crafty.b().
See http://sonargame.com/2011/06/05/action-lists/ I think we can create a system that is more closely integrated with the component entity system of Crafty and more intuitive to use.
Usually the choice between canvas and DOM comes down to performance. If someday we gain a webgl rendering implementation this will be even more true. This component will pick render system depending on the current platform based on some predefined algorithm, say DOM on iOS, canvas on IE10 etc. It should be possible to override this algorithm per entity and for the entire game.
It would be beneficial to be able to describe all parts of a Crafty game in individual files and have a way to bring it all back together. If we decide on a standard way to describe things like components, entities, scenes in individual files it would make it much easier to create an editor with powerful features that exploit the structure of the game.
The system described in http://sonargame.com/2011/06/28/component-based-game-objects-in-javascript/ might be of inspiration. Also mpetrovic is working on something similar https://github.com/mpetrovic/js_game/blob/master/components/data_store.js
- Implement Entity Hirarchy
- Decide on Standard for XML format(Smaller than JSON for our purpose!)
- For example:
<entity id="character"components="Color" x="1" y="1">
<entity id="gun" x="4" y="5" />
</entity>
_Note: Components would reside in js files, scences would be defined using a similar syntax
and it would be bound together using a <file>
tag. There would also be a <html>
tag.
Provide various ways to define paths and have an entity move along this path. This could be a part of tween. Make it possible to have the entity rotated so that it always faces forward.
Testing during development is tiresome using the dev tools available in browsers. Crafty should have to ability to inspect and change a lot of stuff at runtime.
I would want to:
- Click on entities and see and change values of all variables, the list of components.
- Pause the game and step through it frame by frame using leopard shortcuts.
- Please add to this list :-)
Crafty Inspector is the first implementation attempt. The approach is to create a html page that contains a lot of extra stuff that inspects the running game and crafty engine. Small changes are introduced in Crafty to facilitate this.
Drawing a bunch of non-changing elements to a canvas (think background art) is expensive. It would be nice to be able to specify which canvas an entity is drawn to.
- Add a method to Crafty to add multiple canvases
- Add a method to associate an entity with a specific canvas
- Add a property to the layer mechanism that forces a layer to be rendered on separate canvas
http://www.html5rocks.com/en/tutorials/doodles/lem
Currently, the attach method, while sufficent isn't very pretty. Furthermore this solution could lead to solution to the other ideas.
- Add method of storing a DOM of entites
- Implement a DOM access method.
- Explanation: A web based interface to create games in Crafty.
- Expected Results: A proof of concept that can produce simple games and organise Crafty components, entities, assets, events and scenes.
- Required Knowledge: JavaScript, HTML5, DOM interaction and organisation
- Explanation: Conduct performance tests of drawing methods, game loop, spatial data structure and other internals of Crafty.
- Expected Results: Find opportunity for optimization in the internals.
- Required Knowledge: JavaScript, Performance Testing, Algorithms & Data Structures
- Explanation: Optimize the internals for mobile performance as well as input. Mainly in mobile browsers (Opera Mobile, Android Browser).
- Expected Results: Mobile browsers can run Crafty games or at least support most features.
- Required Knowledge: JavaScript, Performance Testing, Mobile Browsers
Two types of test should be run on all commits - Performance tests and feature tests
This kind of test should consist of one simple task such as create an entity on the stage and make it move back and forth. The performance score for this test will then be the number of times this task can be executed in a single game without dropping the framerate below 60 FPS.
This is akin to the existing unit tests and the purpose is to ensure that commits don't break existing functionality.
Statistics should be saved so we can graph the development.
If a commit causes a performance test to drop significantly or a feature test to fail an email should be sent to the commiter.
We could use one of these frameworks:
- http://code.google.com/p/js-test-driver/
- https://github.com/jquery/testswarm/
- http://pivotal.github.com/jasmine/ - great bdd tests framework
As chrome is one of the most used browsers, thinking about possible optimizations would be prudent if they are applicable (some of this also applies to other browsers). In short, v8's compiler:
- assigns hidden classes to objects, it hurts if properties get added / removed dynamically
- prefers assignment of properties to
null
, instead ofdelete
ing them - doesn't like property-like accessor and mutator and similar property configurations
- doesn't like that variables, array elements and object properties change hidden types
- doesn't like polymorphic parameter or return types
- return type of
hit
:null
is still instance of hidden array class;false
is not - a function parameter should have the same type across invocations - e.g.
int
andfloat
are different types
- return type of
- doesn't like exception throwing and catching
- doesn't like some new ES6+ features
- doesn't like fiddling too much with function
arguments
, this also includes changing parameters and their types based on the currently used signature determined byarguments.length
.
draw: function (ctx, x, y, w, h) {
if (arguments.length === 4) {
h = w;
w = y;
y = x;
x = ctx;
ctx = this._drawContext;
}
...
}
- has tricky optimizations regarding
for .. in
loops; if I correctly understand, article suggests
var keys = Object.keys(obj);
var key, value;
for (var i = 0, l = keys.length; i < l; ++i) {
key = keys[i];
value = obj[key];
// do stuff ...
}
- doesn't like long scope paths:
- property paths (e.g.
myObj.myProp.myProp
) - closure paths
- property paths (e.g.
var a = 'a';
function createFunctionWithClosure() {
var b = 'b';
return function () {
var c = 'c';
a;
b;
c;
};
}
var f = createFunctionWithClosure();
f();
// when f is invoked, referencing a is slower than referencing b, which is slower than referencing c.
That doesn't mean we should follow these tips blindly, but keeping them in mind doesn't hurt:
- property-like setters and getters are just syntactically too nice to pass up
- Crafty's api design is sleek by allowing users to pass different parameter sequences to a function, which enables multiple function signatures
- Crafty uses
for .. in
for object property iteration in a lot of places, both variants could be profiled
EDIT: preliminary profiling shows marginal difference for varying amounts of properties (from 10, to 10^6) - before doing any changes to existing code base, there should be compelling reasons to do so, especially profiling (see also last link for debugging deoptimizations)
- remember these optimizations may only apply to V8 javascript engine (chrome, node), effort vs gain has to be considered
- Introducing types and other static guarantees (via TypeScript or similar) naturally works in favor of those optimizations. Additionally, Google plans to adopt the concepts of TypeScript to further optimize compiled code ([source]).
- On the other hand, there is probably much to gain by switching gradually to asm.js / WebAssembly