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

What the mask did to successive counter values
Unmasked012345
Masked002244

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

Follow that next branch of LEGION →

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.
Continue through the archiveDirge of Cerberus: Lost Episode →