S3maphore Changelog
Latest:
7fde8f48 - CLEANUP: Punt the playlist editor down the road so we can get this fucker out the doorf620da78 - FIX: Add <--more--> tags to sites
34a2d820 - PERF: More JIT-friendly scripts/omw/music/actor.lua
81569240 - FIX: Recalculate page count when rebuilding the playlist editor to prevent ending up on invalid pages
e3a6882f - FIX: Correct sizing logic for playlist selection
7cb94d96 - FIX: Align left panel playlist page size with rendered height; flatten layout
157b4b35 - FIX: Improve playlist text sizing
8e55961f - FIX: Correct left panel sizing/overdraw, localize math functions
6fe833cc - FEAT: Responsive playlist editor via displayTier module + onViewportResized
ff5bd45b - CLEANUP: Don't need explicit nil returns!
75308b4e - TWEAK: Category tab hover via mouseMove (focusLoss for clear); click darkens via mousePress/mouseRelease split; selected tab always full-bright
16e4244a - REFACTOR: Split playlist editor left panel into standalone leftPanel module; promote left subtree from Layout to Element; also I forgot the event names for mouse events in UI
7561051a - CLEANUP: Run stylua across s3maphore Lua sources
2304e86d - FIX: Playlist editor gated on PlaylistLoader completion; left panel updates in place via name-chain
c514cb08 - REFACTOR: Build playlist editor once at load, hidden; show/hide toggle visibility
702815b5 - FIX: Playlist editor fails to load; header/track text centering
9d97e947 - FEAT: Single black background at menu transparency; keep left-panel inset, drop debug fills
40998de0 - FIX: Use MWUI constants for left-panel text colors with darkened inactive states
29421f0f - FEAT: Scale left-panel inset with vertical resolution (tighter on small, roomy on 4K)
e2cecb1c - FIX: Derive playlist editor page size from screen height instead of hardcoded 8
ccbfe2a9 - CLEANUP: Remove redundant manual pause/unpause for playlist editor
6aed3525 - FEAT: Close playlist editor on engine Interface-mode exit via UiModeChanged
bfc69df1 - FEAT: Rename playlisteditor -> playlistEditor to match camelCase require
78723f6f - FEAT: Open playlist editor as Interface mode with no vanilla windows
02567df0 - FEAT: Move playlist editor window to the Windows layer
a457f0b7 - FEAT: Wrap playlist editor input handlers in async:callback
baebfe5c - FEAT: Add category tabs and pagination to playlist editor
58c115d3 - CLEANUP: Meh I like fixed sizes better (for now)
e5f9501c - FEAT: Actually display the list of active playlists
32820293 - FEAT: Inset the playlist list box a bit
c52457c2 - FEAT: Add borders between main window elements
11536296 - CLEANUP: Use actual variable names
18891196 - FEAT: Add double borders on the outside of the window
b8cc3ca7 - CLEANUP: Migrate PlaylistEditor into a dedicated subdir because this is gonna get messy
4133d4ca - FEAT: Initial revision of the playlist editor window
12e22913 - FIX: Don't update PlaylistState when the world is paused
afa47f6b - FEAT: Track currently selected spell school + fighting stance in PlaylistState, also refactor requires in core.lua
e5eb6fe8 - FIX: I.S3maphore.state needs __pairs for view() to work on it
3ed870d9 - FEAT: Properly check fallback playlists for their activity state, AND take fallbacks of fallbacks into consideration for track selection with a max recursion depth of ten
e11fe21e - FEAT: Add isInCombat, getCombatTargets to I.S3maphore, improve annotations (again)
3adf738e - CLEANUP: Format playlistrules
80b31628 - CLEANUP: Minor privatization refactor for PlaylistRules to isolate cache-related functions from the PlaylistRules public API
b7a7d8d7 - CLEANUP: Remove a couple fields from PlaylistRules and localize them instead
2a5760cc - CLEANUP: Run stylua on the whole mod
b5d62ec8 - CLEANUP: Run formatter on util.lua
d680472c - FIX: Never try to set the metatable on ones that are already read-only
51afbac0 - CLEANUP: Major overhaul of S3maphore's interface including exporting PlaylistRules, PlaylistState, public combat target checking, and Cod3x-compatible completions
a818e5e3 - FIX: Make musicmanager throw angrily if a playlist override attempts to change priority buckets
d40f379c - CLEANUP: Refactor core.lua to use H3lp Yours3lf's state machine module
e6d04282 - CLEANUP: Switch from storing raw dynamic stats in PlaylistState to ONLY storing the normalized values
13eb9a80 - CLEANUP: Reove staticStrings entirely and remove further string metamethod lookups
ae827271 - CLEANUP: Migrate combat target polling into combatState.lua
51bcbf48 - CLEANUP: Migrate a bunch of stuff out of core.lua and into playlistState.lua and trackSelection.lua
5c697a17 - FEAT: Dehardcode the shit out of death track assignments
382df1e0 - CLEANUP: Flatten CellPresence fields back into PlaylistState for simplicity
6c3df577 - FEAT: Dehardcode killcounts in s3maphore and track them with global storage
3649154c - FIX: CellPresence elements are userdata and can't be iterated with next, t style loops
62bb33e9 - CLEANUP: Reformat/rearrange musicManager functions and switch queuedEvent.name sentinel from nil to empty string
3a554e62 - CLEANUP: Minor style nit
b4d91977 - FIX: Correct timing bug in silenceManager now that it's NOT called every frame, switch to randomGen, hoist locals
2de11be3 - CLEANUP: Allocate TargetChangeData in the SendEvent call instead of in the script body
95f2adba - CLEANUP: Remove lazy combatState construction, add waitingOnPresence guard, inline onSoundEnabledChanged
7ed0cf52 - FEAT: Replace isUnderwater with movementMode, add state change flags, restore handler chain round-robin
a0ee0eab - CLEANUP: Merge S3maphoreInitializationComplete into first call to S3maphoreUpdateCellPresence to simplify event-chaining and remove one more hardcoded SP semantic + minor allocation optimization
ee8f5175 - FIX: Correct throw in :subscribe handler as these can't be iterated with `next` loops
154208db - FEAT: Add combatTargetTagged and weatherType rule
132fef34 - FIX: weather is actually just a string now
65b5f69b - CLEANUP: Actually remove contentFileCount because it already exists on playlistState and we can minimize function calls this way
49038ccb - FEAT: Add total object count to PlaylistState
974619e5 - FEAT: Add contentFileCount rule to detect the number of objects placed by a specific mod
b1779b8e - FEAT: Add typeCount rule for checking bounded ranges of object counts. EG a rule could check if there are more than ten creatures or containers in a cell
6f70ab13 - CLEANUP: Remove redundant check in static collection
864a399a - FEAT: Add contentTag rule to support playlists based on tagging specific mods
186e469d - CLEANUP: Deploy caching helper across all rules, sort requires, examples for tagger rules
07df2d73 - CLEANUP: Add a caching helper to minimize cell caching boilerplate in playlistrules
7b950c8d - FEAT: Add cellHasTag playlist rule
d1378c76 - CLEANUP: Remove unused variable in actor.lua
e394eeed - FIX: Replace deepToString with a version that isn't completely terrible
ae4eb7b2 - CLEANUP: Minor optimization to debug logging so we don't call :get every time
c3e70aa5 - PERF: hoist gameSelf.id in combatState hot loop
a4c9c3ed - REFACTOR: gate debugLog format behind DebugEnable, strip redundant guards
5acd8fa4 - CLEANUP: Gigantic formatter pass on s3maphore
76358648 - REFACTOR: eliminate staticList, add deprecated wrappers, fix snapshot bug
37b843aa - FEAT: Add structured music metadata registry instead of bastardizing localizations
ba1fcd90 - CLEANUP: Correct old annotations for GameObject (where is that even coming from?)
8d574d40 - REWRITE: Migrate cell presence tracking to coroutine-driven global sweep
f52a49eb - CLEANUP: Actors who aren't in combat should't trigger combat cache clears
119ddf7d - CLEANUP: Remove unused vars in musicUtil
2802da7b - CLEANUP: Silence lifetime warning (fix in cod3x!!!)
c8435dff - CLEANUP: I guess I just committed a semi-broken state in actor.lua?
8cc6ff71 - CLEANUP: Rename self to gameSelf in actor.lua
8765df9e - FEAT: Massive refactor of playlistRules.lua
4ac87912 - FIX: Change combatTargetType rule semantics to match-any instead of match-all
f63a8338 - FEAT: Add a small helper to combatState to track whether an actor is currently in combat or not
9af480de - FEAT: Switch combatTargets to an array and use numeric-for loops to iterate it and remove next usage when interfacing with it
c967a3d2 - FEAT: Improve the combat event scheduler with a dynamic one that distributes capped batches between 4 and 16 to try ensuring every actor is updated every 1/3 of a second
a6e4744e - FEAT: Add settings to prevent combat music based on whether the player is actually being targeted, enemy health thresholds, and enemy level thresholds
4c8bb747 - CLEANUP: Change setting group names
ab1973cc - FIX: Making PlaylistRules read-only also makes all of the inner fields read-only and it dies lol
2b7b643d - FIX: Correct inconsistency in S3maphoreClearTargetCache eventData
30ca0dbe - CLEANUP: Add a dedicated clear function so I don't have to rewrite it 100 times for non-rubic0n users
ba42eecc - FIX: Correct annotations for PlaylistState.combatTargets
b9a61f1f - FIX: Strict read-only metatable was broken
a99f1c88 - CLEANUP: Correct variable shadowing in combatTargetMatch by renaming the per-actor result
649cf338 - CLEANUP: Remove combat state mutation from dynamicstatthreshold rule
b6f446bf - FIX: Send the object reference in S3maphoreClearTargetCache instead of the id
23d23803 - CLEANUP: Correct typo in S3maphoretypes
17cfca78 - REVERT: Actually I prefer hardcoding to 4
cd4b261b - CLEANUP: Run formatter, fix lint warning
8cad4c1f - FEAT: Instead of a hardcoded batch size, shrink dynamically according to frameTime (except when paused)
0bc3b291 - CLEANUP: Run formatter
f9b11ee7 - FIX: Route death tracks through the S3maphoreSpecialTrack event instead of playing them directly
4dfa1422 - FIX: Don't resolve playlists or update combat state if the player is dead
4a6a973c - CLEANUP: Remove unintentionally-committed log
3e99eca7 - FIX: Re-add S3maphoreTrackChanged and ensure all track changes are routed through it
5b1537b5 - FEAT: Major refactor of playlist loader to sort playlists at load-time, enabling much faster deterministic ordering of playlist resolution
aba9885b - CLEANUP: My mama said while loops are the devil
388beb50 - CLEANUP: Reformat core.lua and localize string functions
5650b3e9 - CLEANUP: Remove unnecessary check & explicit nil check
01c898d9 - CLEANUP: No explicit nil params ! ! !
a620079d - CLEANUP: Further narrow optimization of staticCollection.lua, less locals, more BRRR
a0160f4d - CLEANUP (S3maphore): Generalized and extreme refuckulation of the whole thing for performance and fanciness
8783e912 - CLEANUP: Slight refactor and rearrangement of staticCollection.lua
ce0c5458 - FEAT: Actors clear their s3maphore cache on death
dcf5bf21 - FEAT: Major overhaul of core.lua to be almost entirely event-based. Playlist resolution now no longer happens onUpdate but instead during relevant state changes such as (newly-added) hourly events, cell changes, combat state changes, and target death
5e3ff924 - CLEANUP: No explicit nil declarations ! ! !
282eca01 - CLEANUP: Formatting in musicSettings.lua
1a176642 - FIX: Copy playlists when dumping them from the interface so the originals don't become read-only
0e15a232 - CLEANUP: Run formatter, fix placement of realUpdateActorChain
fc55004b - CLEANUP: Don't process the combat chain until the coroutine loader is finished running
57eb4b69 - FEAT: Major architectural rewrite of actor.lua. Use a bounded queue to check for actors in combat
16f5d8a9 - FIX: Use the correct loop counter when updating the targets table
bc13acca - FIX: Don't reassign a new table when updating targets but instead manually kill-refill
620c1b23 - CLEANUP: Even narrower refactor of actor.lua to minimize C++ calls and early-outs
16bdec59 - FEAT: Refactor actor builtin for less allocations, lookups, and locals
9b6e6c2c - FIX: Correct non-existent import in S3maphore core
d1ed43fc - CLEANUP: Remove s3maphore dependency on non-existent H3 modules
22b8ad2a - CLEANUP: Place priority for General Dungeon playlist *above* MUSE ones
61091681 - CLEANUP: Remove interior-only filter from MUSE Dwemer and Daedric
377f668d - CLEANUP: Remove useless file
7a6b49d9 - CLEANUP(S3maphore): Localize and annotate some stuff in omw/music/actor.lua
ac02eca5 - CLEANUP: Assert `self.cell` exists in s3maphore after cell transition
73c712ea - FIX: Re-add `require` to playlistenv
90280ded - CLEANUP (s3maphore): scripts/s3/music/util is player-context
f274c998 - FIX: Actually fix it
15557613 - FIX: Add `table` to PlaylistEnv
d6a45c62 - CLEANUP: Remove isOpenMW.lua from S3maphore so it can be pulled from H3
8269960e - FIX: Add context annotations to S3maphore
a6f99997 - FIX: Correct old S3maphore playlists still utilizing native engine types
a3198dd6 - FIX: Don't require playlistPriority in playlists
7e2e185d - CLEANUP: Run formatter on s3maphore core
558618a1 - CLEANUP: Don't allocate a new closure in deepToString
e14a4aec - 7.2: What to withold
8486fecc - C-02: Documentation Is Not Optional
da6944b2 - CLEANUP: Integrate silence track handling into the onUpdate call chain
48455ca3 - FIX: When constructing an updatingSettingsTable, copy all values out of the original table and into the shadow table, if an original table was provided
9e9054c7 - CLEANUP: Improve handling in MusicManager.skipTrack
3b18afed - CLEANUP: Localize more stuff in updateCellHasCombatTargets
a9ae2546 - CLEANUP: Reduce userdata lookups in updateCellHasCombatTargets
215a5d6e - CLEANUP: Rearrange and simplify the onUpdate handler chain for readability and SPEEEEEEEEED
e485c601 - FEAT: Switch from using direct events for track change handling to the explicit handler pattern the OpenMW API uses
622d946d - FEAT: Add new reason states for playlist and track changes
f8570e5c - CLEANUP: Make a dedicated EventData table and start importing H3 modules
037b099a - CLEANUP: Shut up the LLS
8f69d9dc - CLEANUP: Further optimize door iterations by using localized squared lengths and not even bothering to execute any real code during cell transitions
7eb88b00 - FIX: Correct string replacement throw lol
845076e7 - CLEANUP: Migrate the implementation of combat target detection into the player script so that we can use the `nearby` module
41f29745 - CLEANUP: Consolidate all the parts of the global onUpdate into one big function
be876db8 - CLEANUP: Remove useless interface functions
3c0baa74 - FEAT: (Slightly) further optimize the main onFrame by integrating sound enablement checks into the dispatcher system
3a6187ff - CLEANUP: Further optimize global script with preallocated tables
c6bcea5f - CLEANUP: We can use onUpdate now since it runs when the world is paused; update variable names to reflect that and use the onUpdate handler
84b05158 - CLEANUP: Refactor since this does literally nothing else
8e32406e - CLEANUP: This is no longer necessary since cell transitions are handled by the global script
3395023f - CLEANUP: Don't do cell change tracking in the player script at all anymore and only do it in the global script
6fd1f3de - FIX: Add a unified makeReadOnly impl with better support for recursion and also allows optionally copying the table and throwing on invalid keys
8f5ac17f - FEAT: Add a deep copy function to music utils
142535f0 - FIX: Un-break the builtin playlists since they no longer rely on api specific code
4e9781f2 - FEAT: Add a new, `isExploring` setting, for explore playlists to use which allows the separate disablement of explore playlists, just like battle ones
9fc7f208 - CLEANUP: Correct type annotations for combatTargets
7986f7a2 - CLEANUP: Register the special playlist differently, so the LLS recognizes it
cb67eab1 - FIX: Since we don't immediately play music anymore, we have to return when events are queued, otherwise we play music twice when turning playback back ON after it having been disabled
1f9e2b33 - CLEANUP: Flush old vars/forceSkip earlier to ensure toggling music doesn't accidentally preserve old state
9ad98fb8 - CLEANUP: Simplify the boolean logic around switching tracks a bit
78c267f4 - CLEANUP: Only actually stream music as a final response to the S3maphoreTrackChanged eventHandler, for better compatibility
f08b902f - CLEANUP: Do cell change tracking in the global script
3e154971 - CLEANUP: Clear the queued event data after it's been emitted
3828c1ed - CLEANUP: This is no longer needed as upon death a special track plays and switches out the onFrame function
0505d091 - CLEANUP: Hoist queued events and handle music enable/disablement entirely in the async handler
7f0ee292 - FIX: Always load the special playlist as it is the only one which MUST exist
c6a5f85e - FIX: Correct a bad reference to the local playlistsTracksOrder
d4717111 - CLEANUP: So I guess that whole thing can just go away
959b2c12 - CLEANUP: So I guess we never actually return the original table then
93a75a7a - CLEANUP: Further optimize updating settings tables and fix MWSE behavior again
7f18c086 - CLEANUP: Further optimize updating settings groups and fix the MWSE behavior as well
60066f4e - FIX: Improve write behavior of updating settings tables
93dbae40 - FIX: Don't presume the existence of Explore and Battle playlists anymore
fc1b9819 - CLEANUP: Use rawget instead
c14d45db - FIX: Correct a throw when writing values to auto-updating setting tables that aren't in the settings group
541bd34c - CLEANUP: Gate all debug logs behind an explicit check that debug logging is enabled to avoid unnecessary and expensive :format calls
a944e017 - CLEANUP: There's a DebugEnable setting too
2ca5088b - FIX: Wrong variable in failed lookup error for makeStrictReadOnly __index function. Also, error on level 2
adc742b4 - FIX: Move @class annotation so the assignment on construction doesn't cause complaints
c50f9936 - CLEANUP: Fix type annotations for interrupt modes
b358cb51 - FIX: Remove fightingActors as it now only exists as a property of the PlaylistState
1f18efd2 - CLEANUP: Major refactor of the core module to remove a bunch of stuff and account for it all being in dedicated files
e3501182 - CLEANUP: Refactor PlaylistRules to not require constructor arguments and instead directly import and assign relevant stuff
c8f12793 - FIX: Un-break the silence manager by constructing the auto-settings table with a prebuilt one that includes the updateSilenceParams function instead of trying to update it after the fact which doesn't work
b57c252b - FIX: Un-break the playlist loader by importing the music manager and constructing our own Playback table
29b5d2c9 - CLEANUP: Useless comment
68b8c941 - CLEANUP: Hoist the print override into its own function
2a33023e - FEAT: Migrate MusicManager into its own file separate from the core
4a1d9c1e - FEAT: Add a dedicated file for the core settings, which is API agnostic and cacheable
962f59bb - CLEANUP: Add a dedicated file for Playlist state
4a027a83 - FIX: Correct stack overflow in makeStrictReadOnly __index function lol
c9ca6c2c - FEAT: Add some bad annotations for GameObject, which don't actually have anything
829759fe - CLEANUP: Queued event name is optional, and will now be used to determine whether to send one as the main table is cached
2246f817 - CLEANUP: Improve type annotations and also make the state change reasons enum strict read only
882e40ad - FEAT: When assigning values to auto-updating setting tables, update the associated setting group as well (OpenMW only)
1eefa94a - CLEANUP: None of these actually get used
cac75d94 - CLEANUP: Hide tes3 global somewhere
e172fc2f - FIX: But we actually have to give an MCM path
14367139 - FEAT: Make the updating settings table constructor accept an (optional) input table for better ergonomics
5968e34a - CLEANUP: This is now API agnostic
e3f12582 - FEAT: Make auto updating table constructor work in MWSE too
86675d49 - CLEANUP: Actually the playlist loader really only needs to be a single file
ed9b5602 - CLEANUP: Add a dedicated module for checking if we're in OpenMW or not and use it when needed
053d1206 - CLEANUP: Improve type annotations for read only tables, and make an updating settings table constructor
f74292cf - CLEANUP: Migrate the rest of the coroutine loader into its own file, which returns the core loader function
92052801 - CLEANUP: Refactor silence manager not to have external dependencies and be prepped for MWSE deployment
cec95881 - CLEANUP: Simplify the silenceManager setup since none of the necessary stuff is actually stateful, that whole constructor function thing was pretty dumb
eb8f2f53 - CLEANUP: Migrate the enums into their own files
e41cbaa2 - CLEANUP: Start migrating the loader into its own directory, starting with the environment
cc73405b - CLEANUP: Rename helpers to musicUtil in core
f3b43faa - CLEANUP: Seriously, fix alphabetization in musicUtil
492f6afc - CLEANUP: Alphabetize, organize, and rearrange musicUtil
fb6582d0 - CLEANUP: Make a new StrictReadOnly function and don't throw on regular read-only tables.
db828cf8 - CLEANUP: Fix the _ENV annotations as that doesn't work in Lua 5.1
d0aed0c4 - CLEANUP: Nullify the contents of the original `helpers` module and migrate it to scripts/s3/music/util
e118ca9f - CLEANUP: Switch core to use `@module` for types instead of an actual require
23845787 - FIX: Correct a throw caused by not passing a prefix to deepToString
bef3c247 - FIX: We start with 0 playlists now because the builtins are dehardcoded
450d9eec - CLEANUP: More consistent style of require statements
9612eb2a - FEAT: Add lua-based makeReadOnly for cross-platform-ness
28004034 - CLEANUP: Remove some unused vars in core