• Stars
    star
    161
  • Rank 233,470 (Top 5 %)
  • Language
    F#
  • License
    Other
  • Created over 2 years ago
  • Updated over 2 years ago

Reviews

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

Repository Details

An F# port of the 1992 classic Wolfenstein 3D

F# / Fable Wolfenstein

Try it in a browser here: https://www.jamesdrandall.com/wolf3d/

A work in progress F# port of Wolfenstein 3D. Wolfenstein was a formative experience for me! I was big into my PC gaming and the shareware scene when it came out and I remember not knowing anything about it but downloading it from a BBS, installing it, and then excitedly running round the house proclaiming "THIS CHANGES EVERYTHING" over and over again. No one cared.

Screenshot

I had a go at writing a raycaster myself, in C, after I'd played this back in 92/93 and I did get something running but it was both slow and fish eyed. It remained an itch to be scratched and so this F# port seems to have somehow happened.

I've generally tried to keep things fairly functional with performance taking a bit of a hit in some cases as a result.

The engine will run in the browser using Fable or as a native app on Mac, Windows and Linux - I've only got a Mac to hand at the moment so that's all I've tested. In theory should work on other platforms...

The majority of the core code is shared between the two implementations though I didn't set off with multi-targetting in mind. I wrote the Fable version first and so if you look at the desktop code you will see I'm essentially writing some lightweight JS runtime (DataView predominantly) implementations.

Some of the code is rather scruffy and their are some arguments about ints and floats! Was learning as I went... Now its pretty much solved will slowly refactor into something cleaner over time. The Open GL code in the desktop port (I don't use OpenGL to render the game scene, rather I use it to render a single raycast texture) may look excessive - to expedite things I simply picked up some code from a virtual console I've been working on on and off for a year or two and used that.

I aim to at least get the AI working (and you can see the seeds of that in the code) and I will probably add the Wolfenstein health / info bar. Beyond that... don't know. Other fun projects to be built!

Prerequiresites

On Windows install OpenAL SDK from https://www.openal.org/downloads/

Running

Controls in both cases:

Cursor keys - movement Left Ctrl - fire Space bar - action (e.g. open door)

Browser

Compatible with node 16, 17, 18.

To run the game:

  • Navigate to the browser folder
  • Install dependencies: npm ci
  • Start the compiler in watch mode and a development server: npm start
  • After the first compilation is finished, in your browser open: http://localhost:8080/

To build it for distribution

  • npm run build

Desktop

You will need .net 6 installed to run this. To run the game:

  • Navigate to the desktop folder
  • Enter: dotnet run

Implementation / File Format Notes

Things I found...

Orientable Sprite Layouts

Orientable enemies (i.e. those that can face away from the player - e.g. guards, dogs etc.) have the following index layout (using a compass to define things as shown below):

   N            G
W     E
   S            P
Sprite Faces direction
0 S (towards player)
1 SW
2 W
3 NW
4 N
5 NE
6 E
7 SE

Their are then a number of repetitions of this block for various animation frames:

Block Description
0 Stationary - block of 8 sprites as above
1 Running frame 1 - block of 8 sprites as above
2 Running frame 2 - block of 8 sprites as above
3 Running frame 3 - block of 8 sprites as above
4 Running frame 4 - block of 8 sprites as above

The number of running frames can vary by enemy type - the above example is for a guard but a dog is different:

Block Description
0 Stationary - block of 8 sprites as above
1 Running frame 1 - block of 8 sprites as above
2 Running frame 2 - block of 8 sprites as above
3 Running frame 3 - block of 8 sprites as above

So their are 40 sprites for the position and movement state of each enemy.

Their are then an arbitary (per enemy type) number of death sprites and firing sprites.

Sounds

Sound Index Description
0 Huh guards
1 Dog bark
2 Door close
3 Door open
4 Player machine gun
5 Player pistol
6 Or is this the player pistol?
10 Chain gun
11 Machine gun
20 Mein leben
21 Guard pistol
29 Double bark
32 Yeah
33 Shite
34 Aieeee
35 Ohohaw

Player -> Enemy Bullet Hit Detection

Considered a couple of approaches for detecting what, if any, enemy the player will hit if they fire. I could have cast a ray or rays but given the renderer has just walked the object tree and done the depth sorting and clipping I instead take note of the front most sprite that is in the centre of the viewport and apply a tolerance to it.

Asset Extraction

Didn't really want to process WLx files by myself so I used a couple of tools to extract the assets.

Firstly Wolf3dExtract to retrieve the components and then ImageMagick to convert textures from PPM to PNG format.

Screen Layout

Wolfenstein ran at 320x200. The actual 3D viewport max size is 304x152 - the viewport is surrounded by a 1 pixel black border Their is a 3 pixel border teal border at the top of the viewport above the black border and a 7 pixel border to the left and right of that black border.

Sprites

To generate the sprites use Slade to open the VSWAP.WL1 or VSWAP.WL6 file and select all the files beginning with SPR. Right click, graphics, export PNG.

Then with ImageMagick:

mogrify -extent 64x64 -gravity center -background none SPR*.png

License

I've included the Shareware assets in this public repository. And all copyrights of the original game clearly remain with the copyright holders and all props to the geniuses behind the original game (I have no idea if Carmack, Romero, et al. are still copyright holders).

All my efforts (so the F# code and surrounding build systems) are under the MIT license.

More Repositories

1

FunctionMonkey

Write more elegant Azure Functions with less boilerplate, more consistency, and support for REST APIs. Docs can be found at https://functionmonkey.azurefromthetrenches.com
C#
293
star
2

SimpleVoxelEngine

A simple voxel engine written from the ground up in C++ and OpenGL
C++
196
star
3

AccidentalFish.FSharp.Validation

Simple validator DSL / library for F#
F#
88
star
4

csharp-wolfenstein

CSharp port of Wolfenstein using the funky new language features
C#
70
star
5

WebAPI2AuthenticationExample

Demonstrates how to authenticate using OAuth with Web API 2 and the built in OWIN based OAuth authentication server. The example client is an iOS application written using Xamarin but the C# code will work on any .Net platform.
JavaScript
65
star
6

Simple-Paging-Grid

Lightweight HTML / JavaScript grid designed with Twitter Bootstrap in mind for dynamic server loaded and client embedded data.
JavaScript
56
star
7

AccidentalFish.AspNet.Identity.Azure

Azure table storage based identity provider for ASP.Net 4.5 - swap out for the default Entity Framework implementation
C#
49
star
8

AngularJS-OAuth2

Package for allowing an AngularJS application to authenticate with an OAuth 2 / Open ID Connect identity provider using the implicit flow.
JavaScript
46
star
9

react-azure-adb2c

Looking for a maintainer - if interested please get in touch in issue #13
45
star
10

AzureFromTheTrenches.Commanding

A configuration based commanding and mediator framework that supports command dispatch and execution in-process, over HTTP or over Azure Storage Queues. Written to .NET Standard 2.0 and supports many popular runtimes including .NET Core and .NET 4.6.x.
C#
45
star
11

Pholly

A F# friendly wrapper for Polly providing expressive functional resiience patterns.
Jupyter Notebook
40
star
12

StravaRideAnalysis

A sample application for React and the Strava API designed to illustrate common problems and there solutions
HTML
23
star
13

fsharp-doom

F# version of Doom using original rendering techniques (BSP etc.)
F#
20
star
14

FormSharp

No one likes the drudgery of building form logic. Banish it with F#.
F#
18
star
15

FluentAnimate

Fluent API for UIView animations in Xamarin.iOS
C#
17
star
16

CommandMessagePatternTutorial

Source code to go along with blog posts illustrating the usefulness of the command message pattern in cloud application architecture
C#
17
star
17

WebAPI2MobileFacebookAuthentication

Sample Visual Studio and Xamarin projects demonstrating how to use a Facebook login to authenticate with Web API 2 in a native mobile application.
JavaScript
15
star
18

AccidentalFish.ApplicationSupport

Dependency injectable application framework for Azure applications providing patterns, abstractions and implementations for common activities
C#
14
star
19

AFCircularGestureRecognizer

iOS gesture recognizer that responds to a single finger circular movement
Objective-C
13
star
20

Vsts-GitHub-Pages-Publish

A VSTS build and release task that publishes to GitHub Pages
PowerShell
12
star
21

StravaAPIProxy

A CORS enabled API proxy for Strava that also supports their token exchange process
JavaScript
12
star
22

AngularJS-OAuth2-IdentityServer3-Sample

Sample showing how to use the AngularJS-OAuth2 plugin with IdentityServer3 and Web API
JavaScript
11
star
23

RuntimeFSharpCompilation

Code to accompany blog post
F#
10
star
24

AzureFromTheTrenches.ServerlessBlog

A simple blog implementation for Azure Functions
C#
9
star
25

graphPaper

iPad application for simple vector art and HTML5 / Objective-C code generation
Objective-C
8
star
26

Img2Svg

Converts a bitmap to an SVG file with each pixel represented as a rect
F#
7
star
27

A-Star-Pathfinding

Demonstration of the A* path finding algorithm implemented using JavaScript and HTML canvas.
JavaScript
7
star
28

FSharpTetris

What it says on the tin.
F#
6
star
29

ServerlessLinkShortener

Ridiculously simple serverless (AWS) link shortener
F#
6
star
30

webGLite

A WebGL and TypeScript version of the classic BBC Micro game Elite. A work in progress.
TypeScript
6
star
31

fableTrek

F#
4
star
32

FableElmishScaffold

Visual Studio Code extension for scaffolding of CRUD operations in a F# Fable Elmish style app.
TypeScript
4
star
33

AzureAdOffice365MultiTenantedAuthentication

C#
4
star
34

fsharp-simpleraycaster

A very simple raycast implementation in F#
F#
4
star
35

FunctionMonkey-ToDo-MediatR

The FunctionMonkey ToDo sample using MediatR for the commanding / mediator framework
C#
4
star
36

FunctionMonkeyVideoSeries

Code to go with the video series on Function Monkey, Azure Functions, and the commanding / mediator pattern
C#
4
star
37

Insanely-Simple-Blog

A very simple blog system for embedding in a MVC 4 website using Web API, Backbone and Handlebars
JavaScript
4
star
38

AzureFunctionsSimpleRestApiExample

Simple example of a REST API delivered using Azure Functions
C#
3
star
39

PaddTrekF-

Learning F# with a variant of the classic Star Trek game.
F#
3
star
40

CycleCycleCycle.com

A website for tracking cycling activity
JavaScript
3
star
41

Objective-C-Expression-Tree-Framework

An Objective-C framework suitable for use on the iPhone that implements expression trees, including parsing from strings.
Objective-C
3
star
42

FunctionMonkey-ToDo

Sample back end for a simple Function Monkey ToDo app.
C#
3
star
43

FarmerDbUp

https://www.azurefromthetrenches.com/azure-sql-database-deployment-with-farmer-dbup-and-github-actions/
F#
2
star
44

fableLambdaExample

Demonstrates using F# and Fable to author a API Gateway triggered Lambda and CDK to deploy it
F#
2
star
45

AngularJS-OAuth2-Sample

Sample application for AngularJS-OAuth2
ApacheConf
2
star
46

StravaTokenManager

C# project for managing the Strava token exchange process
C#
2
star
47

AzureLeaseExample

Example of using blob leases
C#
2
star
48

AccidentalFishAngularJSPack

A set of directives and services I find useful to use with AngularJS
JavaScript
2
star
49

fsharp-simpleraycaster-textured

F#
2
star
50

IoCAntipatternFix

Demonstrates a solution to the "every class is public" anti-pattern
C#
2
star
51

6502-Emulator

6502 emulator written in C# as a portable class library
C#
2
star
52

FunctionMonkeyMultiTargettingDemo

Demonstrates how to target both ASP.Net Core and Azure Functions from a single code base.
C#
1
star
53

GpuMandelbrot

A Mandelbrot rendered using a fragment shader on the GPU
JavaScript
1
star
54

HierarchicalToolbar

Hierarchical toolbar for iOS as used in Fluent Mind Map
C#
1
star
55

BasicCommanding

C#
1
star
56

fable-react

Minimal template for Fable and React using Fake and Paket
JavaScript
1
star
57

serverlessJsScalingComparison

Comparisons for scaling
JavaScript
1
star
58

FunctionMonkey-FSharp

Documentation for the F# version of Function Monkey
CSS
1
star
59

PaddTrekJs

JavaScript and HTML version of Padd Trek
JavaScript
1
star
60

AzureLinkboard

Open source bookmark management for Azure
C#
1
star
61

ThreeDSpectreMaze

Small program that uses Spectre.Console to render a maze in the console
C#
1
star
62

fromModularMonolithToMicroservice

C#
1
star
63

The-Game-of-Life

Basic HTML5 and JavaScript implementation of the Game of Life
JavaScript
1
star
64

ServiceBusScheduler

Mediator based command scheduler for the Azure Service Bus
C#
1
star
65

Mandelbrot-Set

A JavaScript, HTML Canvas and Web Worker implementation of the Mandelbrot set.
JavaScript
1
star
66

ServerlessWebNotifier

Simple serverless web page change notifier
F#
1
star
67

FunctionMonkey-ToDo-FSharp

Demonstration of using the FSharp version of Function Monkey
F#
1
star
68

AccidentalFish.ExpressionParser

Simple expression parser for .net (supports .NET Standard 1.3 and higher). Functional but still work in progress.
C#
1
star