Logging game events to text file
#1
(UPDATE 3/21/2024: I figured all of this out, see here for my solution!)

Hey everyone,

New member here.  Want to first say thank you for all the incredibly detailed documentation on how this game works on the backend.  This site is a fantastic resource for those just getting into coding cheats for this game.

I'm working my way through the tutorial posts, learning how all of this works. I'm not going to take a shortcut and ask for a solution to my specific need, but instead, I want to know whether a specific aspect of my end goal is possible.  In the end, I want to be able to log game events to a text file in real time - specifically, item usage.  The most important parts of my project are logging when a star, thunderbolt, or blooper are used.

So my question is, if I'm able to isolate which parts of memory those events are stored in, is there a way to dump those parts of the memory to a text file?  It doesn't seem that Dolphin Memory Engine has this type of real-time export functionality.  Dolphin's logger can write to a file in real time, but I'm unsure whether I can get the memory to be output into the logger.  Has anyone ever done this before?  If all else fails, I suppose I could use an OCR on an open memory viewer window, but that solution isn't ideal.

For those curious, my project involves a tournament where the lights in the arena change in real time according to item usage  Smile
Reply
#2
(03-02-2024, 09:56 PM)seanmcnally Wrote: Hey everyone,

New member here.  Want to first say thank you for all the incredibly detailed documentation on how this game works on the backend.  This site is a fantastic resource for those just getting into coding cheats for this game.

Welcome to MarioKartWii.com. Thank you for the kind words.

(03-02-2024, 09:56 PM)seanmcnally Wrote: I'm working my way through the tutorial posts, learning how all of this works. I'm not going to take a shortcut and ask for a solution to my specific need, but instead, I want to know whether a specific aspect of my end goal is possible.  In the end, I want to be able to log game events to a text file in real time - specifically, item usage.  The most important parts of my project are logging when a star, thunderbolt, or blooper are used.

Yes that's possible.

(03-02-2024, 09:56 PM)seanmcnally Wrote: So my question is, if I'm able to isolate which parts of memory those events are stored in, is there a way to dump those parts of the memory to a text file?  It doesn't seem that Dolphin Memory Engine has this type of real-time export functionality.  Dolphin's logger can write to a file in real time, but I'm unsure whether I can get the memory to be output into the logger.  Has anyone ever done this before?  If all else fails, I suppose I could use an OCR on an open memory viewer window, but that solution isn't ideal.

For those curious, my project involves a tournament where the lights in the arena change in real time according to item usage  Smile

Yes, you can dump those parts/information to a text file. However, for what you've described in your final sentence, you wouldn't need that information kept in a text file. You can write up a code that keeps that information into an allocated portion of memory, and then another code can read those memory contents and know how to modify the arena lights based on the memory contents (items being used) present.

A primitive way to do this is using the "EVA Method". You will encounter this tutorial sometime shortly after the Assembly Tutorial. If you've haven't yet ran across my Learn PPC Index Thread, here it is - https://mariokartwii.com/showthread.php?tid=1114

You can think of it as the PPC Gecko Coding Bible/Quran. You don't need to complete all the threads. It is overwhelming, Try to get up to the Intermediate Category all completed. You will see the "Using the Exception Vector Area' thread is what I was mentioning about earlier.
Reply
#3
Thanks for your reply!  To clarify what I meant in my last sentence, I'm talking about a physical space in the real world.  I have RGB lights that can be controlled via UDP, and I intend to use Chataigne to read the text file and change the lights when a particular item is used (quick flash on and off a few times for lightning, RGB scroll for star). 

It looks like I actually figured out how to do what I need, by simply adding a breakpoint in Dolphin with the instruction "Write to Log".  Then, under the log tab, check "Write To File", and Chataigne can just read the .log file from there and use its own logic to change my lights.  The only thing left is figuring out where an "item used" breakpoint is...any hints? Wink

(03-04-2024, 01:38 AM)Vega Wrote: for what you've described in your final sentence, you wouldn't need that information kept in a text file. You can write up a code that keeps that information into an allocated portion of memory, and then another code can read those memory contents and know how to modify the arena lights based on the memory contents (items being used) present.

I assume you thought I was talking about a virtual arena? Unless you're suggesting something different, in which case I'm all ears.  Thanks again for your kind response!
Reply
#4
I was assuming arena lights to a few particular courses/stages.

There's a multitude a ways to find an item-used breakpoint. However, there's many codes already on this site that use memory addresses that "hook" to some load/store instruction for when an item is used.

https://mariokartwii.com/showthread.php?tid=1995 Here's one for example.

Unnamed has the source of the code at the bottom. I'll let you figure out what's going on in his code.
Reply
#5
Well, I've gotten this far:

Unnamed is using 8078894C as the instruction breakpoint.  Adding that successfully breaks whenever someone uses an item...

...but that's a problem, since it happens *whenever someone uses an item*, including CPUs.  We're only interested in our four players, and we're only interested in specific items.  I'm guessing this may have more to do with a memory breakpoint than with an instruction breakpoint?
Reply
#6
For codes/addresses that execute per every player/CPU, sometimes a certain non-volatile register (r14 thru r31) will hold the Slot number of the specific player. Human players always get the lower slots (i.e. Player 1 is always slot 0). So for a 4 person multiplayer, slots 0 thru 3 are for the real players. 4 thru 11 for the CPUs.

After that, you can then write some assembly to set up a conditional for the code to never execute for the CPUs.

https://mariokartwii.com/showthread.php?tid=1962

There are other codes on this forum that contain instructions (which you can essentially copy) that can give the slot of the current Player at any time. Stebler's pretty speedometer contains such code.
Reply
#7
Hm, I'm wondering, do I need to write a code to achieve what I'm looking to do?  I'm following your advice, going to read and watch through all the tutorials up to the intermediate level, I'm currently still at beginner.  I'm hoping once I get to intermediate I'll be able to figure it out.  But given that I don't intend to actually affect gameplay in any way, just play a vanilla game while writing events to dolphin's log, is what I'm asking for too complicated to simply have a breakpoint that can watch for each of the events I need?  The breakpoints I need are:

- Any time P1-P4 uses a starman
- Any time anyone (human or CPU) uses a lightning bolt
- Any time anyone (human or CPU) uses a blooper

I have a few other stretch goals but if I can just find those three hypothetical breakpoints I'll be happy.  I'm hoping I don't need to do anything too complicated with reading parts of memory and making my own code to write things to other parts of memory.  I've read though that dynamic memory isn't always in the same spot...so maybe looking for a breakpoint at a specific spot wouldn't work?
Reply
#8
You need a hook address (Breakpoint) that occurs whenever an item is used and a register (r14 thru r31) contains the Slot. Regarding the slot part, if you don't have such a register, that can be coded in "from scratch". Basically there are some functions embedded in the game's memory which you can use (call) to get info (i.e. Slot of Player).

Basically you will write a code that does this..
*If Item used was Bolt or Blooper, then Execute
*Load Slot of Player (not required if this is already contained in a non-volatile register)
*Check Slot of Player (check for numbers 0 thru 3)
*If Slot of Player is 0 thru 3, and Item used is Star, then Execute

The issue that will arise is what will constitute "Execute". I personally don't know how Dolphin's .log files work. Are the .log files able to determine a Conditional Write Breakpoint? Or can the .log files tell what what value is written when a Write Breakpoint occurs?

For example. the term Execute could mean "byte value of 1 written to 0x80001500"
By default code will write byte value of 0 to 0x80001500.

0x80001500 is an address from what is known as the Unused EVA Area. Link - https://mariokartwii.com/showthread.php?tid=1106

If the .log files can differentiate between the two diff byte values being written at that address, then you should be good to go. Have RGB lights do an action for byte 1, and a different action for byte 0.

Of course you can have more options. Like byte 0 = Nothing met. Byte 1 = Bolt. Byte 2 = Blooper. Byte 3 = Star from human Player.
Reply
#9
So, dolphin's logs will look like this.  I set up a memory breakpoint at 80343e80 just as a test to see controller buttons being pressed, I got this (it constantly reads/writes every frame in a controller's case but does not in the case of other breakpoints):

36:22:802 Core\PowerPC\BreakPoints.cpp:381 N[MI]: MBP 80005f50 ( --- ) Write8 0 at 80343e80 ( --- )
36:22:819 Core\PowerPC\BreakPoints.cpp:381 N[MI]: MBP 801af7b0 ( --- ) Read16 80 at 80343e80 ( --- )
36:22:819 Core\PowerPC\BreakPoints.cpp:381 N[MI]: MBP 80005f50 ( --- ) Write8 1 at 80343e80 ( --- )

So if I know a particular breakpoint, I can get what bytes are being written/read. 

The other thing to note is that Chataigne can do all kinds of if/then logic, and store custom variables.  I don't need to do it all within the wii.  Really all dolphin needs to do is dump information, and I can handle the logic on the other end.  So, I have two ideas on how I could do this.

1) Assuming such breakpoints exist, add a memory breakpoint when P1-P4 hits an item block, another breakpoint when the item received is a star, another four breakpoints for when p1-p4 uses an item.  Chataigne can then remember what players have what items, and execute logic based on when a particular player uses an item.

2) A different approach not directly involving item use. When the events we're targeting happen, other things happen as well, like sound effects, model loads, etc.  Perhaps we can find a breakpoint for when the starman music plays, or when the lightning bolt/blooper sound effects play.  Or maybe find the breakpoint for when the karts get smaller due to lightning, or when the ink splashes on the screen, or when the karts change color due to a starman.

Which approach do you think would work best?
Reply
#10
As long as the Breakpoint Address has a non-volatile register that contains the Slot (Unnamed's code address), and as long as Dolphin logs in Register info for Instruction BPs, then you should be able to do all the logic in Chataigne with Option 1.

If Dolphin Instruction BP logs doesn't meet such requirements, you will need to do some ASM coding.

I would first follow the Basic GVR Usage tutorial I've linked earlier to see if any register from r14 thru r31 holds the Slot value.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)