anchor.diff:          static let getOpenNeighborPositionMsFromPositionM occupationMap positionM =
               let openDirections = getOpenDirectionsFromPositionM positionM occupationMap
               Set.map (fun direction -> positionM + dtovm direction) openDirections
  +
  +        static let getCharacterAnimationStateByActionBegin tickTime characterPosition characterAnimationState actionDescriptor =
  +            let currentDirection = characterAnimationState.Direction
  +            let direction = ActionDescriptor.getActionDirection characterPosition currentDirection actionDescriptor
  +            { characterAnimationState with
  +                Direction = direction
  +                AnimationType = CharacterAnimationActing
  +                StartTime = tickTime }
  +
  +        static let getCharacterAnimationStateByActionEnd tickTime characterAnimationState =
  +            { characterAnimationState with
  +                AnimationType = CharacterAnimationFacing
  +                StartTime = tickTime }
  +
  +        static let makeNavigationNodes occupationMap =
  +        
  +            // make the nodes without neighbors
  +            let nodes = Map.map (fun positionM _ -> { PositionM = positionM; Neighbors = [] }) occupationMap
  +
  +            // OPTIMIZATION: populate node neghbors imperatively for speed
  +            Map.iter
  +                (fun positionM node -> 
  +                    let neighborPositionMs = List.ofSeq <| getOpenNeighborPositionMsFromPositionM occupationMap positionM
  +                    let neighbors =
  +                        List.fold
  +                            (fun neighbors neighborPositionM ->
  +                                match Map.tryFind neighborPositionM nodes with
  +                                | Some node -> node :: neighbors
  +                                | None -> neighbors)
  +                            []
  +                            neighborPositionMs
  +                    node.Neighbors <- neighbors)
  +                nodes
  +
  +            // teh nodes
  +            nodes
  +
  +        static let tryGetNavigationPath touchPosition occupationMap (character : Entity) =
  +            let nodes = makeNavigationNodes occupationMap
  +            let goalNode = Map.find (vftovm touchPosition) nodes
  +            let currentNode = Map.find (vftovm character.Position) nodes
  +            let optNavigationPath =
  +                AStar.FindPath (
  +                    currentNode,
  +                    goalNode,
  +                    (fun n n2 -> if n2.PositionM.Y <> n.PositionM.Y then 2.0f else 1.0f), // prefer horizontal walk to vertical for predictability
  +                    (fun n -> 0.0f))
  +            match optNavigationPath with
  +            | null -> None
  +            | navigationPath -> Some (navigationPath |> List.ofSeq |> List.rev |> List.tail)
  +
  +        static let cancelNavigation (character : Entity) =
  +            let characterActivity = character.ActivityState
  +            let characterActivity =
  +                match characterActivity with
  +                | Action _ as action -> action
  +                | NoActivity -> NoActivity
  +                | Navigation navDescriptor -> Navigation { navDescriptor with OptNavigationPath = None }
  +            Entity.setActivityState characterActivity character
  +
  +        static let determineCharacterTurnFromDirection direction occupationMap (character : Entity) opponents =
  +            match character.ActivityState with
  +            | Action _ -> NoTurn
  +            | Navigation _ -> NoTurn
  +            | NoActivity ->
  +                let openDirections = getOpenDirectionsFromPosition character.Position occupationMap
  +                if Set.contains direction openDirections then
  +                    let walkDescriptor = { WalkDirection = direction; WalkOriginM = vftovm character.Position }
  +                    NavigationTurn { WalkDescriptor = walkDescriptor; OptNavigationPath = None }
  +                else
  +                    let targetPosition = character.Position + dtovf direction
  +                    if List.exists (fun (opponent : Entity) -> opponent.Position = targetPosition) opponents
  +                    then makeAttackTurn <| vftovm targetPosition
  +                    else NoTurn
  +
  +        static let determineCharacterTurnFromTouch touchPosition occupationMap (character : Entity) opponents =
  +            match character.ActivityState with
  +            | Action _ -> NoTurn
  +            | Navigation _ -> NoTurn
  +            | NoActivity ->
  +                match tryGetNavigationPath touchPosition occupationMap character with
  +                | Some navigationPath ->
  +                    match navigationPath with
  +                    | [] -> NoTurn
  +                    | _ ->
  +                        let characterPositionM = vftovm character.Position
  +                        let walkDirection = vmtod <| (List.head navigationPath).PositionM - characterPositionM
  +                        let walkDescriptor = { WalkDirection = walkDirection; WalkOriginM = characterPositionM }
  +                        NavigationTurn { WalkDescriptor = walkDescriptor; OptNavigationPath = Some navigationPath }
  +                | None ->
  +                    let targetPosition = touchPosition |> vftovm |> vmtovf
  +                    if Math.arePositionsAdjacent targetPosition character.Position then
  +                        if List.exists (fun (opponent : Entity) -> opponent.Position = targetPosition) opponents
  +                        then makeAttackTurn <| vftovm targetPosition
  +                        else NoTurn
  +                    else NoTurn
  +
  +        static let determineDesiredEnemyTurn occupationMap (player : Entity) (enemy : Entity) rand =
  +            match enemy.ControlType with
  +            | Player ->
  +                debug <| "Invalid ControlType '" + acstring enemy.ControlType + "' for enemy"
  +                (NoTurn, rand)
  +            | Chaos ->
  +                let nextPlayerPosition =
  +                    match player.ActivityState with
  +                    | Action _ -> player.Position
  +                    | Navigation navigationDescriptor -> NavigationDescriptor.nextPosition navigationDescriptor
  +                    | NoActivity -> player.Position
  +                if Math.arePositionsAdjacent enemy.Position nextPlayerPosition then
  +                    let enemyTurn = makeAttackTurn <| vftovm nextPlayerPosition
  +                    (enemyTurn, rand)
  +                else
  +                    let (randResult, rand) = Rand.nextIntUnder 4 rand
  +                    let direction = Direction.fromInt randResult
  +                    let enemyTurn = determineCharacterTurnFromDirection direction occupationMap enemy [player]
  +                    (enemyTurn, rand)
  +            | Uncontrolled -> (NoTurn, rand)
  +
  +        static let determineDesiredEnemyTurns occupationMap player enemies rand =
  +            let (_, enemyTurns, rand) =
  +                List.foldBack
  +                    (fun (enemy : Entity) (occupationMap, enemyTurns, rand) ->
  +                        let (enemyTurn, rand) = determineDesiredEnemyTurn occupationMap player enemy rand
  +                        let occupationMap = OccupationMap.transferByDesiredTurn enemyTurn enemy occupationMap
  +                        (occupationMap, enemyTurn :: enemyTurns, rand))
  +                    enemies
  +                    (occupationMap, [], rand)
  +            (enemyTurns, rand)
  +
  +        static let determinePlayerTurnFromTouch gameplayAddress touchPosition world =
  +            let (field, player, enemies) = getParticipants gameplayAddress world
  +            if not <| anyTurnsInProgress2 player enemies then
  +                let touchPositionW = Camera.mouseToWorld Relative touchPosition world.Camera
  +                let occupationMapWithAdjacentEnemies =
  +                    OccupationMap.makeFromFieldTilesAndAdjacentCharacters
  +                        (vftovm player.Position)
  +                        field.FieldMapNp.FieldTiles
  +                        enemies
  +                match determineCharacterTurnFromTouch touchPositionW occupationMapWithAdjacentEnemies player enemies with
  +                | ActionTurn _ as actionTurn -> actionTurn
  +                | NavigationTurn navigationDescriptor as navigationTurn ->
  +                    let firstNavigationNode = List.head <| Option.get ^^ navigationDescriptor.OptNavigationPath
  +                    let occupationMapWithEnemies = OccupationMap.makeFromFieldTilesAndCharacters field.FieldMapNp.FieldTiles enemies
  +                    if Map.find firstNavigationNode.PositionM occupationMapWithEnemies then CancelTurn
  +                    else navigationTurn
  +                | CancelTurn -> CancelTurn
  +                | NoTurn -> NoTurn
  +            else NoTurn
  +
  +        static let determinePlayerTurnFromDetailNavigation gameplayAddress direction world =
  +            let (field, player, enemies) = getParticipants gameplayAddress world
  +            if not <| anyTurnsInProgress2 player enemies then
  +                let occupationMapWithEnemies = OccupationMap.makeFromFieldTilesAndCharacters field.FieldMapNp.FieldTiles enemies
  +                determineCharacterTurnFromDirection direction occupationMapWithEnemies player enemies
  +            else NoTurn
  +
  +        static let determinePlayerTurnFromInput gameplayAddress playerInput world =
  +            match playerInput with
  +            | TouchInput touchPosition -> determinePlayerTurnFromTouch gameplayAddress touchPosition world
  +            | DetailInput direction -> determinePlayerTurnFromDetailNavigation gameplayAddress direction world
  +            | NoInput -> NoTurn
  +
  +        static let determinePlayerTurn gameplayAddress world =
  +            let player = getPlayer gameplayAddress world
  +            match player.ActivityState with
  +            | Action _ -> NoTurn
  +            | Navigation navigationDescriptor ->
  +                let walkDescriptor = navigationDescriptor.WalkDescriptor
  +                if player.Position = vmtovf walkDescriptor.WalkOriginM then
  +                    let field = getField gameplayAddress world
  +                    let enemies = getEnemies gameplayAddress world
  +                    let occupationMapWithEnemies = OccupationMap.makeFromFieldTilesAndCharacters field.FieldMapNp.FieldTiles enemies
  +                    let walkDestinationM = walkDescriptor.WalkOriginM + dtovm walkDescriptor.WalkDirection
  +                    if Map.find walkDestinationM occupationMapWithEnemies then CancelTurn
  +                    else NavigationTurn navigationDescriptor
  +                else NoTurn
  +            | NoActivity -> NoTurn
  +
  +        static let determineEnemyActionActivities enemies =
  +            List.foldBack
  +                (fun (enemy : Entity) precedingEnemyActivities ->
  +                    let enemyActivity =
  +                        let noPrecedingEnemyActionActivity =
  +                            List.notExists ActivityState.isActing precedingEnemyActivities
  +                        let noCurrentEnemyActionActivity =
  +                            List.notExists (fun (enemy : Entity) -> ActivityState.isActing enemy.ActivityState) enemies
  +                        if  noPrecedingEnemyActionActivity &&
  +                            noCurrentEnemyActionActivity then
  +                            match enemy.DesiredTurn with
  +                            | ActionTurn actionDescriptor -> Action actionDescriptor
  +                            | NavigationTurn _ -> NoActivity
  +                            | CancelTurn -> NoActivity
  +                            | NoTurn -> NoActivity
  +                        else NoActivity
  +                    enemyActivity :: precedingEnemyActivities)
  +                enemies
  +                []
  +
  +        static let determineEnemyNavigationActivities enemies =
  +            List.foldBack
  +                (fun (enemy : Entity) enemyActivities ->
  +                    let noCurrentEnemyActionActivity =
  +                        List.notExists
  +                            (fun (enemy : Entity) -> ActivityState.isActing enemy.ActivityState)
  +                            enemies
  +                    let enemyActivity =
  +                        if noCurrentEnemyActionActivity then
  +                            match enemy.DesiredTurn with
  +                            | ActionTurn _ -> NoActivity
  +                            | NavigationTurn navigationDescriptor -> Navigation navigationDescriptor
  +                            | CancelTurn -> NoActivity
  +                            | NoTurn -> NoActivity
  +                        else NoActivity
  +                    enemyActivity :: enemyActivities)
  +                enemies
  +                []
   
           static let runCharacterNavigation newNavigationDescriptor gameplayAddress characterAddress world =
               let desync = desync {
  
positive.code:             | Navigation newNavigationDescriptor -> runCharacterNavigation newNavigationDescriptor gameplayAddress characterAddress world
              | NoActivity -> runCharacterNoActivity characterAddress world
  
          static let determineCharacterTurnFromDirection direction occupationMap (character : Entity) opponents =
              match character.ActivityState with
              | Action _ -> NoTurn
              | Navigation _ -> NoTurn
              | NoActivity ->
                  let openDirections = getOpenDirectionsFromPosition character.Position occupationMap
                  if Set.contains direction openDirections then
                      let walkDescriptor = { WalkDirection = direction; WalkOriginM = vftovm character.Position }
                      NavigationTurn { WalkDescriptor = walkDescriptor; OptNavigationPath = None }
                  else
                      let targetPosition = character.Position + dtovf direction
                      if List.exists (fun (opponent : Entity) -> opponent.Position = targetPosition) opponents
                      then makeAttackTurn <| vftovm targetPosition
                      else NoTurn
  
          static let makeNavigationNodes occupationMap =
          
              // make the nodes without neighbors
              let nodes = Map.map (fun positionM _ -> { PositionM = positionM; Neighbors = [] }) occupationMap
  
              // OPTIMIZATION: populate node neghbors imperatively for speed
              Map.iter
                  (fun positionM node -> 
                      let neighborPositionMs = List.ofSeq <| getOpenNeighborPositionMsFromPositionM occupationMap positionM
                      let neighbors =
                          List.fold
                              (fun neighbors neighborPositionM ->
                                  match Map.tryFind neighborPositionM nodes with
                                  | Some node -> node :: neighbors
                                  | None -> neighbors)
                              []
                              neighborPositionMs
                      node.Neighbors <- neighbors)
                  nodes
  
              // teh nodes
              nodes
  
          static let tryGetNavigationPath touchPosition occupationMap (character : Entity) =
              let nodes = makeNavigationNodes occupationMap
              let goalNode = Map.find (vftovm touchPosition) nodes
              let currentNode = Map.find (vftovm character.Position) nodes
              let optNavigationPath =
                  AStar.FindPath (
                      currentNode,
                      goalNode,
                      (fun n n2 -> if n2.PositionM.Y <> n.PositionM.Y then 2.0f else 1.0f), // prefer horizontal walk to vertical for predictability
                      (fun n -> 0.0f))
              match optNavigationPath with
              | null -> None
              | navigationPath -> Some (navigationPath |> List.ofSeq |> List.rev |> List.tail)
  
          static let determineCharacterTurnFromTouch touchPosition occupationMap (character : Entity) opponents =
              match character.ActivityState with
              | Action _ -> NoTurn
              | Navigation _ -> NoTurn
              | NoActivity ->
                  match tryGetNavigationPath touchPosition occupationMap character with
                  | Some navigationPath ->
                      match navigationPath with
                      | [] -> NoTurn
                      | _ ->
                          let characterPositionM = vftovm character.Position
                          let walkDirection = vmtod <| (List.head navigationPath).PositionM - characterPositionM
                          let walkDescriptor = { WalkDirection = walkDirection; WalkOriginM = characterPositionM }
                          NavigationTurn { WalkDescriptor = walkDescriptor; OptNavigationPath = Some navigationPath }
                  | None ->
                      let targetPosition = touchPosition |> vftovm |> vmtovf
                      if Math.arePositionsAdjacent targetPosition character.Position then
                          if List.exists (fun (opponent : Entity) -> opponent.Position = targetPosition) opponents
                          then makeAttackTurn <| vftovm targetPosition
                          else NoTurn
                      else NoTurn
  
          static let cancelNavigation (character : Entity) =
              let characterActivity = character.ActivityState
              let characterActivity =
                  match characterActivity with
                  | Action _ as action -> action
                  | NoActivity -> NoActivity
                  | Navigation navDescriptor -> Navigation { navDescriptor with OptNavigationPath = None }
              Entity.setActivityState characterActivity character
  
          static let determineDesiredEnemyTurn occupationMap (player : Entity) (enemy : Entity) rand =
              match enemy.ControlType with
              | Player ->
                  debug <| "Invalid ControlType '" + acstring enemy.ControlType + "' for enemy"
                  (NoTurn, rand)
              | Chaos ->
                  let nextPlayerPosition =
                      match player.ActivityState with
                      | Action _ -> player.Position
                      | Navigation navigationDescriptor -> NavigationDescriptor.nextPosition navigationDescriptor
                      | NoActivity -> player.Position
                  if Math.arePositionsAdjacent enemy.Position nextPlayerPosition then
                      let enemyTurn = makeAttackTurn <| vftovm nextPlayerPosition
                      (enemyTurn, rand)
                  else
                      let (randResult, rand) = Rand.nextIntUnder 4 rand
                      let direction = Direction.fromInt randResult
                      let enemyTurn = determineCharacterTurnFromDirection direction occupationMap enemy [player]
                      (enemyTurn, rand)
              | Uncontrolled -> (NoTurn, rand)
  
          static let determineDesiredEnemyTurns occupationMap player enemies rand =
              let (_, enemyTurns, rand) =
                  List.foldBack
                      (fun (enemy : Entity) (occupationMap, enemyTurns, rand) ->
                          let (enemyTurn, rand) = determineDesiredEnemyTurn occupationMap player enemy rand
                          let occupationMap = OccupationMap.transferByDesiredTurn enemyTurn enemy occupationMap
                          (occupationMap, enemyTurn :: enemyTurns, rand))
                      enemies
                      (occupationMap, [], rand)
              (enemyTurns, rand)
  
          static let determinePlayerTurnFromTouch gameplayAddress touchPosition world =
              let (field, player, enemies) = getParticipants gameplayAddress world
              if not <| anyTurnsInProgress2 player enemies then
                  let touchPositionW = Camera.mouseToWorld Relative touchPosition world.Camera
                  let occupationMapWithAdjacentEnemies =
                      OccupationMap.makeFromFieldTilesAndAdjacentCharacters
                          (vftovm player.Position)
                          field.FieldMapNp.FieldTiles
                          enemies
                  match determineCharacterTurnFromTouch touchPositionW occupationMapWithAdjacentEnemies player enemies with
                  | ActionTurn _ as actionTurn -> actionTurn
                  | NavigationTurn navigationDescriptor as navigationTurn ->
                      let firstNavigationNode = List.head <| Option.get ^^ navigationDescriptor.OptNavigationPath
                      let occupationMapWithEnemies = OccupationMap.makeFromFieldTilesAndCharacters field.FieldMapNp.FieldTiles enemies
                      if Map.find firstNavigationNode.PositionM occupationMapWithEnemies then CancelTurn
                      else navigationTurn
                  | CancelTurn -> CancelTurn
                  | NoTurn -> NoTurn
              else NoTurn
  
          static let determinePlayerTurnFromDetailNavigation gameplayAddress direction world =
              let (field, player, enemies) = getParticipants gameplayAddress world
              if not <| anyTurnsInProgress2 player enemies then
                  let occupationMapWithEnemies = OccupationMap.makeFromFieldTilesAndCharacters field.FieldMapNp.FieldTiles enemies
                  determineCharacterTurnFromDirection direction occupationMapWithEnemies player enemies
              else NoTurn
  
          static let determinePlayerTurnFromInput gameplayAddress playerInput world =
              match playerInput with
              | TouchInput touchPosition -> determinePlayerTurnFromTouch gameplayAddress touchPosition world
              | DetailInput direction -> determinePlayerTurnFromDetailNavigation gameplayAddress direction world
              | NoInput -> NoTurn
  
          static let determinePlayerTurn gameplayAddress world =
              let player = getPlayer gameplayAddress world
              match player.ActivityState with
              | Action _ -> NoTurn
              | Navigation navigationDescriptor ->
                  let walkDescriptor = navigationDescriptor.WalkDescriptor
                  if player.Position = vmtovf walkDescriptor.WalkOriginM then
                      let field = getField gameplayAddress world
                      let enemies = getEnemies gameplayAddress world
                      let occupationMapWithEnemies = OccupationMap.makeFromFieldTilesAndCharacters field.FieldMapNp.FieldTiles enemies
                      let walkDestinationM = walkDescriptor.WalkOriginM + dtovm walkDescriptor.WalkDirection
                      if Map.find walkDestinationM occupationMapWithEnemies then CancelTurn
                      else NavigationTurn navigationDescriptor
                  else NoTurn
              | NoActivity -> NoTurn
  
          static let determineEnemyActionActivities enemies =
              List.foldBack
                  (fun (enemy : Entity) precedingEnemyActivities ->
                      let enemyActivity =
                          let noPrecedingEnemyActionActivity =
                              List.notExists ActivityState.isActing precedingEnemyActivities
                          let noCurrentEnemyActionActivity =
                              List.notExists (fun (enemy : Entity) -> ActivityState.isActing enemy.ActivityState) enemies
                          if  noPrecedingEnemyActionActivity &&
                              noCurrentEnemyActionActivity then
                              match enemy.DesiredTurn with
                              | ActionTurn actionDescriptor -> Action actionDescriptor
                              | NavigationTurn _ -> NoActivity
                              | CancelTurn -> NoActivity
                              | NoTurn -> NoActivity
                          else NoActivity
                      enemyActivity :: precedingEnemyActivities)
                  enemies
                  []
  
          static let determineEnemyNavigationActivities enemies =
              List.foldBack
                  (fun (enemy : Entity) enemyActivities ->
                      let noCurrentEnemyActionActivity =
                          List.notExists
                              (fun (enemy : Entity) -> ActivityState.isActing enemy.ActivityState)
                              enemies
                      let enemyActivity =
                          if noCurrentEnemyActionActivity then
                              match enemy.DesiredTurn with
                              | ActionTurn _ -> NoActivity
                              | NavigationTurn navigationDescriptor -> Navigation navigationDescriptor
                              | CancelTurn -> NoActivity
                              | NoTurn -> NoActivity
                          else NoActivity
                      enemyActivity :: enemyActivities)
                  enemies
                  []
  
          static let tryRunEnemyActivity gameplayAddress world newActivity enemyAddress =
              if newActivity <> NoActivity then
                  let enemy = World.getEntity enemyAddress world
  
negative.code:                 | CancelTurn -> Some NoActivity
                  | NoTurn -> None
  
              // run player activity
              let world =
                  match optNewPlayerActivity with
                  | Some newPlayerActivity ->
                      let playerAddress = getPlayerAddress gameplayAddress
                      runCharacterActivity newPlayerActivity gameplayAddress playerAddress world
                  | None -> world
  
              // determine (and set) enemy desired turns if applicable
              let world =
                  match optNewPlayerActivity with
                  | Some (Action _)
                  | Some (Navigation _) ->
                      let gameplay = World.getScreen gameplayAddress world
                      let rand = Rand.make gameplay.OngoingRandState
                      let player = getPlayer gameplayAddress world
                      let enemies = getEnemies gameplayAddress world
                      let (enemyDesiredTurns, rand) = determineDesiredEnemyTurns occupationMap player enemies rand
                      let enemies = List.map2 Entity.setDesiredTurn enemyDesiredTurns enemies
                      let world = World.setEntities (getSceneAddress gameplayAddress) enemies world
                      let gameplay = Screen.setOngoingRandState (Rand.getState rand) gameplay
                      World.setScreen gameplayAddress gameplay world
                  | Some NoActivity
                  | None -> world
  
              // run enemy activities in accordance with the player's current activity
              let world =
                  let player = getPlayer gameplayAddress world
                  let enemies = getEnemies gameplayAddress world
  