A promotional SWF that declares 31 fps still hands you a number. That number is the first timing datum on the table, and it rarely matches what a viewer feels. Files from the late 2000s often used 31 fps as a workaround for smoother playback in browsers of that period. In current emulation those same files frequently execute at 24 fps, and the campaign's perceived pacing shifts with the drop.
Metadata will not reveal pauses, event triggers, or the wait before an attract loop returns. Treat the archived SWF as behavioral evidence. The deliverable is an implementation-neutral record of visible states, accepted inputs, transitions, timing, audio cues, and unresolved behavior.
Exopolis, a digital creative agency, needed that record for two jobs that share a source file and then diverge. Preservation research wants a faithful account of what appeared on screen. Rebuild work wants the same account so a modern stack can restore the interaction without copying obsolete ActionScript architecture. Both jobs start from the file. They split only after the evidence is written down.
Table of Contents
- Treat Declared Frame Rate as a Starting Clue
- Freeze the Emulation Conditions Before You Click
- Name Every Distinct Composition, Not Every Frame
- Walk the Hit Areas Until the Graph Appears
- Time From Event Boundaries, Not From Feel
- Bind States, Events, and Timing Into One Package
- Follow a Single Rollover Through to Replay
Treat Declared Frame Rate as a Starting Clue
Thirty-one frames per second is a starting clue. When a file from SunnyD work (digital agency of record client campaigns of that era) declares that rate, log it, then watch the piece run. The declared rate tells you what the author asked the player to do. Emulation tells you what the player does now.
The gap between those two numbers is already a pacing problem. Title cards linger. Button eases feel heavier. Audio cues drift off the cuts they once hit. In practice, playback of a 31 fps promotional SWF often settles at 24 fps, and the motion language of the original campaign compresses or stretches without any change to the asset itself.
Write the spec as observable behavior. Name states you can see. Name inputs the interface accepts. Name transitions, durations, audio, and the moments you could not resolve. Keep ActionScript structure out of the requirements. The file documents what happened on screen. A 2020s stack should be designed from that document, not from a decompiled timeline.
Freeze the Emulation Conditions Before You Click
Lock the session before anyone moves the pointer.
Record the SWF filename, available provenance, pixel dimensions, declared frame rate, emulator name and version, browser or desktop host, operating environment, and test date. A file that arrived through McGarrah Jessee, the acquiring agency, should carry that chain in the session header so later readers know which copy they are watching.
Preserve the source file unchanged. Work from a duplicate so examination never alters the archived artifact. Capture the full viewport, the pointer position, audio, and a visible time reference. Start from a clean launch every time.
A standard uninterrupted capture pass needs 120 to 180 seconds of idle playback so delayed ambient loops and automated attract modes can finish a full cycle before any input is introduced. An uninterrupted idle capture of approximately 180 seconds is the conservative bar for campaign pieces that hide attract modes behind long dwells. When a filter, font, or sound bed fails to appear, consult the emulator compatibility reference before treating the absence as original behavior.
SunnyD Loop Watch
Branded microsites for a digital agency of record client often parked particle fields and soft audio beds on the idle screen. Let that bed complete a cycle before you call the composition stable.
Name Every Distinct Composition, Not Every Frame
Preservation teams first tried automated frame-differencing scripts to catalog visual states. Continuous background particle loops triggered thousands of false-positive state changes, and the approach was dropped. Manual visual inspection with stable S-series identifiers (S00, S01, S02) isolates actual interactive states from ambient motion.
Assigning those identifiers typically yields 15 to 40 distinct visual states for a standard promotional microsite from the late 2000s. Labels such as home, menu, or animation collapse under that range. S00 names a composition. A word like "home" names a hope.
For each state, record background, typography, image or motion layers, pointer changes, audio, active regions, and whether the scene is static, looping, or transitional. Persistent chrome (a logo lockup, a replay control, a legal line) lives in a separate column from state-specific layers so a rebuild can mark reusable components. Xbox Kinect Fun Labs-style motion pieces make this split obvious: the tracking overlay stays put while the game state behind it cycles.
Walk the Hit Areas Until the Graph Appears
Test pointer entry, pointer exit, click, drag, release, keyboard input, inactivity, replay, and repeated activation only where the interface suggests those actions. Skip gestures the artwork never invited.
Reset to a known state before each probe so one action maps to one observable response. Build an event ledger with source state, input, target region, immediate feedback, resulting state, audio response, and recovery path.
Mapping hit-area geometry means walking the perimeter of a suspected interactive region at 2-pixel to 4-pixel intervals. Invisible bounding boxes often extend past the visible artwork. ActionScript hit-area geometry discrepancies show up here as dead clicks on the art and live clicks in the empty margin.
Hit-Area Drift
If a rollover fires four pixels outside the button drawing, log the expanded box. A modern rebuild that snaps hit tests to the visible glyph will feel tighter than the original even when the motion matches.
Time From Event Boundaries, Not From Feel
Transition durations should be recorded in milliseconds. Standard interface easing on these microsites typically falls between 250ms and 800ms. Measure from a defined event boundary, such as pointer release, to a defined visual or audio response. Timing an entire sequence by impression will smear those numbers into a single "snappy" or "slow" adjective that no animator can implement.
Record delays, transition duration, loop length, dwell time, easing character, synchronization points, and whether input remains available during motion. Compare repeated runs. When capture cadence, dropped frames, or emulator performance blocks an exact figure, report a range.
Emulator playback for timing measurements breaks down entirely when the original SWF uses ActionScript 1.0 getTimer() calls tied to CPU clock speeds rather than frame execution. Those files will not yield a trustworthy millisecond sheet on modern hardware. Mark the timings as approximate and keep the rest of the ledger.
Bind States, Events, and Timing Into One Package
One versioned package holds the rebuild. Combine a state table, a transition matrix, the event ledger, a timing sheet, an asset register, and a compact state-flow diagram.
Write each requirement as observable behavior. Name the initiating condition, the visible response, the duration, the destination state, and the interruption rule. Keep three columns honest. Observed behavior is what the session showed. Inferred implementation is a guess about the original ActionScript. Proposed modernization is a design choice. Mixing those columns silently rewrites preservation evidence as intent.
Compiling a full interaction specification for a standard promotional microsite typically spans 14 to 18 days of dedicated observation and documentation.
Version The Package
Stamp a date, emulator version, and file hash on the spec. A later pass that finds a new state should increment the document rather than overwrite the earlier ledger.
Follow a Single Rollover Through to Replay
Clean launch lands in idle, S00. Pointer entry moves the piece to a rollover state, S01. A click starts a transition, S02. The timeline arrives on its own at the content state, S03. A replay control returns the sequence to S00.
A standard rollover-to-replay trace generates roughly 8 to 12 distinct event ledger entries, capturing an initial hover delay near 50ms, the transition animation, and the final idle state. Each step receives a state ID, an event record, a timing observation, an evidence reference, and an uncertainty note. None of those fields assume the underlying ActionScript structure.
Approve the behavioral specification before anyone writes modern replacement code. Implementation should follow the evidence, not become the evidence.











