Dictionary causing error: illegal instruction 4 in my SpriteKit Game

Hi,


I am fairly new to iOS development and half way through developing a SpriteKit game in Swift 4, but I have come up against an error that I really don't know how to deal with.


I am using a dictionary to supply points to create the wall boundaries on a tilemap. However, if I uncomment the lines that are currently commented from 'room21' of my dictionary, I firstly get a message in XCode 9.2 saying there has been a bug which it will attempt to recover from, and if I build the code I get 'Command failed due to signal: illegal instruction 4'.


Any help here would be greatfully recieved as it is really holding up my progress!


I've attached a snippet from my controller here:


import UIKit
import SpriteKit
import GameplayKit

protocol GameManager: class {
    var stateMachine: GKStateMachine! { get set }
    var currentScene: SKScene? { get set }
    var emptyTiles:[Int:Array<CGRect>] { get set }
    var edgeTiles:Array<EdgeTileEntity> { get set }
    var brickTiles:Set<BrickTileEntity> { get set }
    var gameScene:GKScene? {get set}
    func didEnterTitleScene()
    func didEnterPlayScene()
}
class GameViewController: UIViewController, GameManager {
  
    var stateMachine: GKStateMachine!
    var currentScene: SKScene?
    var emptyTiles = [Int : Array<CGRect>]()
    var edgeTiles = Array<EdgeTileEntity>()
    var brickTiles = Set<BrickTileEntity>()
    var gameScene:GKScene?
  
    var points = [
        "room1":[
            [[0,1760],[640,0],[640,-64],[576,-64],[576,-32],[32,-32],[32,-288],[64,-288],[64, -320],[448,-320],[448, -352],[0,-352],[0,0]],
            [[576,1632],[64,0],[64,-96],[32,-96],[32,-64],[0,-64],[0,0]],
            [[608, 1472],[32,0],[32,-64],[-64,-64],[-64,-32],[0,-32],[0,0]]
        ],
        "room2":[
            [[640,1760],[640,0],[640,-64],[608,-64],[608,-32],[96,-32],[96,-64],[0,-64],[0,0]],
            [[640,1632],[32,0],[32,-32],[352,-32],[352,-192],[608,-192],[608,-32],[640,-32],[640,-224],[256,-224],[256,-192],[320,-192],[320,-64],[32,-64],[32,-96],[0,-96],[0,0]],
            [[640,1472],[32,0],[32,-32],[64,-32],[64,-64],[0,-64],[0,0]]
        ],
        "room3":[
            [[1280,1760],[640,0],[640,-128],[608,-128],[608,-32],[384,-32],[384,-96],[352,-96],[352,-32],[320,-32],[320,-160],[288,-160],[288,-32],[32,-32],[32,-64],[0,-64],[0,0]],
            [[1280,1600],[32,0],[32,-160],[416,-160],[416,-64],[448,-64],[448,-160],[608,-160],[608,-96],[640,-96],[640,-192],[0,-192],[0,0]]
        ],
        "room4":[
            [[1920,1760],[640,0],[640,-64],[512,-64],[512,-32],[32,-32],[32,-96],[160,-96],[160,-128],[0,-128],[0,0]],
            [[1920,1504],[32,0],[32,-64],[96,-64],[96,-96],[0,-96],[0,0]],
            [[2528,1536],[32,0],[32,-128],[-96,-128],[-96,-96],[0,-96],[0,0]]
        ],
        "room5":[
            [[2560,1760],[640,0],[640,-352],[544,-352],[544,-320],[608,-320],[608,-32],[64,-32],[64,-64],[0,-64],[0,0]],
            [[2560,1536],[480,0],[480,64],[544,64],[544,32],[512,32],[512,-32],[32,-32],[32,-96],[64,-96],[64,-128],[0,-128],[0,0]]
        ],
        "room6":[
            [[3200,1760],[640,0],[640,-352],[608,-352],[608,-32],[32,-32],[32,-320],[544,-320],[544,-352],[0,-352],[0,0]]
        ],
        "room7":[
            [[0,1408],[448,0],[448,-32],[32,-32],[32,-320],[224,-320],[224,-224],[256,-224],[256,-352],[0,-352],[0,0]],
            [[544,1408],[96,0],[96,-96],[64,-96],[64,-32],[0,-32],[0,0]],
            [[576,1248],[64,0],[64,-192],[-224,-192],[-224,-64],[-192,-64],[-192,-160],[32,-160],[32,-32],[0,-32],[0,0]]
        ],
        "room8":[
            [[640,1408],[64,0],[64,-32],[32,-32],[32,-96],[0,-96],[0,0]],
            [[896,1408],[384,0],[384,-32],[0,-32],[0,0]],
            [[1120,1280],[160,0],[160,-224],[-192,-224],[-192,-192],[128,-192],[128,-32],[0,-32],[0,0]],
            [[640,1248],[32,0],[32,-160],[160,-160],[160,-192],[0,-192],[0,0]]
        ],
        "room9":[
            [[1280,1408],[640,0],[640,-96],[608,-96],[608,-32],[0,-32],[0,0]],
            [[1280,1280],[32,0],[32,-192],[608,-192],[608,-128],[640,-128],[640,-224],[0,-224],[0,0]],
            [[1568,1248],[64,0],[64,-32],[0,-32],[0,0]],
            [[1760,1248],[160,0],[160,-32],[0,-32],[0,0]]
        ],
        "room10":[
            [[1920,1408],[96,0],[96,-32],[64,-32],[64,-64],[32,-64],[32,-96],[0,-96],[0,0]],
            [[2432,1408],[128,0],[128,-128],[96,-128],[96,-96],[64,-96],[64,-64],[32,-64],[32,-32],[0,-32],[0,0]],
            [[1920,1248],[128,0],[128,-32],[0,-32],[0,0]],
            [[1920,1152],[32,0],[32,-64],[608,-64],[608,32],[640,32],[640,-96],[0,-96],[0,0]]
        ],
        "room11":[
            [[2560,1408],[64,0],[64,-64],[32,-64],[32,-128],[0,-128],[0,0]],
            [[2560,1184],[32,0],[32,-128],[0,-128],[0,0]],
            [[2752,1312],[224,0],[224,-224],[256,-224],[256,-256],[192,-256],[192,-32],[32,-32],[32,-256],[-32,-256],[-32,-224],[0,-224],[0,0]],
            [[3104,1408],[96,0],[96,-224],[64,-224],[64,-32],[0,-32],[0,0]],
            [[3168,1120],[32,0],[32,-64],[-32,-64],[-32,-32],[0,-32],[0,0]]
        ],
        "room12":[
            [[3200,1408],[544,0],[544,-32],[32,-32],[32,-224],[0,-224],[0,0]],
            [[3200,1120],[32,0],[32,-32],[64,-32],[64,-64],[0,-64],[0,0]],
            [[3808,1408],[32,0],[32,-352],[-480,-352],[-480,-320],[0,-320],[0,0]]
        ],
        "room13":[
            [[0,1056],[256,0],[256,-32],[32,-32],[32,-320],[192,-320],[192,-224],[544,-224],[544,-256],[224,-256],[224,-352],[0,-352],[0,0]],
            [[352,1056],[288,0],[288,-64],[256,-64],[256,-32],[0,-32],[0,0]],
            [[608,928],[32,0],[32,-224],[-160,-224],[-160,-192],[0,-192],[0,0]]
        ],
        "room14":[
            [[640,1056],[160,0],[160,-32],[32,-32],[32,-64],[0,-64],[0,0]],
            [[928,1056],[352,0],[352,-352],[160,-352],[160,-288],[192,-288],[192,-320],[320,-320],[320,-32],[0,-32],[0,0]],
            [[640,928],[32,0],[32,-192],[288,-192],[288,-160],[320,-160],[320,-224],[0,-224],[0,0]]
        ],
        "room15":[
            [[1280,1056],[640,0],[640,-128],[608,-128],[608,-32],[416,-32],[416,-96],[384,-96],[384,-32],[352,-32],[352,-96],[320,-96],[320,-32],[32,-32],[32,-64],[256,-64],[256,-96],[32,-96],[32,-320],[64,-320],[64,-192],[96,-192],[96,-320],[160,-320],[160,-352],[0,-352],[0,0]],
            [[1504,736],[64,0],[64,-32],[0,-32],[0,0]],
            [[1632,736],[64,0],[64,-32],[0,-32],[0,0]],
            [[1760,992],[96,0],[96,-128],[160,-128],[160,-288],[0,-288],[0,-256],[64,-256],[64,-224],[96,-224],[96,-256],[128,-256],[128,-160],[64,-160],[64,-32],[0,-32],[0,0]]
        ],
        "room16":[
            [[1920,1056],[640,0],[640,-352],[0,-352],[0,-192],[32,-192],[32,-320],[608,-320],[608,-224],[544,-224],[544,-256],[512,-256],[512,-192],[608,-192],[608,-32],[544,-32],[544,-128],[416,-128],[416,-256],[384,-256],[384,-96],[512,-96],[512,-32],[32,-32],[32,-128],[0,-128],[0,0]]
        ],
        "room17":[
            [[2560,1056],[32,0],[32,-320],[608,-320],[608,-288],[640,-288],[640,-352],[0,-352],[0,0]],
            [[2720,1056],[64,0],[64,-96],[0,-96],[0,0]],
            [[2944,1056],[64,0],[64,-96],[0,-96],[0,0]],
            [[3136,1056],[64,0],[64,-64],[32,-64],[32,-32],[0,-32],[0,0]],
            [[3168,928],[32,0],[32,-96],[0,-96],[0,0]]
        ],
        "room18":[
            [[3200,1056],[64,0],[64,-32],[32,-32],[32,-64],[0,-64],[0,0]],
            [[3328,1056],[512,0],[512,-352],[384,-352],[384,-320],[480,-320],[480,-32],[0,-32],[0,0]],
            [[3200,928],[32,0],[32,-96],[0,-96],[0,0]],
            [[3424,832],[192,0],[192,-32],[128,-32],[128,-128],[64,-128],[64,-32],[0,-32],[0,0]],
            [[3200,768],[32,0],[32,-32],[128,-32],[128,-64],[0,-64],[0,0]]
        ],
        "room19":[
            [[0,704],[224,0],[224,-32],[32,-32],[32,-320],[192,-320],[192,-96],[224,-96],[224,-352],[0,-352],[0,0]],
            [[448,704],[192,0],[192,-352],[64,-352],[64,-320],[96,-320],[96,-288],[128,-288],[128,-256],[160,-256],[160,-32],[0,-32],[0,0]]
        ],
        "room20":[
            [[640,704],[320,0],[320,-32],[32,-32],[32,-320],[64,-320],[64,-352],[0,-352],[0,0]],
            [[1088,704],[192,0],[192,-192],[160,-192],[160,-160],[128,-160],[128,-128],[96,-128],[96,-96],[64,-96],[64,-64],[32,-64],[32,-32],[0,-32],[0,0]],
            [[960,384],[256,0],[256,32],[288,32],[288,64],[320,64],[320,-32],[0,-32],[0,0]]
        ],
        "room21": [
            [[1280,704],[160,0],[160,-64],[128,-64],[128,-32],[32,-32],[32,-192],[0,-192],[0,0]],
            [[1504,704],[64,0],[64,-32],[0,-32],[0,0]],
            [[1632,704],[64,0],[64,-32],[0,-32],[0,0]],
            //[[1760,704],[160,0],[160,-64],[128,-64],[128,-32],[32,-32],[32,-64],[0,-64],[0,0]],
        ],
        "room22": [
          
        ]
    ]
  
    var pathsForBoundaries = [String:[CGMutablePath]]()
    var startOfBoundaries = [String:[CGPoint]]()
  
    override func viewDidLoad() {
        super.viewDidLoad()
      
        /
      
        gameScene = GKScene(fileNamed: "GameScene")!
      
        let scene = gameScene?.rootNode as! GameScene
      
        guard let wallMap = scene.childNode(withName: "Wall Map") as? SKTileMapNode else { fatalError("Missing wall map") }
        guard let brickMap = scene.childNode(withName: "Brick Map") as? SKTileMapNode else { fatalError("Missing brick map") }
      
        let tileSize = wallMap.tileSize
        let brickSize = brickMap.tileSize
      
        for (key, wallcollection) in points {
          
            startOfBoundaries[key] = [CGPoint]()
            var pathArray = [CGMutablePath]()
          
            for walls in wallcollection {
                startOfBoundaries[key]?.append(CGPoint(x: walls[0][0], y: walls[0][1]))
                let newWallArray = walls.dropFirst()
              
                let path = CGMutablePath()
                var pointArray = [CGPoint]()
              
                for wall in newWallArray {
                    pointArray.append(CGPoint(x: wall[0], y: wall[1]))
                }
                path.addLines(between: pointArray)
                path.closeSubpath()
                pathArray.append(path)
            }
          
            pathsForBoundaries[key] = pathArray
          
            for (index, path) in pathsForBoundaries[key]!.enumerated() {
                print(startOfBoundaries[key]![index])
                let tile = EdgeTileEntity(location: startOfBoundaries[key]![index], path: path)
                edgeTiles.append(tile)
            }
        }
      
        for col in 0...wallMap.numberOfColumns - 1 {
            for row in 0...wallMap.numberOfRows - 1 {
                let tileDefinition = wallMap.tileDefinition(atColumn: col, row: row)
              
                let brickTopLeft = brickMap.tileDefinition(atColumn: col * 2, row: row * 2 - 1)
              
                let isTopLeft = brickTopLeft?.userData?["brickTile"] as? Bool
              
                if(isTopLeft ?? false) {
                    let x = CGFloat(col * 2) * brickSize.width
                    let y = CGFloat(row * 2 - 1) * brickSize.height
                    let tl = BrickTileEntity(location: CGPoint(x: x, y: y), size: brickSize, center: CGPoint(x: brickSize.width / 2, y: brickSize.height / 2))
                    let tr = BrickTileEntity(location: CGPoint(x: x + brickSize.width, y: y), size: brickSize, center: CGPoint(x: brickSize.width / 2, y: brickSize.height / 2))
                    let bl = BrickTileEntity(location: CGPoint(x: x, y: y - brickSize.height), size: brickSize, center: CGPoint(x: brickSize.width / 2, y: brickSize.height / 2))
                    let br = BrickTileEntity(location: CGPoint(x: x + brickSize.width, y: y - brickSize.height), size: brickSize, center: CGPoint(x: brickSize.width / 2, y: brickSize.height / 2))
                    brickTiles.insert(tl)
                    brickTiles.insert(tr)
                    brickTiles.insert(bl)
                    brickTiles.insert(br)
                }
              
                let brickHere = (isTopLeft ?? false) ? true : false
              
                if(tileDefinition == nil && !brickHere) {
                    let x = CGFloat(col) * tileSize.width
                    let y = CGFloat(row) * tileSize.height
                    let empty = CGRect(x: x, y: y, width: tileSize.width, height: tileSize.height)
                  
                    let mapCol = floor(CGFloat(col) / 20) + 1
                    let mapRow = 5 - floor(CGFloat(row) / 11)
                  
                    let room = { () -> Int in
                        if(mapRow > 1) {
                            return Int((mapRow - 1) * 6 + mapCol)
                        } else {
                            return Int(mapCol)
                        }
                    }()
                  
                    if(emptyTiles[room] == nil) {
                        emptyTiles[room] = Array<CGRect>()
                    }
                  
                    emptyTiles[room]?.append(empty)
                }
            }
        }
      
      
        stateMachine = GKStateMachine(states: [
            GameTitleState(withController: self),
            GamePlayState(withController: self)
        ]);
      
        stateMachine.enter(GameTitleState.self);
    }
Accepted Answer

Those errors both indicate that the Swift compiler cannot handle those initializations, and is crashing as a result. You should submit a bug report.


Swift is probably finding your nested arrays too complicated. One alternative might be to use a tuple for your coordinate pairs, rather than an array. So, instead of:


[960,384]


you would write:


(960,384)


Another approach would be to move all those wall definitions into a JSON text file, and use JSONDecoder to decode them during startup.

Thanks for the advice, I was indeed able to overcome the problem by using tuples instead of arrays. I'll also have a go at reporting a bug for this issue.

Dictionary causing error: illegal instruction 4 in my SpriteKit Game
 
 
Q