Giter VIP home page Giter VIP logo

aether's Introduction

CodeCombat

Build Status Coverage Status

CodeCombat is a multiplayer programming game for learning how to code. See the Archmage (coder) developer wiki for a dev setup guide, extensive documentation, and much more to get started hacking!

It's both a startup and a community project, completely open source under the MIT and Creative Commons licenses. Since it's a game (with really cool tech), it's really fun to hack on. Join us in teaching the world to code! Your contribution will go on to show millions of players how cool programming can be.

Whether you're novice or pro, the CodeCombat team is ready to help you implement your ideas. Reach out on our forum, our issue tracker, or our developer chat room on Slack, or see the docs for more on how to contribute.

MIT for the code, and CC-BY for the art and music. Please also sign the CodeCombat contributor license agreement so we can accept your pull requests. It is easy.

Note: the levels on codecombat.com are not open source.

API

We offer a partner API for SSO, user management, progress data, etc., with API docs here and SDKs here. You'll need client credentials, so get in touch with us if you have a use case for that.

For the very simplest case that can power some data integrations with your CodeCombat account, you can fetch https://codecombat.com/db/user/your-user-name-or-id to get some user progress stats. For example, Beeminder uses this API to help you commit to learning to code.

Nick Winter George Saines Scott Erickson Matt Lott Catherine Weresow Maka Gradin Rob Blanckaert Josh Callebaut Michael Schmatz Josh Lee Dan TDM Alex Cotsarelis Alex Crooks Alexandru Caciulescu Andreas Linn Andrew Witcher Axandre Oge Bang Honam Benjamin Stern Brad Dickason Carlos Maia Chloe Fan Dan Ristic Danny Whittaker David Liu David Pendray Deepak1556 Derek Wong Dominik Kundel Glen De Cauwsemaecker Ian Li Jeremy Arns Joachim Brehmer Jose Antonini Katharine Chan Ken Stanley Kevin Holland Laura Watiker Michael Heasell Michael Polyak Mischa Lewis-Norelle Nathan Gosset Oleg Ulyanicky Paul Buser Pavel Konstantynov Popey Gilbert Prabhsimran Baweja Rachel Xiang Rebecca Saines Robert Moreton Ronnie Cheng Ruben Vereecken Russ Fan Shiying Zheng Sébastien Moratinos Thanish Muhammed Tom Steinbrecher Yang Shun Tay Zach Martin

aether's People

Contributors

basicer avatar catsync avatar dariusf avatar davidliu314 avatar deepak1556 avatar devast8a avatar differentmatt avatar dkundel avatar dpen2000 avatar hcs64 avatar hypercubed avatar lucasfarias avatar nerdbeere avatar nwinter avatar phoenixeliot avatar rafmonteiro avatar schmatz avatar sderickson avatar solreynolds avatar spacewander avatar thgil avatar ultcombo avatar vickychijwani avatar walkingtospace avatar xavion3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aether's Issues

Coverage stopped working again

I don't really understand what's going on with it. It's throwing this:

Running "jasmine_node:runCoverage" (jasmine_node) task
Exception loading: /Users/winter/Desktop/aether/coverage/instrument/lib/test/aether_spec.js
{ [Error: ENOENT, no such file or directory '/Users/winter/Desktop/aether/node_modules/iota-compiler/coverage']
  errno: 34,
  code: 'ENOENT',
  path: '/Users/winter/Desktop/aether/node_modules/iota-compiler/coverage',
  syscall: 'open' }
Failed to execute "jasmine.executeSpecsInFolder": Error: ENOENT, no such file or directory '/Users/winter/Desktop/aether/node_modules/iota-compiler/coverage'
...

Does Gruntfile.coffee somehow need to exclude node module's own coverage stuff?

Aether crashes while transpiling.

Aether really doesn't like it when you have a variable on the left, use the nonexistent => operator, and then anything on the right.

A simplified test case for this is

var blah;
blah => 3

The original code which triggers a crash is

var gold = gold;
if (gold => 50)
{
var type = 'soldier';
if(this.built.length % 10 === 0)
    type = 'artillery';
else if(this.built.length % 5 === 2)
    type = 'archer';

//this.say('Unit #' + this.built.length + ' will be a ' + type);
this.build(type);}

Add more tests for CoffeeScript

@deepak1556 has implemented CoffeeScript support, but we don't have many tests to make sure it's working. Just re-implementing some of the basic tests we have for JavaScript code but in CoffeeScript would for each of the test suites would suffice to cover most of the cases.

Aetherjs.com site a month out of date

It seems that either the the website hasn't been updated since about March 20th or something has broken in the demos. This is because the missingThis bug for using functions as parameters is still there, if it isn't an out of date site that will have to be fixed.

Implement argument/return validation

Possibly using JSDoc comments somehow? It would be nice if Aether could handle making runtime errors when user code didn't conform to validation.

No AST for invalid CoffeeScript

The current CoffeeScript compiler does not provide a similar method to parse_dammit from acorn. Therefore we can currently not provide any detailed error information in projects such as CodeCombat. The folks of michaelficarra/CoffeeScriptRedux however seemed open to a contribution in that direction.

Bad error messages relating to tmp3[tmp4] when calling undefined function

You can see this in the dev test page with this code when foo is not defined:

foo.indexOf("bar");

Safari gives TypeError: 'undefined' is not a function (evaluating 'tmp3[tmp4](tmp6)')

screenshot 2014-01-06 14 05 46

Firefox gives Line 19508: TypeError: tmp3[tmp4] is not a function.

screenshot 2014-01-06 14 09 10

Chrome does it right: Error: Object ... has no method 'indexOf'

These are a common error message and it's totally impossible to debug what's going on without the original variable name, especially when line numbers still aren't working.

To fix, will need to watch where the error is being generated and perhaps do a transform to head it off.

Add access JavaScript builtins

From the forum:

This is the line of code being used:
var mycars = new Array();

This is the error message:
TypeError: undefined is not a function

Probably the Array constructor needs to be added to the createFunction context, and perhaps needs to be accounted for in the makeCheckThisKeyords transform which try to determine whether an identifier is available.

This is probably the same bug that people are seeing not being able to use parseInt, Infinity, and perhaps many other things that are part of JavaScript like NaN and other types of objects.

Calculate style

Metrics on things like what kind of indentation and bracket style the code uses, whether it uses recursion or regular expressions, etc. The old design doc had something like this:

aether.style;
// -> (after having transpiled)
{
    loc: 35,
    sloc: 28,
    statements: 29,
    score: 0.64,  // or something
    conceptsUsed: {
        recursion: true,
        objects: false,
        arrays: false,
        strings: true,
        Math: false,
        //functions: true,
        anonymousFunctions: false,
        ifStatements: true,
        elseStatements: true,
        switchStatements: false,
        forLoops: true,
        whileLoops: false,
        doWhileLoops: false,
        classes: false,
        regularExpressions: false,
        ternaryOperators: false,
        undefined: false,
        null: false,
        NaN: false
        // ... many more
    },
    identifiers: {
        variableNames: ["dx", "dy", "enemies", "nearestEnemy", "nearestDistance", "enemy"],  // names of variables used, perhaps will contain function parameters, properties of non 'this' objects
        functionNames: ["distance_squared"],  // names of functions used
        propertyNames: []  // properties of 'this' objects
    }
    // what else?
}

I'm sure something much better could be thought up.

Dev page doesn't handle infinite loops

When using Aether in CodeCombat, we run the code in the web worker and handle infinite loops with timeouts and aborting the worker. On the dev page, it's easy to accidentally create an infinite loop temporarily, from which there is no escape. We should probably hook up the same sort of mechanism whereby we run the code in the worker and send the results back.

Write dev docs

It's currently not described how to run/hack on Aether itself.

Remove unused `languageVersion` option

It might be simpler to have separate python2 and python3 languages, or javascript and javascript_harmony languages, for example, rather than this currently-unused languageVersion option.

Upgrade to JSHint 3

It might be time for this, although it's hard to tell how far along JSHint is. Having better control over the error messages and globals would be nice.

CoffeeScript Parser throws Exception

The currently used CoffeeScript compiler throws an exception when the syntax doesn't fit. This makes a switch between JavaScript and CoffeeScript impossible unless you always clear the code first (not useful esp. for CodeCombat).

Configure JSHint to really only accept the globals we give it

I tried to get JSHint to not prepopulate a ton of globals, but it didn't work. Maybe JSHint has been upgraded and has a working way to do this now. (Or maybe I was just being dumb the first time.)

We should also add quick options for different environments' globals like JSHint does.

Make Aether really aware of which methods are available

Currently it doesn't know, during the transpilation phase, when you try to call a method on this that doesn't exist. It used to guess, just based on a crappy list of common methods that shouldn't be in the Aether repo at all, but I think even that isn't working.

Instead, we should transpile with the this as context so that we can know what methods are and aren't defined (although we'll have to be careful, since the user might define more methods herself). Then we can resurrect the ... has no method X messages and the (did you mean method Y?) messages, maybe even do a little bit of typechecking, etc.

Autocomplete

See the CodeCombat Autocomplete interface issue for context. Basically, Aether should be able to provide introspection on available properties for anything so that we can use it to suggest appropriate autocompletions based on their types and values and such. I'll write more about how we might do this later.

API protection messing with strict equality checking

At least, that's what I think is happening. See this:

screenshot 2014-05-29 15 11 01

In Greed:

var items = this.getItems();
var peons = this.getByType('peon');
if(peons[0]) {
    var item = peons[0].getNearest(items);
    var index = items.indexOf(item);
    var index2 = _.indexOf(items, item);
    var index3 = items.indexOf(peons[0].getNearest(items));
}

If I hover over index2, I get 6. index and index3, though, are -1.

Think about adding step messages to flow

For each statement, you could also generate a step message of what was achieved, like jsdares does:

screenshot 2014-01-31 15 12 33

Is this worthwhile? @janpaul123, did you see any good results from having the step messages? I'm wondering if it will be redundant with the other hover debugging stuff, or also useful.

Make accessing undefined variables throw an error

In JavaScript, if I try to access an undefined variable, maybe like this:

var foo = 1;
var bar = ofo + 2;

–then it should throw an error, because there is no ofo. But instead, in this transpilation scheme, it just adds 2 to undefined and doesn't throw an error. Maybe we can either find and reverse the behavior that does that, or at least throw an error ourselves.

Use localeval for improved security

Because we aren't yet locking down the prototype chain on builtins, this kind of exploit is still possible in multiplayer:

(function(){}).__proto__.constructor("var x=new XMLHttpRequest();x.open('GET','/auth/whoami',false);x.send();var u=JSON.parse(x.responseText);u.name='Lel I Hax U';x=new XMLHttpRequest();x.open('PUT','/db/user/'+u._id,false);x.setRequestHeader('Content-Type','application/json');x.send(JSON.stringify(u));")();

/*
var x=new XMLHttpRequest();
x.open('GET', '/auth/whoami',false);
x.send();
var u = JSON.parse(x.responseText);
u.name = 'Lel I Hax U';
x=new XMLHttpRequest();
x.open('PUT', '/db/user/'+u._id,false);
x.setRequestHeader('Content-Type','application/json');
x.send(JSON.stringify(u));
*/

There is code in localeval starting around L59 that seems to handle this.

  1. Will this prevent that attack?
  2. Should we use localeval directly or just adapt its code?

Builtin prototypes need more protecting

I'm working to get these new tests to pass:

  it 'should protect builtin prototypes', ->
    codeOne = '''
      Array.prototype.diff = function(a) {
        return this.filter(function(i) { return a.indexOf(i) < 0; });
      };
      var sweet = ["frogs", "toads"];
      var salty = ["toads"];
      return sweet.diff(salty);
    '''
    codeTwo = '''
      var a = ["just", "three", "properties"];
      var x = 0;
      for (var key in a)
        ++x;
      return x;
    '''
    aether = new Aether()
    aether.transpile codeOne
    fn = aether.createFunction()
    ret = fn()
    expect(ret.length).toEqual(1)

    aether = new Aether()
    aether.transpile codeTwo
    fn = aether.createFunction()
    ret = fn()
    expect(ret).toEqual 3  # <-- fails
    expect(Array.prototype.diff).toBeUndefined()  # <-- fails
    delete Array.prototype.diff  # Needed, or test never returns.

It's pretty hard for me to understand what needs to change with the protectBuiltins stuff, though. @devast8a any pointers?

Rewrite user method calls so we can yield within them

Currently, we only support yieldsConditionally and yieldsAutomatically within the top-level function the user is coding, not in any nested functions, because we don't rewrite their calls to those functions to handle the generatorification. Relevant code is here. Instead, we should figure out how to rewrite all user method calls so that we can support the yields inside those functions.

var fooGenerator = foo();
while (true) {
  var result = fooGenerator.next();
  if (result.done) break;
}

This is pretty important for doing more complex plan-based levels in CodeCombat and for the Lua parser that @basicer is working on, which creates a lot of inner functions to make scoping work properly.

Don't use API protection on user-defined inner functions

See this thread. Basically, things going in and out of function boundaries have API protection applied during the transpiler, which means you can't write their properties. We probably don't need it for this case, since you defined your own function, so any argument you passed to it is already protected.

function test(arg)
{
    arg.id = 3;
}
var o = {id:1};
test(o);
this.say("id: " + o.id"); // always says id: 1

Get the "use strict"; back in there somehow

I tried to insert this into every function created, but it's getting JS_WALA normalized away to tmp2 = 'use strict';. Need to insert it after normalization, maybe before any VariableDeclaration node.

Get error line numbers working again

Aether should have support for knowing on which line errors happen, sometimes. It now doesn't ever work, so that part is broken. But really a better strategy is needed for transferring and preserving range information throughout the various steps of transpilation. See src/transforms.coffee's makeGatherNodeRanges for the hacky way I've been doing it so far.

Once range information is included in the generated UserCodeProblems, then in CodeCombat they'll automatically start to show line numbers in the error messages as well as showing error annotation cells next to the errored-out lines.

For RuntimeProblems, there's currently a getAnonymousErrorRange attempt that used to sometimes work in Chrome and now no longer works. Instead, runtime errors should know their ranges because of a transform that we run as part of, or in addition to, makeInstrumentStatements, whereby we log the range of the statement we're about to run so that if it errors out, we know where the error was and can attach it to the generated RuntimeProblem. That would also then automatically start showing the ranges properly in CodeCombat.

One working on this would note that makeInstrumentStatements is currently not instrumenting everything we would it to as a statement, so a few more types of AST nodes might need to be handled.

We should also clean up how ranges were being done throughout so that we always had support for both offset-based and row/column-based indexing instead of having to slowly recalculate it in many places.

Erroneous error messages when using the Vector class

Moved from codecombat/codecombat#683

If you type Vector.subtract(a, b); in a spell (confirmed in Dungeon Arena), the spell would fail with the message:

Missing this. keyword; should be this.Vector. There is no function Vector, but this has a method Vector.

While there is a function Vector and this does not actually have a method Vector. The error message prevents the spell from being cast, thus prohibiting use of the class.

Figure out actual ES5/ES6 option

Currently we accept the languageVersion option as either ES5 or ES6, but then we ignore it and parse everything with Esprima Harmony (ES6) or Acorn's loose mode (ES5). Hmm. We should either stop pretending the option is meaningful, or make it work.

Improve execution counting to more better correspond to running time

We haven't fully figured out what to do with statement counting for non-JS languages, which will probably end up generating more statements than writing JS. We might do a per-language statement multiplier, or we might rework the statement counting to weight statements more according to how long they actually take (so calling distanceSquared() would be cheaper than distance()).

Execution time would be better, but then it wouldn't be deterministic and would vary widely from system to system. We can eventually make it smarter until it more closely parallels execution time. At least, that's the hope.

Help people with `this` inside nested functions

People have problems defining their own functions and then getting this references to work inside them (since this suddenly changes). Even if this is how JS is supposed to work, it's super confusing for most players. Maybe there's something we can do to let them know when we can guess that their this isn't what they are expecting?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.