Hi,
I am currently thinking about solving a specific NES-game not by myself, but by using the A*-algorithm.
But in order to do this, I need an emulator that I can control via some kind of API:
- Bring the NES to a specific memory-state
- Specify the buttons pressed
- Advance a frame
- Get the new memory-state
Does something like this exist?
No, I don't want to use LUA :)
Thank you
Andreas
Emulator Coder, Site Developer, Site Owner, Expert player
(3576)
Joined: 11/3/2004
Posts: 4754
Location: Tennessee
You don't want to use lua, yet our lua-implemented emulators do exactly what you described, and do it easily (in fact, that was the main functionality that motivated lua integration to begin with).
So you are asking for someone to re-implement what's already built due to your resistance to a particular language?
I was hoping that something like this does already exist. Especially FCEUX has so many extensions that I thought that there must be some kind internal of API that might also be exposed for external usage.
About the language of choice:
It's always easier to do something in the language you know instead of learning a new one with new ways to get things done:
- Is there a nice IDE for lua?
- What about debugging the scripts?
- How do I get access to a database?
- What about structuring the code into modules?
A language with a nice IDE and Debugger :-)
Like C# or Java. So for Windows, some dll would suffice. I don't need the gui. Just a dll where I can load a rom, set the machine's state, the controller-input and read the RAM to check the input's results.
In another forum, someone is basically controlling the GUI of FCEUX using C#. But IMO this can neither be fast nor reliable.
I suggest reading a book or something about Lua. It's very extensible. It has Object-Oriented features.
Also check out a site like Luaforge. You can import any Lua module you want into your emulator and Lua script. There's a gui function for generating screen shots (may vary by emulator) which is easily handled using the `gd` library.
As for a debugger, I have no idea. All my code just works the first time. I think it's Mountain Dew.
I do sincerely doubt that LUA is by far the easiest way to do that.
Having the emulator-functions (http://www.fceux.com/web/help/fceux.html?LuaScripting.html) in a dll would be the easiest for me and I would already have written an adapter and be in the "fun-zone" by now :-)
Without this, I am reading and trying around how to solve the issues that stand in my way:
- how to integrate some SQL-module
- how to serialize an object
- finding a way to hash an object for faster comparison
All these are issues that I would not have in my preferred language and more will probably come up very soon.
While trying so solve these issues, I am finding myself tempted to just crawl through the sources of FCEUX and find the necessary hooks myself. But this is not the easiest thing to do either...
All I wanted to do is to try a simple A*-search, which might work very well for a bunch of games. A proof of concept (for the first few seconds of the game) would take only about a day for me in C#. After having read several hours about Lua, I am not even sure, the stuff I want to do is possible at all. Actually doing it, will probably take much more than a week.
I suspect you'd have more luck figuring out how to write the necessary inter-language glue code needed to control Lua from your language of choice.
Bottom line is, though, that FCEU/FCEUX were never approached as "the emulator is a library", but rather as "the emulator is a program". In the latter situation it makes far more sense, from an ease-of-development (of the emulator) sense, to embed a scripting language than it does to convert the entire emulator into a library. Certainly the latter approach makes future hypothetical developers' lives easier, but it's harder to implement in the here-and-now.
So I'm sympathetic to your problem, but I can't bring myself to say that FCEUX is doing anything wrong.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
This sounds like an interesting approach, I did not think about yet.
Using sockets might actually do the trick (but wouldn't be fast).
Perhaps the WinAPI-Library contains something useable as well.
Have you done something like that before?
About the design:
"wrong" is a hard word and I would never say that about FCEUX. I do know how tough it often is to maintain an old codebase. A modern design would probably be to build the emulator-library first and the frontend on top of it. But since I do not know the internals, I don't want to judge anything. I was just hoping that this kind of API does exist somewhere :-)
Whole emulated system memory or whole host process memory?
The first isn't the complete state (there are e.g. CPU registers), and the second contains all sorts of irrelevant stuff (that likely differs even if states are identical).
I've written C <-> Python glue code using SWIG in the past; it's a bit clunky (and SWIG takes some getting used to) but it does work. Lua itself is designed to be easily embedded in other programs (which is why it's the scripting language of choice for many, many games), though I don't know if that means you can simultaneously embed a single Lua instance in two separate programs.
Sockets might well be your most straightforward option, since it seems like you're going to have to have some inter-process communication. You might want to look up ways to do remote procedure calls (RPCs) in Lua; there's at least one library that can do it. That would save you from having to manually interact with sockets, as well as from having to devise your own protocol. The basic concept for RPCs is that you have a server that exposes a set of functions, and a client that connects to the server and learns about those functions; the client then can "call" the functions as if they were local objects, with the RPC library automatically handling the transfer of arguments and return values to/from the network.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Joined: 4/17/2010
Posts: 11495
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
Ilari wrote:
AndiHoffi wrote:
Is there a way to get a whole memory-dump in lua? I did not find anything like it in the doc. Without the memory-dump, I can stop the whole thing immediately, since there would be no way to detect equal states (that have been reached on two different ways).
Whole emulated system memory or whole host process memory?
The first isn't the complete state (there are e.g. CPU registers), and the second contains all sorts of irrelevant stuff (that likely differs even if states are identical).
Wouldn't one only need critical addresses values?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Is there a way to get a whole memory-dump in lua? I did not find anything like it in the doc. Without the memory-dump, I can stop the whole thing immediately, since there would be no way to detect equal states (that have been reached on two different ways).
Whole emulated system memory or whole host process memory?
The first isn't the complete state (there are e.g. CPU registers), and the second contains all sorts of irrelevant stuff (that likely differs even if states are identical).
Wouldn't one only need critical addresses values?
First of all: I think, I found the method minutes after posting. That's why I removed the question hoping nobody saw it yet :-)
About the critical addresses:
In order to rate a state, I do only need a few critical addresses. But in order implement an efficient search, I need to detect duplicate states.
E.g. in most jump'n'run-games it does not matter if you keep the jump-button pressed or not, while you are falling down. So I do need the whole machine-state in order to check if the same state was reached in two different ways. This consists at least out of the following things: frame-counts, full memory-dump, registers, buttons pressed. Perhaps the memory-dump can (and should) be filtered some more if the game saves some really unimportant stuff there (like a statistical buttons-pressed-count...). I did not check this yet, since I am still in the middle working on a proper communication with Lua.
Joined: 4/17/2010
Posts: 11495
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
If a game has some complex RNG (Konami games), comparing ram dumps won't do the trick. Basic game state might be the same, but some addresses (of different relevance) might change. But anyway, you can save a state and hash it, or a part of it (where ram is saved), and compare the whole state. And yes, there are lua hashing functions :)
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
First, I'm very pleased to see such topic, since I stumbled myself with so many overhead while trying to hack/experiment a way to get PSX encoding done with better sound. Sadly this little project, need yet an another real redesign for making it work better with the OO way(possibly with the help of the Koneki IDE instead of using my average text editor[Sublime Text2] and adding proper Luadoc that somehow enable extra autocomplete feature, but hey I guess it's not important here and nobody care), so I can push the process even further with better handling of more complex case such as disc switch, get better overall maintenance, etc.
Thought even if you manage to get Lua OO right, you are still bound to get some more headache for trying to figure advanced some advanced stuff like making a third-party library for multithreading to work with Lua. Particularly if you intend to give some work to your CPU and these queue these item. Personally I just feel like coding such thing in Lua isn't fun and usualy there aren't any kind framework to help for such issue. Thought, maybe it isn't that bad when know exactly what you're doing, while you keep relaying on other people library and you got a good grasp of the best OO pattern for Lua.
But yeah, enough with my issue and back to the subject. Does a reasonable passerelle between Lua and your favorite code language exist?
Derakon wrote:
Sockets might well be your most straightforward option, since it seems like you're going to have to have some inter-process communication. You might want to look up ways to do remote procedure calls (RPCs) in Lua; there's at least one library that can do it. That would save you from having to manually interact with sockets, as well as from having to devise your own protocol.
Even if this is bit slow on the long run and you might have to write a parser in both Lua and your favorite language. That really sound like the easiest way to go.
There's also the Windows named pipe that might work with the lua module winapi, but I doubt it's any faster either.
That said, a more radical solution would be to directly add an extra API next to Lua implemention for your favorite emulator. Then this API would probably support one of the fastest IPC implementation(credit to Nach for pointing this out to me, some month ago), but I guess that using socket or RPCs would still be the way to go and in such case, you wouldn't save much performance from handling communication with Lua.
feos wrote:
And yes, there are lua hashing functions :)
Yes, you can easily hash any string in Lua without problem. But I'm kinda unsure about the actual performance for grabbing the whole memory state from? I mean can you simply use memory.readbyterange(0x0, [max_length_memory]) and get the string quick enough and hash it? That would probably need some test, but if it work I guess it's all fine!