Level: Extra Extrapolation


Hi, I just finished creating a level about movement prediction. Could someone try it out?

Could you complete it? Was it hard? etc.


I could complete it, no problem! The obvious solution (to me) works, here’s what I did:

var shell_air_time = 3.4; // in seconds
var ogre = this.getNearestCombatant();
var x = 0;
var y = 0;
if(ogre) {
x = ogre.pos.x + ogre.velocity.x * shell_air_time;
y = ogre.pos.y + ogre.velocity.y * shell_air_time;
this.attackXY(x, y);

I like it, it’s a solid level and it works. If anyone solved it some other way, be sure to put it here. The more varied solutions it can handle, the better.

Some ideas to improve:

  • Add a specific article to the guide. Some story description (“the ogre is literally running circles around our artillery! Cheeky ogre…”), and a hint as to how to do it, and anything else specific to the level you want to say to learners. You can add documentation on the settings tab of the level editor.
  • Have Anya come in and narrate and add a goal with the scripts so that you have an objective specified on the upper left (probably not necessary in this level, I certainly understood the goal but good to learn how to do).
  • Some minor spelling and grammar errors in the default code comments. “Oh no”, “ogre’s movement”, “where he is”.

Advanced ideas for improvement

  • Maybe have the ogre taunting the artillery in the level. Something along the lines of ‘Nyeh nyeh nyeh you can’t hit meeeee’ unless his health is less than maximum in which case he might say ‘Ow! Lucky shot…’
  • Try adding a ‘cool cam’ at the end, that is when the goal is finished, have it play through from the beginning to the end with the artillery and ogre having a spirited dialogue. See other levels and how their victory scripts are constructed to see how we do it, in particular Emphasis On Aim with its ‘success’ script, which gets triggered when all goals are successful.
  • Add a ‘general article’ to the guide, that is something on a topic this level teaches that could be used in other levels teaching the same topic. I’m working on one teaching if/else for another level, to give you an idea what I’m thinking.

Hope that helps!

Oh and, if you have any ideas for improvement for the editor that you thought of while making this, please tell us as well!

Edit: hid my solution.


I enjoyed this level. It always gives a good feeling when we successfuly predict something :wink:.
It can be hard for people with lack of physics knowledge, though.

The design is not professional, but it can soon become :stuck_out_tongue:.


var shell_air_time = 3.4; // in seconds

var ogre = this.getNearestCombatant();
if(ogre) {
    predictedX = ogre.pos.x + ogre.velocity.x*shell_air_time;
    predictedY = ogre.pos.y + ogre.velocity.y*shell_air_time;
    this.attackXY(predictedX, predictedY);

To the staff and Discourse team: isn’t it possible to add a “spoiler” (hide) option? It could be useful, just a suggestion. :wink:


Ah, I like this! Nice tree in the lower left. This munchkin is surprisingly resilient–perhaps a larger ogre (with increased movement speed in the Patrols Component) instead? Amazed that you were able to make such a good level using the level editor in its current state! Would love to hear any feedback on the editor itself that you have. Anything you were trying to do but couldn’t figure out how?

If you have trouble figuring out how to add scripts to do the stuff Scott suggested above, we could help you through it, maybe in a Google Hangout or in HipChat. The script editor is pretty opaque right now.

I’d also make the default code use shellAirTime instead of shell_air_time to follow our convention of lower camel case instead of snake case for JavaScript. And probably getNearestEnemy makes more sense than getNearestCombatant in this one.

Let me try the spoiler with my solution:

var shellAirTime = 3.4; // in seconds
var ogre = this.getNearestCombatant();
if(ogre) {
target = ogre.velocity.copy().multiply(shellAirTime).add(ogre.pos);
this.attackXY(target.x, target.y);

Yeah, so you surround spoilers in [spoiler ] [ /spoiler] tags (without those spaces), but it currently doesn’t work with code formatting. I see Discourse is soon introducing a much cooler spoiler plugin, so maybe that one will handle code.


Well in this engine you can do a lot <3! I’m just poking around. Treema has a few issues but i added them on the github issue page. The editor could use a delete button.


I like the level a lot, simple to the point. I am also fairly new to coding so it felt good to get this one right. Also this is more for Nick and the team, levels should show you other ways you could have coded it once you have beaten it. Maybe collect the code of others who have beaten it and have a sort of rating system so people could get new ideas? just a thought.

Heres mine:

var shellAirTime = 3.4; // in seconds

var ogre = this.getNearestEnemy();
if(ogre) {
this.attackXY(ogre.pos.x + shellAirTime * ogre.velocity.x, ogre.pos.y + shellAirTime * ogre.velocity.y);


It’s an amazing level and whether liking it or not, people that solved this had their physics skills improved a little, which for me is the best of all. I’d encourage A LOT if people could build a mathematics section of levels, where the focus wouldn’t be JavaScript learning, but mathematics logic applied. This way, we could use such section to explain how Bhaskara, Pythagoras and other mathematicians concepts are applied to the real world.


Wonderful engine you created here.

Forked this level to create a quick pattern recognition type level. Shortening the ogre’s path was kinda enough, but allows targeting through coordinates. As component scripts are read-only then I can’t add random coordinates that are generated when the spell is cast/script is compiled and ran.

Even so I can’t actually do any pattern recognition since the event chooseAction triggers only when the artillery is ready to fire again. I don’t have per frame event nor an event that would trigger when the ogre changes velocity.

Also no idea why the arty got bugged visuals, that is the cannon itself has an offset.


Thanks @pendrokar! Since we’re nearing the end of our great raster -> vector migration, I’m somewhat surprised that you were able to get the level editor to work at the moment! I’ll upload a gigantic set of fixes in the next day or two that should fix, among other things, the artillery offset problem.

Would you like to be able to add new Components or improve the current ones? I could get your account enabled for editing them. (We don’t have super-fine-grained permissions on them yet, so we’d just trust you to not break any of the existing Components.)

This new level is pretty cool–the idea is to track the ogre’s path and then fire at him after the second time he goes through it and you know where he’ll be? What would the desired code look like, in an ideal world where you had all the programming tools you needed for the level? I may be able to figure something out.


Either an event that is dispatched per frame or an event that dispatches when Ogre changes velocity. Then I can add them to an array until the position and velocity repeats, allowing me to confirm a pattern and then calculate along that path.


The levels have to run deterministically based solely on the player’s code, but that doesn’t mean that we can’t use randomness. Just thought of this: what if there was a Component that allowed the Ogre to use random numbers based on the input source code? So if you made any change to the code, the ogre would move to completely different places. With enough variation in ogre pathing (and shots required), it would take a ton of random tweaking before the ogre happened to move to the target positions you had in the code.

Another alternative is to have a more explicit way of setting random seeds, so that you as a player could make sure your code works on one seed, then switch the seed a few times to make sure the code can handle other possibilities. The code would have to work on several different seeds to be counted as victorious.

Something like this is needed for a lot of levels, actually. The other obvious way to prevent hard-coding of values is to limit the number of statements used, but then that requires the level require more statements’ worth of values than the code needed to generate them, which can make the levels much larger than they’d otherwise need to be.

I’m kind of digging the random-seed-based-on-player-code idea, actually.

chooseAction() is dispatched per frame, but only when the artillery is ready to act. So you could just setAction("idle") when you don’t want to shoot. It’s also possible to add event handlers for things like enemy target changes; would just need new Components that work kind of like Says and Hears but limited to the visualRange of Sees.


For some reason, when the game loads I win immediately. When the ogre gets to (35,12), it runs into the tree and just stops, and the artillery kills it.


Oops, you’re right! Try refreshing the page and playing again–I’ve removed the offending trees.


I am a beginner at coding and this level really has me stumped.

This is my code, but whenever I cast it it says it is “out of range.” Can someone please help me figure out the error in my code?

var shellAirTime = 3.4; // in seconds

var ogre = this.getNearestEnemy();
if(ogre) {
this.attackXY(ogre.pos.x + ogre.pos.xshellAirTime, ogre.pos.y + ogre.pos.yshellAirTime);


I think you almost have it, but you’re adding the ogre’s pos times the time to the pos, where it should be his velocity. Make sense?


Oh I see, because Distance = Rate * Time. Thanks for your help!


my solution is:

var shellAirTime = 3.4; // in seconds

var ogre = this.getNearestEnemy();
if (ogre!==null)

if(ogre) {
    this.attackXY(ogre.pos.x, ogre.pos.y);
    this.say("it's dead");



Here’s another solution, tried to minimize the memory required, and the code altogether.

var t = 3.4; // in seconds
var o = this.getNearestEnemy();
if(o) { this.attackXY(o.pos.x+o.velocity.xt, o.pos.y+o.velocity.yt); }


I had a strange problem with this level (maybe a bug?)
The Ogre is actually killed after 3 shoots (?), but but the level still runs.

Here is my code. looks very close to the codes posted here…

var shellAirTime = 3.4; // in seconds
var ogre = this.getNearestEnemy();

if (ogre) {
    var predictionX = ogre.pos.x + ogre.velocity.x * shellAirTime;
    var predictionY = ogre.pos.y + ogre.velocity.y * shellAirTime;
    this.attackXY(predictionX, predictionY);


Me too.
And I copy the code above, and find it also has this problem.