
Show HN: Untrusted, a JavaScript adventure game you play by modifying its source - alnis
http://alex.nisnevich.com/untrusted/
======
alnis
Hey guys, one of the developers here.

Thank you all so much for all of your feedback! I never thought this game
would become so popular.

It seems that our server is more or less overloaded right now, so AJAX
requests for new levels are sometimes failing. This appears to be the cause of
the bugs that some of you have experienced where levels load incorrectly or
are overwritten by previous levels. Sorry about that. :-/ We will work on
making the game more robust in the case of failures like this.

If you want to run the game locally, you can clone it from
[https://github.com/AlexNisnevich/untrusted](https://github.com/AlexNisnevich/untrusted)
and follow the instructions there.

~~~
ihaveqvestion
I installed the latest version of this, and of Node, on my Windows computer,
and I had to change "~/node_modules" to "./node_modules" in the final line of
Makefile (in the "runlocal" target) - the http-server module was installed in
the current directory. Otherwise it's working great; thanks!

~~~
alnis
Good catch -- I fixed the Makefile to actually go along with how http-server
is installed in the README.

------
ajanuary
The level files are 503ing, but it looks like the level counter is still
incrementing if I go out of the exit and back in again. You might want to add
some response code validation in.

    
    
        GET http://alex.nisnevich.com/untrusted/levels/10_ambush.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/11_robot.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/12_robotNav.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/13_robotMaze.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/14_crispsContest.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/15_exceptionalCrossing.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/16_lasers.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/17_pointers.jsx 503 (Service Unavailable) jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/19_documentObjectMadness.jsx net::ERR_CONNECTION_REFUSED jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/20_bossFight.jsx net::ERR_CONNECTION_REFUSED jquery.min.js:6
        GET http://alex.nisnevich.com/untrusted/levels/21_endOfTheLine.jsx net::ERR_CONNECTION_REFUSED

~~~
alnis
Sadly, our server couldn't handle the load.

I've set up a mirror at:
[http://alexnisnevich.github.io/untrusted/](http://alexnisnevich.github.io/untrusted/)

We're currently working on handling the AJAX responses more robustly. The
level counter should no longer increment on a failed request.

~~~
Natsu
Thanks for the fun game!

Could you possibly help us by putting in a ruler that marks the map
coordinates? Yes, I can read the code to find where things are (or count), but
there were a few times where it was somewhat inconvenient.

~~~
alnis
Thanks for the feedback! We've been thinking about doing that, but the
challenge is making it inconspicuous enough to not clash with our minimalist
aesthetic.

~~~
V-2
It could be more discrete, eg. an apostrophe every 10 blocks.

------
antimagic
Here's an Iron Man inspired solution for the boss battle :)

    
    
        map.placeObject(map.getWidth()/2, 5, 'block');
        //map.placeObject(map.getWidth()/2, 1, 'block');
        var player = map.getPlayer();
        map.defineObject('missile', {
            'type': 'dynamic',
            'symbol': '^',
            'color': 'blue',
            'interval': 100,
            'projectile': true,
            'behavior': function (me) {
                me.move('up');
            }
        });
        
        function jericho()
        {
        	var i;
        	for (i = 3; i < map.getWidth() - 3; i++)
            {
            	map.placeObject(i, map.getHeight() - 1, 'missile');
            }
        }
        player.setPhoneCallback(function()
        {
        	jericho();
        });

~~~
ryanjshaw
For the truly lazy, this was my approach:

    
    
        map.overrideKey('up', function() {
            if (map.countObjects('boss') > 0) {
                for (var x = 0; x < map.getWidth(); x++) {
                    map.placeObject(x, map.getHeight()-5, 'missile');
                }
            } else {
                map.overrideKey('up', null);
            }
        });

~~~
antimagic
Nice. Lacks drama though, where's the dash through the rain of bullets to
recover the missile launcher? :D

~~~
pygy_
I monkey-patched Math.random() to launch horizontal missiles at the top of the
screen and always return 1.

:-)

------
jpolitz
This worked for the whole first chapter for me (and has some obvious further
applications):

    
    
        startLevel["constructor"]("m",
        "console.log(m);" +
        "var old = m.placeObject;\n" +
        "m.placeObject = function(x,y,t) { \n" +
        "console.log(t);\n" +
        "if (t === 'exit' || t === 'computer') {\n" +
        "console.log('adding' + t);\n" +
        "return old['ca' + 'll'](m, x,y,t) }};")(map);
    

EDIT: I wonder if you could wrap the user's code in, e.g.
[https://code.google.com/p/es-
lab/wiki/SecureEcmaScript](https://code.google.com/p/es-
lab/wiki/SecureEcmaScript), and use this to gamify finding bugs in that
sandbox :-)

~~~
jacktoole1
nice!

similarly,

    
    
        var oldPlaceObject = map.placeObject;
        var newPlaceObject = function(x, y, type) {
        	if (type !== 'block') {
            	map.placeObject = oldPlaceObject;
            	map.placeObject(x, y, type);
                map.placeObject = newPlaceObject;
            }
        };
        map.placeObject = newPlaceObject;
    

was my solution to multiple levels ;).

~~~
kybernetikos
I also had to overwrite the map.verifyXitems (or whatever it was) to return
true regardless.

------
christiangenco
I love this game! Such a cool idea, and very well executed.

My biggest critique so far is that it's extremely hard for me to tell the
difference between #311 and #000 for the `.disabled` lines (I'm mildly red-
green colorblind). Changing it to #711 fixed it for me, but I can imagine it
would be impossible to even see #F11 for certain colorblind individuals.
Perhaps some other kind of indication that a line is editable, or a more
drastic #FFF/#000 distinction?

~~~
Natsu
That can be solved without changing the colors of anything, BTW :)

~~~
Natsu
I just realized that I misread you and it's too late to edit. You're talking
about lines of source code (and I do agree, I was really confused on the level
where you can only edit a tiny section of code I missed), whereas I thought
you were referring to the lasers puzzle (I just moved the exit for that).

------
lawl
This is fun. But I have one wish. Overwrite console.log() so it logs onto the
website and I don't need to open firebug :)

Edit: I think I solved lvl two to four all the same way. Not sure if that's
intended. But I also don't want to spoil it for others.

Edit 2: This worked again at lvl 6, so I'll assume that's a bug. Click this
pastebin for spoilers:
[http://pastebin.com/yfhDhE7P](http://pastebin.com/yfhDhE7P)

~~~
alnis
Good catch! We haven't been checking yet for tampering with functions, but we
probably should. Don't think of it as a bug so much as a cheatcode you
discovered :-)

~~~
gizmo686
Aww, I thought that was to easy. That trick works for basically any level.

Also, is there a good way to completly prevent tampering with functions, or is
this just going to be an arms race?

~~~
TeMPOraL
> _Also, is there a good way to completly prevent tampering with functions, or
> is this just going to be an arms race?_

Let's hope for an arms race - it will be far more fun and educating at the
same time.

~~~
skrebbel
hmm a multi player javascript API tampering arms race game would be pretty
awesome too.

------
th0br0
You should reinit the map though, otherwise doing this on level 2 causes funny
bugs (and makes the game rather easy ;)

    
    
        maze.create = function() {};
        var tmp = map.placeObject;
        map.placeObject = function(x, y, t) {
        	if(t == 'exit') tmp(x,y,t);
        };

~~~
untitaker_
level 2 can be solved by using the two "unlocked" lines to comment out the
whole maze.create call, too.

~~~
zenojevski
Related: things like these do not work, because of implementation.

    
    
        if (false) // <- inserted by me
        for (var ...) { // <- existing code
            ...code...
        }
    

Too bad, because extra `for`s could be fun...

------
alnis
Attention!

The main site is overloaded, but I've set up a mirror at:
[http://alexnisnevich.github.io/untrusted/](http://alexnisnevich.github.io/untrusted/)

All level-loading issues should be resolved on it, since they were tied to
AJAX failures. Let me know if you experience any problems on the mirror site.

~~~
someone13
Thanks for the game! Credits don't load on the mirror - I get a 404 on the
AJAX call.

~~~
alnis
Oops, it should work now.

------
columbo
That was great,

Here's making the boss kill itself

[https://gist.github.com/anonymous/2d45242a73f72847417b](https://gist.github.com/anonymous/2d45242a73f72847417b)

~~~
zenojevski
Much earlier but: defense by excessive reaction.

[https://gist.github.com/anonymous/0bd9b9d36892ffe6dbbf](https://gist.github.com/anonymous/0bd9b9d36892ffe6dbbf)

~~~
alnis
These are both beautiful.

------
tripzilch
I solved the jump/gravity level without having to edit any code, dunno if
that's supposed to be possible, but: if you press+hold the UP key, keyboard
repeat rate will be fast enough that you "fly", allowing you to cross the gap
(and even save yourself if you happen to fall in it).

I also solved the DOM level without editing anything, I just pressed some keys
and it transported me to the next level before I even had an idea what was
going on.

(im playing on Firefox / Linux, in case that makes a difference)

Oh and thanks for this game, it's EXTREMELY COOL and I had a lot of fun
playing it all the way to the credits screen (and I'm going to go back now to
see if that's _really_ the last level or not ...)

------
bcherry
You had me at "The continuing adventures of Dr. Eval"

------
chacham15
Am I the only one spending more time on figuring out how to cheat than
actually doing the level the way you are supposed to?

------
pritambaral
Level 6 can be cleared without modifying the code at all:

[http://home.iitb.ac.in/~pritambaral/level6.mp4](http://home.iitb.ac.in/~pritambaral/level6.mp4)
(16K)

[http://home.iitb.ac.in/~pritambaral/level6.webm](http://home.iitb.ac.in/~pritambaral/level6.webm)
(31K)

[http://home.iitb.ac.in/~pritambaral/level6.gif](http://home.iitb.ac.in/~pritambaral/level6.gif)
(161K)

EDIT: Seems to have been fixed. Leaving comment for archival purposes?

~~~
phsource
Seems to have been fixed; I now see
[http://i.imgur.com/dQeC01W.png](http://i.imgur.com/dQeC01W.png)

~~~
thret
Level 6 doesn't work for me at all. I can get there several ways but the exit
doesn't function.

Also, is it possible for counter drones to kill the red drone? Mine wouldn't,
all they do is block him.

------
cbhl
This must be resulting in a lot of new gists on GitHub... is it odd that I
wish I could sign in with my GitHub account so that the level saves showed up
as gists under my name?

------
zenbowman
Pretty cool game bud, I actually think this is a superior environment for
learning to program than many of the richer 3-d interfaces I've seen.

------
DocG
THANK YOU.

I have 0 knowledge about writing all kinds of code. This is perfect to start
with. Specially thanks to the API part.

------
aaronem
This is fun! But I've run into a problem. Advancement past level 14 seems to
be bugged; upon completion, the keys in my inventory were replaced with a
capital A which I assume to represent the algorithm, but then level 14
reloaded with a message at the bottom saying "You have lost the Algorithm!"
Re-completing the level works, but the same thing happens, as many times as I
like; the last time, I saw "run 17_pointers.jsx" scroll past, but still got
the map and code for level 14.

My solution to level 14 [1] involved a state variable on the me object; could
that have broken something?

[1]
[https://gist.github.com/anonymous/8e4f11c26e5e6fe3d7d6](https://gist.github.com/anonymous/8e4f11c26e5e6fe3d7d6)

~~~
alnis
This seems to be tied to a bug some other people have experienced where new
levels don't load correctly and are overwritten with existing levels.

Try going to level 15 and resetting the level (Ctrl-4). Does that help at all?

~~~
aaronem
It does! Thanks, and thanks for a fun, engrossing diversion on a rainy Monday
afternoon.

(Update: Each time I enter a level, it loads as level 13, and I have to reset
it to get the correct map and code -- just a heads-up in case it helps with
debugging. Chrome 33.something, Windows 7 x64.)

------
javajosh
Very cool! I'm stuck on level 7 because it seems that the script isn't
editable _anywhere_. Related note, the color scheme for highlighting editable
lines might want to change, because "black on dark maroone" doesn't exactly
jump out.

Love that you're auto-gisting solutions. That was clever - I presume you are
browsing through searching for the common description tag? I also like the API
popup, although I didn't see it until I got stuck on the (uneditable) level 7.
I verified this because $('.editableLines') == [] in console! Perhaps this is
a very fancy meta-game that you can only win with a pull request? :)

~~~
alnis
Thanks!

Does your level 7 not look like
[http://i.imgur.com/AFTxPWC.png](http://i.imgur.com/AFTxPWC.png) ?

~~~
grandsham
He means level 8, I think. Or at least I have the same problem with level 8
(intoTheWoods)

~~~
alnis
Oh, there's a small bit of editable text at the bottom of level 8 (line 100).
Sorry if it's not very clear - we may work on the color scheme a little.

------
fijter
Very cool game, thanks :) One minor issue in the API docs:

canvasContext.beginPath() Begins drawing a new shape.
canvasContext.beginPath(x, y) Sets the end coordinates of a line.

this second beginPath should be lineTo, took a minute to debug in level 16 :)

~~~
toxine
lineTo doesn't work anymore so level 16 is broken :'(

------
Dou8Le
Chrome seems to crash every four or five levels and it forces me to reload the
page. It's a tad annoying going back through my levels.

Perhaps consider a level select, since it's able to remember your solutions?

~~~
alnis
There is a level select! :-) It's in the Menu (Ctrl-0). We really should bring
more attention to it.

~~~
Dou8Le
Ah, yes. That's very convenient.

I don't see anywhere to edit on level 21, and level select says there's one
more...

~~~
alnis
Hmm, do you notice anything different about the menu now that you're on level
21?

~~~
Dou8Le
Credits don't load. t_t

EDIT: OK they load now, servers must have been busy.

EDIT2: Credits load on the main site but not on the mirror.

------
throwawayLSKDNF
Level 5 should have more mines.

With only 75, the level is easily solved via
[https://en.wikipedia.org/wiki/Big_sky_theory](https://en.wikipedia.org/wiki/Big_sky_theory)

~~~
segmondy
Why, it's not about the number of mines, so long as there's a path, it's very
easy to solve. The number of mines is irrelevant.

------
resist_futility
Anybody think of another way to do the robot levels without adding any state?

[https://gist.github.com/db41e069df7bae142248](https://gist.github.com/db41e069df7bae142248)

~~~
SheeEttin
[https://gist.github.com/anonymous/12b15e3de9340655ed78](https://gist.github.com/anonymous/12b15e3de9340655ed78)

Variable to control the direction the robot moves, changed with the function
phone.

------
jayferd
Content note: plays sound.

Did the quick ^W at work :|

~~~
maaaats
The tab only plays sound while active here, a nice touch I think.

------
devilshaircut
I broke level 4. Is there an obvious way that I am missing to reset at the
level you're on when the reset functionality provided under the text editor is
insufficient?

~~~
alnis
The Reset button should completely reset editor state for the level. What
happened?

~~~
devilshaircut
Btw, I should have said first that I love this game idea and myself and my
coworkers have been playing it a bit for the last 20 minutes or so.

I broke my game by reassigning the getWidth method to return an invalid value:

map.getWidth = function() { return 1; }

The approach worked with a valid value: ( map.getWidth = function() { return
6; } ) and I beat the level, but I had to replay the previous 3 levels.

Some suggestions (Again, we loved the game!) \- Provide some interface to
conveniently index all the solution Gists. \- Provide some way to quickly skip
to last level played.

Other thoughts: \- Enjoyed the look, feel, and user interaction. \- The music
was great. \- I will keep playing this game. :)

~~~
alnis
Oh, quick note - you can skip to the last level played in the Menu (Ctrl-0).
We should probably make that more obvious.

~~~
devilshaircut
Ah - I see what menu does now. I love this game and have uncovered a few
broken game states. This mainly happens when I reassign one of the API
methods. Are you interested in user-submitted issues? Let me know; I could
email them to you or log them on your GH; whatever is convenient.

~~~
alnis
User-submitted issues would be great! Logging them on GitHub would be the most
convenient.

------
muxxa
Using CTRL+Q for the phone is dangerous on a mac, as it's easily confused with
APPLE+Q which closes the browser window, losing your progress.

\---

Edit: it saves the game state in localstorage; kudos!

~~~
wging
At the top left, in 'Chrome', there's a useful 'Warn before Quitting' option.

------
jblz
Very fun. I found a bug that lets me skip levels 8-11 by using this code in
the phone callback on level 7:

    
    
      if ( ! ( player.cc && player.cc.length ) ) {
           player.cc = ['#f00', '#ff0', '#0f0'];
      }
      player.setColor(player.cc.shift());
    

It says it's loading the next level, but the code and gamefield remain stuck
on level 7 until you push it to level 12.

~~~
alnis
We're glad you like it!

No clue why that's happening, but we'll continue to investigate.

------
mandlar
I'm not sure what happened with level 4 multiplicity, but I placed a 2nd exit
inside the box. Then when I go through it says it completed the level but I'm
still on the multiplicity level. Reseting does not fix.
[https://gist.github.com/anonymous/0dafb64fad2ddd6fd451](https://gist.github.com/anonymous/0dafb64fad2ddd6fd451)

~~~
alnis
A few people have reported a similar bug. I don't think that it's level
specific but has something to do with the next level not leading correctly
upon completing a level.

We're still not sure why it happens or when (it seems to only affect a few
people), but we'll try to figure it out.

There aren't any errors you can see in the JavaScript console, are there?

~~~
mason55
It happened twice to me, once on 4 once on 8 I think. Both times it happened
when I went through the exit then went back to it.

------
Bartweiss
On level 15, my deaths keep changing the editable window. I'll die and then
the last several characters (4 I believe) of my code get swapped to uneditable
until I reset.

I'm also encountering a bunch of exceptions during game execution instead of
at build, which are making things rather hard to beat. I'd list them but they
vanish faster than I can read them.

------
Ellipsis753
Does anyone know of a nice way to unlock levels for the mirror? I'm on the
first jQuery one but all I see is black text on a white screen. No players and
nothing changes when I use the arrow keys. I can't find anything in the code I
can edit either. I'd like to try the mirror but I don't want to have to play
though the whole game again?

~~~
alnis
Can you show me what the jQuery level looks like for you? I want to make sure
that it's working correctly.

~~~
Ellipsis753
It's fixed now with the servers no longer overloaded (although for some reason
I had to start again).

What was happening was that the highlighting of you and the boss were not
showing. So just the page without anything interactive.

------
madvlad
Not sure if you noticed this yet or not, but it is possible to comment all
code following an allowed block by leaving an open "/*". This allows the
player to write their own code to overwrite what should be uneditable.

not sure if you would want to disallow this or not, but i find it allows for
some interesting hacky solutions.

------
jasonkester
Awesome game.

One thing it drives home for me is just how distracting music is when I'm
trying to code. It pulled up that first listing and I literally _could not
parse it_ until I muted the audio. Then it immediately turned back into code.

It's like music just turns off the switch that connects the eyeballs to the
brain. Amazing.

------
Slix
This music is awesome. What genre is it?

~~~
alnis
It's from a combination of electronic sub-genres by some independent artists.
You can see the full list of tracks here:
[https://github.com/AlexNisnevich/untrusted#soundtrack](https://github.com/AlexNisnevich/untrusted#soundtrack)

------
shangxiao
I wasn't sure how to show all the mines on the minesweeper map, so I just
place them all at the top... was this supposed to be the point? :)

Anyhoo, nice game, it doesn't matter how you solve it, as it still proves that
eval is evil ;)

~~~
lawl
Ctrl+1 for API docs. There's an API to change the color of a tile :)

------
arcatek
Very fun, however once I reached the level with the DOM, I catched the
opponent but the game went crazy and submitted a lot of queries to Gist (when
I closed the tab, the counter was at 64, and Github was serving 403).

------
frankienwafili
In order to fix that short delay before movement when you hold down a movement
direction you should make pressing the arrow keys set a corresponding movement
boolean to true. Then just move whenever the boolean is true.

Great game!

------
kccqzy
I actually used a "private API" in level 14, crisps contest.

[https://gist.github.com/anonymous/dacd3f1de73a59b5983e](https://gist.github.com/anonymous/dacd3f1de73a59b5983e)

Is this cheating?

~~~
shawabawa3
I completely cheated (added an extra key by setting a trace in the console)
because I looked for an editable line for about 10 minutes and couldn't find
it.

Solved it now by changing greenKey to theAlgorithm

~~~
swordsmith
Could you explain how you would do this? There doesn't seem to be an editable
line, what's the trick?

------
jbeja
I reach level 60, says the counter(just because the game buged after i try to
clear level 6): [http://imgur.com/ty9JlXz](http://imgur.com/ty9JlXz).

~~~
prawks
Same thing happened to me on level 9 (I think?):

[http://i.imgur.com/eYHoebE.png](http://i.imgur.com/eYHoebE.png)

------
ezarowny
I really like that it has WASD/Arrow/Vim controls. Props.

------
mszmszmsz
Level 12: remote control!

[https://gist.github.com/anonymous/dd3e906ad36d87158528](https://gist.github.com/anonymous/dd3e906ad36d87158528)

------
pritambaral
Borks at level 7, upon touching phone with undebuggable message on canvas:

    
    
      d up the function p 1, found:oad the level
      Wone! number of exits ...

~~~
tinacgh
Alnis, love the game! But I also ran into unexpected behavior after clearing
level 7 (change your color). It kept reloading the same level, but opening up
new levels in Level select. Even so, clicking on higher levels keeps reloading
the same colors.js screen.

Another weird thing I noticed was that next to the computer and telephone in
the inventory, two letters "k" appeared. I'm using Firefox 28 on Windows 7.

Here's the solution I used for colors.js
[https://gist.github.com/anonymous/ab5cd3b393c290fbf8c1](https://gist.github.com/anonymous/ab5cd3b393c290fbf8c1)

~~~
alnis
This might be tied to the issue that mandlar, pokpokpok, and valgaze have been
having, but I haven't been able to reproduce it yet.

Does resetting these levels (Ctrl-4) help at all?

~~~
tinacgh
Yes, Ctrl-4 does work, thanks for the tip!

------
Aardwolf
I'm not sure what the real intention of the level "Multiplicity" was, but just
placing an exit anywhere you want works just as well!

~~~
alnis
Multiplying the exits is useful ;-)

~~~
Aardwolf
Heh but then what was the real intention of the earlier maze level? I already
multiplied the exit there :)

Anyway, really nice work with the game!

~~~
alnis
Thanks! The intended solution to the maze level was commenting everything out.
But of course, all of these have multiple solutions :-)

------
bayonetz
A simple nuclear trick for LvL two and on:
[http://pastebin.com/c7vqzrU3](http://pastebin.com/c7vqzrU3)

------
crawfordcomeaux
How long before "Twitch plays Untrusted"?

------
riverjiang
Any tips for level 17? I can't seem to figure out a solution for the
teleporters using the getObjectCoords hint that was given

~~~
amoonki
I did it by drawing on the canvas to mark the way. (I'm trying not to spoil
it, apologies if this is too vague).

~~~
rfirnrohr
I'm stuck on the teleporters one as well. Can we please have another hint?

~~~
dannysb
This level is hard. It took me a while until I found the coords for the
transporters I was looking for but in the end I done it :). tip: find the
transporter from the spawn point and the one where the exits is and link them
together

------
jimmaswell
I forgot about comments on lvl 2 and used if(0){} and was wondering what the 4
was until I remembered / __/ , hah

------
nanidin
> "If you can read this, you are cheating! D:"

Loaded the site, popped open the Chrome Dev Tools, and was thoroughly
disappointed.

~~~
tehwebguy
Why were you disappointed?

~~~
nanidin
Well, the title says you play the game by modifying the game's source. Turns
out you don't modify the game's source, you modify specific snippets of code
that are provided on the page.

Last weekend I hacked around in the source of various online games, I
anticipated this to be a similar experience but was disappointed to find that
we weren't supposed to actually change the game's source.

~~~
SheeEttin
Well you can play it that way too, if you want. Try overriding some of the
internal functions using creative methods. :)

------
vjeux

        map.validateExactlyXManyObjects = function() {};
    

lets you put an exit tile next to your character on every level

~~~
lawl
Been there, done that:
[https://news.ycombinator.com/item?id=7548257](https://news.ycombinator.com/item?id=7548257)

------
tyilo
I didn't get the last 3 DOM-based ones. I just randomly hit my arrow keys and
until I completed the levels.

Otherwise a very cool game!

~~~
alnis
Oh, only level 19 is DOM-based - level 20 and 21 are different. You may have
been unable to load correctly them due to the stress on the server, but you
should check them out at some point :-)

~~~
bchoi08
woot. got 21 too finally :)

------
icedog
Level 1 just reloads after I get to the exit.

~~~
alnis
The game was broken for a bit, and it's possible that your saved state got
corrupted.

Try restarting the game by running localStorage.clear() in the JavaScript
console, then refreshing the page. Does that fix it?

------
marijn
Seems to be overloaded now. Multiple 503s.

------
neil_s
Any tips for level 9? I can't seem to find a handle on the raft to be able to
modify its behaviour directly.

~~~
paulhodge
Is there anything else you could modify to change what the raft does?

~~~
31cup
Yes...but I can't do it at an intelligent time.

~~~
alnis
Do you have any tools available to you that let you execute code at a chosen
time?

~~~
31cup
hah, I tried that multiple times, i get: You are not allowed to use call!

~~~
nhaehnle
Yeah, it seems odd that the setPhoneCallback is forbidden in this level,
because that solution would fit the sequence of levels very well. Luckily,
there are other ways to cross the water, and some other commenters in the
thread already hinted at them ;)

~~~
alnis
setPhoneCallback works perfectly for me in level 9 -- in fact, it's my
intended solution:
[https://gist.github.com/anonymous/6e5606649b3cb0d60797](https://gist.github.com/anonymous/6e5606649b3cb0d60797)

~~~
nhaehnle
Seems this was a combination of my mistake and a bug that you might have fixed
in the meantime. I intended to assign the player object to a variable player
but made a mistake. The resulting error message was "player.setPhoneCallback
not allowed" or something like that, but that was yesterday and with a
different browser version (Firefox). Now when I tried to reproduce it, I get
"player is not defined", which is much more helpful :)

I suspect that the GP ran into the same problem.

------
wingerlang
Any way I can go to a level directly? I was on level 12 but my computer died,
and it did not save any progress.

~~~
ekmartin
Did you check the menu at ^0?

~~~
wingerlang
Ah, they were saved there! Thanks!

------
davearch
This is awesome but it keeps repeating the first level! I get the solution but
then it just reloads everything.

~~~
alnis
The game was broken for a bit, and it's possible that your saved state got
corrupted.

Try restarting the game by running localStorage.clear() in the JavaScript
console, then refreshing the page. Does that fix it?

------
epsylon
Is there any solution to the ambush level other than the obvious solution of
moving the drones out of the way?

~~~
SheeEttin
Of course. I made them harmless and walked right through them.

~~~
epsylon
Tried that, but for some reason I couldn't disable the onCollision by
assigning it to some dummy function. Do you mind sharing your solution?

~~~
SheeEttin
I wish we could retrieve the solution we used for past levels. :(

Okay, I think I've replicated it. I just overrode onCollision with empty
braces, so the final definition looked like this:

    
    
        map.defineObject('attackDrone', {
            'type': 'dynamic',
            'symbol': 'd',
            'color': 'red',
            'onCollision': function (player) {
                player.killedBy('an attack drone');
            },
            'behavior': function (me) {
            },
            'onCollision': function (player) {
            }
        });
    

Note that you're closing the game's braces, inserting another definition, then
re-opening braces to match the game's closing ones.

------
lectrick
I tried to move the exit inside the walls. I was unable to edit any of the
code. I thought that was the point?

~~~
maaaats
Ctrl+5 to reload the level after you changed it. Did you do that? On one of
the levels I created a new exit inside, and it worked.

------
tinacgh
Is there an easy way to transfer progress between computers? (other than
saving your solution Gists?)

------
tall
level 35!
[https://gist.github.com/anonymous/25b4b4b56f844368a37c](https://gist.github.com/anonymous/25b4b4b56f844368a37c)
here's to calling into the code behind using pattern matching and the nifty in
operator

------
anigbrowl
Loved it, but exiting on Level 1 just causes level 1 to reload for me and
never unlocks level 2.

~~~
alnis
Does the mirror
[[http://alexnisnevich.github.io/untrusted/](http://alexnisnevich.github.io/untrusted/)]
work for you?

------
YuMS
LV 20 Math.random = function() {return 1;} map.getPlayer().hasItem =
function() {return true;}

------
resist_futility
Any tips on level 15? Once the player is killed what could I possibly do?

~~~
cheepin
I actually figured something out with this which is weird, because I don't
think it has to do with exceptions. I passed in a new object of an undeclared
type and just walked across the water, which I can't explain.

Can anyone help?

~~~
SheeEttin
I'm trying with

    
    
        player.killedBy(function(){throw new Exception();});
    

...but then that just means I get killed by "function(){throw new
Exception();}".

Edit: never mind, got it. Overriding onCollision helps. :)

[https://gist.github.com/anonymous/2868beb0cee19259ebb5](https://gist.github.com/anonymous/2868beb0cee19259ebb5)

------
pacofvf
:'( I'm stuck at crispsContest.js lvl

~~~
majugi
This level was driving me crazy (mostly because of the character limit). The
solution that I found is kind of silly: it turns out the removeItem function
is dumber than you probably think it is.

~~~
SheeEttin
A good solution would be to remove an invalid item, and the function should
silently try to remove the invalid item, but still allow passage. For some
reason, even when you have the green key, but try to remove an invalid item,
it still doesn't let you through, despite apparently returning false
(passable).

Additionally it doesn't support injection there, so while
"player.removeItem('greenKey'); player.additem('greenKey');" should work, it
says "TypeError: undefined is not a function".

~~~
9193-on
I approached it like this:

player.removeItem('greenKey'); return 0;} if(1==1){('');

Full link:
[https://gist.github.com/anonymous/c78b439d8f2369e03f68](https://gist.github.com/anonymous/c78b439d8f2369e03f68)

Basically, this let's you delete the green item once. After that, it makes
sure that return true is never reached (because of the 1==1), so next passages
through green are allowed. Kinda liked the sneaky (''); myself :P

------
cheepin
aww, I tried to sacrifice my phone for an easier solution for the last
problem, but apparently I need it in the end.

------
tpae
stupid drones, me.selfDestruct (tableflip)

~~~
henryw
I made a wall to circle around the drone. Pretty fun.

~~~
Siliconic
I found it easier to make myself invincible.

map.getPlayer().killedBy = function() {};

Drone just follows you around like harmless puppy.

[https://gist.github.com/anonymous/dfb6822e683ea7418ea8](https://gist.github.com/anonymous/dfb6822e683ea7418ea8)

~~~
BostX
Neo: What are you trying to tell me? That I can dodge bullets? Morpheus: No,
Neo. I'm trying to tell you that when you're ready, you won't have to. :)

------
gabemart
Can anyone give me a hint for level 12?

~~~
XaspR8d
You're defining a robot's properties, so you might want to define its
properties. That'll open the door to higher-level navigation logic.

(Being obtuse is difficult...)

------
icemelt8
Stuck at level 13 :(

~~~
amoonki
I solved it by basing the robot's movements off my own using my position.
Hopefully that's vague enough to be a decent hint but not a giveaway...

------
cproctor
I won!

------
Jupiterlyght
dang this is awesome

------
BostX
In level 10 ambush I set

    
    
            function (me) {}
    

for the red and yellow drones and

    
    
            function (me) {
                var r = 'right:'+me.canMove('right');
                var l = 'left: '+me.canMove('left')
                alert(r+'; '+l);
            }
    

for the green drones. But I always get 'right:true; left: true'. WTFFFFFF? :-(
Please please fix that, please!!!

~~~
mszmszmsz
Level 10 can be solved by code injection :)

[https://gist.github.com/anonymous/d65048c34bd6874478a1](https://gist.github.com/anonymous/d65048c34bd6874478a1)

