Skip to content

An AI written in Lua for FCEUX that plays Yoshi for the NES.

Notifications You must be signed in to change notification settings

cjbell630/Yoshi-NES-AI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This is a Lua AI that plays Yoshi for the NES! It is meant to run on FCEUX, but it could possibly work on other emulators.

Click below to watch a demo!

Alt text

USAGE

Requirements:

To use:

  1. Load the game with FCEUX.
  2. Click File -> Lua -> New Lua Script Window
  3. Click Browse and find and open yoshi-nes-ai.lua
  4. Enter arguments (optional - see below)
  5. Click Run
  6. Click Restart at anytime to restart from the beginning.

Arguments (positional only):

[num_players]    [options]
      1          [gamemode]     [level]        [speed]         [music]         [randomization]
      2          [level (user)] [speed (user)] [level (ai)]    [speed (ai)]    [randomization]
  • num_players - 1 or 2
    • 1: watch the ai be cool
    • 2: play against the ai
      • the gameplay is kinda choppy cause the ai technically cheats and allows itself more than 1/60th of a second to make decisions. I plan to fix this sometime.
  • gamemode - A or B
  • level - 1, 2, 3, 4, or 5
  • speed - low or high
  • music - 1, 2, 3, or off
  • randomization - on or off
    • because of the nature of NES games, the game will yield the EXACT same sequence for a given AI build and settings, no matter what. This is because the AI will always make the same inputs, and the randomness of NES games is dependent on user input. So in order to be able to have a unique game each time, if randomization is set to on, the script will perform tiny pauses on the menu screen according to RNG based on the system clock of the user's computer.

Example arguments:

1 A 4 low off
1 B 1 high 2 on
2
2 1 low 5 high on

ABOUT SOURCE CODE

tl;dr:

I used two tools to merge and reduce the source Lua files into a single compact file for ease of use. That file is not intended to be read by humans, and in fact, I haven't ever really read it myself. So if you would like to read the code and see what's going on, check out the files in src.

If you're wondering about the terrible-looking code in build/yoshi-nes-ai.lua (the release file), or the weird build scripts, or the fact that I even HAVE a build script to begin with, then here's the explanation:

  • This was originally a single, massive, unreadable script. Later on, I thought that was stupid, so I broke it up into multiple files for readability and general conviencience for myself.
  • It wasn't until later that I realized this would be very inconvenient for people who just want to download the script and see it work. So I spent a while searching, and finally found lua-amalg, a [working!] tool that merges multiple Lua files into one. Thanks a whole lot to everyone who worked on that!
  • Then, I read about luasrcdiet, another really useful program that removes whitespace, among MANY other things, to massively reduce the size of a Lua file. Aside from just general curiosity, I figured this would be a positive thing for the end user, as anyone wanting the read the code would be much better off reading the separate files anyway.
  • Finally, I got a bit too curious and used lua-amalg on all the luasrcdiet files, and then used luasrcdiet on itself (or rather, a copy of itself), and was left with two nicely packaged build tools that I then put in build/scripts, along with the shell script I use to run them.

All that goes to say this: there's no need to build if you just want to mess around with the code. FCEUX, which this script was designed for use with, supports multiple Lua files through calling the main script. The only time you'd really need to build is if you edited the source code and submitted a pull request, in which case I'd see it first anyway. So yeah.

CHANGELOG

  • 1.0.0
    • Remade placement algorithm from scratch.
    • Added quick swapping (matching 1 block, swapping, then matching the block underneath it)
    • Does what I want it to, but lots of movements are unnecessary and awkward. Plus, there are a lot more improvements that can be added (see TODO below)
    • Added multiplayer mode (vs. ai)
  • 0.0.1 (First GitHub commit)
  • Original Build (February 2020)

TODO

  • Make desicions based on previous decisions more often - i.e. if a move is decided, base the next move off of the state of the board after that block has landed
    • will allow for quick swaps (where a block is matched, and then another block is placed where the previous block was matched)
      • conditions for this:
        • a matchable block with another matchable block below it (not matchable to the first one obv)
        • a column 1 or more blocks shorter than the first column for the second block to temporarily target before doing the actual swap
    • will also allow for more strategic placement of blocks which cannot be matched
  • Make the bot automatically continue to the next round in B mode
    • consider doing so through memory manipulation to skip the extremely long cutscene
  • apparently does not check for matching tops and heights properly - I watched it swap two columns topped with goombas that were the same height
    • FOUND ISSUE: see code that says something like "TODO should this check for complete equivelance or check if they're the same height and top?" (in ai.lua around line 34)
  • for situations where two of the same block type are falling, choose the fastest set of moves to match them, so rather than make 5 moves to get something underneath the first falling block, make 1 move to get it under the last.
  • integrate block placement with move generation so that wildcards can be chosen based on number of moves rather than randomness or numerical order
  • add the ability for the ai to change its mind on placements once it sees the next set of falling blocks
  • add a countdown timer for multiplayer mode
  • force it to run at 60fps

TIMES

All times for B mode on high speed.

build Lv. 1 Lv. 2 Lv. 3 Lv. 4 Lv. 5 Lv. 6
Feb 25 2020 3:23
0.0.1 3:00, 1:19, 1:08, 1:08 1:26, 2:51, 1:30 1:15, 3:35, 0:37 4:18, 3:26, 4:33 1:56, 2:04, 3:05 1:09, LOST, 3:53
0.0.1 Average (not counting losses) 1:38.75 1:55.66 1:49 4:05.66 2:21.66 2:31
1.0.0
1.0.0 Average (not counting losses)

LEGAL

  • I own a copy of Yoshi for the NES.
  • I do NOT distribute ROMs or emulators. You will have to find/rip those yourself. Do not ask me for either of them.
  • I hold absolutely NONE of the rights to any of the properties associated with Yoshi for the NES. Those belong to Nintendo and any other respective groups.
  • This project is purely meant as an add-on to the original game. It is not intended to infringe upon any copyrights whatsoever. If you find that it has done so, please contact me and I will fix it.