Solomon's Key!
I am surprised to see that there is no existing discussion thread for this game.
It is a
puzzle game where the protagonist, who is an old and clumsy magician, can conjure into existence and dissipate solid bricks.
I have previously created a TAS of it.
498M completes all rooms, including all secrets, excluding the fairy bonus rooms, and thus gets the best ending.
I have long planned to improve it, but progress has been extremely slow.
This is a difficult game to TAS, because the game's
timings are extremely volatile. Really. It seems like the game does not obey any frame granularity whatsoever. The timer ticks at different rates, and frames can be lost without any apparent lag occurring.
Due to changes in my life I am not going to expend personal labor in TASing this game.
Here is a table that collects the timings from my previous run (measured in game timer):
[1] ― or
[2] if Nach has noticed my URL restore request.
Now, I created
a bot once to play levels in this run. However, despite my extensive and best efforts, I have not been able to create a bot that bests the volatileness features of the game's timings.
In fact, Randil managed to create a test that completed the 1st room with 9370 (more) left in the timer, while expending the same number of frames as my bot did.
Here is the
source code of my bot:
http://bisqwit.iki.fi/kala/solomonbot1.cc (Modified to not require coroutines ― this version assumes that FCEUI_FrameAdvance() actually runs a frame and does not just set some flag. Should be easy (hah!) to port to LUA.)
This bot is
not autonomous. It works like this:
1. Operator (you) defines an objective. An objective is Dana's coordinates must reach a certain rectangle, and the maximum number of frames to expend doing the objective.
2. Operator creates a savestate at the beginning of the scene that the bot must play from
3. Operator runs the bot, tells to start from that savestate.
4. Bot runs, and when it reaches the objective, it saves and reports the success, refines the input, saves and reports it again, then tries harder (tighter time limits).
5. When the operator is satisfied, he takes the movie again, replays the input that the bot defined, then goes to step 1.
To help the bot, the operator can add extra conditions occasionally. For example, if Dana's Y coordinate > 0x5C, it might indicate that Dana has fell from the platform and the attempt is failure. Or he might require that Dana must pick the key during this objective.
I am releasing this to the TASvideos community in the hope that it is
useful to someone. If anyone wants to obsolete my TAS,
go ahead. It was created with Famtasia, too!
Techniques involved in this bot:
― Generate random input (attributes: hold L or R for quite some frames, occasionally change, sometimes hit A, possibly while ducking; sometimes jump).
― If the given input accomplishes the goal within the allowed time, yay! Then attempt to refine that input with certain mutation types:
― Mutation method 1: Delete a random frame from the input
― Mutation method 2: Randomly duplicate some frame
― Mutation method 3: Randomly add a new input frame somewhere in between
― Mutation method 4: Swap two random sections of the input sequence
― Mutation method 5: Change some frame into new random input
― If the mutated input accomplishes the goal faster, yay
― If the mutated input accomplishes the goal in the same time, but with better bonus pickups, yay
― If the mutated input accomplishes the goal in the same time, but the input is simpler than the previous find, yay
― If no improvement has been achieved after N mutations, go back to generating new random inputs
Input simplicity is emphasized because the bot is supposed to report its generated inputs to the human operator, and the human is supposed to repeat them by reading them from the text.
RAM map at:
http://bisqwit.iki.fi/jutut/solokey.map
Disassembly of the game (with labels on RAM/ROM address where known). If you know more RAM / ROM addresses, let me know and I'll update the disassembly.