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 them_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_PlayerInputthresholds). 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 atm_fSpeedBlendDownSpeedrather than at once. - Jump: launches at 8 m/s straight up (
m_JumpZ, the same attribute the game’sStatePlayerMasterJumpreads) 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_fSneakHeighton 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_fAutoCrouchTestDistance1 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_fSlidePercentNotCancelable0.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 fromm_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.
- it first measures the room above you, then sweeps a box your size forward 50 cm (
- 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 ofFluidFriction) 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
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_01sits on the ground under the target, pitched 90° down as the game places it.Blink_Fall_01floats at the target when it’s above the ground.Blink_Mantle_01shows 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_fMoveBlurMaxStrengthand 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_JumpStyleinDefaultPlayerState.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’sm_fRaySpeedScalesettings). 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..._BigChainmid-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_ProbeExtentsswept 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*_Masteranimation 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_animdecodes 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, thenPowers_Cast_Blink_In,…_Loopand…_Outaround a blink). Changes crossfade over 0.18 s. - Camera bone: the view is the skeleton’s
camera_jntbone, so the arms sit exactly where the game puts them at its 75° FOV. - Sword: held on the
RightHandWpnsocket. 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_Inand_LooptriggerPs_Tattoo_Glow_02on the hand’sTattoosocket at 0 s (so it re-fires on every 0.33 s loop while you aim), and_OuttriggersPs_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.
-
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).
-
Stairs on the right, 20 cm risers up to a 3 m balcony.
-
Gravel patch on the left and a puddle on the right, for footsteps and their dust and splashes.
-
Pool behind you to the left: 4 m deep, for swimming and climbing out.
-
Slide lane: a crawl beam 1 m off the ground that only fits you crawling.
-
Lean pillars to peek round.
-
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.
-
The perch: an 11 m pillar you can only reach by blinking upward from the rooftops.
-
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
Worldimplementation. 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 zerohalfis a line trace.
The others have defaults:
overlaps,water(the water volume at a point),ladder,blink_blocked(the game’s blink-blocking volumes) andpawn(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
Inputeach 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 isTwk_Pawn_Corvo.Twk_Pawn_Corvo_Release. It points at one attribute set per difficulty (eachDisAttributeholds 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
.gitignoreis 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.

Comments
…