Skip to content

Conversation

@metallicity
Copy link
Contributor

@metallicity metallicity commented Sep 1, 2025

There's a lot of code related to TV broadcasts, and I didn't even cover half of it or look very deep into the exact narc structure. I mostly aimed to keep this as small as possible while still reaching enough understanding along the way to give accurate front-facing names to all the various script sub-commands and constants involved. There are a few things I'm a little shaky on for exactly how program "segments" are represented and retrieved, since I avoided touching that code more than necessary, but I'm fairly confident about all the function/macro/constant names I landed on. Some of the param/variable names around "segments" might have room for improvement.

The basic structure of a player interaction with a generic TV goes like this:

  • Do one of the following based on the current status, reseting on a week-long program schedule for each 15 minute interval:
    • TV_BROADCAST_STATUS_BEGIN (the program has no previously played segments and isn't marked as finished):
      • Show the program's "greeting" message
      • Find the first segment to play, and if it exists:
        • Show the "lead segment intro" message, then the message for the first segment
      • If there is no segment to play (this same check is also made before each subsequent segment):
        • Show the program's "extended farewell" message (often a player call-to-action for more program material)
        • Mark the program as finished (until the time slot rotates)
    • TV_BROADCAST_STATUS_CONTINUE (the program has 1-3 previously played segments and isn't marked as finished):
      • Find the next segment to play, and if it exists:
        • Show the program's "next segment intro" message, then the message for the next segment
    • TV_BROADCAST_STATUS_FINISH (if the program has played the maximum 4 segments and isn't marked as finished):
      • Show the program's shorter "farewell" message
      • Mark the program as finished (until the time slot rotates)
    • TV_BROADCAST_STATUS_FINISHED (the program is marked as finished):
      • Show a random commercial message
    • Any other result would technically also play a commercial, but in practice this unconditional branch is unreachable

@lhearachel
Copy link
Collaborator

lhearachel commented Sep 5, 2025

Copying details provided by @cbt6 in this Discord message. This page lists some segment names and details.

arc/tv/00000.bin

The first (24 * 4) * 7 = 672 = 0x2A0 bytes is a table indicating the program on air at that time slot:

       | Sun | Mon | ... | Sat |
-------+------------------------
7.00pm |_____|_____| ... |_____|
7.15pm |_____|_____| ... |_____|
.      |  .  |  .  | .   |  .  |
.      |  .  |  .  |  .  |  .  |
.      |  .  |  .  |   . |  .  |
6.30pm |_____|_____| ... |_____|
6.45pm |_____|_____| ... |_____|
ID Program
1 Battling Trainers
2 Trainer Research
3 Pokémon Battle Watch
4 A Trainer's Day
5 Sinnoh News Net
6 Rack 'Em Up Records
7 Sinnoh Now
8 Trend Tracker Show
9 Pokémon Variety Hour

The remaining bytes of 00 are unused.

arc/tv/00001.bin

This is an array of length 9 (corresponding to the same program enum in 00000.bin), where each element is of struct { u8 programType; u8 segmentTypes[11]; }. The total file size is thus 9 * (1 + 11) = 108 = 0x6c bytes.

  • programType is one of the TV_PROGRAM_TYPE_\w+ constants.
  • segmentTypes is a list of possible segments for that program. The values are to be parsed differently depending on the program's program type.

Program Types

Any missing number for a given program type is an invalid segment.

Type 1: TV_PROGRAM_TYPE_INTERVIEWS

ID Segment
2 Battle Tower Corner
4 Your Pokémon Corner
6 The Pokétch Watch
7 Contest Hall
9 Right-On Photo Corner
10 Street Corner Personality Checkup
11 Three Cheers for Poffin Corner
13 Amity Square Watch
14 Battle Frontier Frontline News single
15 In-Your-Face Interview qn 1
16 In-Your-Face Interview qn 2
17 In-Your-Face Interview qn 3
18 In-Your-Face Interview qn 4
19 Battle Frontier Frontline News multi

Type 2: TV_PROGRAM_TYPE_TRAINER_SIGHTINGS

WIP

Type 3: TV_PROGRAM_TYPE_RECORDS

WIP

Type 4: TV_PROGRAM_TYPE_SINNOH_NOW

ID Segment
1 Discovering Groups
2 On-the-spot weather
3 Your Town’s Best Three
5 News Flash - Swarm
9 Berry Lookout
12 Pokémon Research Corner
15 News Flash - Roamer
17 Pokémon photo rating

Type 5: TV_PROGRAM_TYPE_VARIETY_HOUR

ID Segment
1 Search for the Red GYARADOS
2 Sinnoh Sports
3 At the Surf's Edge
4 Pokétch Detective Ketch Appy
5 Sinnoh Hot Hit Tunes
6 The Professor Evolves Eight Times
7 We Love the GTS!
8 Diary of a Poké Romantic

@metallicity
Copy link
Contributor Author

metallicity commented Sep 6, 2025

None of this was too surprising, but I wasn't exactly sure what I was expected to do about it. As a proof of concept, I implemented the segments for the "interview" program type, and all of my assumptions about how things worked mostly seemed to play out. Still some missing pieces to how certain data is loaded, but it's a fair bit more clear than before, and again I don't think it's really feasible to document everything in a single PR (either in terms of the logic, or just all the different segment types).

@cbt6
Copy link
Collaborator

cbt6 commented Sep 9, 2025

I don't have time to list out each occurrence, but here's the main gist:

  • script command function names are to be prefixed with a verb (this applies to sub-commands in e.g. ScrCmd_235 too)
  • try as much as possible to name keep naming consistent (e.g. ScrCmd_CheckTVInterview and TVInterview_IsEligible)
  • prefix const data with s for static data or g for global data accordingly
  • avoid using macros where text message IDs are involved as it makes it harder to grep for, just list them out in full

@metallicity
Copy link
Contributor Author

@cbt6 I made all the fixes you requested here, though the "keep naming consistent" point could still have some remaining issues somewhere, given its the hardest to identify.

Copy link
Collaborator

@lhearachel lhearachel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for how long it took me to get back to this one. I have some polish-comments below and a couple of suggestions / opportunities for more discussion. Thanks for your patience. 🙏

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Is it safe to rename this translation unit to, e.g., scrcmd_tv_broadcast at this time? The remaining scripting commands in the file also appear to be related to TV broadcasts.

I am personally fine with waiting for those other commands to be documented; I'll leave the decision to you. 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done so for scrcmd_tv_broadcast, and also renamed unk_0206CCB0 to tv_episode_segment, since both are documented enough that their purpose seems clear.

Comment on lines 237 to 240
typedef struct TVBroadcastSegmentData_BattleTowerCorner {
UnkStruct_0202E7FC outcome;
u16 customMessageWord;
} TVBroadcastSegmentData_BattleTowerCorner;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Does the Data portion of these specialized-structs for each segment convey anything meaningful? I'm leading towards no, but I'm curious what you think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unwound into a more general problem of "segment" both meaning "a particular kind of segment" and "a particular instance of the former" (with this struct encoding the specific data needed to populate the templated messages for the latter). In the end, I landed on "program segment" to describe the generic version and "episode segment" to describe the specific version. A particular program will have some regular recurring "segment", and then a specific episode of that program will have the actual "segment" that is recorded and played. If there was any clear pair of alternatives to "segment" which would do away with the need for these specifiers, I couldn't come up with any.

Brief summary of changes:

  • TVBroadcastSegment -> TVProgramSegment
  • TVBroadcastSegmentData -> TVEpisodeSegment
  • segmentTypes -> programSegmentIDs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants