Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Efficiently record user input synced to clock cycle in the emulator and output into JSON #3

Open
goblinoats opened this issue Aug 16, 2023 · 4 comments
Labels
Core Missing functionality core to a working product help wanted Extra attention is needed
Milestone

Comments

@goblinoats
Copy link
Collaborator

This is necessary to run the emulator client-side and to efficiently send back play state to the proving server. If we wanted to send the full trace from the client payload would be something like 36Mb every second.

Is it possible that someone could fake the input synced to clock cycles using a bot or a prerecorded script? Yes. We can think about how to fight this later. There are many ways to counter this or to at least make it palatable in the game theoretic sense. One cool idea, special controllers with tamper proof hardware signing keys ;)

Either way, we're going to need this feature to get to a prototype.

@goblinoats goblinoats added the help wanted Extra attention is needed label Aug 16, 2023
@goblinoats goblinoats added this to the Proof Engine milestone Aug 16, 2023
@goblinoats goblinoats added the Core Missing functionality core to a working product label Aug 16, 2023
@StarkFishinator
Copy link

To reduce the payload, instead of sending the full trace, we can only send the non-zero inputs, along with their clock cycle.
If this is not enough, we can break down the input, and consider each button separately. Then, for each button, we could send the non-zero occurations, along with the clock cycle.

In order to do this, I'm going to see how the actual payload is outputted, and see how to only grab what we need. I will do this by looking the following files in emulator/src : input.rs, bus.rs, trace.rs

@goblinoats
Copy link
Collaborator Author

Nice! I was thinking the same thing. As you've noted we need a space efficient representation for the user input script and the most space efficient representation as far as I can tell is to just record a change in the button state sync'd to clock cycle.

If a player holds down a button on the controller it will send a sequence of 1s into the bus as long as the button is pressed. This is actually redundant for our transcript, because we can recreate that later when we replay. All we need is to know if the button has gone from ON to OFF and vice versa.

Note this issue directly feeds into #4 , so please consider that as well in your design.


Some more thoughts for you...

NES controller has 8 inputs
0 - A
1 - B
2 - Select
3 - Start
4 - Up
5 - Down
6 - Left
7 - Right

We can use each bit in an uint8 to represent the configuration of buttons currently pressed. Then our transcript will register every time a change happens and update the current configuration to denote if the button is on or off. For example:

A,B,Select,Start,Up,Down,Left,Right
1 0. 0. 0. 0. 0. 0. 1

So, the tuple (129, 30203) represents A ON, Right ON, All else OFF at clock cycle 30,203.

This makes replay pretty straightforward too. We just have a big ol queue of inputs at certain cycles and when the emulator hits the cycle A it just pops off the corresponding input A, updates some headless player to mash that A sequence of buttons until the next input B is reached at clock cycle B.

Will wait for your reply after looking at those files to see if this is feasible.

@StarkFishinator
Copy link

Thank you for the additionnal infos !
First, I am trying to replicate your result. I ran the cargo run --release test_roms/cpu/nestest.nes --trace --instr_name INX command mentionned in the trace.md file, and the trace is only 5kb. I tried other .nes files in the test_roms/cpu folder, but I still get similar results. How do you proceed to get your 36Mb file?

@goblinoats
Copy link
Collaborator Author

That 36Mb is an estimate for the number of instructions in the trace for each second of gameplay. That nestest.nes trace is just for sample output. It's for testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core Missing functionality core to a working product help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants