4 ms·
How did you (or how does one) discover that the game state consists of the variables enemy.{x,vx,eyeVx}, player.{x,vx}, powerTicks? (And are there others?)
by svat 3y ago
How did you (or how does one) discover that the game state consists of the variables enemy.{x,vx,eyeVx}, player.{x,vx}, powerTicks? (And are there others?)
- lifthrasiir 3y agoThe source code for the page doesn't have any reference to a game-specific source code, so it must have been loaded dynamically and can be found from devtools [1]. You can then read the actual code and find that every state is in the global scope, so they are directly accessible without any trick. It hasn't been minimized so all variable names make sense and you can even guess their purposes without actually checking. [1] https://abagames.github.io/crisp-game-lib-11-games/pakupaku/main.js https://abagames.github.io/crisp-game-lib-11-games/pakupaku/...
- mrb 3y agoI reverse-engineered it. This whole exercise took me about 30 minutes while half coding and half watching a TV show. Since the JS code was neither minified nor obfuscated, it was easy. Here are my exact steps: In Chrome, right-click on the page -> View Source. Go to the "Sources" tab. When you open the tree on the left you find a file, that was dynamically loaded (so you wouldn't have found it by just looking at the HTML source of the main page), https://abagames.github.io/crisp-game-lib-11-games/pakupaku/main.js https://abagames.github.io/crisp-game-lib-11-games/pakupaku/... that seems to contain the game's code. And indeed it's less than 200 lines and implements the core game logic. There is a main function, update(), containing a conditional "if (!ticks)" that seems to do initialization. "ticks" is probably zero at the start of the game. The code initializes multiple variables, including "player" and "enemy": if (!ticks) { player = { x: 40, vx: 1 }; enemy = { x: 100, eyeVx: 0 }; multiplier = 0; addDots(); powerTicks = animTicks = 0; } Then with a bunch of console.log() statements added to the update() function (just edit the code and type Ctrl-S to save it, Chrome allows this sort of in-place code editing), I got a sense that player.x and enemy.x was the x position, with the scale going from 0 (left edge) to 100 (right edge). Then with more console.log() statements I found enemy.eyeVx was normally 0 when the enemy is a ghost or 1 or -1 if the ghost has been eaten and its eyes are flying respectively right or left. Some of the code is less readable, for example: if (enemy.eyeVx === 0 && (c.a || c.b || c.c)) { if (powerTicks > 0) { play("powerUp"); addScore(10 * multiplier, enemy.x, 30); enemy.eyeVx = player.x > 50 ? -1 : 1; powerTicks = 0; multiplier++; } else { play("explosion"); end(); } } I figured by literally typing "play(...)" in the dev console that these functions play a sound. Therefore based on the sound names "powerUp" and "explosion" I realized this code block is called when pac-man collides with a ghost. And either it has a power-up ("powerTicks > 0") or not, in which case it dies. At this point I had the meaning of "player", "enemy" and "powerTicks" and that's all I needed to write the bot.