A game engine with Lua & C++

For a while now I’ve been working on writing a new game engine in C++. It has been a long process, and I’ve restarted it a number of times with each successive time getting closer and closer to a usable engine. Getting caught in a loop of writing and rewriting a project sucks, so I’m forcing myself to stick with the current iteration.

This is the Wake engine. Right now it is at the stage that I can create shaders and draw meshes. The engine itself is largely in C++, with scripting in Lua. Getting Lua scripts to work how I wanted was pretty time consuming: I had to bind a large amount of classes in order to allow the kind of math you need in games to be performed from within the scripts. I managed to bind all the vector and matrix classes from GLM along with the quaternion class.

I’m not going to go too much into the design of the engine just yet, as it is still in flux, but here’s the bit of code that it took to render the above video:

-- First we need to create the shader to display the cube.
-- Wake doesn't currently have any built in shaders, so we need to define our own here.
-- The first argument to Shader.new is the vertex shader. The second is the fragment shader.
local shader = Shader.new(
[[
#version 330 core
layout (location = 0) in vec3 position;

uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;

void main()
{
  gl_Position = projection * view * model * vec4(position, 1.0);
}
]],
[[
#version 330 core
uniform float time;

out vec4 outColor;

void main()
{
  outColor = vec4((sin(time) + 1) / 2, (cos(time) + 1) / 2, ((sin(time) + 1) / 2 + (cos(time) + 1) / 2) / 2, 1.0);
}
]]
)

local shaderTime = shader:getUniform("time")
local shaderView = shader:getUniform("view")
local shaderProj = shader:getUniform("projection")
local shaderModel = shader:getUniform("model")

-- There's no mesh generation functions at the moment, so we have to
-- define the cube manually for now. The first argument is the list of vertices,
-- the second is the list of indices.
local mesh = Mesh.new(
{
  Vertex.new{-1, -1, 1},
  Vertex.new{1, -1, 1},
  Vertex.new{1, 1, 1},
  Vertex.new{-1, 1, 1},
  Vertex.new{-1, -1, -1},
  Vertex.new{1, -1, -1},
  Vertex.new{1, 1, -1}
  Vertex.new{-1, 1, -1}
},
{
  2, 1, 0,
  0, 3, 2,

  6, 5, 1,
  1, 2, 6,

  5, 6, 7,
  7, 4, 5,

  3, 0, 4,
  4, 7, 3,

  1, 5, 4,
  4, 0, 1,

  6, 2, 3,
  3, 7, 6
})

-- White background (r, g, b, a)
engine.setClearColor(1, 1, 1, 1)

local view = math.lookAt({4, 3, 3}, {0, 0, 0}, {0, 1, 0})
local projection = math.perspective(math.radians(45), 800 / 600, 0.1, 1000)

-- Events in wake are bound using the 'bind' function
engine.tick:bind(function(dt)
  -- Use the shader
  shader:use()
  shaderTime:set1f(engine.getTime())
  shaderView:setMatrix4(view)
  shaderProj:setMatrix4(projection)

  local rot = engine.getTime() / 2
  local mat = math.rotate(rot, {1, 0, 0})
  mat = math.translate(mat, {math.sin(engine.getTime() / 2) * 2, 0, 0})
  shaderModel:setMatrix4(mat)

  -- Draw the mesh
  mesh:draw()
end)

The Wake engine is released under the MIT license, and source code can be found here.

More Complex Dungeon Generation

Note that each image in this post is from a separate run of the generator.

The code written and released with this article is under the MIT license.

DungeonGen-1

This is going to be a quick article about procedural dungeon generation in unreal engine. I recently came across this article on Gamasutra, which describes a really cool dungeon generation algorithm used by TinyKeep. I decided I wanted to try implementing it in Unreal Engine 4, so here are some notes on my attempt.

DungeonGen-2

This is the first step of the generation process: Create a large number of randomly sized regions within a circle. Note that they are green in this image as green represents “default” regions, which don’t yet have a purpose.

DungeonGen-3

Next comes separation. I don’t want any of the regions overlapping, so I used a simple separation steering behavior. The Gamasutra article uses a physics engine to do this part, but I see that as unnecessary and over the top for what could be a very simple algorithm. Using a physics engine also means you don’t get nearly as much control over the results, so I went with the original way TinyKeep used.

Here are the basics of the separation algorithm I used. The main thing to node is that I only apply separation to a region based on what other regions are overlapping. In my actual code, there’s also a bit that keeps track of how many “ticks” separation has occurred for (how many times it has gone through the while loop), and if that number gets too large then it breaks out of the loop so that we don’t end up with an endless loop situation. There’s some inefficiency in the code as the number of checks for separation grows exponentially with the number of regions, and it could easily benefit from some sort of spatial partitioning, but it still runs fairly fast and doesn’t need to be too efficient since this is meant to run during a loading screen as opposed to while the game is being played.

DungeonGen-4

Here’s where I start assigning purposes to different regions. I find the average size of the regions, then find the set of all regions above that size * a multiplier. I mark all regions in that set as “main” regions, which are highlighted in red. These will be used to figure out how the hallways of the dungeon should be generated.

DungeonGen-5

It may be a bit hard to see in the above image, but there are blue lines creating a graph of all main regions. This graph is the Delaunay triangulation of the centers of each main region. This will be used in the next few steps to create hallways. To actually generate the Delaunay triangulation, I used this code, modified to use Unreal Engine’s constructs (such as FVector2D).

DungeonGen-6

Now it is really hard to see, but the blue lines are still there. There are quite a few less of them, and that is because this is a minimum spanning tree of the previous graph. This guarantees that all main rooms are reachable in the graph, while also not duplicating any paths. I used Prim’s algorithm since it was simple to implement. Here is my implementation, and again it would probably benefit from some better data structures but it is fast enough for my purposes.

DungeonGen-7

The problem with the MST is that it makes a fairly boring dungeon where every path leads to a dead end. It works as a starting point, but there should be some cycles in the main region graph. As such, I randomly choose some edges from the original triangulation graph that aren’t a part of the MST and add them to the final graph.

DungeonGen-8

Here you will notice that all of the green regions are now black. This is because I’ve set their type to “none”. Regions of type “none” will be deleted completely from the dungeon when the algorithm completes, so I set everything that isn’t a main region to “none”. You’ll also notice that the blue lines now create corners and always follow the X or Y axis. This is because they will be used to create the final hallways that connect the main rooms. The algorithm to figure out how to lay out the lines for hallways is pretty simply and explained in the Gamasutra article, but here’s my implementation.

DungeonGen-9

Now I find the intersection between each of the blue lines and the unused regions, then add them back in to the dungeon. They are highlighted in pink here because they are marked as hallways. You will notice that doing this still doesn’t connect all regions together, which is why the next step happens…

DungeonGen-10

Look at all those tiny pink squares! I do a check around each line to find any space that isn’t taken up by any region, then fill that in with a small hallway region. Ideally this would have another step which optimized regions of the same type that are adjacent into a single region, but that’s a topic for another day.

DungeonGen-11

The final two steps are show here: The first is to remove any unused regions, and the second is to “tag” regions as needed. Regions can have tags which is used to define what a region is used for. Right now, there are only three tags defined: None, Start, and Exit. None is applied to everything by default, while Start and Exit are applied to main regions. Right now the generator chooses a random main region for the Start tag, and then finds the furthest main region from that one and uses it as the Exit tag.

That’s it for the dungeon generation algorithm. All that is left is to actually spawn geometry, which is something I am still working on.

I have plans to release the generation code as open source in the near future, but not until I’ve finished tuning it a bit. Thanks for reading!

HFOSS: Quiz #2

1) Please expand each of the following acronyms (1 pt each):

  • 1.1) IRC – Internet Relay Chat
  • 1.2) FOSS – Free & Open Source Software
  • 1.3) OLPC – One Laptop Per Child
  • 1.4) DVCS – Distributed Version Control System
  • 1.5) FSF – Free Software Foundation
  • 1.6) PR – Pull Request

2) What is the short, two-letter name for the OLPC computers used in the final project for this class? (1 pt)

XO

3) Please give the one-word name for the interface used in the OLPC computers? (1 pt)

Sugar

4) What is the grade level at which we are targeting our OLPC applications? (1 pt)

4th

5) Briefly define each of the following instructional theories, giving the role of the instructor in each (2 pt each):

  • 5.1) didactic – Using a consistent scientific approach towards teaching. The teacher gives instructions (lectures) to the students who play a passive part in the process.
  • 5.2) dialectic – A more debate/discussion focused approach, where the class is focused on discussion with the teacher.
  • 5.3) constructivist – The instructor is there not to teach but to facilitate discussion to help students understand the content themselves.

6) Several elements are combined in different ways to form the various Creative Commons licenses.
Please match each shorthand given in the numbered list with the letter next to the description of that license element below (1 pt for each match).

  • 6.1) NC ___
    • C) You may not use the work for commercial purposes.
  • 6.2) SA ___
    • A) You must convey the same rights “downstream” that were conveyed to you by “upstream”.
  • 6.3) ND ___
    • D) You may not make changes to the work.
  • 6.4) BY ___
    • B) You must attribute the contributions of the original or upstream creators of the work.

7) The presence of which license elements make a license “non-free” in the eyes of the FSF? (give the letters, 1 pt each)

ND

8) Which license element is a copyleft? (give the letter, 1 pt)

SA

9) Name two projects which distribute a body of non-software, free culture data, and briefly name or describe the kind of data. (1 pt each)

YouTube has the option of distributing free videos under CC licenses.

OpenGameArt.org distributes free game assets (textures, images, audio, etc) under a variety of licenses (including CC-BY, CC-BY-SA, GPL 2/3, CC0, LGPL 2.1/3, and others).

10) We’ve discussed “the four R’s” as a shorthand for the freedoms attached to software for it to be considered “free” or “open source”. List or describe each. (eg, if you can remember the “r” word you can just give that. If you cannot remember the term, but can describe the freedom involved, that also counts). Various “r” words are roughly synonymous for some of the freedoms, but we’re counting freedoms here, not synonyms so if you give two (or more) terms for the same freedom, it only counts once. For the purposes of this quiz, “remix” does not count as describing any of them. (1pt each)

  • 10.1) Read
  • 10.2) Run
  • 10.3) Revise
  • 10.4) Redistribute

True or False: You cannot sell GPL’d software (1pt)

false

True or False: You can fork a GPL licensed Project and release it under an MIT license? (1 pt)

false

True or False: You can fork a MIT licensed Project and release it under an GPL license? (1 pt)

true

When does a work become “copyrighted” by an Author? (3 pt)

When it enters a tangible medium.

HFOSS: Team Proposal #2

Team Proposal

List your other team members below

  • Sean Maraia
  • Sam Bloomberg

Which project did your team choose?

We will be creating a game involving matching words to their definition in the form of a card memory game.

What will each team member’s role be?

Sam – Reading definitions from a file, game logic

Sean – UI, frontend stuff

Source Code Repository URL?

https://github.com/redxdev/Matching

How will you communicate with them? (i.e. IRC Channel, Email Addresss, mail lists, issue trackers, etc…)

Talking. We are roommates.

What are the easy parts?

  • The game itself

What are the hard parts?

  • Learning pygame

How will you overcome both?

By looking over the documentation of pygame.

A new version of hvzsite

This week a new version of https://hvz.rit.edu/ went live. I’ve been running RIT’s Humans vs Zombies website since the Fall of 2014, and this is the second major upgrade to the website that I’ve made.

A humans vs zombies website isn’t just there to market the game; it actually plays a part in the game itself. Players have to register when they are tagged (or tag someone) by typing both their unique id along with whomever tagged them into the “infect” page on the website. This allows us to keep track of who is still alive and who is a zombie. The website also handles dispersing mission information to each team, antiviruses, and tracks the location of each infection.

The newest incarnation of the website is written in NodeJS using Sails for the server, which provides a simple REST API, and Ember for the client. The entire website is open source under the MIT license (check it out at GitHub).

The new version of the website is actually a bit more generic than the last one: Any references to RIT’s specific game have been put in configuration files so that they can easily be swapped out for other names. I’m still working on making game rules configurable (and there’s no “starve timer” yet which I know some games use). I’m always open to suggestions (and pull requests) on how to make it better!

The other major new part of the website is that absolutely everything is done over a REST API. The built in client uses this API to communicate for everything except authentication. The old version of the website exposed almost everything as a REST endpoint, but none of the admin panel was accessible from REST. Now, everything can be done over REST.

My main plans going forward with this incarnation of the website are to A. make it generic enough to support any game run anywhere and B. clean up the UI. On that second point, I’m really not a designer. I did my best for the website but I’m the last person you’d ask for making a really good looking website. That isn’t a huge deal, though, since the current website looks decent enough and is usable.

Again, the GitHub is here, and the source is under the MIT license. For reference, the old PHP version of the website is here.

Developing Zombie Wave Survival in 1 Week

For the past week, I’ve been working on a small project. I’ve been wanting to learn how to do multiplayer in unreal engine, but every time I tried to learn it I’d get stuck on the fact that there is a lack of good examples. Well, the wonderful Tom Looman released an example project for a third person zombie survival game a little while back, so I decided to try using it as a reference to create a simple game.

Zom NineRooms Editor 1

My game is a first person wave survival game with full coop multiplayer support, along with a simple lobby system. The code is heavily based on Tom Looman’s, however it has been adapted for a first person project and I avoided using his weapon system in favor of something that would allow me a bit more control from blueprints.

Zom In-Game NineRooms 1

Maps define a list of waves, with each wave containing a list of what can spawn and how many. The game then chooses random spawns for each enemy, and throws them at the player. There’s a money system which allows you to buy ammo, health, and unlock new areas, and there’s a scoreboard which shows your stats compared to your friends.

Zom In-Game NineRooms 2

Zom In-Game NineRooms 3

I’m not completely sure what I’ll be doing with this project, or how much further I’ll be going. I’ll likely post a video of it when I’ve gotten some more done.

HFOSS: Cmder CommArch

This is a short report about hfoss community architecture for the Cmder project.

Describe the project.

Cmder is a portable wrapper around the windows command line that adds tabbed command windows, hotkeys, configurability, support for multiple shells, and more.

Give a brief history of the project.

Cmder is based on ConEmu and according to the readme was created out of pure frustration over the lack of a usable console emulator on windows.

Who approves patches? Who has commit access?

The lead developer along with the handful of members of the cmderdev team.

How many total PRs?

244 closed pull requests and 7 open.

What is the calloway coefficient of fail?

165, however the entire thing is heavily skewed against anything that might be open source on windows which makes this metric practically useless for something that doesn’t even make sense in a non-windows environment.

Has there been any turnover in the core team?

Nope.

Does the project have a lead developer?

MartiUK/Martin Kemp

How is the project’s participation trending?

It seems to have gotten pretty popular since it has been created. There are quite a lot of pull requests and issues for a small, newish project.

Would the project survive if the core team was hit by a bus?

As it is, probably not as there is only one main developer, but since the ConEmu project would still exist only the additional customizations that cmder provides would pose any problem.

Does the project have any official “on-boarding” process in place?

There is a CONTRIBUTING.md file but that’s about it.

Does the project have documentation available?

Aside from their website, cmder.net and a tiny bit on the wiki, not really. It mostly depends on the documentation for ConEmu and a knowledge of standard key bindings.

If you were going to contribute to this project, but ran into trouble or hit blockers, who would you contact and how?

I’d use the project’s issue tracker which seems decently active.

What is the decision making process?

It is controlled by the lead developer, which makes sense for a small project like this.