Baekalfen/PyBoy

Force clock value

debnet opened this issue · 8 comments

Correct me if I'm wrong, but I believe PyBoy supports internal clock with MBC3 cardriges.

Is it possible to force and freeze clock value in a simple way for testing purposes?

I read something about editing memory at specific offsets but alas with no success.
https://gbdev.io/pandocs/MBC3.html#the-clock-counter-registers

Thanks!

There is no way of doing that atm.

What do you want to use it for? Maybe we should add it.

If you follow the documentation you sent, you can change the Real Time Clock (RTC). But you'll have to repeatedly set it

Edit: Ok, maybe not

There is no way of doing that atm.

What do you want to use it for? Maybe we should add it.

I'm using PyBoy with my students in reinforcement learning course, and we are using Pokemon Gold/Crystal.
We need to have the clock to be the same for all students whenever they decide to run their model on the game because some events ingame are tied to the ingame clock.

I've introduced a PR which should help. When the students start a game for the first time, they'll tell the game what they want their time to be (i.e. Sunday, 3:25PM). This is in reference to the internal counter in the emulation. What I've added, is the option to always have the internal counter be 0 on all values. This should keep the in-game time from changing.

I also found some other RTC bugs, and I'm surprised it even worked before.

Could be glorious to have it editable during runtime. Is it possible? Thank you!

Could be glorious to have it editable during runtime. Is it possible? Thank you!

It's not something I can consistently control from the emulator across games.

I'd say you have some options:

  1. Hack the registers like this:
    # Reset seconds
    pyboy.memory[0x4000] = 0x08
    pyboy.memory[0xA000] = 0
    # Reset minutes
    pyboy.memory[0x4000] = 0x09
    pyboy.memory[0xA000] = 0
    # Reset hours
    pyboy.memory[0x4000] = 0x0a
    pyboy.memory[0xA000] = 0
    # Reset days (low)
    pyboy.memory[0x4000] = 0x0b
    pyboy.memory[0xA000] = 0
    # Reset days (high)
    pyboy.memory[0x4000] = 0x0c
    pyboy.memory[0xA000] = 0
  2. Make a routine in the game menus to change the time (is there a setting in the menu?)
  3. ROM hacking, overriding the function and return the desired time
    # http://149.154.154.153/wiki/Tetris_(Game_Boy):ROM_map
    # Replacing:
    # ROM0:206E FA 13 C2 ld a,(C213) ;load next Tetromino in accumulator
    # ROM0:20B0 F0 AE ld a,(ff00+AE)
    patch1 = [
    0x3E, # LD A, Tetromino
    shape_number, # Tetromino
    0x00, # NOOP
    ]
    for i, byte in enumerate(patch1):
    self.pyboy.memory[0, 0x206E + i] = byte
    patch2 = [
    0x3E, # LD A, Tetromino
    shape_number, # Tetromino
    ]
    for i, byte in enumerate(patch2):
    self.pyboy.memory[0, 0x20B0 + i] = byte

    https://github.com/pret/pokegold/blob/0d3575ce8e47bd1c70336bff8261257abf92b1dc/engine/rtc/rtc.asm

Could be glorious to have it editable during runtime. Is it possible? Thank you!

This:

they'll tell the game what they want their time to be

Is the game asking, not PyBoy

I'm using PyBoy with my students in reinforcement learning course

Would you be able to share your course material with me? We can do it privately, I just wanted to try experimenting with RL myself.