Repo ↗ · Source README ↗ · Markdown & license bundle

Image reference (original game): Dishonored · original-game artwork, provided by IGDB. Image rights remain with their respective owners. This illustrates the referenced original game, not the actual visuals of this rewrite or mod.

Source maintainer: Nacholmo · Revision: baf903eb45c1 · Catalogued: 2026-10-12

Source license: MIT · LICENSE-APACHE · LICENSE-MIT · Article: Source README (format adapted)

The source README follows, with formatting adapted for this site and images replaced by source links. Feature, completion and testing claims belong to its authors and have not been independently playtested here. The Traditional Chinese translation was prepared with AI assistance.


sinhonor

Dishonored’s first-person movement and Blink in Rust, with a Bevy test course to try them in.

It isn’t a rewrite of the game. It’s a portable motion kit: walk, sprint, crouch, jump, fall, slide, mantle, lean, swim, ladder, Blink, Agility, the sword and the assassinations, built the way 2010-rust-rewrite-mashup brings Skate 3 into MW2. The movement lives in its own crate, crates/dis_motion, which only depends on glam. It knows nothing about Bevy, so the same controller can be dropped into any game that can answer a box sweep.

No game files ship with this repository. Every number, sound, effect, texture, mesh and animation is read at startup from your own installed copy of Dishonored.

Run it

You need Rust (https://rustup.rs) and Dishonored installed. From this folder:

cargo run --release -p sinhonor_demo

The first build takes a few minutes (Bevy is big); after that it’s quick.

Finding the install. It uses --game "" if you give it, then the DISHONORED_DIR environment variable, then common Steam library paths, including the extra libraries listed in Steam’s libraryfolders.vdf. --difficulty easy|normal|hard|veryhard picks which of Corvo’s attribute sets is used (Normal by default), and --agility 1 or 2 starts with Agility’s first or second level.

On Linux the demo runs natively on Wayland with a real pointer lock. Under X11 the cursor is confined and re-centred instead.

Controls

Action Keyboard / mouse
Move / look WASD / mouse
Jump, or mantle when a ledge is in reach (hold it through the jump for Agility’s power jump) Space
Crouch (toggle, like the game’s default binding) Ctrl or C
Slide Crouch while sprinting
Sprint / slow walk Shift / Alt
Lean left / right Q / E
Blink: hold to aim, release to go Right mouse or F
Blink tier I / II 1 / 2
Agility: none, I, II (cycles) 3
Sword attack, assassination of an unaware guard, or drop assassination while falling onto one Left mouse
Make the guards notice you (sword fights) or lose you (assassinations) T
Mute game sounds M
Blink debug gizmos (target footprint and ground line) G
Show or hide Corvo’s arms and sword H
Reset to spawn R
Toggle help F1
Free the cursor (press again to quit) Esc

The moves

Distances are in metres; the game works in Unreal units, where 1 uu = 1 cm.

  • Walk, run, sprint, sneak: the game’s own gait rules (NOTES.md §5h). The speeds are the m_GroundSpeed* attributes from Corvo’s release tweak (Twk_Pawn_Corvo_Release), per difficulty: he runs at 4 m/s, sprints at 6 m/s and sneaks at 2.75 m/s, all times 0.9 while his sword is in hand (m_SwordUnsheathedSpeedFactor), so 3.6, 5.4 and about 2.5 m/s in practice. A light push on a stick walks, a lighter one slow-walks (DisTweaks_PlayerInput thresholds). Pushing within 20° of sideways (50° when moving back) is strafing, and within 40° of straight back is backing up: each has its own factor for running and sprinting (m_GroundStrafeMultiplier*, m_GroundBackwardMultiplier*), so a forward diagonal runs at full speed. Sprint needs a firm push but works in any direction, and ends sneaking. Acceleration is 20 m/s² (m_AccelerationRate), scaled by the same factor, with UE3’s ground friction of 8 and its braking. When the top speed drops (letting go of sprint, crouching) it blends down at m_fSpeedBlendDownSpeed rather than at once.
  • Jump: launches at 8 m/s straight up (m_JumpZ, the same attribute the game’s StatePlayerMasterJump reads) under 15 m/s² of gravity (DefaultGame.ini). That’s a 2.1 m apex. The vertical speed of whatever you stand on is added, as the game does. Air control is the engine’s, with Corvo’s 20% (m_fAirControl): the push is a fifth of the ground acceleration, it switches off for a frame when it would push you into something, and from run speed up it can steer but not add speed (NOTES.md §5h).
  • Fall: touching down faster than 22.5 m/s reports fall damage (m_MaxSpeedBeforeFallingDamage; there’s no health, so the HUD logs it). The landing dip and the camera shake scale with how hard you hit.
  • Crouch (sneak): the collision shrinks from 1.75 m tall to 1.3 m (m_fSneakHeight on Corvo’s tweak), keeping your feet in place. Standing up only happens if there’s room.
  • Crawl: walk at a gap too low to stand or sneak through and Corvo crouches lower by himself, to 66 cm (m_fCrouchHeight, the engine’s crouch), then gets back up once the way ahead is clear (m_fAutoCrouchTestDistance 1 m).
  • Slide: crouch while sprinting. Your velocity eases from where you started down to sneak speed over the game’s 1.1 s (m_fSlideTime), gently at both ends. The first half can’t be cancelled (m_fSlidePercentNotCancelable 0.5); after that, crouch stands you up, jump jumps out of it and pulling back stops it. Slide into something that turns you more than 25° (m_fSlideVelocityDeactivateAngle) and you stop dead with a camera shake.
  • Mantle: jump at a ledge, or hold forward or jump while falling past one. The ledge finder is the game’s own (NOTES.md §5f), with the heights from m_pMantleTweaks:
    • it first measures the room above you, then sweeps a box your size forward 50 cm (m_MantleEdgeSearchDist) at heights rising 12 cm at a time (m_LineCheckStepSize). The first wall it meets must be near-vertical and facing you (within 20° and 45°). From then on the box stays pressed against it and reaches 20 cm in (m_fMantleForwardMoveAmount). The first height where that reach is clear is the top of the edge;
    • the top must be no steeper than 45°, and a standing box must fit going over it; otherwise you climb crouched;
    • under 44 cm you just step up (MaxStepHeight). Low edges, 55 cm–1.2 m, are a step-up mantle: three quick moves (to the wall, up, 20 cm on) with the view catching up over 0.2 s (m_fLowMantleStepUpBlendTime). Medium (1.2–1.7 m) and high (1.7–2.3 m) ones turn you to face the edge and climb along the animation’s own root motion, its rise stretched to the edge’s height, until the animation’s exit (Empty_MantleMedium, …High, or the crouched ones). Over 2.3 m is too high, so Blink up;
    • falling faster than 10 m/s you can only catch edges at least 1.55 m above your feet (m_fFallSpeedForLedgeGrab, m_fLedgeGrabMantleMinEdgeHeight), and past 20 m/s none (m_fMaxFallSpeedForMantle). After a blink, the Blink finder (m_pMantleBlinkTweaks) has no minimum height.
  • Lean: Q and E lean, standing still. As in the game (NOTES.md §5g), your head is a point on a lever around a pivot two body heights below it (m_fLeanHeightPct): the lean pushes it out at 10 m/s (m_fLeanSpeed), it swings out and drops a little until the lever is 15° over (m_fMaxLeanAngle, giving up to 5° more if you keep pushing), and a spring (springiness 80, damping 12) brings it back. The camera tilts by half the angle, the view can turn only 60° and pitch 35° from where the lean started, and the head never goes through a wall.
  • Swim: walk into deep water and you swim at up to 6 m/s (m_WaterSpeed), toward where you look, with the sword put away. It’s the engine’s swimming: acceleration and steering as on the ground, but the water’s friction (half of FluidFriction) slows you continuously instead of braking. The kit holds your eyes at the surface. Swim at a ledge and jump to climb out.
  • Ladder: walk into one to grab on. You climb at 2.54 m/s (LadderSpeed) toward where you look, and step off onto the landing at the top. Jump to leap off where you’re looking at 5.25 m/s (m_fJumpImpulse), twice that under a low ceiling.
  • Camera: head bob and roll scale with speed (the bob and roll amounts from DefaultCamera.ini), landings dip the view on a spring, and the FOV is the game’s 75°.

Blink reproduces the behaviour of the game’s DishonoredActivePowerComponent_Blink, specified in our own words in NOTES.md §5. Its numbers come from Twk_Blink’s per-level array.

  • Range: a squashed sphere. Looking level or down, you reach 11 m (tier I) or 16 m (tier II). Looking up, the aim is scaled until its height reaches 5 m, so you can blink a long way across but only 5 m up.
  • Targeting runs every frame while you hold the button. A 20 cm box is swept along your aim. If it hits a wall close in front of you (within 3 m) the ray is nudged up, then sideways, 30 cm at a time, so you can blink past corners. From the hit it pulls back in half-radius steps until your whole body fits, but never behind the camera. That’s why blinking at a wall puts you just in front of it. Then it drops a sweep to find the ground and raises the target so you fit above it.
  • The marker is the game’s own particle systems. Blink_Ground_01 sits on the ground under the target, pitched 90° down as the game places it. Blink_Fall_01 floats at the target when it’s above the ground. Blink_Mantle_01 shows when the target is a ledge. The vertical beam is the systems’ far LOD, which only spawns beyond 2.56 m, as in the game.
  • Travel: on release, physics switches to flying, and if you’re standing Corvo crouches so low gaps fit (the target stays the same point, so a crouched body arrives with its feet higher, which is how Blink reaches ledges above you). He then moves 1 m every 10 ms (about 100 m/s), in sub-moves of at most 50 cm, without collision: the targeting sweeps already made the path safe. Travel stops at the target, if it would pass it, or on touching a pawn.
  • Arrival: your velocity from before the blink is restored, so blink-jumping keeps momentum. Then comes the game’s post-blink ledge check (a step-up or a full mantle, using m_pMantleBlinkTweaks) and an attempt to stand up.
  • Cooldown: 1 s, with the game’s cooldown lens effect (Twk_Blink_Cooldown, white streaks thrown back past the camera) and a decaying wobble.
  • Screen effect: the game’s warm-up wobble, travel distortion and blur curves (m_fMoveBlurMaxStrength and friends) drive a dedicated lens pass with radial blur, a dark tunnel vignette, animated peripheral distortion and subtle colour separation, alongside the FOV punch. The aim point stays sharp, and the pass fades with the game’s cooldown curve. HDR bloom softens the targeting glow; the arms and HUD remain crisp.

Agility

Agility is the game’s passive power Celerity. It follows the game’s behaviour, specified in NOTES.md §5e. Its two levels are read from DefaultPlayer.ini’s power list, and each level’s attribute modifiers are applied to Corvo’s attributes the way the game applies them: a level replaces the one before rather than adding to it.

  • Power jump: jump and keep holding Space. At the top of the jump Corvo is kicked up again at 13 m/s (Attribute_JumpZ_PowerJump, which is nothing without Agility). That’s about 7.8 m in all, instead of 2.1 m. Letting go before the top gives an ordinary jump. Only one kick per jump. The game has two more jump styles in its code (a higher jump cut short by letting go, and a push that lasts while held); the install picks this one (m_JumpStyle in DefaultPlayerState.ini), and the kit supports all three.
  • Landing: both levels raise the fall-damage and fall-death speeds (22.5 to 25.5 m/s, and 29 to 35 m/s).
  • Level II also makes Corvo sprint 30% and swim 10% faster, plays landings and mantles 50% faster, and changes the sideways and backward sprint multipliers.

Sword

Left mouse swings Corvo’s sword. It follows the game’s behaviour, specified in NOTES.md §5c, with the numbers from his sword’s tweak (DisTweaks_MeleeAttackPlayer).

  • Chains: the first swing is a forehand. Press again within 1 s (m_fMaxChainAttackTime) and the next is a backhand, then forehand again. A press during a swing’s chain window is kept and starts the next swing as soon as the current one allows. Each swing’s timing (when the blade can hit, the chain window, when the next may start, when it ends) comes from its animation’s notifies.
  • Reach: 2.1 m (m_fMaxContextRange), longer when you’re moving forward faster than 4 m/s: 3.15 m at a sprint (the player pawn’s m_fRaySpeedScale settings). The blade is a 1.2 m wide box swept from the camera along your view during the swing’s attack zone.
  • Damage: 10 per blow (the sword’s m_MeleeDamage), on guards that have noticed you (press T); unaware ones are assassinated instead. Guards have 25 health, the game’s default for a character, so the third blow kills. When a blow will kill, Corvo plays the finishing swing (Sword_Ready_Fatality_Generic_*) instead.
  • Sneak attack: crouched, Corvo swings his sneak attack (Sword_Sneak_Attack_Small).
  • Walls: if the blade meets the world before a character, the swing recoils (..._Big, or ..._BigChain mid-chain) and the camera shakes (m_fCamShake_OnHitEnv).
  • The HUD shows the targeted guard’s health. The swings play their own sounds.

Assassination

Attack a guard that hasn’t noticed you and Corvo kills it outright. It follows the game’s behaviour, specified in NOTES.md §5d, with the numbers from his sword’s DisTweaks_Assassinate tweak.

  • Who: the guard under your crosshair within 2.75 m (m_fMaxContextRange), if its awareness allows it: unaware, surprised, suspicious or begging (m_AssassinateOnAwareness), and not running. The game has no angle test: from behind is the usual way in, but an unaware guard can be killed from the front too. The HUD shows the prompt.
  • The side you’re on picks the kill, as for the drop assassination.
  • Slow or fast: the first kill is the slow, deliberate one. Then come 4 to 8 fast ones, and at least 90 to 120 s, before the next slow one (m_NumFinishersBeforeSlow_*, m_fTimeBeforeSlow_*).
  • The guard is moved, not Corvo: it is turned and set in front of him where its half of the paired animation puts it (1 to 1.2 m), and Corvo plays his half (Sword_Ready_Assassination_[Fast]<Side>_Master) with its sounds and camera motion, held until it releases him.
  • No room (a box of m_Assassination_Generic_ProbeExtents swept to the guard’s torso meets the world) or falling: the plain stab (Sword_Ready_Assassination_Generic), and the guard stays put.

Drop assassination

Fall onto a guard and attack, and Corvo kills them from above. With Blink it’s the classic stealth kill: blink up beside or above a guard, then drop. It follows the game’s behaviour, specified in NOTES.md §5b. The numbers come from Corvo’s sword tweak (DisTweaks_DropAssassinate).

  • Finding a target: while you fall, Corvo’s collision box is swept along where the fall will take him over the next 4 s (m_fHitWindowInSeconds), assuming at least 1 m/s downward (m_fMinDropDownVel). If that path hits nothing, it is swept straight down instead. A guard it hits counts if you’re falling, not rising, if your feet are above its torso, and if nothing stands between you. The HUD shows the prompt.
  • In reach (your feet within 3.5 m of its torso, m_fMaxDropDistToTarget): attacking kills straight away.
  • Further up: attacking locks on. Corvo stops drifting, his fall speed doubles, steering and powers are disabled, and the kill starts as soon as he’s in reach. If the guard stops being a valid target on the way down, the fall carries on as normal.
  • The side is whichever of the guard’s front, back, left or right you’re on. Each side has its own kill. The guard’s half of the game’s paired animation puts Corvo 50 cm in front of it, 80 cm to its side or 60 cm behind it, facing it. Those positions are read from the City Watch’s animations in a mission package.
  • The kill: Corvo plays the side’s Sword_Ready_Assassination_Drop*_Master animation and its sounds. The view follows the animation’s camera bone down over the body and back up. You get control back when the animation releases you (about 1.6 to 1.8 s in). Guards don’t need to be unaware.

Corvo’s arms, sounds and effects (from your copy of Dishonored)

At startup the demo loads Corvo’s first-person arms, his sword, their textures and animations, the motion sounds and the particle effects from your install. Nothing from Dishonored is included in this project; each run reads these from the files below.

File (under DishonoredGame/CookedPCConsole) What it provides
Startup.upk Corvo’s tweak tree (speeds, jump, mantle, slide, camera), his sword’s attack, assassination and drop-assassination tweaks and damage, the default character health (Twk_Pawn_DefaultNPC), the sword (Wpn_PlySwords.Wpn_PlySword01), all 385 first-person animations (Ply_*) and their effect notifies, the swimming and lens-drip effects
Engine.upk The arms (Ply_Player.Skm_Player) and their textures, engine defaults (floor angle, friction)
DishonoredGame.upk Pawn collision and eye height, Twk_Blink, the Blink markers and lens effect, footstep, slide, landing and splash effects, and the cobble, rock and plank textures the test course is dressed with
Textures.tfc and the other .tfc caches Texture mips, read by byte range
Bank_Footsteps.pck, Bank_Player.pck, Bank_Power_Player.pck, Bank_UI_Ingame_Water.pck Footsteps per surface and gait, slides, landings, mantles, crouch and stand, fall wind, sprint breath, swim strokes, and Blink’s warm-up, cast and fizzle
Bank_Weapon.pck, Bank_Impact.pck The sword and impact sounds the drop-assassination and sword animations post
L_Streets1_P.upk (or another mission package with the City Watch’s animations) Where each side’s drop and ground assassination puts Corvo (the victims’ anchor_jnt)
../Config/DefaultGame.ini, DefaultPlayerState.ini, DefaultCamera.ini Gravity, lean, swim, FOV, bob and roll

The movement needs only the tuning. Everything else is optional and skipped with a warning if it’s missing.

How the arms work.

  • Animations: Dishonored cooks its animations in Sony’s Edge format (built for the PS3’s SPUs), which is why other UE3 viewers can’t play them. crates/edge_anim decodes them.
  • Layers: a base layer plays the sword hand and body (Sword_Ready_Idle/Walk/Run/Sprint, Sword_Sneak_*, Sword_SlideLoop, Empty_Swim*, the mantles, Sword_Ready_JumpLandSmall, the sword swings and the assassinations). A left-arm layer plays the power hand (Powers_Idle/Walk/Sprint/Jump, then Powers_Cast_Blink_In, …_Loop and …_Out around a blink). Changes crossfade over 0.18 s.
  • Camera bone: the view is the skeleton’s camera_jnt bone, so the arms sit exactly where the game puts them at its 75° FOV.
  • Sword: held on the RightHandWpn socket. It’s put away for the unarmed (Empty_*) swim animations.
  • Drawing: the arms and sword are skinned on the CPU and drawn by a second camera on their own layer, so they never clip into walls.
  • Effects from the animations: when Blink is cast, the gold glow and smoke on the back of the hand come from the animations themselves. Powers_Cast_Blink_In and _Loop trigger Ps_Tattoo_Glow_02 on the hand’s Tattoo socket at 0 s (so it re-fires on every 0.33 s loop while you aim), and _Out triggers Ps_Tattoo_Glow_04. The swim strokes put splashes on the fingers the same way. The demo reads every one of these notifies, so the effects keep the game’s timing.
  • Glowing tattoo: a mask derived at runtime from the installed arm textures follows the skin’s UVs and uses the material’s gold power-hand colour. Its brightness rises while targeting and fades after travel. Depth fading softens smoke and glow cards where they meet the hand.

Sound. Wwise sound packages are parsed and their Vorbis audio converted to Ogg in memory. Footsteps follow your gait and the surface under you (stone, wood, gravel, water, roof tiles, metal). Set SINHONOR_LOG_SFX=1 to print each cue as it plays.

Effects. The game’s Cascade particle systems are simulated and drawn as sprites and mesh particles, at the game’s distance LODs. They include the Blink marker’s original swirl meshes and arrival streaks, slide dust, landing dust, footstep puffs on gravel and water, water splash, swimming wake, and drips on the lens after you climb out of water. Square sprites retain their square shape, including axis-locked glow cards. Hard landings also shake the camera.

What’s still approximate:

  • Not yet exact: the lean’s wall collision and the swimmer’s surface hold are the kit’s own, and the ladder is a simple model.
  • Camera: the head bob is procedural. The game drives it from a camera animation (Ply_Nav_LocoCamera_at), which the Edge decoder can now read but nothing plays yet.
  • Effects: SubUV flipbooks and the original materials’ scrolling/distortion graphs aren’t done. Mesh particles use cooked LOD 0 geometry, UVs, vertex colours and rotation curves. The particle materials, tattoo brightness and Blink lens shader approximate the look; they do not reconstruct the original shaders. The world camera uses HDR bloom.
  • Smoke: the hand smoke is simulated relative to the camera, so it doesn’t trail behind you as it does in the game.
  • Sword: no impact sounds, sparks or blood yet (they come from the game’s contact system). With several guards in one swing the kit hits the nearest, where the game orders them by the swing’s direction. Guards don’t fight back, so there’s no blocking, parrying or sword locks.
  • Assassinations: the guards are boxes that topple over (after being moved into place for a ground assassination). No guard model plays its half of the kill, and the bend-time, story-character and carrying-a-body variants aren’t in.
  • Drop assassination: the guards are boxes that topple over. No guard model plays its half of the kill yet, and the kill animations’ blood lens effect isn’t shown.

NOTES.md §6 has a fidelity table for every part.

The test course

A blockout course dressed with the game’s textures (crates/sinhonor_demo/src/level.rs). You start facing along it.

  1. Mantle wall, 8 m ahead: five blocks of rising height, 30 cm (step up), 90 cm (low), 1.5 m (medium), 2.2 m (high) and 3.2 m (too high, so Blink onto it, or power-jump with Agility).

  2. Stairs on the right, 20 cm risers up to a 3 m balcony.

  3. Gravel patch on the left and a puddle on the right, for footsteps and their dust and splashes.

  4. Pool behind you to the left: 4 m deep, for swimming and climbing out.

  5. Slide lane: a crawl beam 1 m off the ground that only fits you crawling.

  6. Lean pillars to peek round.

  7. Ladder tower, 6 m up, then rooftops with gaps of 8 m, 10 m and 14 m. Tier I clears the first, and the last needs tier II.

  8. The perch: an 11 m pillar you can only reach by blinking upward from the rooftops.

  9. Four dummy guards (red boxes; the dark band is their front) with 25 health. They start unaware, so attacking one assassinates it; press T and they notice you, so the sword fights them instead. Blink stops at them, and you can drop-assassinate any of them:

    • two in the open: blink up beside one and fall onto it;
    • one with its back to the balcony: walk off the edge onto it;
    • one below the first rooftop: walk off the roof, lock on and dive.

    R stands them back up.

Using the motion kit in another game

dis_motion only needs two things from a host game:

  • A World implementation. Only one method is required:

    • sweep(start, end, half): move a box along a path and report the first blocking hit (point, normal, and whether it started inside something). A zero half is a line trace.

    The others have defaults: overlaps, water (the water volume at a point), ladder, blink_blocked (the game’s blink-blocking volumes) and pawn (a character’s centre, floor, torso height, facing, health, awareness and whether it’s running, for the sword and the assassinations). Every move is built on these, so any collision a host has will do. BoxWorld (axis-aligned boxes) is included.

  • An Input each frame: move axes, look delta, and jump, crouch, sprint, walk, lean, Blink and attack buttons.

Then:

let data = dis_data::load(&install, dis_data::Difficulty::Normal)?;
// Agility's levels are 1 and 2; leave this out for none.
let data = data.with_power(dis_data::powers::AGILITY, 1);
let mut motion = Motion::new(MotionTuning::from_game(&data), spawn, yaw);
// every frame
let events = motion.update(&world, &input, dt);

Read back motion.camera.eye, motion.yaw, motion.pitch, motion.camera.roll and motion.camera.fov_deg for the camera, motion.state and events (including power_jumped, and mantled with mantle_impact for a hard catch) for animation and sound, motion.blink (mode, target and fx screen parameters) for Blink’s visuals, and motion.takedown (the prompt, the lock-on and the kill under way) plus events.drop_assassination and events.assassination (which also says where to put the victim) to kill the target on your side, and motion.melee (the swing playing and the target) plus events.melee (swings, hits with their damage, wall strikes) for the sword. Coordinates are Unreal-style: Z up, centimetres. Convert at your boundary.

Tests

cargo test --workspace

crates/dis_motion/tests/motion.rs drives the controller with scripted input. It checks:

  • settling on the floor and running at run speed;
  • the gait: full speed straight ahead and on the forward diagonal, the strafe factor sideways and on the back diagonal, the backward factor straight back, walking and slow walking on a light push, the sprint’s backward factor, and the sword’s slowdown;
  • the top speed blending down after a sprint, and braking to a dead stop;
  • air control steering without adding speed past ground speed, and the terminal velocity;
  • the jump apex against ballistics;
  • Agility’s power jump: only when jump is held to the top, once, and not without the power; and the other two jump styles;
  • stepping up small ledges and mantling tall ones; the edge finder’s step-up for low edges and animation-driven climb (facing the edge) for high ones, refusing walls at a glancing angle, crouching under a low roof, and catching edges only well past them when falling fast;
  • the slide easing to crouch speed, cancelling only after its first part, and stopping dead when a wall turns it;
  • the lean swinging the head out on its lever to the angle limit, holding the view, and springing back;
  • auto-crouching under a low gap, and crawling under one too low to sneak under;
  • Blink reaching a wall and keeping momentum, staying on the floor when cast crouched, and its squashed-sphere range;
  • swimming at the surface, at water speed with the sword put away and gliding when you let go, climbing a ladder, and leaping off it along the view;
  • the sword: forehand and backhand chaining, hitting a guard in reach and finishing it with a killing blow, recoiling off a wall, missing out of reach, the reach growing with forward speed, and the sneak attack when crouched;
  • the ground assassination: killing an unaware guard from behind with the victim placed in front, refusing guards in combat or running, slow then fast kills, and the plain kill when the world is in the way;
  • the drop assassination: a kill in reach, the lock-on dive from higher up, the side chosen from the target’s facing, the landing place, sweeping Corvo’s box, and no target when something is in the way, when rising or on the ground.

One test runs on your install’s real tuning when it can find it, and skips otherwise.

Where the numbers come from

All the tuning is read at runtime by crates/dis_data, and cargo run --release -p dis_data --example dump_tuning prints everything it found.

  • Corvo’s tweak tree (Startup.upk): the root is Twk_Pawn_Corvo.Twk_Pawn_Corvo_Release. It points at one attribute set per difficulty (each DisAttribute holds four values, Easy to VeryHard), the mantle tweaks, a separate mantle tweak used after a blink, and the camera tweaks.
  • Pawn defaults (DishonoredGame.upk, Engine.upk): collision size, crouch size, step height, eye height, ladder speed, walkable floor angle and friction, from the class default objects.
  • INI files: gravity, lean springs, swim strokes, FOV, bob and roll, the jump style, and the powers’ upgrade levels with their attribute modifiers.
  • Animations (Startup.upk): slides and landings last as long as the animations that play them, and mantles follow their animation’s root motion until its exit notify.
  • Behaviour: Blink’s targeting, travel, end and screen effect, and the jump, follow the behaviour specified in NOTES.md §5; the drop assassination follows §5b, the sword §5c, the ground assassination §5d, Agility §5e, the mantle §5f, the slide and lean §5g and walking §5h. No game code, decompiled or otherwise, is in this repository.

Layout

crates/dis_motion/     the motion kit: engine-agnostic, depends only on glam
  src/controller.rs    the state machine: walk, crouch, jump, fall, slide, mantle, swim, ladder, Blink travel
  src/blink.rs         Blink targeting, range, pull-back, stepping, cooldown and screen parameters
  src/melee.rs         the sword: swing choice and chaining, reach, target, blade sweep, wall recoil
  src/takedown.rs      drop and ground assassinations: targets, lock-on dive, sides, pacing and placement
  src/camera.rs        eye height, bob, roll, landing dip, lean spring, FOV
  src/collide.rs       collide-and-slide on top of World::sweep
  src/boxworld.rs      a World made of axis-aligned boxes, water, ladders and pawns
  src/tuning.rs        MotionTuning, built from the game's values
  tests/motion.rs      one test per move, by scripted input
crates/dis_data/       finds the install and loads tuning, sounds, effects, arms, textures and sword and drop-assassination data from it
crates/upk/            UE3 package reader: LZO, names, imports, exports, tagged properties, textures, skeletal/static meshes
crates/edge_anim/      Sony Edge animation decoder
crates/wwise/          Wwise sound packages (AKPK, bank v65) to Ogg
crates/cascade/        UE3 Cascade particle systems: loading, materials and simulation
crates/sinhonor_demo/  the Bevy test course
  src/main.rs          app, input, camera, sounds, effect triggers, HUD, autopilot
  src/hands.rs         Corvo's arms and sword: animation layers, CPU skinning, viewmodel camera
  src/blink_post.rs     Blink radial blur and lens distortion render pass (embedded WGSL)
  src/fx.rs            particle rendering, in the world, on the lens and in the viewmodel
  src/level.rs         the test course, as data
NOTES.md               research notes: formats, the game's motion and Blink, credits

The examples/ of upk, cascade, edge_anim, wwise and dis_data are the dev tools used to work all this out: package dumps, particle simulation, texture and animation probes, and a reference finder.

Screenshot mode

cargo run --release -p sinhonor_demo -- --autopilot shots plays a scripted route with no mouse needed: a mantle, a blink, the ladder, the rooftop blink, a slide, a close-up of the Blink marker and the arrival lens effect. It prints the motion state at each checkpoint, saves a PNG of each into shots/, and quits. Add --route fx for the effects route instead: the Blink marker near and far, mid-travel, gravel, puddle, falling into the pool, swimming and climbing out. --route drop plays the three drop assassinations: off the balcony, diving from the rooftop, and blinking up beside a guard. --route sword chains three swings into a guard, swings at a wall and makes a sneak attack. --route assassinate assassinates one guard from behind (slow) and another from the side (fast). --route lean leans out from behind a pillar both ways and slides into a wall. --route agility holds a jump at the 3.2 m block without Agility and then with it (power jump, then onto the block), and sprints with Agility II. It’s handy for checking nothing broke after a change.

Purpose and scope

sinhonor is an independent, non-commercial research and interoperability project. Its aim is to understand how Dishonored’s player movement, Blink, sword and assassinations feel, and to make that feel usable in other games through original code.

  • You need your own copy. It works only with a legitimately purchased install. The demo reads that install on your machine, at runtime.
  • Nothing from the game is distributed. This repository contains no game assets, data, configuration, executable code or decompiled code, and none is generated into it. The .gitignore is a whitelist so none can be committed by accident.
  • The game is left untouched. Nothing here modifies, patches or injects into the installed game or its files. It doesn’t run alongside the game, doesn’t connect to any online service, and doesn’t bypass any copy protection or access control.
  • The code is original. The file-format readers are written from public format documentation (credited below and in NOTES.md) and from examining the file formats so the data can be read. The movement, Blink, sword and assassination code implements a behaviour specification written in our own words. No code from the game or from other projects’ decompilations is used.

Dishonored and its content belong to ZeniMax Media and Arkane Studios. If you hold rights in that content and have a concern about anything here, please open an issue and it will be addressed promptly.

Credits and licenses

Built with help from UE Viewer, UELib, ue3-tools, dishonoredrecompiled’s format notes, CodeRed-Generator, ww2ogg and lewton, on Bevy and glam. Structural references: iw4L, gang-beasts-rust, benilla and 2010-rust-rewrite-mashup; dishonored-bevy was consulted for facts only. NOTES.md §8 has the full list with licenses.

This project is dual-licensed under MIT or Apache-2.0. Dishonored is a trademark of ZeniMax Media; this project is not affiliated with Arkane Studios or Bethesda.


License and provenance

The README and its translation retain MIT terms. Changes comprise translation, links and formatting. Editable Markdown, the original README, LICENSE and NOTICE files are included in the linked bundle. This grants no rights to the original games, their assets or trademarks.

LICENSE-APACHE

Apache License
                        Version 2.0, January 2004
                     http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

   "License" shall mean the terms and conditions for use, reproduction,
   and distribution as defined by Sections 1 through 9 of this document.

   "Licensor" shall mean the copyright owner or entity authorized by
   the copyright owner that is granting the License.

   "Legal Entity" shall mean the union of the acting entity and all
   other entities that control, are controlled by, or are under common
   control with that entity. For the purposes of this definition,
   "control" means (i) the power, direct or indirect, to cause the
   direction or management of such entity, whether by contract or
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
   outstanding shares, or (iii) beneficial ownership of such entity.

   "You" (or "Your") shall mean an individual or Legal Entity
   exercising permissions granted by this License.

   "Source" form shall mean the preferred form for making modifications,
   including but not limited to software source code, documentation
   source, and configuration files.

   "Object" form shall mean any form resulting from mechanical
   transformation or translation of a Source form, including but
   not limited to compiled object code, generated documentation,
   and conversions to other media types.

   "Work" shall mean the work of authorship, whether in Source or
   Object form, made available under the License, as indicated by a
   copyright notice that is included in or attached to the work
   (an example is provided in the Appendix below).

   "Derivative Works" shall mean any work, whether in Source or Object
   form, that is based on (or derived from) the Work and for which the
   editorial revisions, annotations, elaborations, or other modifications
   represent, as a whole, an original work of authorship. For the purposes
   of this License, Derivative Works shall not include works that remain
   separable from, or merely link (or bind by name) to the interfaces of,
   the Work and Derivative Works thereof.

   "Contribution" shall mean any work of authorship, including
   the original version of the Work and any modifications or additions
   to that Work or Derivative Works thereof, that is intentionally
   submitted to Licensor for inclusion in the Work by the copyright owner
   or by an individual or Legal Entity authorized to submit on behalf of
   the copyright owner. For the purposes of this definition, "submitted"
   means any form of electronic, verbal, or written communication sent
   to the Licensor or its representatives, including but not limited to
   communication on electronic mailing lists, source code control systems,
   and issue tracking systems that are managed by, or on behalf of, the
   Licensor for the purpose of discussing and improving the Work, but
   excluding communication that is conspicuously marked or otherwise
   designated in writing by the copyright owner as "Not a Contribution."

   "Contributor" shall mean Licensor and any individual or Legal Entity
   on behalf of whom a Contribution has been received by Licensor and
   subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   copyright license to reproduce, prepare Derivative Works of,
   publicly display, publicly perform, sublicense, and distribute the
   Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   (except as stated in this section) patent license to make, have made,
   use, offer to sell, sell, import, and otherwise transfer the Work,
   where such license applies only to those patent claims licensable
   by such Contributor that are necessarily infringed by their
   Contribution(s) alone or by combination of their Contribution(s)
   with the Work to which such Contribution(s) was submitted. If You
   institute patent litigation against any entity (including a
   cross-claim or counterclaim in a lawsuit) alleging that the Work
   or a Contribution incorporated within the Work constitutes direct
   or contributory patent infringement, then any patent licenses
   granted to You under this License for that Work shall terminate
   as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
   Work or Derivative Works thereof in any medium, with or without
   modifications, and in Source or Object form, provided that You
   meet the following conditions:

   (a) You must give any other recipients of the Work or
       Derivative Works a copy of this License; and

   (b) You must cause any modified files to carry prominent notices
       stating that You changed the files; and

   (c) You must retain, in the Source form of any Derivative Works
       that You distribute, all copyright, patent, trademark, and
       attribution notices from the Source form of the Work,
       excluding those notices that do not pertain to any part of
       the Derivative Works; and

   (d) If the Work includes a "NOTICE" text file as part of its
       distribution, then any Derivative Works that You distribute must
       include a readable copy of the attribution notices contained
       within such NOTICE file, excluding those notices that do not
       pertain to any part of the Derivative Works, in at least one
       of the following places: within a NOTICE text file distributed
       as part of the Derivative Works; within the Source form or
       documentation, if provided along with the Derivative Works; or,
       within a display generated by the Derivative Works, if and
       wherever such third-party notices normally appear. The contents
       of the NOTICE file are for informational purposes only and
       do not modify the License. You may add Your own attribution
       notices within Derivative Works that You distribute, alongside
       or as an addendum to the NOTICE text from the Work, provided
       that such additional attribution notices cannot be construed
       as modifying the License.

   You may add Your own copyright statement to Your modifications and
   may provide additional or different license terms and conditions
   for use, reproduction, or distribution of Your modifications, or
   for any such Derivative Works as a whole, provided Your use,
   reproduction, and distribution of the Work otherwise complies with
   the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
   any Contribution intentionally submitted for inclusion in the Work
   by You to the Licensor shall be under the terms and conditions of
   this License, without any additional terms or conditions.
   Notwithstanding the above, nothing herein shall supersede or modify
   the terms of any separate license agreement you may have executed
   with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
   names, trademarks, service marks, or product names of the Licensor,
   except as required for reasonable and customary use in describing the
   origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
   agreed to in writing, Licensor provides the Work (and each
   Contributor provides its Contributions) on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied, including, without limitation, any warranties or conditions
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   PARTICULAR PURPOSE. You are solely responsible for determining the
   appropriateness of using or redistributing the Work and assume any
   risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
   whether in tort (including negligence), contract, or otherwise,
   unless required by applicable law (such as deliberate and grossly
   negligent acts) or agreed to in writing, shall any Contributor be
   liable to You for damages, including any direct, indirect, special,
   incidental, or consequential damages of any character arising as a
   result of this License or out of the use or inability to use the
   Work (including but not limited to damages for loss of goodwill,
   work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses), even if such Contributor
   has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
   the Work or Derivative Works thereof, You may choose to offer,
   and charge a fee for, acceptance of support, warranty, indemnity,
   or other liability obligations and/or rights consistent with this
   License. However, in accepting such obligations, You may act only
   on Your own behalf and on Your sole responsibility, not on behalf
   of any other Contributor, and only if You agree to indemnify,
   defend, and hold each Contributor harmless for any liability
   incurred by, or claims asserted against, such Contributor by reason
   of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

   To apply the Apache License to your work, attach the following
   boilerplate notice, with the fields enclosed by brackets "[]"
   replaced with your own identifying information. (Don't include
   the brackets!)  The text should be enclosed in the appropriate
   comment syntax for the file format. We also recommend that a
   file or class name and description of purpose be included on the
   same "printed page" as the copyright notice for easier
   identification within third-party archives.

Copyright 2020 Cameron Hart

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

LICENSE-MIT

MIT License

Copyright (c) 2026 sinhonor contributors

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.