• Stars
    star
    1,454
  • Rank 31,164 (Top 0.7 %)
  • Language
    Swift
  • License
    Other
  • Created about 5 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Tutorial series demonstrating how to build a retro first-person shooter from scratch in Swift

Retro Rampage

PayPal Travis Swift 5 License Twitter

Screenshot

New!

The first chapters of Retro Rampage are now available as a video tutorial series, produced by the great folks at objc.io (with Yours Truly as guest presenter).

About

Retro Rampage is a tutorial series in which you will learn how to build a Wolfenstein-like game from scratch, in Swift. Initially the game will be targeting iPhone and iPad, but the engine should work on any platform that can run Swift code.

Modern shooters have moved on a bit from Wolfenstein's grid-based 2.5D world, but we're going to stick with that template for a few reasons:

  • It's feasible to build Wolfenstein's 3D engine from scratch, without a lot of complicated math and without needing to know anything about GPUs or shaders.

  • It's simple to create and visualize maps that are constructed on a 2D grid, avoiding the complexities of 3D modeling and animation tools.

  • Tile grids are an excellent way to prototype techniques such as procedural map generation, pathfinding and line-of-sight calculations, which can then be applied to more complex worlds.

Background

Ever since I first played Wolfenstein 3D on a friend's battered old 386 back in 1993, I was hooked on the First-Person Shooter.

As an aspiring programmer, I wanted to recreate what I had seen. But armed only with 7th grade math and a rudimentary knowledge of BASIC, recreating the state-of-the-art in modern PC 3D graphics was hopelessly beyond my reach.

More than two decades later, a few things have changed:

We have the iPhone - a mobile computer many hundreds of times more powerful than a DOS-era desktop PC; We have Swift - a simple, powerful programming language with which to write apps and games; Finally - and most importantly - we have the Wolfenstein source code, and the wizardry behind it has been thoroughly demystified.

I guess now is as good a time as any to scratch that quarter-century itch and build an FPS!

Tutorials

The tutorials below are designed to be completed in order, and each step builds on the code from the previous one. If you decide to skip ahead, project snapshots for each step are available here.

The tutorials are written with the assumption that you are already familiar with Xcode and are comfortable setting up an iOS project and adding new files to it. No knowledge of advanced Swift features is required, so it's fine if you've only used Objective-C or other C-like languages.

Part 1 - Separation of Concerns

Unlike most apps, games are typically designed to be independent of any given device or OS. Swift has already been ported to many platforms outside of the Apple ecosystem, including Android, Ubuntu, Windows and even Raspberry Pi. In this first part, we'll set up our project to minimize dependencies with iOS and provide a solid foundation for writing a fully portable game engine.

Part 2 - Mazes and Motion

Wolfenstein 3D is really a 2D game projected into the third dimension. The game mechanics work exactly the same as for a top-down 2D shooter, and to prove that we'll begin by building the game from a top-down 2D perspective before we make the shift to first-person 3D.

Part 3 - Ray Casting

Long before hardware accelerated 3D graphics, some of the greatest game programmers of our generation were creating incredible 3D worlds armed only with a 16-bit processor. We'll follow in their footsteps and bring our game into the third dimension with an old-school graphics hack called ray casting.

Part 4 - Texture Mapping

In this chapter we'll spruce up the bare walls and floor with texture mapping. Texture mapping is the process of painting or wall-papering a 3D object with a 2D image, helping to provide the appearance of intricate detail in an otherwise featureless surface.

Part 5 - Sprites

It's time to introduce some monsters to keep our player company. We'll display these using sprites - a popular technique used to add engaging content to 3D games in the days before it was possible to render textured polygonal models in real-time with sufficient detail.

Part 6 - Enemy Action

Right now the monsters in the maze are little more than gruesome scenery. We'll bring those passive monsters to life with collision detection, animations, and artificial intelligence so they can hunt and attack the player.

Part 7 - Death and Transition

In this part we'll implement player damage, giving the monsters the ability to hurt and eventually kill the game's protagonist. We'll explore a variety of damage effects and techniques, including a cool Wolfenstein transition called fizzlefade.

Part 8 - Target Practice

We'll now give the player a weapon so they can fight back against the ravenous monsters. This chapter will demonstrate how to extend our drawing logic to handle screen-space sprites, add a bunch of new animations, and figure out how to implement reliable collision detection for fast-moving projectiles.

Part 9 - Performance Tuning

The new effects we've added are starting to take a toll on the game's frame rate, especially on older devices. Let's take a break from adding new features and spend some time on improving the rendering speed. In this chapter we'll find out how to diagnose and fix performance bottlenecks, while avoiding the kind of micro-optimizations that will make it harder to add new features later on.

Part 10 - Sliding Doors

In this chapter we add another iconic feature from Wolfenstein - the sliding metal doors between rooms. These add some interesting challenges as the first non-static, non-grid-aligned scenery in the game.

Part 11 - Secrets

Time to add bit of intrigue with the introduction of a secret passage, hidden behind a sliding push-wall that doubles as a zombie-squishing booby trap. Moving walls pose some interesting problems, both for the rendering engine and collision detection - we get to find out what a wall looks like from the inside and what the world looks like from the outside!

Part 12 - Another Level

In this chapter we add a second level and an end-of-level elevator that the player can use to reach it. We'll demonstrate a number of new techniques including animated wall decorations, and how the command pattern can be a handy substitute for delegation when using structs.

Part 13 - Sound Effects

It's time to end the silence! In this chapter we add sound effects to the game, demonstrating how to stream MP3 files on iOS with minimal latency, as well as techniques such as 3D positional audio.

Part 14 - Power-ups and Inventory

Long before games made the leap into 3D, power-ups were a staple feature of action-oriented games. In this chapter we add a medkit and a new weapon for the player to collect on their travels around the maze.

Part 15 - Pathfinding

Right now the game's zombie inhabitants only follow the player if they have line-of-sight. In this chapter we'll enhance the monster intelligence by adding pathfinding using the A* algorithm, so they can chase you through doors and around corners.

Part 16 - Heads-Up Display

In this chapter we add a heads-up display showing the player important information such as how many bullets they've got left, and whether they're about to die. This tutorial covers a bunch of new techniques such as text rendering, sprite sheets, dynamic image tinting, and more!

Part 17 - Title Screen

In this part we add more polish to the game in the form of a title screen. Adding a single, static screen seems simple enough, but it provides an opportunity for some long-overdue refactoring, as well as enhancements to the nascent text rendering system we introduced in Part 16.

Part 18 - Computer Aided Design

Tired of laboriously laying out levels by hand? In this part we dip a tentative toe into the fascinating world of procedural generation. Specifically, we will attempt to eliminate some of the effort involved in placing items in a level by having the computer do it for us. We will also learn about Random Number Generators, and how to generate unpredictable output in a repeatable fashion.

Reader Exercises

Each tutorial includes a "Reader Exercises" section at the end. These exercises are intended as an optional challenge for readers to check that they've followed and understood the material so far - completing the exercises is not a prerequisite for starting the next tutorial.

The questions are arranged in ascending order of difficulty:

  • The first is usually a trivial modification to the existing code.
  • The second requires a bit more thought.
  • The third may require significant changes and enhancements to the game engine.

Some of the more advanced questions will eventually be answered, either in a later tutorial or in an Experiments PR (see below). If you are stuck on one of the exercises (or if you've completed an exercise and want to show off your solution) feel free to open a PR or Github issue.

Bugs

I've occasionally made retrospective fixes after a tutorial chapter was published. This will be called out in a later tutorial if it directly impacts any new code, but it's a good idea to periodically check the CHANGELOG for fixes.

Experiments

If you're up-to-date with the tutorials, and can't wait for the next chapter, you might like to check out some of the Experiments PRs on Github.

These experiments demonstrate advanced features that we aren't quite ready to explore in the tutorials yet.

Further Reading

If you've exhausted the tutorials and experiments and are still eager to learn more, here are some resources you might find useful:

Acknowledgments

I'd like to thank Nat Brown and PJ Cook for their invaluable feedback on the first drafts of these tutorials.

Thanks also to Lode Vandevenne and Fabien Sanglard, whom I've never actually spoken to, but whose brilliant explanations of ray casting and the Wolfenstein engine formed both the basis and inspiration for this tutorial series.

All sound effects used in the project were obtained from zapsplat.com. These may be used for free with attribution. See https://www.zapsplat.com/license-type/standard-license/ for details.

All graphics were drawn (badly) by me, in Aseprite.

Tip Jar

I started this tutorial series thinking it would take just a few days. Many months later, with no end in sight, I realize I may have been a bit naive. If you've found it interesting, please consider donating to my caffeine fund.

Donate via PayPal

More Repositories

1

iCarousel

A simple, highly customisable, data-driven 3D carousel for iOS and Mac OS
Objective-C
11,991
star
2

SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
Swift
7,417
star
3

FXBlurView

[DEPRECATED]
Objective-C
4,941
star
4

iRate

[DEPRECATED]
Objective-C
4,114
star
5

FXForms

[DEPRECATED]
Objective-C
2,929
star
6

SwipeView

SwipeView is a class designed to simplify the implementation of horizontal, paged scrolling views on iOS. It is based on a UIScrollView, but adds convenient functionality such as a UITableView-style dataSource/delegate interface for loading views dynamically, and efficient view loading, unloading and recycling.
Objective-C
2,648
star
7

layout

A declarative UI framework for iOS
Swift
2,222
star
8

iVersion

[DEPRECATED]
Objective-C
1,955
star
9

NullSafe

NullSafe is a simple category on NSNull that returns nil for unrecognised messages instead of throwing an exception
Objective-C
1,941
star
10

XMLDictionary

[DEPRECATED]
Objective-C
1,139
star
11

AutoCoding

AutoCoding is a category on NSObject that provides automatic support for NSCoding and NSCopying to every object.
Objective-C
1,067
star
12

GZIP

A simple NSData category for gzipping/unzipping data in iOS and Mac OS
Objective-C
980
star
13

FastCoding

A faster and more flexible binary file format replacement for NSCoding, Property Lists and JSON
C
975
star
14

AsyncImageView

[DEPRECATED]
Objective-C
908
star
15

iConsole

[DEPRECATED]
Objective-C
860
star
16

FXLabel

[DEPRECATED]
Objective-C
817
star
17

Expression

A cross-platform Swift library for evaluating mathematical expressions at runtime
Swift
803
star
18

CountryPicker

CountryPicker is a custom UIPickerView subclass that provides an iOS control allowing a user to select a country from a list. It can optionally display a flag next to each country name, and the library includes a set of 249 high-quality, public domain flag images from FAMFAMFAM (http://www.famfamfam.com/lab/icons/flags/) that have been painstakingly re-named by country code to work with the library.
Objective-C
738
star
19

SoundManager

Simple sound and music player class for playing audio on Mac and iPhone
Objective-C
631
star
20

FXImageView

FXImageView is a class designed to simplify the application of common visual effects such as reflections and drop-shadows to images, and also to help the performance of image loading by handling it on a background thread.
Objective-C
629
star
21

Euclid

A Swift library for creating and manipulating 3D geometry
Swift
606
star
22

Base64

[DEPRECATED]
Objective-C
578
star
23

FXKeychain

[DEPRECATED]
Objective-C
556
star
24

MustOverride

Provides a macro that you can use to ensure that a method of an abstract base class *must* be overriden by its subclasses.
Objective-C
524
star
25

LayerSprites

LayerSprites is a library designed to simplify the use of sprite sheets (image maps containing multiple sub-images) in UIKit applications without using OpenGL or 3rd-party game libraries. Can load sprite sheets in the Coco2D format.
Objective-C
505
star
26

GLView

[DEPRECATED]
Objective-C
474
star
27

FXNotifications

An alternative API for NSNotificationCenter that doesn't suck
Objective-C
391
star
28

ShapeScript

The ShapeScript 3D modeling app for macOS and iOS
Swift
383
star
29

VectorMath

A Swift library for Mac and iOS that implements common 2D and 3D vector and matrix functions, useful for games or vector-based graphics
Swift
364
star
30

ReflectionView

[DEPRECATED]
Objective-C
360
star
31

Swiftenstein

Simple Wolfenstein 3D clone written in Swift
Swift
357
star
32

LRUCache

LRUCache is an open-source replacement for NSCache that behaves in a predictable, debuggable way
Swift
353
star
33

JPNG

JPNG is a bespoke image file format that combines the compression benefits of JPEG with the alpha channel support of a PNG file. The JPNG library provides an Objective-C implementation of this format along with transparent JPNG loading support for iOS and Mac OS.
Objective-C
338
star
34

StandardPaths

StandardPaths is a category on NSFileManager for simplifying access to standard application directories on iOS and Mac OS and abstracting the iCloud backup flags on iOS. It also provides support for working with device-specific file suffixes, such as the @2x suffix for Retina displays, or the -568h suffix for iPhone 5 and can optionally swizzle certain UIKit methods to support these suffixes more consistently.
Objective-C
337
star
35

ViewUtils

ViewUtils is a collection of category methods designed that extend UIView with all the handy little properties and functionality that you always wished were built-in to begin with.
Objective-C
325
star
36

FXPageControl

Simple, drop-in replacement for the iPhone UIPageControl that allows customisation of the dot colour, size and spacing.
Objective-C
298
star
37

BaseModel

BaseModel provides a base class for building model objects for your iOS or Mac OS projects. It saves you the hassle of writing boilerplate code, and encourages good practices by reducing the incentive to cut corners in your model implementation.
Objective-C
288
star
38

OrderedDictionary

This library provides OrderedDictionary and MutableOrderedDictionary subclasses.
Objective-C
277
star
39

ColorUtils

[DEPRECATED]
Objective-C
257
star
40

Tribute

A command-line tool for tracking Swift project licenses
Swift
246
star
41

OSNavigationController

[DEPRECATED]
Objective-C
234
star
42

iNotify

[DEPRECATED]
Objective-C
226
star
43

Consumer

Mac and iOS library for parsing structured text
Swift
224
star
44

FPSControls

An experimental implementation of touch-friendly first-person shooter controls using SceneKit and Swift
Swift
216
star
45

OSCache

OSCache is an open-source re-implementation of NSCache that behaves in a predictable, debuggable way.
Objective-C
200
star
46

RequestQueue

[DEPRECATED]
Objective-C
175
star
47

FXReachability

Lightweight reachability class for Mac and iOS
Objective-C
173
star
48

Chess

A simple Chess game for iOS, written in Swift
Swift
171
star
49

Sprinter

A library for formatting strings on iOS and macOS
Swift
166
star
50

CryptoCoding

CryptoCoding is a superset of the NSCoding protocol that allows for simple, seamless AES encryption of any NSCoding-compatible object.
Objective-C
148
star
51

RequestUtils

A collection of category methods designed to simplify the process of HTTP request construction and manipulation in Cocoa.
Objective-C
142
star
52

CubeController

CubeController is a UIViewController subclass that can be used to create a rotating 3D cube navigation.
Objective-C
142
star
53

HTMLLabel

[DEPRECATED]
Objective-C
139
star
54

NSOperationStack

[DEPRECATED]
Objective-C
117
star
55

SVGPath

Cross-platform Swift library for parsing SVGPath strings
Swift
105
star
56

HRCoder

HRCoder is a replacement for the NSKeyedArchiver and NSKeyedUnarchiver classes that uses a human-readable/editable format that can easily be stored in a regular Plist or JSON file.
Objective-C
104
star
57

iPrompt

[DEPRECATED]
Objective-C
99
star
58

Presentations

Code samples and projects for presentations that I have given
Objective-C
99
star
59

FXPhotoEditView

[DEPRECATED]
Objective-C
92
star
60

StackView

StackView is a class designed to simplify the implementation of vertical stacks of views on iOS. You can think of it as a bit like a simplified version of UITableView.
Objective-C
73
star
61

WebContentView

[DEPRECATED]
Objective-C
69
star
62

StringCoding

StringCoding is a simple Mac/iOS library for setting object properties of any type using string values. It can automatically detect the property type and attempt to interpret the string as the right kind of value. It's particularly oriented towards iOS app theming (see README for details).
Objective-C
57
star
63

ArrayUtils

[DEPRECATED]
Objective-C
50
star
64

Swune

Swift/UIKit reimplementation of the Dune II RTS game
Swift
46
star
65

Parsing

Supporting code for my talk entitled "Parsing Formal Languages with Swift"
Swift
42
star
66

MACAddress

[DEPRECATED]
Objective-C
39
star
67

RotateView

Objective-C
35
star
68

FXParser

[DEPRECATED]
Objective-C
34
star
69

RandomSequence

A class for creating independent, repeatable pseudorandom number sequences on Mac and iOS
Objective-C
28
star
70

FloatyBalloon

This is the source code for a simple game called Floaty Balloon, based on the gameplay of Flappy Bird. It was created as a tutorial for http://iosdevelopertips.com
Objective-C
25
star
71

Concurrency

Full source code for a simple currency calculator app
Objective-C
15
star
72

FXJSON

[DEPRECATED]
Objective-C
15
star
73

PNGvsJPEG

This is a simple benchmark app to compare JPEG vs PNG loading performance on iOS. Spoiler: JPEG wins.
Objective-C
6
star