Editing
Talk:Topic
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Reverse engineering == I'm looking into precisely how infos are randomized. Findings so far: * If a Topic Info's "Hours Until Reset" cooldown is active, then the selection algorithm acts as though that Topic Info doesn't even exist. This means that flags like "Random End" won't influence randomization. * Ditto for if the info is a deleted record, or if it's flagged as "Say Once" but doesn't belong to the Player Dialogue tab. Using Lua as pseudocode: <pre lang="lua"> function topic:pick_info( result, -- C++ bool&; Lua can't do that so let's imagine it's a table like { _value = ... } subject, -- ref target, -- ref arg4, -- bool arg5, -- optional topic arg6 -- optional unknown struct (intrusive linked list; possibly related to ExtraSayToTopicInfo) ) result._value = false if self:is_deleted() then return nil end local infos_done_before_repeating = {} local final_candidate_topic_infos = {} local random_ended = false local last_seen_candidate = nil if self.owning_quest and (self.owning_quest.quest_flags & 1) -- started and !(self.owning_quest.quest_flags & (1 << 7)) -- Stage Wait and !self.owning_quest.promote_task then if self.owning_quest.dialogue_conditions:IsTrue(subject, target, self.owning_quest) then for _, info in ipairs(self.infos) do local esp13 = { _value = false } -- in C++, another raw bool that gets passed by reference if info and (not info:is_in_cooldown()) then if info:check_conditions(esp13, subject, target) then if info.is_random_end then random_ended = true end if arg4 or (arg5 and TOPIC_SUBTYPE_DEFINITIONS[arg5.subtype].unk04 == 0) then while arg6 then if not arg6.next and not arg6.data then break end if arg6.data.unk0C == info then goto after_gather_for_randomization end if arg6.data.unk14 ~= self.owning_quest then goto continue end if arg6.data.unk10 == self then goto after_gather_for_randomization end ::continue:: arg6 = arg6.next end end if not info.is_random then if #final_candidate_topic_infos == 0 then return info end break end if this.do_all_before_repeating and info.info_flag_15 then infos_done_before_repeating[#infos_done_before_repeating + 1] = info else final_candidate_topic_infos[#final_candidate_topic_infos + 1] = info end end end ::after_gather_for_randomization:: if (not arg4) and esp13._value then -- -- Boolean `esp13` is false if the info is deleted, a misplaced "Say Once" info, etc.. -- I'm not sure what happens to this boolean otherwise, i.e. if the info is able to -- try its conditions but then the conditions don't match. -- result._value = true last_seen_candidate = info end if random_ended then break end end end end if self.do_all_before_repeating and #final_candidate_topic_infos == 0 then for _, info in ipairs(infos_done_before_repeating) do info.info_flag_15 = false -- sentinel bit 0x8000 in the info flags mask end final_candidate_topic_infos = infos_done_before_repeating end if #final_candidate_topic_infos > 0 then if #final_candidate_topic_infos == 1 then return final_candidate_topic_infos[0] end -- Pick a random candidate: return final_candidate_topic_infos[math.random(#final_candidate_topic_infos)] end if arg4 then return nil end return last_seen_candidate end </pre> [[User:DavidJCobb|DavidJCobb]] ([[User talk:DavidJCobb|talk]]) 01:29, 8 April 2026 (EDT) :In particular, static analysis suggests that if a Topic Info's conditions don't test as true, then the presence of the "Random End" flag or the absence of the "Random" flag on that info don't affect anything. For example, given the following infos: :{| class="wikitable" |+ Caption text |- ! Conditions met !! Flags !! Text |- | Yes || Random || This is Line A |- | Yes || Random || This is Line B |- | No || Random, Random End || This is Line C |- | Yes || Random || This is Line D |- | No || || This is Line E |- | Yes || Random, Random End || This is Line F |} :Manual examination of the compiled code suggests that it would be possible for an NPC to say any of A, B, D, and F; the intervening Random-End and non-random lines fail to break the topic into separately randomized groups because those lines' conditions aren't met and their flags therefore do not influence the random selection. This is very counterintuitive, particularly given how infos are documented to work on the main page, but it aligns with the behavior I've been seeing while working on a mod with lots of infos and very complex info conditions. [[User:DavidJCobb|DavidJCobb]] ([[User talk:DavidJCobb|talk]]) 01:52, 8 April 2026 (EDT) ::Just to really drive the point home, here's a screenshot of that table with some scribbling on it to more clearly denote the randomized line groups you would expect versus those that the game actually uses [per my reverse engineering and what behaviors I'm seeing in-game] given the condition results per line: ::[[File:Topic Random End jank example for talk page.png]] ::As for how this behavior arose? You'd only run into problems with this if you have a topic consisting solely of groups of randomized lines, wherein some groups have overlapping conditions, not all lines within a group have the exact same conditions, and multiple groups have their Random End lines fail to match conditions. The case that led ''me'' to run into this was a topic that checks an NPC's location and reports it to the player, with variable wording based on the NPC's gender. The topic contained one group of randomized lines per location, but lines within a group were interleaved by gender (i.e. male/female/male/female), such that the "Random End" flag was placed on female lines, and therefore asking about a male NPC could cause you to hear lines from multiple groups (including the "I don't know where he is" group). It's quite conceivable that the behavior I'm documenting here -- the flags being ignored -- is literally just a bug that Bethesda never ran into due to how specific things have to get for this to actually cause problems. ::[[User:DavidJCobb|DavidJCobb]] ([[User talk:DavidJCobb|talk]]) 02:27, 8 April 2026 (EDT)
Summary:
Please note that all contributions to the CreationKit Wiki are considered to be released under the Creative Commons Attribution-ShareAlike (see
CreationKit:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
Namespaces
Page
Discussion
English
Views
Read
Edit source
Add topic
View history
More
Search
Navigation
Landing page
Tutorials
Game Systems
Editor Reference
Scripting Reference
Recent changes
Help
Tools
What links here
Related changes
Special pages
Page information
Page values