Jam
This weekend I
attended the
Guildford Game Jam organised by
@Kilo_bytes and
hosted at the new offices of the lovely @RocketdeskUK. There were about 15+ people in
teams of one to four with a few floating jammers creating audio and art assets for multiple teams. I took my creaky old laptop and managed to
build a game using Apparance in the two (and a bit) days.
|
Guildford Game Jam: 2 Choices |
Here's how it went...
Idea
Given the
limitations of the Apparance tech at this stage in its development I constrained to something that was non-interactive, i.e. with no moving
parts. I couldn't even rely on collision
to build any form of physical puzzles.
The main theme for
the event was 'two choices' so I was thinking about exploration of a branching
space where each choice led you towards
one of many final destinations. Each split
would have some clues as to the kind of outcome you were heading towards. You would have to fly through the
rooms and doors pretending that you couldn't collide with anything. At the very least I needed my stand-alone
player app to support camera controls (mouse/keyboard, and ideally game-pad) for
this to be possible.
Pre-production
In anticipation of
the jam I worked on tidying up the Apparance Player a bit and adding support for
the following that I was going to or probably going to need:
- Command line option support -
to select the level of control (I still wanted the house viewer to work,
but also free-cam).
- Mouse and keyboard control of
camera - for flying round environments (this would also be good for
demonstrating the Future City scene).
- Game-pad support - I really
wanted to be able to try navigating using a game-pad, it should be much
more accessible.
Once I had all this
up and running it meant I could run the Old House demo, fly around Future City,
and support the game jam all with one player, each using different command line
options to launch.
|
Command line options now supported by the standalone Apparace Player application. |
Day 1
Setup
The first day (just
Friday evening really) was an opportunity to meet the jammers and catch up with
some friends. We all set up, and started
discussing ideas. I was open to the idea
of working in a team, but within the short time-scale I don't think it would
have been possible to get someone up to speed using the Apparance tools
(particularly as they aren't 'consumer ready' yet). As it was I worked solo.
Dungeon
Reuse
I had intended to
start pretty-much from scratch, building an new world to navigate, but once I
got playing around with some of my old test scenes I realised I could get a
long way with the room-subdivision work I'd already done.
|
Early dungeon generation experiments. A good starting point for a maze. |
Playing with this
and re-thinking my goal I decided that a simple maze of rooms with clues in to
some final decision would work well and I had the room network to support
it. I was thinking that the puzzle
should be finding your way through the maze and clues leading you towards the
correct exit (one bad, one good), for example, bones or treasure scattered on
the floor.
To
Collide or Not To Collide
At this point I was
starting to think that having to manually fly round the level with
user-implemented collision was really going to spoil the experience. I decided that, back at home, I'd try to
implement some simple physics for the player controller.
Day 2
Early
Hacking
Up early, I started
hacking in some collision systems before I headed back to the Rocketdesk office
for the 10 am start. I got to the point
where I could tag generated triangles with a material the engine picked up as
collision and passing off to the camera controller each frame. A bit messy but it would work, as long as I
could actually do the collision and simple motion sim. I found a neatly encapsulated bit of
sphere-triangle sweep collider code that I was going to use. But first, a 'day at the office'.
Beginning
& End
Back at the Jam I
set about building start and exit rooms that bolted onto the generated
'dungeon' space.
|
Basic level structure test, start room (blue), maze, exit rooms; bad (red) and good (green). |
This meant that I
had a basic level design that I could fly through from start to (a choice of)
finish. A good start.
Doors
The original dungeon
work just had open doorways so I quickly stuck the doors from the Old House
project in them to divide up the rooms a bit more.
|
We can use the door procedure from the old house experiment |
|
Doors in place, double for wider opening. |
As it stands
Apparance doesn't have an moving object support so there was no way to animate
the doors opening. Instead I had the
cheeky idea of switching between open and closed doors based on the detail
level and letting the detail blend system provide the transition.
|
Door opening hack in action; high LOD open, low LOD closed. |
This is very hacky, but just the sort of things you try and get away with at a jam. It adds a lot to the feel of the rooms.
Late
Hacking
Back at home (after
an evening out at the local Nov 5th fireworks display) I set about integrating
the collision test code into the engine.
It's a piece of code I found written by
Igor Kravtchenko, which does
exactly what I wanted.
For simple
environment collision and movement simulation, all you need is sphere-triangle swept
collision testing. Basically, the player
(camera) sits on top of a ball which is moved around by the controller. Each frame you do a sweep test as you attempt
to move the ball a bit and adjust the new position according to the collision
results. There are lots of edge cases
that would break, but this should have been enough for me to move round a
'boxy' level. After much coding
late into the night I managed to get a rough version working. Things were looking promising.
|
Collision testing against tagged triangles. |
This wasn't to last though...
Day 3
In the cold light of
day, my physics experiments from the previous night started unravelling (too many edge cases, falling through the world, etc) and I
decided to abandon the idea as I didn't have enough time to sort them out. Back to fly-cam.
The game at this
stage wasn't much of a game as there were no clues to help you choose your
final room. Puzzles were needed, so I headed out to the jam room again for the final day.
Puzzles
Mulling over the
puzzle mechanics the previous night I came up with the idea of mysterious
symbols in each room providing clues to the final rooms outcome. It would work like this:
- A set of symbol design are
available.
- This set is split into three
sub-sets 'good', 'evil', and 'neutral' symbols.
- Each room in the maze will be
clearly distinguishable as either a good clue room or an evil clue room.
- Each clue room has a few
symbols in it, some selected from the good/evil symbols according to the
room type, and some from the neutral set.
- The two final rooms will have
a similar set of clues, from which the player must infer the exit type.
Difficulty
The difficulty of
the game can be adjusted by varying a number of elements of the game:
- Number of symbols.
- Number of symbols shown in
clue rooms.
- Proportion of neutral symbols
shown in clue rooms.
- Size of maze.
To simplify the
level authoring, the difficulty level is chosen at random based on the game
seed in effect. This means that you
choose difficulty by changing the seed until you find a difficulty you are
happy with (more on this later). Most of the difficulty modifiers above were easy to hook up, but unfortunately I
didn't have time to implement maze size changing (it would be simple to
add though).
Symbols
So I set about
implementing the symbol set manipulation (as a bit-field) for generating the
sets, and extracting sub-sets, driving symbol generation, etc. As I worked I quickly set up unit tests to make
sure each step worked properly. I needed
to be sure it was correct as any inconsistency would break the puzzles.
|
Test rigs for bit-field operations: Pick, Split, and Count |
Symbol (glyph)
generation was a quick mixture of base shapes, colour, scaling, distribution,
and variation.
|
Sample glyph family. |
Combining these gave
a generation step where from a game seed we could generate a consistent set of
symbols for use through a given level.
|
Glyph sets and choosing example |
From these it is
possible to then generate a set of symbols for use in each room, good+neutral
and evil+neutral, the choice randomised by a varity seed (different for each
room).
|
Example glyph panel for clue rooms |
I chose to always
show four symbols in each room, with each room being designated good clue/evil
clue from the room seed. This could be
varied by difficulty if desired.
|
Glyphs on the walls of good/evil clue rooms. |
I intended for the symbols to be more subtly placed around the room and built into the decoration of objects, but this was far too much given the time constraints and I ended up just plastering them on the walls.
Exits
The two exit rooms
needed to be clearly different to the other rooms and also the way you make the
final choice needed to be 'no return'.
By colouring the room a neutral colour and making the final exit a hole
in the floor it nicely fulfilled both of these requirements. Under the two exit rooms (which by the way
are switched at random) I constructed suitably rewarding and punishing
environments to indicate whether the player chose the right room or not. You will have to play the game if you want to
see what they are. :O]
Start Screen
I managed to squeeze in game seed and difficulty indicators above the starting door to provide a bit of a start screen/menu/front-end to the game.
|
Game start room with seed/difficulty indicator. |
The controller support I added earlier included a key/button to select the seed value going into the top-level procedure. By driving the difficulty off this seed (at random) it doubles as a difficulty select too.
Postpartum
The final 'game' was
playable and enjoyed by a few of the fellow jammers so I'm happy to have met
that criteria at least. It did have the
'two choices' element, and maybe even the 'the player cannot win' modifier as
you can't actually escape the dungeon. I
was a bit disappointed that I didn't manage to get the physics working as this
would make the game easier to play and overall experience more claustrophobic, as well as the ending drop to doom/glory
more dramatic. I had an ongoing issue
with the rendering engine struggling on laptops which really got me down and is
something I really need to diagnose.
This week I'm going
to try and resolve the rendering issues, finish the physics, and wrap it all up
in a package for release on itch.io so you can have a play. It's quite exciting that this will be the
first release using the Apparance technology, and I look forward to your
feedback.
Coincidentally this
week is also
Procedural Generation Jam 2016 week and since my game meets the requirements for
that I will look to release it into the proc jam circuit too. Watch this space for an update!
|
ProcJam is also going on this week. |
As for the jam
experience, I found the environment an odd one working solo and would have
maybe got more done at home in my own office, but I would have missed out on
the creative and collaborative atmosphere.
It's good to meet and interact with people, especially those with
similar interests and passions, and I endeavour to continue doing things like this as I work to get
Apparance more exposure. At this stage the tools and tech isn't ready for collaboration at such a short notice, and I
continue to realise that it's still a very technical process to build
procedures. It strikes me as very much
'geometry programming' than sculpting of assets, which may or may not be a
problem long-term. I think it's 'just
different'. Thanks to everyone involved and it was great to see everyone's projects played at the end.
|
Me pointing as a willing victim plays through my game. |