Wolfenstein3D clone in Go

WolfenGo

This is a clone of Wolfenstein3D written in Go, based on Wolfenstein3DClone and licensed under GNU/GPLv2.

Pull requests are welcome.

Plan

  • initial conversion
  • fix remaining bugs
  • add audio effects

Build Dependencies

WolfenGo uses glfw C bindings, which in turn need some Linux userland headers to be installed. Example of dependencies installation on a Debian-based system:

apt-get install libgl1-mesa-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxxf86vm-dev

Building

make

Then you can run:

bin/wolfengo

There are some constants in main.go that can be toggled to enable further debugging/experimentation.

Controls

Use W,A,S,D to move the player around and E to open doors; by clicking in the game window you will enable free mouse look, that can be disabled with ESC.

Pressing Q causes the game to quit, as it does closing the game window itself.

History

Aside from some dead/unused code that I have dropped and bugs inadvertently introduced in the porting process, this is my (gdm85) literal conversion of the Java Wolfenstein3D clone by BennyQBD; feel free to spin up the Java original version to check how identical and indistinguishable the two are.

Notable differences:

  • map format has been changed, see relative section
  • enabled VSync
  • although extra shaders are included, they are not used by default in any way

Although mathgl could have been used for the 3D math/raycast operations, I preferred to keep the simpler original structures.

Some lessons learnt during the porting process:

  • after 10 years I last experimented with OpenGL debugging, it's still hard. apitrace helped a lot
  • Go's int is 64bit on 64bit platforms, a visual inspection doesn't tip off this easily and one could skip the fact that OpenGL needs to know the proper size (4 or 8 bytes)
  • a minus sign here and there can screw up a lot of projections/translations

Development started on 4 January and completed with the first release on Github on 24th January with squashed/cleaned up commits. See also my blog post about WolfenGo initial release for extras about the development/porting process.

Map format

The map format has been changed as well to be easier to edit via text editors (although the new format it's far from being final).

Some extensions have been added for other items (FPS lore quiz: where have you seen this map format already?)

The first lines of the map define walls:

wall1   {1.00,0.75,0.75,1.00}
wall2   {0.25,0.00,0.00,0.25}

The values in curly braces are texture coordinates from the tileset WolfCollection.png. After that follows the lengthmap definition to indicate map size:

lengthmap       032

The value 32 means that this is a 32x32 map.

Subsequently there are the MAP, PLANES and SPECIALS sections, each of them describing with n = 32 lines of n = 32 characters either a wall value, a floor/ceiling value or a special item. Wall characters start at 1 and (unfortunately) right now can as well go above 9.

The special items that are currently supported are:

  • m to indicate a small medkit
  • e to indicate an enemy
  • d to indicate a door
  • A to indicate player start position
  • X to indicate level exit

Thanks

Obviously thanks to BennyQBD for the initial clone Java sources and also to https://github.com/go-gl/gl which - although not easy to master - is indeed in a good status for usage in Go OpenGL projects.

Comments
  • Crash on OS X 10.11

    Crash on OS X 10.11

    Love your work!

    After building on OS X 10.11 with Go 1.5.3 I see a crash immediately on startup.

    Fail occurs at line 104 of src/main.go

    if debugGL {                                                                                                                                         
        gl.DebugMessageCallback(debugCb, unsafe.Pointer(nil)) // this is line 104
        gl.Enable(gl.DEBUG_OUTPUT)                                                                                                                          
    } 
    

    Commenting out line 104 results in the program no longer crashing. Visuals are incorrect though, appearing similar to the image from your article https://cdn-images-2.medium.com/max/1600/1*cV4XLDX-LPkYrVfS-6Vo_g.png

    Here is the output from the crash.

    $ bin/wolfengo 
    WolfenGo v0.1.0, Copyright (C) 2016 gdm85
    https://github.com/gdm85/wolfengo
    WolfenGo comes with ABSOLUTELY NO WARRANTY.
    This is free software, and you are welcome to redistribute it
    under GNU/GPLv2 license.
    2.1 INTEL-10.8.77
    fatal error: unexpected signal during runtime execution
    [signal 0xb code=0x1 addr=0x0 pc=0x0]
    
    runtime stack:
    runtime.throw(0x430e3a0, 0x2a)
        /usr/local/go/src/runtime/panic.go:527 +0x90
    runtime.sigpanic()
        /usr/local/go/src/runtime/sigpanic_unix.go:12 +0x5a
    runtime.asmcgocall(0x401fd3a, 0xc8200c7d40)
        /usr/local/go/src/runtime/asm_amd64.s:696 +0x70
    
    goroutine 1 [syscall, locked to thread]:
    runtime.cgocall(0x41885c0, 0xc8200c7d90, 0x0)
        /usr/local/go/src/runtime/cgocall.go:120 +0x11b fp=0xc8200c7d60 sp=0xc8200c7d30
    github.com/go-gl/gl/v2.1/gl._Cfunc_glowDebugMessageCallback(0x0, 0xc82002c080, 0x0)
        github.com/go-gl/gl/v2.1/gl/_obj/_cgo_gotypes.go:10901 +0x35 fp=0xc8200c7d90 sp=0xc8200c7d60
    github.com/go-gl/gl/v2.1/gl.DebugMessageCallback(0x44bdf70, 0x0)
        /Users/sbarr/projects/github.com/wolfengo/.gopath/src/github.com/go-gl/gl/v2.1/gl/package.go:19050 +0x74 fp=0xc8200c7db8 sp=0xc8200c7d90
    main.main()
        /Users/sbarr/p/github.com/wolfengo/src/main.go:104 +0x3dc fp=0xc8200c7f10 sp=0xc8200c7db8
    runtime.main()
        /usr/local/go/src/runtime/proc.go:111 +0x2b0 fp=0xc8200c7f60 sp=0xc8200c7f10
    runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1721 +0x1 fp=0xc8200c7f68 sp=0xc8200c7f60
    
    goroutine 17 [syscall, locked to thread]:
    runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1721 +0x1
    
  • separated render thread and Logic update

    separated render thread and Logic update

    Hi,

    Should we use separate threads to run our logic updates and render game.

    Https://github.com/gdm85/wolfengo/blob/master/src/main.go#L175

    Maybe refactor using GO channels, and so on. How could we rewrite this piece of code to achieve that?

  • GL_INVALID_ENUM in glEnable(GL_DEPTH_CLAMP)

    GL_INVALID_ENUM in glEnable(GL_DEPTH_CLAMP)

    Ubuntu 14.04 LTS Go 1.6

    I tried to get Wolfengo running in an Ubuntu VM after encountering the issues with OpenGL on OSX in issue #1

    I had to install the following packages: mesa-common-dev, libxrandr-dev, libxcursor-dev, libxinerama-dev, libgl1-mesa-dev, libxi-dev

    Also, I had to make some minor tweaks to the Makefile to have an absolute GOBIN path rather than a relative path. (Was getting the error "cannot install, GOBIN must be an absolute path" until I changed the GOBIN variable assignment.)

    I am able to compile it successfully, but I get an error when running it:

    WolfenGo v0.1.1, Copyright (C) 2016 gdm85
    https://github.com/gdm85/wolfengo
    WolfenGo comes with ABSOLUTELY NO WARRANTY.
    This is free software, and you are welcome to redistribute it
    under GNU/GPLv2 license.
    2.1 Mesa 10.1.3
    panic: [GL_DEBUG] source 33350 gltype 33356 id 1 severity 37190 length 43: GL_INVALID_ENUM in glEnable(GL_DEPTH_CLAMP)
    
    goroutine 1 [running, locked to thread]:
    panic(0x5fa420, 0xc82000a4e0)
        /usr/src/go/src/runtime/panic.go:464 +0x3e6
    main.debugCb(0x824c00008246, 0x914600000001, 0x2b, 0xc82000e360, 0x2b, 0x0)
        /home/mike/go/src/wolfengo/src/main.go:69 +0x39f
    wolfengo/vendor/github.com/go-gl/gl/v2.1/gl.glowDebugCallback_gl21(0x824c00008246, 0x914600000001, 0xc80000002b, 0x7fff9fca34a0, 0x0)
        /home/mike/go/src/wolfengo/vendor/github.com/go-gl/gl/v2.1/gl/debug.go:29 +0x8e
    wolfengo/vendor/github.com/go-gl/gl/v2.1/gl._cgoexpwrap_4b34acd434eb_glowDebugCallback_gl21(0x824c00008246, 0x914600000001, 0x2b, 0x7fff9fca34a0, 0x0)
        wolfengo/vendor/github.com/go-gl/gl/v2.1/gl/_obj/_cgo_gotypes.go:45785 +0x53
    wolfengo/vendor/github.com/go-gl/gl/v2.1/gl._Cfunc_glowEnable(0x7f9eff47fb60, 0x3030000864f)
        wolfengo/vendor/github.com/go-gl/gl/v2.1/gl/_obj/_cgo_gotypes.go:12707 +0x3a
    wolfengo/vendor/github.com/go-gl/gl/v2.1/gl.Enable(0x3030000864f)
        /home/mike/go/src/wolfengo/vendor/github.com/go-gl/gl/v2.1/gl/package.go:19502 +0x2b
    main.main()
        /home/mike/go/src/wolfengo/src/main.go:124 +0x45c
    
  • Crash on Arch Linux

    Crash on Arch Linux

    Commenting out the panic on line 67 of main.go allows the application to run normally.

    ./bin/wolfengo 
    WolfenGo v0.1.0, Copyright (C) 2016 gdm85
    https://github.com/gdm85/wolfengo
    WolfenGo comes with ABSOLUTELY NO WARRANTY.
    This is free software, and you are welcome to redistribute it
    under GNU/GPLv2 license.
    4.5.0 NVIDIA 358.16
    panic: [GL_DEBUG] source 33350 gltype 33361 id 131185 severity 33387 length 164: Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
    
    
    goroutine 1 [running, locked to thread]:
    main.debugCb(0x825100008246, 0x826b00020071, 0xa4, 0xc8200142c0, 0xa4, 0x0)
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/src/main.go:67 +0x348
    github.com/go-gl/gl/v2.1/gl.glowDebugCallback_gl21(0x825100008246, 0x826b00020071, 0x7f47000000a4, 0x7f4778e6b400, 0x0)
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/.gopath/src/github.com/go-gl/gl/v2.1/gl/debug.go:29 +0x8e
    github.com/go-gl/gl/v2.1/gl._Cfunc_glowBufferData(0x7f477ab8be80, 0x8892, 0x80, 0xc82008e080, 0x88e4)
            github.com/go-gl/gl/v2.1/gl/_obj/_cgo_gotypes.go:7307 +0x35
    github.com/go-gl/gl/v2.1/gl.BufferData(0x8892, 0x80, 0xc82008e080, 0x88e4)
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/.gopath/src/github.com/go-gl/gl/v2.1/gl/package.go:18265 +0x47
    main.(*Mesh).addVertices(0xc82043f650, 0xc8204f9db0, 0x4, 0x4, 0xc82000e200, 0x6, 0x6, 0xc800000000)
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/src/mesh.go:53 +0x197
    main.NewMesh(0xc8204f9db0, 0x4, 0x4, 0xc82000e200, 0x6, 0x6, 0x496600, 0x0, 0x0)
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/src/mesh.go:30 +0xb1
    main.(*Object).initMedkit(0xb9f0a0, 0x0, 0x0)
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/src/medkit.go:51 +0x404
    main.main()
            /mnt/btrfs/Programming/Go/src/github.com/gdm85/wolfengo/src/main.go:129 +0x4b2
    
    goroutine 17 [syscall, locked to thread]:
    runtime.goexit()
            /usr/lib/go/src/runtime/asm_amd64.s:1721 +0x1
    
  • Player cannot shoot enemies

    Player cannot shoot enemies

    I've narrowed this down to line 303 in src/level.go. It appears that this is returning nil when it should not be. I don't really have the know-how to troubleshoot this further.

    nearestMonsterIntersect := findNearestVector2f(nearestMonsterIntersect, collisionVector, lineStart)

    I've verified nearestMonsterIntersect is not nil when it shouldn't be. I've also began chasing down collisionVector and noticed that the java version had a method monster.getSize() whereas the go version instead accesses the set variables. It seems to work out to be about the same end result, so I don't think this is it.

    lineStart is set in player.go on line 171, then the above problematic function in level.go is called a few lines below that. Is lineStart supposed to be the position of the mouse? I'm not quite following as I'm quite new to golang and a hobby programmer at best.

  • "Fix" for OSX

    I stumbled upon this project and thought it was cool, but noticed an old issue (#4) for incompatibilities with OSX. On a hunch I tried simply upgrading the OpenGL version in case it was a problem with either the go-gl compatibility layer or the underlying c-code itself. It works!

    The change is pretty straight forward. Imports are updated from v2.2 to v4.1-core, the file paths for the shaders is updated to use the shader language version 3.3.0 files that were already in the res/shaders/ folder, and some additional window hints were provided to make OSX happy with the forward compatibility of 4.1.

    The one thing that threw me for a loop was that I was getting unhelpful messages for when compilation of the shaders failed. So, I added better logging output there. At which point, I noticed that for version 4.1 it was complaining about there not being a vertex array object bound. So, I just shoehorned these lines

    var vao uint32
    gl.GenVertexArrays(1, &vao)
    gl.BindVertexArray(vao)
    

    into the compile functon. I have no clue if they make any sense there or not or if they belong elsewhere as I've never touched any of these libs before 30 minutes ago, but it seems to work?

    Anyway, I know this was just a toy project but I figured I'd drop this PR for anyone else interested in it or in case you were inclined to take a stab at updating it.

    Cool project, either way!

  • make error

    make error

    mkdir -p bin .gopath if [ ! -L .gopath/src ]; then ln -s "..../wolfengo/vendor" .gopath/src; fi cd src && GOBIN="../bin/" GOPATH="..../wolfengo/.gopath" go install && mv ../bin/src ../bin/wolfengo cannot install, GOBIN must be an absolute path make: *** [build] Error 1

  • Invalid texture coordinates on Mac OS X

    Invalid texture coordinates on Mac OS X

    (spun from #1)

    Texture coordinates do not appear to be working on darwin systems. I have setup branch debug/tex-coords to test the texture coordinate parameters that are being passed to OpenGL via go-gl, this is my output: https://gist.github.com/gdm85/98f7af432ead9045b238

    If somebody is willing to test with that branch and the output differs, please post a gist. Texture coordinates should always be the same.

    Samples

    As originally reported by @scottjbarr: tiny full texture frames

    And @glycerine: big full texture frames

An attempt to clone the mechanics from the game Majesty.

An attempt to clone the mechanics from the game Majesty. Basically, an indirect control kingdom building simulation.

Jan 4, 2022
Reddit-clone-go - Reddit clone with golang

Generate GraphQL Schema go get github.com/99designs/gqlgen/[email protected] go run gi

Dec 28, 2022
Quickly clone an entire org/users repositories into one directory - Supports GitHub, GitLab, Bitbucket, and more
Quickly clone an entire org/users repositories into one directory - Supports GitHub, GitLab, Bitbucket, and more

ghorg ghorg allows you to quickly clone all of an orgs, or users repos into a single directory. This can be useful in many situations including Search

Jan 1, 2023
A Go "clone" of the great and famous Requests library

GRequests A Go "clone" of the great and famous Requests library License GRequests is licensed under the Apache License, Version 2.0. See LICENSE for t

Dec 23, 2022
a tool for code clone detection

dupl dupl is a tool written in Go for finding code clones. So far it can find clones only in the Go source files. The method uses suffix tree for seri

Dec 12, 2022
A fast clone of the Jekyll blogging engine, in Go

Gojekyll Gojekyll is a partially-compatible clone of the Jekyll static site generator, written in the Go programming language. It provides build and s

Dec 30, 2022
twitter clone front-end for Internet Engineering course - fall 99 built by go+echo

twitter backend build twitter-like back-end for internet engeering course - fall 99 with go+echo+gorm team mates Roozbeh Sharifnasab + Parsa Fadaee +

Nov 9, 2022
A modern UNIX ed (line editor) clone written in Go

ed (the awesome UNIX line editor) ed is a clone of the UNIX command-line tool by the same name ed a line editor that was nortorious for being and most

May 29, 2021
A better way to clone, organize and manage multiple git repositories
A better way to clone, organize and manage multiple git repositories

git-get git-get is a better way to clone, organize and manage multiple git repositories. git-get Description Installation macOS Linux Windows Usage gi

Nov 16, 2022
Dolt is a SQL database that you can fork, clone, branch, merge, push and pull just like a git repository.

Dolt is a SQL database that you can fork, clone, branch, merge, push and pull just like a git repository. Connect to Dolt just like any MySQL database to run queries or update the data using SQL commands. Use the command line interface to import CSV files, commit your changes, push them to a remote, or merge your teammate's changes.

Dec 31, 2022
Quickly clone git repositories into a nested folders like GOPATH.

cl cl clones git repositories into nested folders like GOPATH and outputs the path of the cloned directory. Example: cl https://github.com/foo/bar Is

Nov 30, 2022
🛰️ Clone all your starred GitHub repos

solar ??️ Clone all your starred GitHub repos solar ❓ What is solar? ?? Install ?? macOS ??️ Linux and Windows ?? Commands ??️ solar download ?? Contr

Dec 23, 2022
😎 Yet Another yes clone but in Golang

Yeah Output a string repeatedly until killed. Yet Another yes clone but in Golang. Usage Just like yes: yeah This will print "y" until the process is

Apr 7, 2022
fccCoin Clone written in GoLang

fccCoin Description fccCoin Clone written in GoLang Actual Code for fccCoin written in Python

Oct 2, 2021
A Pac Man clone written in Go (with emojis!)
A Pac Man clone written in Go (with emojis!)

A Pac Man clone written in Go (with emojis!)

Jan 4, 2023
Fancy Git Clone that preserves directory structures

git go-clone This is fancy wrapper around git clone that preserves directory structures. For example, if you have some complex organization, and you w

Sep 24, 2021
A Pong clone made from scratch with Go and C using OpenGL 3.3

Go-Pong A Pong video game clone made with Go lang and OpenGL 3.3 using C. Gameplay Offline Key bindings are 'w' and 's' for the left player and 'up ar

Feb 10, 2022
Image clone controller is a kubernetes controller to safe guard against the risk of container images disappearing

Image clone controller image clone controller is a kubernetes controller to safe guard against the risk of container images disappearing from public r

Oct 10, 2021
Clone of the old gasnow.org, now available at gasnow.dev

Gasnow 2 Clone of gasnow.org Quickstart The application connects to infura to get data from its ethereum full node. In order to do so the following en

Mar 30, 2022
My Simple Instagram-Clone API task submission, conducted by Appointy for internship shortlisting.

go-pointy Go-Pointy is a simple Instagram API Clone, made using GoLang. I had tried my best to not be lazy and finish the tasks, as a beginner to the

Jul 25, 2022