Untrusted
You're trapped, with only your wits and a computer to help you! Fortunately, that's more than enough, IF you have the knowledge to code your way out of this incredibly sneaky and clever JavaScript puzzle game, where the solution lies in the source... and what you make of it.
Read More95 Comments
Okay, I've made a bit of progress... I think.
I figured out you could review past levels via the menu. I checked the syntax, and fixed it.
player.setPhoneCallback(function () {
raftDirection = 'up';
});
...but when I run it, I get an error: "undefined is not a function". I have no idea what's causing it.
I had the same problem trying to ford the river. Here's my dirty work-around:
map.defineObject('turtle', {
'type': 'dynamic',
'symbol': 'O',
'color': '#0f0',
'transport': true, // (prevents player from drowning in water)
'behavior': function (me) {
//just sit there
}
});
for (var y = 5; y
map.placeObject(21, y, 'turtle');
}
alex: No, it does not seem to work!
if (player.getColor('#0f0')) {
player.setColor('#f00');
}
else if (player.getColor('#f00')) {
player.setColor('#ff0');
}
else if (player.getColor('#ff0')) {
player.setColor('#0f0');
}
This code does at least run, but it does not actually change the color to anything BUT red.
I've gotten way past "Fording the River" now. I'm stuck on robotMaze. I have NO idea how to attempt it.
The old "follow the left wall" adage is useless because there's no way to keep track of which way the robot just moved. I'm guessing that the getAdjacentEmptyCells function we're so generously provided with has something to do with the solution, but I've still got nothing.
bdr198524: Hint - player.getColor() doesn't work exactly the way you think it does. Take a look at how it's used elsewhere in the level.
SonicLover: There's an easy way and a hard way to do robotMaze. If you have some background in AI or algorithms, you can probably figure out the hard way. As for the easy way,
consider the fact that the robot is able to see the location of the player
.
...Got lucky with RobotMaze. Now I've gotten much further. Pointers is giving me grief.
I figured out the programming part. I even had the intelligence to make connections that led to traps different colors than connections that didn't.
But the maze itself is a headache. The connections look like a spider's web, so I can barely tell what connects to what. And half the time, the maze literally isn't solvable-- there are zero paths from beginning to end.
In Robot Maze, there is at least one way for the robot to remember its direction from turn to turn:
var color = me.color;
if (color == 'gray') {
dir = 'right';
dir2 = 'down';
dir3 = 'up';
} else if (color == '#f00') {
dir = 'down';
dir2 = 'left';
dir3 = 'right';
} else if (color == '#0f0') {
dir = 'left';
dir2 = 'up';
dir3 = 'down';
} else {
dir = 'up';
dir2 = 'right';
dir3 = 'left';
}
if (me.canMove(dir2)) {
me.move(dir2);
dir = dir2;
} else if (me.canMove(dir))
me.move(dir);
else
dir = dir3;
if (dir == 'right')
me.color = 'gray';
else if (dir == 'down')
me.color = '#f00';
else if (dir == 'left')
me.color = '#0f0';
else
me.color = '#00f';
Ok. I just got back on. I should have thought of the alternate keys, but arrow keys do move the character as well. Thus I didn't think of that.
Second Question: How do you close the computer after picking it up to see the map? I'm sure I'm just being a bit thick, but I ......
Nevermind. It doesn't like IE. When you zoom in in the browser, the game changes relative to the rest of the browser. So that's a bit useless. Chrome works. In IE, my map takes up the entire screen, so the computer takes up the right half of the map. Also, Chrome doesn't make the code side-scroll(at least not so far as I can see.)
I found that my solution for RobotNav was copy/pastable for RobotMaze. If you can control which direction the robot moves, it's very easy. And remember, closing brackets/parentheses don't necessarily have to be used for the same function they originally were.
you can put the Phone Callback function into the script by replacing the end brackets.
Here's my solution for robotMaze (the "clever" AIish way):
if (!me.last_move) me.last_move = 'right';
if (me.last_move == 'right') {
if (me.canMove('up')) {
me.last_move = 'up';
me.move('up');
} else if (me.canMove('right')) {
me.last_move = 'right';
me.move('right');
} else if (me.canMove('down')) {
me.last_move = 'down';
me.move('down');
} else if (me.canMove('left')) {
me.last_move = 'left';
me.move('left');
}
} else if (me.last_move == 'up') {
if (me.canMove('left')) {
me.last_move = 'left';
me.move('left');
} else if (me.canMove('up')) {
me.last_move = 'up';
me.move('up');
} else if (me.canMove('right')) {
me.last_move = 'right';
me.move('right');
} else if (me.canMove('down')) {
me.last_move = 'down';
me.move('down');
}
} else if (me.last_move == 'left') {
if (me.canMove('down')) {
me.last_move = 'down';
me.move('down');
} else if (me.canMove('left')) {
me.last_move = 'left';
me.move('left');
} else if (me.canMove('up')) {
me.last_move = 'up';
me.move('up');
} else if (me.canMove('right')) {
me.last_move = 'right';
me.move('right');
}
} else if (me.last_move == 'down') {
if (me.canMove('right')) {
me.last_move = 'right';
me.move('right');
} else if (me.canMove('down')) {
me.last_move = 'down';
me.move('down');
} else if (me.canMove('left')) {
me.last_move = 'left';
me.move('left');
} else if (me.canMove('up')) {
me.last_move = 'up';
me.move('up');
}
}
The implementation is ugly though. I'd be interested if anyone's got a nicer way to do write it.
How it works:
It's basically a simple algorithm that can solve some mazes (those without "islands" it can get stuck on.) Put briefly, the robot hugs the left wall.
It never even occurred to me that
you could remote control the robot by reading the player's coordinates.
I really like the game so far. My only criticism is that I wish the API docs were more complete/clearer, and that it was made explicit what you're allowed to use from outside the game (what parts of javascript etc.)
e.g. I found by experimenting in the code above I could add an attribute to the robot to give it memory, but it wasn't made clear you could do this. In order to make the robot solve the maze itself you need to be able to give it a memory somehow, and I thought that's what it was trying to get you to do. However it gives you no help doing so.
"If you can read this, you are cheating! D:"
Oh come on. The console is the number one tool for savy javascript coders.
functionList['fortresses'] this hurts in the eyes, a table should not be called List and if used it should be functionList.fortresses
Oh and when you want to smuggle in global variables, you can always add them to "Object", like "Object.x"
Stuck at 07_colors
Alex.nisnevich: I'm at the same point bdr was talking about. I have the same confusion. Using it in the same manner as elsewhere in the code makes it break even more.
Also, I'm not sure that it's an issue with the player.getColor() not working, because when I tried to write the program to work around that,
var colo
if(colo!=1){
if(colo!=2){
if(colo!=3){
colo=1;
};
};
};
map.placeObject(2+colo,4,'block');
if((colo=1) || (colo=4)){
player.setColor('#f00');
}
else if((colo=2) || (colo=5)){
player.setColor('#ff0');
}
else if((colo=3) || (colo=6)){
player.setColor('#0f0');
};
map.placeObject(2+colo,5,'block');
colo++
map.placeObject(2+colo,6,'block');
Yes, the var colo is intended, as I don't know what column and color variables are already taken. It was i, but I decided against that common variable.
The map.placeObject() instances are for figuring out where it goes wrong.
The first two blocks are placed at x=3, as expected. The third is at x=4, as expected.
I press Q again. Nothing happens. If something did happen, there would be two more blocks in the x=4 column, and one in the x=5 column.
I think the player.setPhoneCallback() can only occur once.
Dartania Thorne: The issue with what you're doing is that the colo variable gets reset every time you call the phone.
map.getPlayer().getColor() == "color"
is the best way to check player color. Other people have also beaten the level using things like
changing color based on player position
or
changing color randomly
in the phone callback.
Strange. I thought I had it so it wouldn't be reset. And, after I posted, I added in another placeObject at the top of the function, but let me guess, you can only declare a variable once, which is probably why I had some trouble there.
In the end, I used a bit of brute force.
player.setPhoneCallback(function () {
player.setColor('#f00');
player.setPhoneCallback(function () {
player.setColor('#ff0');
player.setPhoneCallback(function () {
player.setColor('#0f0');
player.setPhoneCallback(function () {
player.setColor('#f00');
player.setPhoneCallback(function () {
player.setColor('#ff0');
});
});
});
});
});
I'm just glad there were only a few color changes.
I solved the robot maze also by wall-hugging. I quite like how the code turned out.
// Run this only once. It defines some helper methods.
if (!me.direction) {
me.direction = 'down';
// Rotate clockwise.
me.rotRight = function(){
switch(me.direction){
case 'left': me.direction = 'up'; break;
case 'up': me.direction = 'right'; break;
case 'right': me.direction = 'down'; break;
case 'down': me.direction = 'left'; break;
}
};
// Rotate anti-clockwise
me.rotLeft = function(){
switch(me.direction){
case 'left': me.direction = 'down'; break;
case 'down': me.direction = 'right'; break;
case 'right': me.direction = 'up'; break;
case 'up': me.direction = 'left'; break;
}
};
// Test to see if we can move in the current direction.
me.canForward = function(){
return me.canMove(me.direction);
};
// Move in the current direction.
me.forward = function(){
return me.move(me.direction);
};
}
// With those methods defined, the actual wall hugger is rather simple.
// This hugs the right wall. Hugging the left wall is achieved
// by first calling me.rotLeft(); and calling me.rotRight(); in the loop.
me.rotRight();
while (!me.canForward()) {
me.rotLeft();
}
me.forward();
Hints for level 2 (each one is more explicit about what to do):
What you'd really like is for the maze to not get created.
You can write code in two places, either side of the code that creates the maze. Can you stop it from being created?
Put comments /* */ around the maze creation code.
Could do more if people request or I feel like it.
The arrow keys only scroll because JiG has iframed the whole game's website, rather than just linking to it. Shame on you.
Instead go and play it on http://alexnisnevich.github.io/untrusted/ where the arrow keys work just fine, because you will be playing it as the author intended, not in a frame, but on his own website.
Untrusted is hosted on JayisGames.com in an iframe with the author's permission, which was freely given when I contacted him days ago to ask. Thanks for asking! -Dora :)
I had a rather different solution to 13_robotMaze:
https://gist.github.com/anonymous/a79b9df258c26ffba06b
if you have a github login, or the spoiler below, but with the indentation destroyed.
if (!('dirs' in me)) {
me.dirs = Array(map.getWidth());
for (var i=0; i
me.dirs[i] = Array(map.getHeight());
}
var keypos = me.findNearest('blueKey');
var dist=0;
var edges = [[keypos.x, keypos.y, '']];
while (edges.length>0) {
var next_edges = [];
while (edges.length>0) {
var edge = edges.shift();
me.dirs[edge[0]][edge[1]] = {
'dist': dist,
'dir': edge[2]
};
var adj_cells = map.getAdjacentEmptyCells(
edge[0], edge[1]);
while (adj_cells.length>0) {
var cell = adj_cells.shift();
var x = cell[0][0];
var y = cell[0][1];
map.setSquareColor(x,y,'#020');
if (map.getObjectTypeAt(x,y) != 'barrier' &&
!(y in me.dirs[x])) {
next_edges.push([x,y,cell[1]]);
}
}
}
edges = next_edges;
dist++;
}
}
if (me.got_key)
me.move('down');
else {
var dat = me.dirs[me.getX()][me.getY()];
if (dat.dist == 0) {
me.got_key = true;
} else switch (dat.dir) {
case 'up':
me.move('down');
break;
case 'down':
me.move('up');
break;
case 'left':
me.move('right');
break;
case 'right':
me.move('left');
break;
}
}
Results:
The robot takes the shortest path through the maze.
Oy. This is way too much like work.
The earlier levels are almost fun, because they give you the tools to use. In later levels, where you kind of have to know Javascript to continue, all vestiges of fun go away. Nevertheless, I think if the API was a little more detailed, with more explicit hints of what is possible, it would greatly improve the playability for those of us who just don't get along with curly braces.
@henry8205: There are a bunch of approaches that seem like they might work for level 10, but here's what I did.
You can use the same code for all three types of drone.
Remember that drones can detect which row they're on.
Just tell each drone to move right if it's on row 11 (or row 13 if you prefer).
Another approach for Robot Maze (I thought of using player position as remote control, but discarded it as too much effort - and the random walk is possible but only if you have the time - and you should be aware that the key is not an empty space, so you need to be clever about your end-condition for the random movement)
if (me.canMove('down'))
me.move('down');
me.move('right');
//regenerate maze (^5) until you get one which this will solve
I'm stuck on Exceptional Crossing - I think I've figured out the hint in the level name, but I haven't figured out how to frack with the code suitably...
Since I've finished the game (and loved it very much), I've decided to make a hintthrough or something:
Remember, when in doubt, check the API for any functions that may be useful.
Level 1:
Pick up the computer, and you'll be able to look at the level's code. Note that you can only edit the black section. The code resembles something that generates blocks (see placeobject and block?).
So, just delete all the code in the black section. Hit execute.
Level 2:
Hmm, a maze here. Execute the level a few times and observe: note that the exit is always observed. Also, you can only place code directly before and after the code. As the level has tell you, you only need to add 4 characters to win this level. (Some basic programming knowledge needed)
What you need are the commenting characters "/* and */". Put /* in the front and */ in the end, and everything between them are "commented", i.e not executed as code.
Level 3:
Uh oh, this time they've enforced validation, which means you can't execute the level whatever way you want. But after simple investigation, the code only check for how many blocks exist on the screen. If we place exactly that many blocks in another way...
Just place 104 blocks that won't block your way to the exit. The simplest way is to edit any x or y inside placeObject to x+2 or y+2 to offset it, effectively shifting the wall sideways to open a gap for you.
Level 4:
Trick level. You can't do much here: you can't overwrite existing blocks, you can't disable the block-generating code, and you can't place the player outside the cell. Oh, I guess this hints you about something.
You can place multiple exits in this level, so just place another exit inside the cell.
Level 5:
This place is filled with mines! The only place you can add codes is directly after which the mines are being generated. Mines are invisible, but if you can somehow make their position visible... Maybe the API gives us something useful.
See the map.setSquareColor? This will help painting all the mines, so that we can see them directly (and avoid them).
Level 6:
An attack drone! It always follows you, and kills you when it touches you. To outrun the robot, you need some objects to constraint its movement.
Just place some walls to block off the drone as you maneuvers and lures it into the wall, and then outrun it. A long horizontal wall above the drone is already sufficient.
Level 7:
Colors. You're now offered with a phone, which can call any function you write up whenever you press Q or Ctrl+6.
The color lock is designed such that it's impassible if the player's color is not the same as it. You must change yourself, i.e your color.
Set up some if statements to set the player's color (via player.setColor function) depends on the current player's color. An example would be
if green->red, if red->yellow, if yellow-> green.
(Note that this is pseudo-code, and is not what javascript if-statement syntax are. Javascript's if syntax is
if(condition) {
something;
}
)
Level 8:
Chapter 2!
This level is very straightforward. First, note the comment that in this level map.placeObject is allowed to overwrite existing object. And you can only choose the function that exists in the code to call. There isn't that many function that's useful to change the map, is it?
Just choose to call "generateForest". As you keep regenerate the whole forest, you occasionally makes way for you to get closer to the exit.
Level 9:
The water drowns you. The raft doesn't, but it only moves in the direction raftDirection, which has a value of "down". Seems like you can only add some code, but you can't place more rafts or exits.
Sure, changing the raft's direction of movement would work, though, the raft should start moving only when you're on it...
Time to use your phone! (If you forgot how to properly set a phone call function, refer to previous levels' code.) Just make so that calling the phone changes raftDirection to "up". Easy.
Level 10:
You've been ambushed by the drones.
There are three types of drones: Attack drones (red), Reinforcement drones (yellow) and Defense drones (green). Attack drones chases you, Reinforcement drones goes left, Defense drones holds their position.
You can modify their behavior code to make the move the way you want. You can't destroy it, but you can always drive them away to make a path for you...
Hint: Game elements are executed top first.
Reinforcement drones doesn't need to do anything at all. Just clear our their behavior code.
You'd want attack drones and defense drones to move sideways to clear a path, but directly calling them to move up/down won't work as they're blocking each other. And since the drone on the top moves first, you can first move it away, then move the one below it up, and clear out a way. You can do the following:
If the drone can't move up, move left/right. Else, move up.
A simple if statement with the appropriate functions from the API does this well.
Then, a pathway will be cleared out.
Level 11:
Robot AI programming, level 1!
In the next 3 levels, you need to obtain a key by navigate the robots to grab the key and cross the barrier, which then you'll grab the key by touching the robot. You can't edit any of the code except the robot's behavior.
As for the easiest level, there's no obstacles at all. The most straightforward way is to go all the way to the right, and then keep going down. As the code comment had say, only me.move and me.canMove is sufficient.
If the robot can move right, move right. Else, move down.
Level 11:
Robot AI programming, level 2!
This time some basic obstacles are enforced. Our code (brought from the previous level) would still work fine, if we can maneuver the robot at those key locations...
You can obtain the robot's position by me.getX and me.getY. Just define some position that the robot should navigate away from the obstacles (only 5 spot are needed).
Level 12:
Robot AI programming, level 3!
Ehh, we now have a randomly generated maze for the robot. The default random motion code given can solve the maze, just that we need to wait a long time waiting for a miracle. Writing an AI code to hug the left wall is also fine. But it'd be easier if we can just manually control the robot...
You can call player.atLocation inside the behavior function, so you can just use the player's location as the control. It's like putting 4 controller buttons at the map: the robot will move up/down/left/right when the player is pressing the corresponding button.
Level 13:
Puzzle time!
You need to get the Algorithm and get out. Locks requires a key to pass through, and comsumes the key if the player passes through. Now, we can choose any item to be removed by the green gate, even those you don't currently have any, but only defined items can be removed, or an exception will be thrown and we can't enter the gate...
There's only one item you won't possibly have when you pass the green gate: the Algorithm. So, just change it onto "Algorithm".
As for the puzzle itself:
Go top-left, get blue and yellow key, back to the center.
Go top-right, get red and blue key, back to the center.
Go down, get the yellow key and the Algorithm, back to the center.
After all the work, we have the Algorithm and the green key. Exit.
Level 15:
Chapter 3: Betrayal!
You need to cross the river, but the water kills you. You can change whatever it is inside the player.killedBy function in the water's behavior, though.
Hint: the level name is "exceptionalCrossing". Exceptions.
Throwing exceptions with player.killedBy function will stop it from executing, hence saving you from death.
As of how... just put in something that isn't defined and isn't a string (surrounded by quotation marks), since killedBy can accept strings.
Level 16:
Killer lasers that kills you if your color is not the same as them is now deployed!
Note that a new class of functions, canvas, is now available. You can see and edit the lines that draws the laser, as well as some space just before startLevel ends.
...Did he say we can't see the color of the laser? That seems to be an easy fix...
Ah, and changing colors, we've done that before.
To see the color of the laser, change "white" to color, which's defined as the laser's color.
Then, you need to change your color. You can reuse your phone call code from level 7 (colors) for this mission. Just note that only "red", "yellow" and "teal" as color can always save you; RGB codes seems to occasionally kills you.
Level 17:
A basic teleporter maze, except that teleporter may go straightly into life-threatening traps.
The targets for each teleporter are shuffled, and we can't do anything to it. Directly placing object doesn't work either, since the map is using canvas to place objects. (And you can't overwrite the existing canvas map, either)
Not every teleporter maze is solvable, but no matter, we can try to see if it actually is solvable. We want to see which teleporters are connected...
As the code has hinted, map.getCanvasCoords will help you in this job. Look for details in the API.
To see the linkages of the teleporters, loop through teleportersAndTraps again (just copy from the code above :D).
If both are teleporters, obtain their coordinates by map.getCanvasCoords, and use their canvas coordinates to draw a line to each other. You can refer to the canvas code in the killer laser level for a proper line-drawing code.
Also, make sure lineWidth is small, or it'll be hard to see all the linkages...
After that, just keep executing the code until you get a solvable condition.
Level 18:
Classic platformer!
So, in this level, you need to get to the other side, but the gap sure looks large, and falling into it will kill you. There's a "gravity" function which keep pulling you down, and is executed regularly via startTimer function. And you can call the jump function, if the block below you is not empty.
Function name can always be misleading, though. Maybe we can just walk through the gap as if it's solid...
Fill the gap!
In other words, build a bridge by place blocks on the top of the gap, so you can walk straight through. Easy!
Level 19:
Nothing in this level, just use arrow to navigate through the page elements. The level ends when you catch the red guy.
Level 20:
Boss!
Yes, this one is hard.
Looking at the code, the Algorithm can only be dropped by the boss, and you need it to exit the level. You can only kill the boss with projectiles (a dynamic object with 'projectile': true), but you can't put any dynamic objects on the map before the level starts, which means you have to put them in runtime.
If you can get the phone, you can definitely do it, but that bullet curtain looks impossible to pass through! Okay, perhaps we should make the boss generate projectiles themselves...
...Hmm... Math.random? What is it, what does it do?
First, obviously, you should define a new projectile that moves anywhere but down. Just copy from the bullet object code.
Then it comes the cleverest part. Redefine the Math.random function! Since the boss has to trigger Math.random per cycle (to see if it's smaller than 0.3), we can tamper with the Math.random function to make the function lay down bullets that brings forth their doom.
Finally, make sure the function returns a number. Bigger than 0.3 is recommended for obvious reasons.
Level 21:
Uh oh, the exit is not working. And it's not like we can edit the level code either.
Though, when we bring up the menu there's now a new section call scripts/, which is basically the source code of the game itself. We can edit map.js, objects.js and player.js. Since the exit object must be defined somewhere, we can look at how the exit works (and why it isn't working) if we look at the codes.
The exit is an object, so we'll look at objects.js.
From the place where 'exit' is defined, there's some line that translate into "proceed to next level if current map isn't the final level".
So what should you do? Erase the condition, of course.
uncopy, especially with 16 and 17 you got in box solutions. There are easier solutions than the game expects you to.
In Level 16
just overwrite the createLaser after the first call with createLaser=function(){}; so there will be only one laser created. Just avoid that, no need for colors.
In levle 17:
Instead of playing around with the canvas like the comments suggest you, just loop once through dynamicObject to find the right/bottom most teleporter, than loop another time to point all teleporters to the goal. Than finish the level in one jump
Level 20: the boss level your solution is interestingly more out of box than mine, mine is pretty in box.
Get all boss dynamic objects and set their direction to 'down'. So the boss goes to the floor, so you can get the phone. Then on the phone callback just spawn a hell lot of bullets to kill the boss.
How to break the game and solve pretty much anything:
Despite some attempts to prevent it, there are lots of ways to get an underscore, and once you have an underscore, you can do lots of things, like calling the functions which normally get spliced into the top and bottom of startLevel to try to prevent you from tampering too much with it:
u = "a_a".charAt(1);
map[u + "startOfStartLevelReached"]();
map[u + "endOfStartLevelReached"]();
This essentially solves most of the levels, since there's usually an editable portion before most of startLevel happens. You can close out startLevel prematurely, and add the start of a new function for whatever was left to go in (that will never be called).
You can then rewrite the end of startLevel to satisfy any validation and place items/exits/etc. however you like.
For example, see my solution to level 13.
Oh, yet more tampering:
You can also sidestep the tampering detection by simply defining startLevel twice. Only the second definition will be used, and the game won't detect it.
For instance, you can do this.
Every time I try to execute my code in level 6 the script running the game crashes. My game freezes and a popup shows up saying the script is busy and do I want to wait for it to complete (which it never does), much like when Flash randomly stops working. I use Firefox, and this is the code I'm trying:
for(x=5; x=map.getWidth()-5; x++){
map.placeObject(x, 5, 'block');
}
Any suggestions?
@uncopy2002: No, it was a genuine bug in the game somewhere - throwing compile-time errors rather than the intended run-time exceptions. Going back to a previous level and coming back in cleared the errors and let me implement your solution.
It's possible to sneak a little bit of executable code into that line, though probably not enough to actually solve the level - but one of my attempts may have broken the game...
Hmm, looks like the less than sign breaks the comment... let's try it again.
Also, you should be using less-than-or-equal sign instead, because for-loop works such that its content executes whenever the second condition holds true. If you use equality, they're not equal in the first place, so the for-loop is directly skipped.
OK, is this a bug, or am I just not seeing something obvious? (The walkthrough skips level 14: is that an oversight, or is it related to whatever obvious thing I'm not seeing?)
When I bring up level 14, without any edits or anything, it says:
> run 14_crispsContest.jsx
[Line 27] SyntaxError: missing } after property list
Line 27 is not editable. What the @#$%!* am I supposed to do here?
@ThemePark:
Please next time search a little before posting rude words against us. Here and since the beginning, we work with the developers not against the developers. When we don't know if a game can be hosted we ask the permission. Sometimes, developers themselves ask to us for hosting their games due to bandwidth issues on their side (Surgeon, The house etc.).
In the case of Untrusted, Dora asked for hosting it and anyway the game can be compiled in a js file and then be hosted anywhere and it's the Alex's wish:
My previous level 15 solution doesn't work aynmore, since now there is a check about the number of lines.
However I still like to come up with solutions that where not intented
In createLaser do this. Now all lasers will be the same and of the way. Again no need to wory about canvas or colors.
Math.random = function(){return 0;}
So I tried to add a print to level 5 and put in document.write(x,y) it now doesn't let me open the level and just gives me this string of numbers '3031281419271012811193664283810664012491513020182818130110261915223314101465281391931411720712725221474354518141414192715136151671267131130210444112653723131733133501919216241742433193210127451782449182579120223174324212111214841671916163439143140131773718271931142344121922017316132426515160131813411013231128156139719892335029233912814162149961126222584914100301217142150437174946230114424462724191309409271017643194964061412325384351215173537839210522748232720323445212466122026820631450111362246161310'
Thanks for the bugfix, Alex!
I know I complained earlier about this being too much like work, but I nevertheless couldn't leave a game unfinished. I used the walkthrough extensively and even looked up solutions on other sites, and I have to say, I've changed my mind: this is probably the most inventive game I've encountered in a long time. It was hard, and I haven't changed my mind about Javascript being the bane of my existence, but this was damn fun. Five mushrooms from me, and congrats to the developers.
Here's a bit of fun on level 20 bossFight:
map.defineObject('shield', {
'symbol': '#',
'color': '#ff4',
'impassable': true
});
for (var x=5; x
map.placeObject(x, map.getHeight() - 4, 'shield');
map.placeObject(x+1, map.getHeight() - 4, 'shield');
map.placeObject(x+2, map.getHeight() - 4, 'shield');
map.placeObject(x+3, map.getHeight() - 4, 'shield');
map.placeObject(x, map.getHeight() - 3, 'shield');
map.placeObject(x+1, map.getHeight() - 5, 'shield');
map.placeObject(x+2, map.getHeight() - 5, 'shield');
map.placeObject(x+3, map.getHeight() - 3, 'shield');
} ;
map.defineObject('missile', {
'type': 'dynamic',
'symbol': '^',
'color': '#ff0',
'interval': 100,
'projectile': true,
'behavior': function (me) {
me.move('up');
}
});
map.getPlayer().setPhoneCallback(function () {
var x = map.getPlayer().getX();
var y = map.getPlayer().getY();
map.placeObject(x, y-4, 'missile');
map.placeObject(x+1, y-3, 'missile');
map.placeObject(x-1, y-3, 'missile');
}) ;
Dodge under the shields to pick up the phone. Then use the Q button to give 'em hell.
Sorry, that code went wrong. (less than looked like a tag)
Try again:
map.defineObject('shield', {
'symbol': '#',
'color': '#ff4',
'impassable': true
});
for (var x=5; x < map.getWidth()-7; x+=7) {
map.placeObject(x, map.getHeight() - 4, 'shield');
map.placeObject(x+1, map.getHeight() - 4, 'shield');
map.placeObject(x+2, map.getHeight() - 4, 'shield');
map.placeObject(x+3, map.getHeight() - 4, 'shield');
map.placeObject(x, map.getHeight() - 3, 'shield');
map.placeObject(x+1, map.getHeight() - 5, 'shield');
map.placeObject(x+2, map.getHeight() - 5, 'shield');
map.placeObject(x+3, map.getHeight() - 3, 'shield');
} ;
map.defineObject('missile', {
'type': 'dynamic',
'symbol': '^',
'color': '#ff0',
'interval': 100,
'projectile': true,
'behavior': function (me) {
me.move('up');
}
});
map.getPlayer().setPhoneCallback(function () {
var x = map.getPlayer().getX();
var y = map.getPlayer().getY();
map.placeObject(x, y-4, 'missile');
map.placeObject(x+1, y-3, 'missile');
map.placeObject(x-1, y-3, 'missile');
}) ;
I know less about Java than I thought, and that's extra disappointing because I have no formal education in Java and I was not optimistic.
On the other hand, a teaching/puzzle game that actually teaches useful life-skills in a fun way, something that's rare after preschool computer games. If anything, these types of games are almost universally underdeveloped, and then the entire genre is disregarded because of the lack of any proof of a viable genre (the same reason online flash is widely disregarded in the same capacity as computer/console games). This, however, is a wonderful proof of concept (and if I could play all the way through on my own merit, might also prove to be a wonderful game).
Learning and vidya games, two of my favorite things. 10/10
JavaScript lets you do pretty much... anything, so there are a lot of "trivial" solutions to the levels.
Level 3
You can cancel the placement of the exit by putting "if(0)" at the end of the input zone. This lets you place the exit right next to you instead.
Level 5
The game expects to see at least 40 mines, but you can actually place them mines yourself. Just make a loop that places all mines in the first row, then use "break" to exit the main loop. This leaves only one mine in the field, so you can stroll to the exit.
Level 6
Redefine the moveToward function so that the drone always moves left.
Level 10
For all the drones, set this.onCollision to a function that does nothing. Then you can pass right through them.
Level 11
You don't actually need to get the key. Notice how the game lets you exit with the code map.getPlayer().hasItem("redKey"). Simply set hasItem to a function that always returns true.
Level 12
Same as level 11.
Level 13
Same as level 11 and 12.
Level 16
As mentioned by fuzzyface before me, you can set Math.random, but you can also redefine getRandomInt to return 0. Then there won't be any lasers in the way.
Level 18
If the gravity function throws an exception, it will fail to do anything, but you can still move normally. "map = null" or "player = null" will cause the coveted error, so that the phone now turns gravity off.
Can't figure out how to use map.getCanvasCoords. I don't know what to do with the result. You can't just use it as x and y because it contains {"x": x, "y": y} and I get an error saying that 2 arguments are required for lineTo and moveTo. For example, if I use the following code:
xy1 = map.getCanvasCoords(t1);
xy2 = map.getCanvasCoords(t2);
ctx.moveTo(xy1);
ctx.lineTo(xy2);
I get the error "'RenderingContext2D': 2 arguments required"
How do I use the strings returned by map.getCanvasCoords?
I think I broke the game permanently. The very first thing I did with the computer was make the level restart with me outside the room with the computer inside, and I can't seem to progress without getting both the box and the computer. I can't change the code back without the computer, so it appears that there's literally nothing I can do.
Refreshing does nothing. Help?
I'm stuck on Level 8...
Basically, I don't program fluently. But on this level, it doesn't seem like I need to -- all I need to do is set
map.getPlayer().setPhoneCallback(functionList["generateForest"]);
right? But, for some reason, all it ever shows me is "Permission denied." I've even tried inputting some of the codes with preset status updates, and it still shows me the same status. Is this a glitch or am I missing something? Should I input it as
map.getPlayer().setPhoneCallback(functionList['generateForest']);
, because the game won't let me change the quotation marks within the clause.
Help?
Beat it. Phew that was tough. Had to check for hints a few times for syntax, but all in all it was an excellent game!
Just curious, for the robot levels did anyone
make the robot player controlled? I used the same code for the second and third robot levels - I just made it so that if the player stands on specific spaces it causes the robot to move in a certain direction. So then I would stand in the "right" space to move it to the right and press the 'wait' key until it went where I want, moved to the "down" space, etc... I didn't see a need to write an AI for the thing but I guess it was a bit cheap :p. Oh well maybe I'll go back and try to solve these puzzles by making the robot automated.
It seems that my cheat for level 11/12/13 has been blocked. Thankfully, there are still holes to exploit.
Level 11/12/13:
// The game checks for tampering by comparing the code of
// the player's original functionality with its current one.
// Unfortunately, it does this by using toString, which I
// can replace by a dummy.
s = "proto" + "type" // the game blocks "prototype", but this is an empty gesture
Function[s].toString = function () { return "nope"; }
map.getPlayer().hasItem = function(item) { return true; }
Papachabre: Yeah! I was wondering with regards to the robot levels why
I hadn't seen more player location based solutions here. They give you the "press R to rest" hint in the comment code, so that led me to the four square solution of "resting" on a square as long as you need to move the robot that direction. Its much easier to code as well, just 4 lines for my version.
I colored the squares too so they looked like a d-pad :)
Saviour-V teleports in...
A most interesting game. There should be more of these.
On a most amusing note, we've all been TROLLED by Level 14.
The name of this stage is "crispscontest". Also, the theme for this area is called, "Da Funk Do You Know 'bout Chip?"
Apart from the theme being pretty catchy, if you look up "sound.js" you'll find the link to the composer's SoundCloud page, but to save you all the grief, I'll put up the URL for the track itself:
Read the description. If you've played ONE particular game before, you'll know that all this is an allusion to...
Chip's Challenge!
Well played, you guys behind Untrusted. Bravo!
Level 17 has better solution:
setTarget() method can be called more than once. We need to find teleporters near player and near exit and connect them.
https://gist.github.com/anonymous/1b7b3f6093174aca9345
Leave a comment [top of page]
Walkthrough Guide
(Please allow page to fully load for spoiler tags to be functional.)
Since I've finished the game (and loved it very much), I've decided to make a hintthrough or something:
Remember, when in doubt, check the API for any functions that may be useful.
Level 1:
Pick up the computer, and you'll be able to look at the level's code. Note that you can only edit the black section. The code resembles something that generates blocks (see placeobject and block?).
So, just delete all the code in the black section. Hit execute.
Level 2:
Hmm, a maze here. Execute the level a few times and observe: note that the exit is always observed. Also, you can only place code directly before and after the code. As the level has tell you, you only need to add 4 characters to win this level. (Some basic programming knowledge needed)
What you need are the commenting characters "/* and */". Put /* in the front and */ in the end, and everything between them are "commented", i.e not executed as code.
Level 3:
Uh oh, this time they've enforced validation, which means you can't execute the level whatever way you want. But after simple investigation, the code only check for how many blocks exist on the screen. If we place exactly that many blocks in another way...
Just place 104 blocks that won't block your way to the exit. The simplest way is to edit any x or y inside placeObject to x+2 or y+2 to offset it, effectively shifting the wall sideways to open a gap for you.
Level 4:
Trick level. You can't do much here: you can't overwrite existing blocks, you can't disable the block-generating code, and you can't place the player outside the cell. Oh, I guess this hints you about something.
You can place multiple exits in this level, so just place another exit inside the cell.
Level 5:
This place is filled with mines! The only place you can add codes is directly after which the mines are being generated. Mines are invisible, but if you can somehow make their position visible... Maybe the API gives us something useful.
See the map.setSquareColor? This will help painting all the mines, so that we can see them directly (and avoid them).
Level 6:
An attack drone! It always follows you, and kills you when it touches you. To outrun the robot, you need some objects to constraint its movement.
Just place some walls to block off the drone as you maneuvers and lures it into the wall, and then outrun it. A long horizontal wall above the drone is already sufficient.
Level 7:
Colors. You're now offered with a phone, which can call any function you write up whenever you press Q or Ctrl+6.
The color lock is designed such that it's impassible if the player's color is not the same as it. You must change yourself, i.e your color.
Set up some if statements to set the player's color (via player.setColor function) depends on the current player's color. An example would be
if green->red, if red->yellow, if yellow-> green.
(Note that this is pseudo-code, and is not what javascript if-statement syntax are. Javascript's if syntax is
if(condition) {
something;
}
)
Level 8:
Chapter 2!
This level is very straightforward. First, note the comment that in this level map.placeObject is allowed to overwrite existing object. And you can only choose the function that exists in the code to call. There isn't that many function that's useful to change the map, is it?
Just choose to call "generateForest". As you keep regenerate the whole forest, you occasionally makes way for you to get closer to the exit.
Level 9:
The water drowns you. The raft doesn't, but it only moves in the direction raftDirection, which has a value of "down". Seems like you can only add some code, but you can't place more rafts or exits.
Sure, changing the raft's direction of movement would work, though, the raft should start moving only when you're on it...
Time to use your phone! (If you forgot how to properly set a phone call function, refer to previous levels' code.) Just make so that calling the phone changes raftDirection to "up". Easy.
Level 10:
You've been ambushed by the drones.
There are three types of drones: Attack drones (red), Reinforcement drones (yellow) and Defense drones (green). Attack drones chases you, Reinforcement drones goes left, Defense drones holds their position.
You can modify their behavior code to make the move the way you want. You can't destroy it, but you can always drive them away to make a path for you...
Hint: Game elements are executed top first.
Reinforcement drones doesn't need to do anything at all. Just clear our their behavior code.
You'd want attack drones and defense drones to move sideways to clear a path, but directly calling them to move up/down won't work as they're blocking each other. And since the drone on the top moves first, you can first move it away, then move the one below it up, and clear out a way. You can do the following:
If the drone can't move up, move left/right. Else, move up.
A simple if statement with the appropriate functions from the API does this well.
Then, a pathway will be cleared out.
Level 11:
Robot AI programming, level 1!
In the next 3 levels, you need to obtain a key by navigate the robots to grab the key and cross the barrier, which then you'll grab the key by touching the robot. You can't edit any of the code except the robot's behavior.
As for the easiest level, there's no obstacles at all. The most straightforward way is to go all the way to the right, and then keep going down. As the code comment had say, only me.move and me.canMove is sufficient.
If the robot can move right, move right. Else, move down.
Level 11:
Robot AI programming, level 2!
This time some basic obstacles are enforced. Our code (brought from the previous level) would still work fine, if we can maneuver the robot at those key locations...
You can obtain the robot's position by me.getX and me.getY. Just define some position that the robot should navigate away from the obstacles (only 5 spot are needed).
Level 12:
Robot AI programming, level 3!
Ehh, we now have a randomly generated maze for the robot. The default random motion code given can solve the maze, just that we need to wait a long time waiting for a miracle. Writing an AI code to hug the left wall is also fine. But it'd be easier if we can just manually control the robot...
You can call player.atLocation inside the behavior function, so you can just use the player's location as the control. It's like putting 4 controller buttons at the map: the robot will move up/down/left/right when the player is pressing the corresponding button.
Level 13:
Puzzle time!
You need to get the Algorithm and get out. Locks requires a key to pass through, and comsumes the key if the player passes through. Now, we can choose any item to be removed by the green gate, even those you don't currently have any, but only defined items can be removed, or an exception will be thrown and we can't enter the gate...
There's only one item you won't possibly have when you pass the green gate: the Algorithm. So, just change it onto "Algorithm".
As for the puzzle itself:
Go top-left, get blue and yellow key, back to the center.
Go top-right, get red and blue key, back to the center.
Go down, get the yellow key and the Algorithm, back to the center.
After all the work, we have the Algorithm and the green key. Exit.
Level 15:
Chapter 3: Betrayal!
You need to cross the river, but the water kills you. You can change whatever it is inside the player.killedBy function in the water's behavior, though.
Hint: the level name is "exceptionalCrossing". Exceptions.
Throwing exceptions with player.killedBy function will stop it from executing, hence saving you from death.
As of how... just put in something that isn't defined and isn't a string (surrounded by quotation marks), since killedBy can accept strings.
Level 16:
Killer lasers that kills you if your color is not the same as them is now deployed!
Note that a new class of functions, canvas, is now available. You can see and edit the lines that draws the laser, as well as some space just before startLevel ends.
...Did he say we can't see the color of the laser? That seems to be an easy fix...
Ah, and changing colors, we've done that before.
To see the color of the laser, change "white" to color, which's defined as the laser's color.
Then, you need to change your color. You can reuse your phone call code from level 7 (colors) for this mission. Just note that only "red", "yellow" and "teal" as color can always save you; RGB codes seems to occasionally kills you.
Level 17:
A basic teleporter maze, except that teleporter may go straightly into life-threatening traps.
The targets for each teleporter are shuffled, and we can't do anything to it. Directly placing object doesn't work either, since the map is using canvas to place objects. (And you can't overwrite the existing canvas map, either)
Not every teleporter maze is solvable, but no matter, we can try to see if it actually is solvable. We want to see which teleporters are connected...
As the code has hinted, map.getCanvasCoords will help you in this job. Look for details in the API.
To see the linkages of the teleporters, loop through teleportersAndTraps again (just copy from the code above :D).
If both are teleporters, obtain their coordinates by map.getCanvasCoords, and use their canvas coordinates to draw a line to each other. You can refer to the canvas code in the killer laser level for a proper line-drawing code.
Also, make sure lineWidth is small, or it'll be hard to see all the linkages...
After that, just keep executing the code until you get a solvable condition.
Level 18:
Classic platformer!
So, in this level, you need to get to the other side, but the gap sure looks large, and falling into it will kill you. There's a "gravity" function which keep pulling you down, and is executed regularly via startTimer function. And you can call the jump function, if the block below you is not empty.
Function name can always be misleading, though. Maybe we can just walk through the gap as if it's solid...
Fill the gap!
In other words, build a bridge by place blocks on the top of the gap, so you can walk straight through. Easy!
Level 19:
Nothing in this level, just use arrow to navigate through the page elements. The level ends when you catch the red guy.
Level 20:
Boss!
Yes, this one is hard.
Looking at the code, the Algorithm can only be dropped by the boss, and you need it to exit the level. You can only kill the boss with projectiles (a dynamic object with 'projectile': true), but you can't put any dynamic objects on the map before the level starts, which means you have to put them in runtime.
If you can get the phone, you can definitely do it, but that bullet curtain looks impossible to pass through! Okay, perhaps we should make the boss generate projectiles themselves...
...Hmm... Math.random? What is it, what does it do?
First, obviously, you should define a new projectile that moves anywhere but down. Just copy from the bullet object code.
Then it comes the cleverest part. Redefine the Math.random function! Since the boss has to trigger Math.random per cycle (to see if it's smaller than 0.3), we can tamper with the Math.random function to make the function lay down bullets that brings forth their doom.
Finally, make sure the function returns a number. Bigger than 0.3 is recommended for obvious reasons.
Level 21:
Uh oh, the exit is not working. And it's not like we can edit the level code either.
Though, when we bring up the menu there's now a new section call scripts/, which is basically the source code of the game itself. We can edit map.js, objects.js and player.js. Since the exit object must be defined somewhere, we can look at how the exit works (and why it isn't working) if we look at the codes.
The exit is an object, so we'll look at objects.js.
From the place where 'exit' is defined, there's some line that translate into "proceed to next level if current map isn't the final level".
So what should you do? Erase the condition, of course.
Posted by: uncopy2002 | April 12, 2014 11:19 AM