I thought I’d messed up the controls. Ashen was running, but moving around felt like somebody had greased the floor. My description at the time was more useful than a general complaint about the D-pad:
“It feels like we have buttered socks on”
“It feels like we have buttered socks on when we're moving”Wakka · October 19, 2026 A09
Press a direction, let go, and keep sliding. We had several sensible suspects: a missed release, a held key that never cleared, or two fingers confusing the input owner. Those were all things our touch controls could get wrong.
I’d already looked beyond this build. “I legit thought I had ported the controls wrong for this,” I wrote. “So I looked it up and nope. You just fuckig slide all around lol.” The movement finding also points to an existing upstream report of slippery Ashen movement. We had a reason to look deeper than where the D-pad sat on the screen.A09A01
Getting to that question had involved a smaller, less glamorous repair first. The 0.1.3 checkpoint records a startup fix that creates Android’s window decor before asking it for the system-bar controller. The movement reports that follow have the native game and surface attached. The shooter could now run long enough to reveal its next problem.A12
The release had already arrived
In the 0.1.4 diagnostic build, we followed the input into the original game. We watched the guest key handler and sampled the player’s movement command and position after completed gameplay frames. Key-up arrived. The movement command became zero. The position kept changing. Our obvious explanation wasn’t holding up.A06
The finding records 92 retained guest key events matching the overlapping Java event log. In one uninterrupted example, the player was still moving 1.194 seconds after release. The report had caught the game receiving the instruction to stop. Sliding continued on the other side of that boundary.A01
We were past the usual sticky-button problem. A larger button or another release event wouldn’t explain movement continuing after the command was already neutral. We needed to look at what happened between the game’s updates.
A clock that counted in pairs
The runtime exposed a 64 Hz tick counter. In the affected EKA1 path, a compatibility mask cleared its lowest bit. The values still increased, but only in pairs.A02
| Unmasked | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Masked | 0 | 0 | 2 | 2 | 4 | 4 |
Two nearby updates could therefore ask the time and get the same answer. The next read would jump by two ticks. The clock still represented roughly 64 tick units per second, but its usable resolution had become coarser. In the earlier trace, 438 of 934 retained completed-frame samples saw zero elapsed ticks—46.9 percent.A02A04A13
Ashen accepted those zero-time updates. Analysis of the original movement code found a braking routine dependent on floor contact, alongside a collision path that could be disrupted by zero elapsed time. The before trace did not record every internal flag, so the full explanation remained a supported mechanism rather than a photograph of every step. It did, however, give the trial a very specific target.A05
The extra wrinkle was where the mask had come from. The finding quotes the nearby upstream comment as describing an unverified Worms World Party workaround. A compatibility decision for another game had become relevant to why this N-Gage shooter would not stop sliding.A02
One instruction, and the floor gets its grip back
We tried bypassing that mask in the dedicated Ashen runtime. The Android change replaced one native instruction so the original counter could pass through unmasked. The game executable, movement constants, touch movement classes and original game files stayed as they were.A03A05A10
It was a narrow experiment, which made the result easy to read. The new report calls itself 0.1.5-clock-trial and announces the clock change. Of 2,816 retained frame samples, only the first stationary startup sample had zero elapsed time. All 2,815 subsequent samples advanced.A07A04A13
The observed frame-callback spacing barely changed: medians of 16.647 milliseconds before and 16.678 after. The interesting difference was what time those callbacks could see. Seven qualifying grounded releases now slowed to zero horizontal velocity in roughly 0.32–0.34 seconds. The velocity fell steadily, and the position stayed put afterward. Two of the quiet intervals lasted more than seven seconds.A04A13
That was what made this repair satisfying. We hadn’t replaced Ashen’s movement system. Giving its original code a more useful answer from the runtime clock was enough to change the braking behavior.
“Yup, it worked. I'm having it pull out the fix and what not so I can publish it. Imma call it bsp - buttered sock patch”Wakka · October 19, 2026 A09
BSP had a name. The buttered socks had finally lost their advantage.
The next runtime question.
Ashen also sent me after something much bigger. Learning how deeply these games depended on Nokia’s original platform software made me want to build an independent Nokia runtime. I’m still working on it. In the meantime, the stopgap lets me play these games while that work continues.L02
Thirteen files, still the same game
For this chapter, we compared the 13 regular game files in the original RAR with the checkpoint inventory. Their filenames, sizes and SHA-256 entries matched. The executable was the same one named in the timing finding. The patch had changed the runtime clock underneath the original Ashen.A10
There are false starts in the paperwork too. AshenFindings.txt is an Omni Devourer investigation that reached its 60-second budget without completing an experiment. Another report is recovering an earlier session and hasn’t captured its movement probe yet. When putting this story together, we kept those separate from the actual movement tests.A08A11
About these records
The finding and both diagnostic phone traces support the clock-resolution repair on the tested phone. The old trace lacks velocity and floor-contact fields; the braking mechanism combines original-code analysis with the before/after observations. Both probes add overhead, and the later APK also contains UI-kit repairs. The general EKA1 clock edit was tested inside an Ashen-only bridge; a multi-game runtime would need a scoped compatibility choice and separate regression work. This chapter ends at the documented clock trial, without claiming an upstream merge, original-hardware timing parity or a completed campaign.A05
The receipts
Selected report lines, investigation notes and recorded feedback behind the story. Each receipt keeps its source and context.
A01 / The key was released; movement continuedMovement investigation
Source: Ashen_Movement_Timing_Finding_2026-10-19.txt · selected lines 12–16, 97–104
RELEVANT UPSTREAM ISSUE https://github.com/EKA2L1/EKA2L1/issues/577 The existing report describes slippery Ashen movement that differs from the reporter's hardware experience. The finding here adds a specific runtime cause to investigate, a minimal compatibility change and measured results. [... selected excerpt ...] Before, v0.1.4-diagnostic: - 934 retained completed-frame samples; 438 (46.9%) had zero elapsed ticks. - Remaining samples had two ticks at a reported rate of 64 Hz. - All 92 retained guest key events matched the overlapping Java event log. - Neutral movement commands were zero while position continued changing. - One uninterrupted example was still moving 1.194 seconds after release. - Median observed completed-frame callback gap: 16.647 ms.
A02 / The clock advances in pairsRuntime investigation
Source: Ashen_Movement_Timing_Finding_2026-10-19.txt · selected lines 26–55
The function computes a 64 Hz tick counter, then applies this mask for EKA1:
static constexpr std::uint32_t TICK_MASK = ~0b1;
...
if (kern->is_eka1()) {
res &= TICK_MASK;
}
The nearby upstream comment describes this as an unverified Worms World Party
compatibility workaround. This file was fetched from the pinned revision and
master on 2026-10-19; the two fetched files were byte-identical and both still
contained the mask. File SHA256:
c238fb67cf1bf60f2cb3d76859ef7cb5b461f9259ed7449339cf33c4174e364f
WHY THE MASK MATTERS
The mask clears the counter's least significant bit. For example:
Raw counter: 0, 1, 2, 3, 4, 5
Masked result: 0, 0, 2, 2, 4, 4
The underlying 64 Hz tick period is 15.625 ms. The masked counter changes only
every 31.25 ms, in increments of two. It still represents approximately 64
tick units per second: this is reduced resolution, not a clock running at
half speed. With game callbacks near 60 per second, many successive reads
produce a zero elapsed-tick delta, followed by a two-tick delta.
The original Ashen timestep calculation accepts zero elapsed time. The
pre-change phone trace showed its movement command clearing after release
while the player's position continued changing. Input release delivery was
not the cause demonstrated by that trace.A03 / One instruction in the runtimeCompatibility trial
Source: Ashen_Movement_Timing_Finding_2026-10-19.txt · selected lines 58–76
The dedicated Ashen runtime was edited; the original game executable was unchanged. No binary is distributed here.
Leave the computed counter unmasked for Ashen:
- res &= TICK_MASK;
+ // Ashen-only runtime: leave res unmasked.
The native time provider, timer origin, tick period and existing pause logic
were left intact. No FPS cap, time-delay setting, minimum-timestep clamp,
forced velocity reset or friction constant was changed.
ACTUAL ANDROID BINARY CHANGE
The delivered test used a reversible binary compatibility edit to the pinned
ARM64 native library; it was not a complete source rebuild of EKA2L1.
Exactly one instruction changed:
Before: and w10, w9, #0xfffffffe
After: mov w10, w9
The subsequent conditional select therefore receives the unmasked counter.
This changes the EKA1 result while preserving the existing EKA2 result.A04 / Before and after the clock changePhone measurement summary
Source: Ashen_Movement_Timing_Finding_2026-10-19.txt · selected lines 97–127
Before, v0.1.4-diagnostic: - 934 retained completed-frame samples; 438 (46.9%) had zero elapsed ticks. - Remaining samples had two ticks at a reported rate of 64 Hz. - All 92 retained guest key events matched the overlapping Java event log. - Neutral movement commands were zero while position continued changing. - One uninterrupted example was still moving 1.194 seconds after release. - Median observed completed-frame callback gap: 16.647 ms. After, v0.1.5-clock-trial: - 2,816 retained completed-frame samples across 61.757 seconds. - One zero-time sample: the first captured frame, stationary at startup. - All 2,815 subsequent captured samples had positive elapsed time. - Tick deltas: 2,621 samples of one tick, 192 of two ticks, two of three ticks. - All 120 retained Java dispatches matched guest input events. - Median observed completed-frame callback gap: 16.678 ms. - Seven clean high-speed grounded releases reached zero horizontal velocity in 321.710-342.649 ms (median 326.537 ms). - Their velocities decreased monotonically and positions stayed fixed after stopping. Two of the neutral intervals lasted 7.484 and 8.616 seconds. - Floor-contact state remained set through those braking sequences. - The user's gameplay video and assessment agreed with the measured repair. The seven release examples require: at least one second before the next movement press, zero movement commands throughout, initial raw horizontal speed >=45000, continuous floor contact through stopping, and the first sample within 50 ms of the guest release. Overlapping inputs, short gaps, airborne releases and already wall-stopped inputs are excluded. Positions and velocities are original fixed-point integers; no metres conversion is assumed. The histories are sampled/retained traces, not every event forever. SUPPORTED INTERNAL BRAKING EXPLANATION
A05 / The braking explanation and its boundaryOriginal-game analysis
Source: Ashen_Movement_Timing_Finding_2026-10-19.txt · selected lines 129–142, 154–175
floor-contact state. It also found a path that clears that state before collision processing, and a zero-timestep collision setup with identical start/end positions. Repeated zero-time updates can therefore interfere with the ground-contact-dependent braking path. The old position trace's braking pattern matched this mechanism; the repaired trace records normal velocity decay with floor contact retained. The old trace did not directly record floor flags or velocity, and the host harness stopped before the complete world-collision query. The full internal ground-contact explanation is supported by code analysis and the traces; the specific counter mask, zero-time deltas and successful repair are the directly demonstrated compatibility finding. Useful original-game analysis addresses for this exact executable: [... selected excerpt ...] The four touch movement/input classes were also identical. The after build integrated UI Kit 1.1.1's startup/dialog release repairs and extended the read-only observer; it was not otherwise a byte-identical APK. Both probes observed the original guest through guarded debugger hooks and added some overhead. Their similar callback intervals and the direct counter change are useful controls; this is not a physical N-Gage timing measurement. Host checks included 180 executions of the actual native ARM64 clock function over tick boundaries, counter wrap/extreme values and EKA1/EKA2 branches. Original ARM input/braking/setup functions were separately checked. The delivered APK's observed movement repair is supported by the real phone report and video. Full game completion, multiplayer, other phones/platforms, original-hardware timing parity and Worms regressions were not tested. UPSTREAM IMPLEMENTATION SCOPE The tested runtime belongs to a dedicated Ashen bridge. Removing this mask there changes its EKA1 counter generally; the binary instruction itself is not guarded by Ashen's UID. For a multi-game EKA2L1 release, a title-specific compatibility option/profile for Ashen (UID 0x101FD3E9) is the appropriate next implementation to evaluate. Preserve the Worms workaround for the game that needs it until broader regression tests establish a safe default. There is no claim that the same change fixes every slippery game.
A06 / The observer is attached to the original gamePhone runtime report
Source: Ashen-20261019-175740-203-manual.txt · selected lines 195–200, 205–218
The selected trace retains monotonic diagnostic timings, not personal identifiers. F rows are completed frame observations; K rows are guest input events. Raw positions are fixed-point integers.
ASHEN MOVEMENT PROBE v1 Hooks use 6r21.app code-segment UID 101FD3E9 and original code fingerprint 5EF10702. EKA1 DLL applications can run inside AppRun; matching is by the exact game image. Guest key handler active: true Completed gameplay frame hook active: true Trace callbacks add overhead. No movement/timing settings are changed. [... selected excerpt ...] # K: boottime_ms,K,event_type(2=up/3=down),scan,raw_before # F: boottime_ms,F,frame,frame_gap_ms,tick_delta,tick_hz,dt_fixed8,state,raw_up,raw_down,raw_left,raw_right,raw_4,raw_6,command_strafe,command_forward,command_vertical,position_x,position_y,position_z,angle_x,angle_y,angle_z,probe_body_us # raw key values are opaque original-game state codes; positions/commands are raw fixed-point integers. 204694394.637,F,2891,16.103,0,64,0,6,0,4,4,4,4,4,0,256,0,-307882,511203,-28656,0,0,3325833,24.4 204694410.044,F,2892,15.407,2,64,8,6,3,4,4,4,4,4,0,256,0,-307948,511221,-28656,0,0,3325833,26.1 204694425.209,F,2893,15.165,0,64,0,6,3,4,4,4,4,4,0,256,0,-307948,511221,-28656,0,0,3325833,21.7 204694446.298,F,2894,21.089,2,64,8,6,3,4,4,4,4,4,0,256,0,-307778,511318,-28656,0,0,3325833,27.6 204694459.833,F,2895,13.535,2,64,8,6,3,4,4,4,4,4,0,256,0,-307502,511419,-28656,0,0,3325833,26.0 204694466.848,K,2,16,3 204694476.332,F,2896,16.499,0,64,0,6,1,4,4,4,4,4,0,0,0,-307502,511419,-28656,0,0,3325833,24.2 204694497.261,F,2897,20.929,2,64,8,6,4,4,4,4,4,4,0,0,0,-307226,511520,-28656,0,0,3325833,26.7 204694509.694,F,2898,12.433,0,64,0,6,4,4,4,4,4,4,0,0,0,-307226,511520,-28656,0,0,3325833,21.2 204694528.685,F,2899,18.991,2,64,8,6,4,4,4,4,4,4,0,0,0,-306950,511621,-28656,0,0,3325833,55.2 204694543.283,F,2900,14.598,0,64,0,6,4,4,4,4,4,4,0,0,0,-306950,511621,-28656,0,0,3325833,27.1
A07 / The clock trial announces exactly what changedPhone runtime report
Source: Ashen-20261019-182247-480-manual.txt · selected lines 190–206
GUEST MOVEMENT PROBE — DIAGNOSTIC Guest hooks observe key-handler arrival and completed frame state. CURRENT APK CLOCK TRIAL: native User::TickCount returns all 64 Hz ticks; the Worms even-tick mask is removed. Previous-session captures can contain an earlier core/probe; identify trace origin by its probe header. Clock: Android CLOCK_BOOTTIME milliseconds; subtract session monotonic start for Java event alignment. Positions/commands are original fixed-point integers, not metres or assumed physics units. Debug callbacks add overhead; this build does not establish original-device movement timing. Up to eight bounded rolling trace parts follow; chronological part numbers determine their order. ashen-movement-status.txt ASHEN MOVEMENT PROBE v2 — CLOCK TRIAL Hooks use 6r21.app code-segment UID 101FD3E9 and original code fingerprint 5EF10702. EKA1 DLL applications can run inside AppRun; matching is by the exact game image. Guest key handler active: true Completed gameplay frame hook active: true Read-only probe; native clock trial removes only the even-tick mask from User::TickCount. Trace callbacks add overhead. Original movement constants and guest files are unchanged.
A08 / A saved investigation with no completed experimentTool investigation record
Source: AshenFindings.txt · selected lines 9–15, 47–51
This is an unfinished tool-side investigation, not evidence that Ashen failed to run.
Status: budget_reached Reason: The investigation time budget was reached. Completed experiments are saved; continue with another budget. Runtime adapter: Not checked Time spent: 60000 ms across 1 saved sessions. Latest chosen overall investigation budget: 60 seconds. Omni stops early when its supported experiments are finished. [... selected excerpt ...] ## Complete experiment ledger No experiment completed in this session. The checkpoint retains the input and unfinished stage.
A09 / Where the buttered socks came fromConversation excerpts
Source: Wakka / saved Ashen conversations / October 19, 2026
Retrieved user-message excerpts, retaining the original wording and spelling. Times are converted from the recorded UTC timestamps to the October 19 Iowa local date/time. The complete conversations are not bundled.
15:10 CDT — “I legit thought I had ported the controls wrong for this. So I looked it up and nope. You just fuckig slide all around lol” 16:12 CDT — “It feels like we have buttered socks on when we're moving” 18:35 CDT — “Yup, it worked. I'm having it pull out the fix and what not so I can publish it. Imma call it bsp - buttered sock patch”
A10 / The original game files survived intactArchive comparison
Source: Ashen.rar compared with the attached Ashen v0.1.3 checkpoint inventory
Fresh archive inspection for this chapter. This comparison publishes file identity only; original game contents are excluded.
13 regular game files were read from the RAR. All 13 filename/size/SHA-256 entries match the checkpoint inventory. Original game executable: 6R21.app Size: 999,536 bytes SHA-256: 4025b0711644c1dfc591d0eb7fac2e3e0fca41a61d7fa9f69d3d1768a706a055 The movement finding records that same executable hash in both timing builds.
A11 / A recovered report is not a fresh boot failurePrevious-session report
Source: Ashen-20261019-175619-826-previous-session.txt · selected lines 1–3, 7–14, 74–85
The report is recovering prior session evidence. Its zero surface/input fields and uncaptured probe section should not be read as a fresh gameplay test.
ASHEN BRIDGE v0.1.4-diagnostic Reason: previous-session Date: Mon Oct 19 17:56:19 CDT 2026 [... selected excerpt ...] Phase: Recovering prior session report Native initialized: false Launch requested: false Surface attached: false Surface dimensions: 0x0 Insets L/T/R/B: 0/0/0/0 Native surface connections: 0 Input dispatches (not FPS): 0 [... selected excerpt ...] Positions/commands are original fixed-point integers, not metres or assumed physics units. Debug callbacks add overhead; this build does not establish original-device movement timing. Two rolling trace parts follow; each header identifies its chronological part number. ashen-movement-status.txt Not captured yet. ashen-movement-0.tsv Not captured yet. ashen-movement-1.tsv Not captured yet.
A12 / The window had to exist before its controls could be builtStartup repair notes
Source: Ashen v0.1.3 / README_FIRST.txt · selected lines 10–14
STARTUP FIX IN v0.1.3 Creates Android window decor before requesting the system-bar controller. Fault capture now precedes gameplay view construction. The global kit remains v1.1.0 with this local hotfix; its included source/JAR/DEX were rebuilt. The real Activity startup and early fault-report regression pass on the host.
A13 / An independent recount of the before/after tracesTrace reanalysis
Source: Ashen-20261019-175740-203-manual.txt + Ashen-20261019-182247-480-manual.txt
Recomputed from retained F/K trace rows, using the finding’s stated release criteria. This is a derived comparison, not a verbatim log. Units are diagnostic milliseconds and original fixed-point state, not measured distance on original hardware.
Independent recount of the retained completed-frame (F) rows: Before: 934 frames; 438 zero-tick samples (46.9%); median callback gap 16.647 ms. After: 2,816 frames; only the initial stationary sample has zero ticks; median callback gap 16.678 ms. Seven qualifying grounded releases, time from guest release to the first zero horizontal velocity: 1. 326.537 ms — release line 457, stop line 477 in the after report. 2. 342.649 ms — release line 780, stop line 801 in the after report. 3. 324.345 ms — release line 2014, stop line 2035 in the after report. 4. 323.657 ms — release line 2363, stop line 2383 in the after report. 5. 340.473 ms — release line 2574, stop line 2596 in the after report. 6. 336.734 ms — release line 2849, stop line 2871 in the after report. 7. 321.710 ms — release line 3150, stop line 3172 in the after report. All seven have monotonically decreasing horizontal speed and fixed positions after stopping. Turning-only keys do not truncate a neutral translation interval.
L02 / The ExEn push and the ongoing Nokia runtime questOwner recollection
Source: Archive-building conversation / owner explanation
Current owner explanation of motivation and ongoing work. It does not establish a completed independent Nokia runtime or a precise release chronology. The source wording is retained.
the big Exen push was in response to me pushing our all of the BREW and J2ME games lol. also Ashen and finding out about nokia games runtimes being interwined witht the game software put me on a quest to make my own nokia runtime lol im still in the process of doing it. bu tin the mean time im a stop gag like with exen.