Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411283 Posts in 69325 Topics- by 58380 Members - Latest Member: bob1029

March 29, 2024, 12:48:31 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
  Show Posts
Pages: [1] 2 3 ... 20
1  Community / DevLogs / Re: Return of the Obra Dinn [Releasing Oct 18] on: June 09, 2019, 06:36:38 PM
Thanks Sunjammer. I hope things are going okay for you these days.

It's been a while since the game's release and I finally have time for a short technical post here. I haven't really thought much about the book specifically but someone asked about the implementation of the page turning and I thought it'd make a decent devlog entry.

Animating the Book

Design-wise the book in Obra Dinn is intended to collect and organize the deluge of information thrown at the player during gameplay. It establishes the chronology of events, shows details for each death, contains clues for identities, and more. I had a few other ideas about how to present this information to the player (a much shorter logbook, a navigable timeline interface, etc) but settled on a story-like book as the most implicitly useful metaphor.

In the beginning when this was supposed to be a quick project, I wanted to keep the UI simple, unadorned, and largely unanimated. The first public demo's logbook uses very simple instant page-flips. By the time I started working on the final book it was already two years into development and I felt that for such a central part of the game it needed to look fancy with proper page-turn transition animations.


Giffing through a few pages in the final book


There were two core technical requirements to make this work:

#1 The ability to render the entire screen to a texture, before post-processing. 
Made relatively easy by Unity's basic design and Obra Dinn's custom rendering pipeline.

#2 The ability to jump instantly to any page of the book within a single Update() frame. 
Made possible by Unity's ability to calculate UI layout manually, and careful UI code design.

To show a page turn animation, the basic process is:

   1. Render the current screen to a texture (Target A)
   2. Change to the next page instantly and render that to another texture (Target B).
   3. Hide the 2D book pages and show a 3D model of the pages with Target A and Target B mapped onto them exactly as the 2D pages.
   4. Play the animation on the 3D model.
   5. Hide the 3D model and show the full 2D book UI, now at the new page.

The 2D book is constructed from Unity standard and custom UI components, which I found pretty nice to work with. The 3D model was built in Maya with skeletal animation for the page turns.


Unity 2D book scene


Maya 3D book scene with a placeholder texture


The 3D scene needs to match the 2D UI exactly, which was a little finicky to set up. Keeping all the UI measurements simple and consistent helped with this (the screen is 800px wide, each page is 310px wide, etc.)


The 3D pages have their UV mapping set to subrects of the full screen render target


Animated page turn in Maya, left and right. The sliding vertical bars thing is the page shadow.


Result in-game and in-editor.


The render-targeted textures are captured before post-processing, so they can be used as regular textures mapped onto geometry and post-processed normally like everything else. I play with the depth scale a little bit during the animation and the page itself stretches the texture out unnaturally, but it moves quick enough to not be very noticeable. Some custom shader code handles depth testing (normally disabled for 2D UI) and faux lighting. You may notice that the shadow texture is pre-dithered in the editor view. Dithering is normally handled in post but sometimes opacity like this has to be done in-scene before post processing. The squareness of the page flip animation itself is a stylistic choice. I tried more natural from-the-bottom-corner turn animations but the less-aligned transforms made things a little too busy against the low resolution 1 bit output.

Once this system was set up I was able to use it for other transitions in the book, most notably the sketch/map/chart unrolling and rolling transitions:


Page-roll modeled in Maya. The geometry is static here. 
Rolling is faked by scrolling the UV coordinates while moving the geometry in code.


Page roll transition in-game and in-editor


Extra

A few random extra bits about the book. First and for some ridiculous reason, I thought it was important that book appear accurately bound. The centerline and edges change as the pages move from one side to the other. This was a total waste of time but sometimes there's no arguing with mid-project insanity.


Binding split and stacked pages shift while moving from cover to cover


Second, the book was designed to fill the game's original 640x360 resolution, with the edge of the pages right against the edges of the screen and no border. 


Original book presentation filling the game's 640x360 resolution


At some point while messing with the fullscreen dither problem, I decided to switch to 800x450 resolution for the entire game. This change came too late to redesign the book for the larger size, and because the layouts were so precise, just scaling it up created too many artifacts. My solution was to add visible front and back inside covers and to center the book against a black screen. I think this unintentionally improved the presentation by adding visual context and giving the dense pages some room to breath.


Inside covers and black border added to fill out the new 800x450 game resolution


One unaddressed consequence of this change is that the 2D book UI content cannot reach outside the 640x360 page boundaries for the 3D page flipping. This makes the bookmarks slightly less functional - logically they should stand above the page but instead they're clipped to the same boundary as the rest of the content.


Bookmarks don't stand above the pages


Lastly, one of the things I added to the game just before release was the final insurance tally. This is a multipage report that summarize the results of your investigation. Being a collection of pages, it would've made logical sense to animate it like the book, lovingly and with excessive attention to detail. Unfortunately, the presentation of the tally is different enough from the book that it would've required quite a bit of additional work. At that point in the development I had almost no energy for something complicated and instead just cheaped out with a twitching page-flip kinda thing. Honestly I don't think anyone noticed or cared.


Cheap-o page change animation for the final insurance tally.
The page number is functionally important to make it clear you're flipping through the report.
2  Community / DevLogs / Re: Return of the Obra Dinn [Releasing Oct 18] on: October 20, 2018, 12:59:19 AM
So now that it's released, I'd like to know about its content from the perspective of a parent.

As a parent, I'd say it's not appropriate for anyone under 16, maybe 18.


I'm kind of curious, how was development time split across all the different tasks you had to do? Like was it engineering 30%, story/design 40%, art 20%, music 10%, etc. I'm particularly interested because you've mentioned multiple times how surprised you were by how long it took, and I'm wondering what tasks in particular ended up being such time-sinks.

I doubt I could break down a percentage like that. The thing that took the most time was the modeling and scene creation, along with all the custom tools to support it. Also, the game's design is one of those "not clear until it's done" sorta things. I spent a while wandering around and spinning my wheels before seeing enough of the whole picture to nail things down.


My only problem, which is becoming more and more upsetting, is that it moves forward automatically too much, I was taking my time reading the first screen and bam!, company letter, didn't even read the rest, then bam! again. Now I'm on the "face tutorial" and it just keeps going without me pressing anything.

There's an issue with the initial release where moving the mouse will skip some text too quickly. I'm fixing that. Otherwise, you can go back and repeat any of the book tutorials by clicking the "?" on the fate popup.
3  Community / DevLogs / Re: Return of the Obra Dinn [Releasing Oct 18] on: October 18, 2018, 10:16:16 AM
I'm excited for the game's release, but also a little sad for the end of this devblog  Coffee

Definitely not the end. I plan to post a bunch of stuff in here about the run up to and through release. Plan.
4  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: October 10, 2018, 10:58:25 AM
Almost there.

5  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: September 14, 2018, 08:53:26 PM
Yup, thanks Paddy Smiley

I have a few things I could post here but work on the game is still at full-on pace. That plus the mundane tasks of actually self-publishing a game will keep me busy right up through launch, so sit tight until after that for more dev posts.
6  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: August 21, 2018, 12:59:59 AM
Is it like the whole ship is visible, or just like the top of the mast peeking over the horizon?

Whole ship, bow to stern.
7  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: August 19, 2018, 10:50:45 PM
As always, your amazing ability to conjugate the artistic and technical parts of the gaming dev is tremendously inspiring.

Thank you! I'm all about conjugation.


Quote
Two questions, if I may:
(1) the dithering tuning seems to focus on camera rotations. [...] Am I wrong?

I couldn't figure out a way to stabilize for translations. At least, not before getting the rotations stable and deciding that was good enough. I mentioned it somewhere, but so many things change onscreen during translation that the dithering issue is just not as noticeable. It's only during rotations that the eye can track everything easily and gets disoriented with screen-mapped dither.


Quote
(2) general question, not sure it is decent to ask this but: not only the amount of inventive and skill is insane, but so is the amount of plain dedication infused in your games. How does this balance out? From the... economic sustainability point of view. Exactly because your dev log is so powerfully inspirational, I wonder if you could comment on this, in general.

I'm not sure the exact question but If you're asking how I can afford to dick around with this game for 4 years, the answer is that Papers Please sold well enough that I'm financially covered for a certain amount of dickage. The bigger challenge for me has been mental - I'm just not built for spending this long on a single project, and I often think about how crushingly poor the original plan to finish this game in 6 months was, or what else I could've been doing all these years.


Homeward Bound

Some good news is that the end is finally in sight. Two weeks ago I put together a rough but completable build of the game that my wife played through from start to finish. She enjoyed it, and watching her play settled a few lingering design doubts. Being so close to the thing for so long, I have zero perspective on the overall experience so it was encouraging to get the sense that maybe it works. My plan from now is to focus on art/audio/music polish.


Have Game Need Ending

For a long time, I've had a vague idea for the game's ending that wraps everything up nicely. It's one thing to have an idea and another to actually execute it in a way that makes sense and feels satisfying to the player. In this case, once the initial implementation was in I kept adding more and more little steps and transitions to make the pacing feel right. On the upside, messing around with the ending lead me to a full bookending, which briefly clarifies the player's task at the start of the game.


Intro communique. Really wanted this to be a telegram but, wrong time period.

Final insurance assessment. A riveting 21 pages of claims. 
The contents depend on how you register the crew member fates during the game.


8  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: May 18, 2018, 08:04:31 PM
Hey guys. It's been a while since I've had anything worth a post here. All my work since the last post has been on boring or spoilerish production line tasks. I'm finally somewhere that I can post a status update with a few interesting notes. At the end of February, I set two deadlines: All the music completed by April 1st, all the audio completed by May 1st. I hit the music deadline and sailed briskly past the audio one.


Structure

The basic gameplay has the player walking around the ship, finding flashbacks. Each flashback starts with an audio-only playback of 10-40 seconds before you're dropped into a frozen 3D walkable scene. The 3D scenes have music but otherwise no sound. There are 49 total flashbacks. The flashbacks are grouped into 10 overall disasters that struck the ship, killing off a few crew members each time. Flashbacks are experienced generally in reverse, with exceptions.


Spreadsheet of all flashbacks, chronological, divided by disaster


Music

My original plan for the music was to just write a bunch of tracks in different styles and assign them to the flashbacks however felt right. As the scope of the game became (dauntingly) clearer I decided that composing a theme for each disaster would help the players orient themselves better. Each disaster now has two one-minute songs: A & B. Flashbacks within a disaster are assigned A or B in a way that ensures the player will likely always alternate between the two, rarely hearing the same song twice in a row during normal play.

Style

To keep with the general setting, all instrumentation is classical. I think in one or two cases I cheat with an electric bass or kick drum track. Mostly though it's just your standard strings, brass, woodwinds, orchestral percussion, organ, harpsichord, etc. I took a few years of piano lessons when I was a kid and played drums in a speed metal band in high school (Megadeath > Metallica). That means I suck at orchestration and have only the smallest shred of awareness about classical instrumentation. Expect to hear some cellos playing beyond their range.

Software

Everything was composed in Logic Pro X. I started out exclusively using Sonokinetic's DaCapo orchestral samples in Kontakt but got frustrated with the slow load times and heavy CPU usage - before this project I'd always used hardware synthesizers that load instantly. DaCapo sounds good enough that I wasn't willing to give it up completely so instead I added a Roland Integra-7 hardware unit for more instant sounds, sequenced in Logic as an external instrument. There are some really nicely-articulated orchestral instruments in the Integra-7 that fit perfectly.

Because I don't like actually using a computer while making music, I went a little goofy and set up separate desk with fullscreened Logic on a low-res TV. This is as close as I could reasonably get to a hardware DAW while still having all the convenience of software.


Composing the music in Logic Pro X


Status

Right now all 20 flashback songs are composed, sequenced, and in the game. There's also a separate theme song for the title screen. Working on the music for a month, I learned a lot of things about the process so my OCD is asking me to kindly go back and mix/master/level/balance everything at some point.


Flashback Voices

The audio for each scene playback is presented like a radio play, with no visuals, and is composed of two basic parts: the recorded vocal performances from the voice actors, and the foley sound effects. All together there are 29 speaking roles in the game, from a wide range of nationalities:

  1 American, 2 Austrian, 1 Dane, 9 British English, 1 French, 1 Indian,
  3 Irish, 1 Italian, 1 Pole, 2 Russian, 1 Swede, 3 Taiwanese, 2 Chinese, 2 British Welsh

Most of the casting and recording so far has been through voices.com. They have a project management service that streamlines submitting jobs and reviewing auditions. All this works great for the more standard nationalities/accents and for a game with so many brief speaking roles I can't imagine a better way. For any non-native English roles I ask friends of the same nationality to review auditions and tell me if someone sounds authentic. Getting a good performance was important but accents also provide gameplay-critical clues so I really want native speakers. This is all complicated by the fact that most of the dialog is in English, so non-native English speakers need to perform in a language foreign to them.


Reviewing auditions on voices.com


I've also worked with a few voice actors individually outside of voices.com. The big ones being the Formosan characters, who all speak in Taiwanese Hokkien. For those I got the help of Johnson Lin from IGDA Taiwan, who hooked me up with Lee-Kuo Chen (Sunhead Games, making Carto). Lee-Kuo was a huge help in first translating all the necessary dialog into Mandarin/Taiwanese, and in finding and managing the Taiwanese voice actors.

All actors record their lines on their own equipment or using a local studio's equipment. That complicates things when putting a scene together, fixing booth quirks and matching recordings to make them sound like they're in the same scene together. When something doesn't sound right or doesn't match up, I usually just obscure the voice slightly with other sounds. Pragmatism.

Random Comments

  • The writing has a huge effect on the quality of the performances. Bad writing can't be acted well and there were characters that auditioned poorly across the board. If no-one can nail a character that usually meant the writing was unnatural and I'd go back to rewrite it and try again.
  • In contrast with a bigger studio, or just a developer that knows that they're doing, I didn't get all the scripts/roles/characters together at once and have it handled efficiently. I've been rewriting the script over the years and casting the voices in phases as I get more nailed down.
  • Pacing is hard to judge on the page. More than once I'd written a long detailed scene with lots of talking, gotten solid performances, found it too long, and cut a large amount of dialog from the final scene.
  • I struggled to use effective expletives in the script. Every single scene ends with a death and it's almost always violent; you expect to hear some cursing. Even though the dialog isn't fully period appropriate I wanted to leave out modern expressions like "fuck!", "shit!", "bullshit!", etc. I also didn't want to fall into cliched pirate or sailor speak. In the end I mostly just removed the expletives or settled for less harsh ones (to me) like "bloody", "fools!", "damn!", etc.
  • One particular actor did a fantastic job with one of the Welsh characters, except that his accent came out as standard English and not proper Welsh. I think he's actually American. Anyways, instead of trying to recast I changed the in-game character to be generic "English."

Status

A few characters are still not cast/recorded. These are all roles that are either from non-English speaking countries (Austria, Poland, etc), or just underrepresented in the easily-accessible voice actor community (Welsh, Irish, etc). I'll cast these in a final pass after the game is fully playable from start to finish and I can build a list of all missing vocal exclamations.


Flashback Sounds

I created all the flashback sounds in Adobe Audition. It's a great non-linear multi-track audio editor with one critical weakness: no track grouping. That means multiple track lanes that all serve the same general purpose can't be grouped and collapsed to make effecting/routing easier. Still, I was able to use the basic bussing and lots of scrolling to deal with comically huge multitrack files. If I was doing this again, I'd probably give Logic Pro X a shot at full multitrack audio editing. It has most of the features of Audition with the added bonus of robust track grouping.


Scene audio composed in Audition. There's 48 more like this.


The difficulty of putting together each scene is based on how conventional it is. A bunch of dudes talking or fighting is easy. The dialog is recorded and video-gamey action sound effects are abundant. The really hard scenes are the ones with complex actions, usually involving unconventional sounds that are much harder to source. I've recorded just a few basic sounds on my own. 99% of the effects I'm using are from existing sound libraries. The main ones:

Pond5
My main go-to for sound effects. I've spent hundreds of $$$ here. Good search, tons of providers, widest overall selection. On the downside, preview clips are slow to play, quality is wildly variant, pricing is a little high ("Fart #95", 1 second, $6) buying sounds requires a comparatively long checkout/download process (even after buying credits), and all previews are overlaid with "POND FIVE!" watermarks, which gets mindbendingly annoying.

SoundSnap
Fewer providers but faster search, fast previews without watermarks, overall higher quality, much faster purchase/download process (one click after buying credits). I usually searched here first.

ASoundEffect
A wide selection of complete sound effect libraries. Probably the highest quality but a fairly limited selection overall. Designers tend to focus on the standard sounds and even if you find something useful/unusual in a library you'll end up buying hundreds of unnecessary sounds along with it. There's no way to preview everything in a library - even the perfectly-tagged sound may not be what you're expecting. Also, library makers have an unfortunate habit of padding their sfx numbers. 11,000 sounds of crashing waves, all basically identical. I only purchased libraries when I had no other choice, and even so ended up spending 90% of the money on things I couldn't use.

Status

All 49 scenes have their first-pass audio complete. Some have missing voices which need to be added. Like with the music, I'll also need to go back and rebalance/remix all the scenes to fit together well.


Efficiencies

Throughout the years of working on this project, I've really enjoyed bouncing around between engineering and creative tasks. Enjoyed maybe a little too much. More than once I'd move forward on something, put it aside to work on something else, and return to the earlier task having completely forgotten the tools/pipeline/systems/everything.

For these last two months I decided the best way to get this shit done was to focus on one thing at a time. One month of music only, one month of audio only. That ended up being a big efficiency win - I was way more productive in each case. I don't think this would've worked that well earlier, before the game was totally nailed down. But still I regret not setting aside more ultra-focus time sooner.
9  Community / DevLogs / Re: Bermuda (working title) on: March 23, 2018, 02:54:10 PM
First gif: sold. Castle gif: megasold.

This is a great look and you're nailing it. Keep it up!
10  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: November 23, 2017, 05:53:02 AM
Fullscreen, Round 3

Thanks everybody for all the suggestions. I tried everything, literally, and concluded that the best way to maintain the game's style and fix the fullscreen discomfort was to stabilize the swimming dither and subdue the flickering dots. I got there in the end, with a few compromises. This is the 3rd full devlog post I've written on this. For each previous version I'd get an idea or find something else to try while checking over it. At this point, don't even care.


Dithering Process

First, a quick explanation. Obra Dinn renders everything internally in 8-bit grayscale then converts the final output to 1-bit in a post-processing pass. The conversion from 8-bit to 1-bit is handled by comparing each source image's pixel to the corresponding dot in a tiling dither pattern. If the image pixel value is greater than the dither pattern dot value, the output bit is set to 1. Otherwise it's 0. The output gets reduced to 1-bit and the viewer's eye will merge the pixels back together to approximate more bits.


Thresholding a source image by a dither pattern


The two components of this process are the source image and the dither pattern. Obra Dinn uses two distinct patterns for different cases: an 8x8 bayer matrix for a smoother range of shades, and a 128x128 blue noise field for a less ordered output.


bayer / blue noise


In-engine result without wireframe lines. Bayer on the sphere, blue noise everywhere else.


Hold Still Please

The basic dithering process works great for static images and much less great for moving or animated images. When the source image changes from frame-to-frame the static dither pattern and low resolution output become a major problem. What should be solid shapes and shades now read as a wiggling mess of pixels.


Moving the sphere


These days, dithering is mostly used when the source image is either static or the output has a high resolution. The first thought when seeing this low-res swimming dither effect is not "yeah that's how dither works" but "what is this warping shaking effect and how can I turn it off."


Exhibit A. Reduced contrast for your comfort.


Try to focus on something here when it moves and behold the crinkled heart of Obra Dinn's fullscreen problems. There are ways to fix this that mostly boiling down to "this style doesn't work, change it." I went pretty far down that path, experimenting with different styles, before swinging back and wondering if maybe I shouldn't let these bullshit little pixels push me around.


Stabilizing The Dither

To give your eyes the best chance at recombining everything, dithering works best when the dither pattern dots have a 1:1 correlation with the output pixels. But, correlating only with the output means that as a scene post effect there's no connection between the geometry being rendered and the pattern that thresholds it. Each frame, moving scene elements threshold against different values. What I want instead is for the dither pattern to be "pinned" to the geometry and to appear stable as it moves with the rest of the scene.

The core of this is a mapping problem. As told by the length of this post, there's a conflict between the ideal dither pattern mapping (1:1 with the screen) and the ideal scene mapping (x:1 with the geometry) so get ready for some compromises. Most of my work was focused on mapping the input dither pattern into different spaces that better correlate the pattern with the scene geometry. Everything here is done at the pre-thresholding stage.


Texel Space

My first try was to map the dither pattern in texel space. This is equivalent to dithering the object textures during scene rendering instead of in a post-processing pass on the 8-bit output. I didn't expect this to work well but wanted to see what a perfectly scene-matched mapping looked like anyways.


Dither pattern in texel space


Ok well, expectations solidly met. The objects are all mapped differently so their pattern scales don't match. Those could be unified. The real problem is the aliasing. Any resampling from one space to another like this will result in aliasing, and dither patterns can't be easily mipped or filtered like traditional textures. Still, to carry it through:


Applied to the moving scene


This isn't a total loss - the pattern is nicely pinned to geometry. The aliasing produces its own swimming effect and unifying or scaling the mappings won't help with that. Texels change size with distance from the camera so there will always be dither pattern pixels that alias badly when resampled to the screen.


Motion Warping

If I want the dither pattern to track the moving geometry beneath it, why not just warp the pattern using the change in position of each rendered pixel in the scene? Indeed why not. This is a bit like a motion blur, where each pixel tracks its movement from the previous frame. In this case, I update the dither texture to keep its pattern moving with the scene. If a scene pixel was not represented in the previous frame, the dither pattern is reloaded there. This technique is made much simpler by the game's static-ness - I only need to worry about the movement of the camera, not individual objects.


Warping the dither pattern to maintain frame-to-frame coherence with the scene


This was a pretty quick & dirty try but a few things are clear. First, it kinda works. Second, a dither pattern needs a neighborhood - it can't be individual pixels. If you consider each pixel individually, as this method does, then you'll get breaks and discontinuities in the pattern which are obvious. I shifted the camera in this test scene to highlight those on the chest here. Viewing the warped dither pattern itself makes this a little easier to see.


Thresholding solid gray with the warping dither pattern


These discontinuities are down to the differing pixel depths and thresholds that I chose. I reasoned an elaborate fix based on tracking regions, averaging their depth and shifting all dither pattern dots in that region by the same amount. A discontinuity along a region boundary could be hidden by sharp lighting changes or a wireframe line. This would've been enabled by the game's existing setup of colored regions for the wireframe generation. When I sat down to implement all that, the depth term dropped out of the first equation I came up with and gave me a much simpler alternative:


Screen-mapping With Offset


When putting together the equations for the warping dither, a very simple transform fell out:
Code:
DitherOffset = ScreenSize * CameraRotation / CameraFov

Shifting the screen-mapped dither pattern based on camera rotation


Basically, this expresses that I want the screen-mapped dither pattern to shift by exactly one screen when the camera rotates through one field of view. That maintains a 1:1 mapping with the screen while also considering a simplified transform of the scene geometry in view. This really only matches the movement at the center of the screen but bless this fucked up world because it's nearly good enough.


Offsetting the dither pattern to track one screen per camera fov rotation


Note how the dithered pixels on the chair appear to mostly move with the geometry. Likewise for the sphere. Planes more perpendicular to the view don't match very well; the floor is still a mess.

So while not being perfect, simply shifting the screen-mapped dither keeps the overall pattern and scene movement close enough that the eyes can better track them together. I was pretty happy with this. While cleaning up the code and committing everything, maybe writing a devlog post or two, the idea of a perfectly-pinned dither kept nagging at me:


World Space - Cube Mapping

The experiments so far suggest that any correlation between the dither pattern and scene geometry would have to ignore depth information from the scene. What this means practically is that the dither can be pinned to the geometry during camera rotation but not during camera translation. This isn't such a bad thing for Obra Dinn considering the slow pace of the game and the observational role of the player. You're normally walking around, stopping, and looking at things. When walking, so many things are changing onscreen that the swimming dither isn't as obvious.

With that in mind, my next attempt was mapping the dither pattern to the geometry indirectly by pre-rendering it onto the sides of a cube centered around the camera. The cube translates with the camera but stays oriented to the world. In the mix: little bit of screen, little bit of scene.


Dither pattern mapped to a cube centered around the camera


Camera's view looking up into a corner. Mapping scaled up for clarity.


The cube's mapping works well when looking directly into the sides, and not so well when aimed into a corner. Still, the dither pattern stays perfectly fixed in 3D space as the camera rotates. Even rough, the result is promising.


Thresholding scene with the cube-mapped dither pattern


Now we're talking. Being a post-processing pass makes this more general than texel-space mapping, which is good. The problem is now down to the particular cube mapping. An ideal mapping would have one texel on the cube always resolve to exactly one pixel on the screen, regardless of the camera rotation. That's not possible with a cube...


World Space - Sphere Mapping

...but I got pretty close with a sphere.


Mapping the dither pattern onto the inside of a sphere


Finding this particular spherical mapping took some time. There's no way to perfectly tile a square texture onto a sphere. It would've been possible to redefine the dither matrices in terms of a hexagon grid or something else that does tile on a sphere. Possible maybe, I didn't try. Instead, I just hacked on the square tiling until this carefully tweaked "rings" mapping of the original dither pattern gave good results.


Applied to the scene


Better than the cube. Still lots of aliasing. The spherically-mapped dot size is very similar to the screen pixel size - off just enough to cause moire patterns. I could feel the closeness, and a very simple fix for this kind of aliasing is to supersample: apply the dither thresholding at a higher resolution and downsample.


Spherically-mapped dither pattern at 2x and downsampled to 1x


Thresholding at 2x, then downsampling to 1x


This is the best I got. There are a few compromises:

    1 The dither pattern dots get larger and less effective at the edges of the screen
    2 The pattern isn't aligned up-down-left-right for most camera rotations
    3 The output is no longer 1-bit due to the final box-downsample

But the upside is pretty lofty:

    1 The dithering is perfectly pinned for all camera rotations. This feels slightly uncanny in-game.
    2 Discomfort from swimming dither is totally gone, even at fullscreen
    3 The pixellated style of the game is preserved

It's possible eliminate compromise #3 by reducing the output back to 1-bit with a simple 50% threshold. The result is still better than without supersampling (the triple comparison directly below is thresholded).


Side by side, by side


In the game's default palette

Wrapup

It feels a little weird to put 100 hours into something that won't be noticed by its absence. Exactly no one will think, "man this dithering is stable as shit. total magic going on here." I don't want to give people problems they didn't know they should have though so it was worth fixing.

The screenspace mapping with offset works best at 1x and the sphere mapping works best at 2x. All scene rendering is at 800x450 now (up from 640x360), which helps legibility without sacrificing the low-res style. The final game will have two display modes: 

DIGITAL
Border-boxed, screenspace offset dither, 1-bit output

ANALOG
Fullscreen, sphere-mapped dither, softened output
11  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: October 19, 2017, 06:01:28 PM
I'm over here jumping hammerheads but apparently you guys came for great whites. Not even sure they're native to this area.

This unpainted corner is all my own fault. I've made a game where recognizing details is important and the visuals work directly against that. Another way to put it is that the chunky pixels affect a great visual style but I need players to see past the individual pixels and into the scenes, characters, faces, and details being represented.

Bennet I'm not an inherent fan of upscaling either but there's an objective reality that the game is hard to play for long periods in fullscreen. Without changing the visuals I can either force large borders and hear players rightfully complain about "black bars", or I can allow fullscreen and have them give up out of discomfort. Think of it like bad VR, where an uncomfortable experience trumps everything else.

There are two possible compromises:
  1. Add more pixels
  2. Add more bits

I've internally decided that adding more pixels is better because it preserves the 1-bit moniker. I'm not totally calcified yet though so I'll play around with adding more bits instead. As JobLeonard noted, maintaining persistence of vision is made harder with large high-contrast pixels. A phosphor or motion-blur effect could help with that. Then the question will circle back to which compromise looks and works better to me. I'll post any results here, hopefully in a few days.

In any case, the original display mode will be an option in the menus, so you can reflect on my stunningly clinical wisdom in not making it the default.
12  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: October 19, 2017, 06:09:05 AM
PAX West 2017


Booth shot (thanks to Chris Kohler)


Showing the game at the IMB Minibooth went great. My goal was to test out the new book and game flow and it seems the changes worked well. Some players embraced the book and some players ignored it but just about everyone was able to proceed through the game without getting stuck. Visually, the presentation was helped by the small-ish monitor mounted away from players' faces. Small physical pixels means the dithering works as it should and the low resolution isn't a distraction. As far as I was concerned, everything was hunky dory.

Having finished the script and sent out character audition scripts before PAX, the moment I got back home there were hundreds of voice actor auditions. That kept me busy for a while but I was able to stop by TGS in mid September to chat with a few fellow indies. One of those indies was Justin from Gattai Games. They're making a black & white horror VR game, "Stifled", which at first glance looks similar to Obra Dinn. I played their demo at PAX and it was great fun. They were showing the same build at TGS and I had a chance to ask Justin what he thought of the Obra Dinn build he played at PAX. His main comment was that it gave him a headache after a few minutes so suit up b/c there's nothing I love more than a problem that needs solving. 

Shark Jumping

This is the point where, as I put this post together, I wonder wtf I'm doing and why I don't just finish the damn game already. Moving on.


Fullscreen Still Looks Bad




A few months Three years ago I made a long post about how the game looks bad in fullscreen. I addressed this problem in a few ways (better dither, optional soft filter, etc) but resisted actually increasing the resolution, the obvious choice. The main reason for that is that I'm leaning heavily into the grungy dither-punk presentation through all levels of the art direction. Everything was designed with a minimum size for details and adding extra fidelity makes the game look worse.

Still though, it's a valid complaint that the game is all-day headaches and I really wanted to spend a little more time on that.


Shades and Lines

Broadly, the game's visuals are split into two separate elements: 1) Dithered texture, and 2) Wireframe lines.


The basic visual components


Zoomed


The game renders natively at 640x360. Doubling to 1280x720 gets finer geometry, more effective dithering, and thinner wireframe lines:



As mentioned I don't like the extra detail, but I also don't like the thinner wireframe lines. The chunkiness is almost totally gone and that's just no good. You can also just start to see how low-poly the geometry is, which I'd rather avoid.

Now's a good time to reiterate that the visuals are really only a problem at fullscreen, large physical sizes. It's hard to communicate it clearly in little screenshots like this so just take my word for it. You can get a slightly better sense by seeing the swimming, flickering pixels in motion while zoomed.


Flickering dither and swimming lines


After thinking about this, it seemed to me that it should be possible to make the visuals more comfortable without adding actual detail, and without giving up the 1-bit limitation. My previous attempts were limited to upscaling the final buffer. That didn't give great results so I expected to try a little harder this time. It occurred to me that I could upscale each visual element (texture, lines) separately and combine them afterwards. Sounds harder already; good start.


Upscaling Dithered Texture

At 640x360, the game uses three separate dithering techniques: error diffusion, bayer pattern, and blue noise pattern:


The three dither techniques at 640x360


Each dithering technique is appropriate for different circumstances and their selection is important at these super low resolutions. With low res and bigger individual pixels, the eye has a harder time merging the dot patterns into shades of gray and I expect this is a major cause of eye strain. Doubling the resolution of the dithering (but not the underlying render) gives a much easier time of combining the dots into shades of gray:


Nearest-neighbor scaled from 640x360 to 1280x720, then dithered


Face closeup

.. Easier to see the grays, RIP chunkiness. It all looks a bit soft and the contrast between small dither pixels and thick line pixels clashes. Now that we've decided it's ok to cheat with mixed resolutions, and we've got all these extra pixels, why not try a coarser and more stylish dither pattern?


WB, chunk.


Looks rough but still captures the texture well, even without error diffusion


Rotating the dither pattern. Bad printer, classic newsprint, or tasteful woodcut? Choices.


Ok well that looks great and was a lot easier than I expected. Job half done.


Upscaling Lines

The wireframe lines were a little trickier. The goal was to upscale the lines into something that looks better and A) is still 1-bit (no blending) and B) doesn't add any information (no higher-res rendering). Since I played around with pixel-based scalers before I started by trying those again:


Upscaling the wireframes with pixel-scalers


There's a lot more algorithms than Scale2x and xBR but the others I tried end up with pretty similar results. Scale2x has the benefit of being fast and simple, xBR is slow and complex. Scale2x doesn't look good here, xBR is promising. After some research I found that xBR is a rule-based technique, designed for general color content. A significant amount of the work is spent on color separation and edge detection. 1-bit wireframes should be faster to handle, and if you're willing to write a custom pixel scaler, indeed they are.

Custom Line Scaler

I made a brief stab at simplifying the xBR algorithm but quickly decided there was too much going on there and it'd be better to just design something new from scratch. Without going into too many details, the algorithm I came up with does a case-by-case matching of the 3x3 pixel neighborhood to determine what the 4 new subpixels would be if the line was rendered at x2 with the same endpoints.


Pixels that match a left-hand pattern are expanded into the right-hand subpixels


I wrote a small Python tool to work this out and there are 24 possible left-hand patterns to match, which is perfectly manageable in shader code. The game takes the x1 wireframe render (640x360) and expands it to x2 (1280x720) in one shader pass. After this initial match-and-expand pass a little more cleanup is required. Line endpoints can be a lot more varied than just the 3x3 square neighborhood, and the border between matched patterns in these lines can leave out subpixels here and there. These missing subpixels can be hack-patched in a following pass that compares new and old pixel positions.


Original x1 line on the left, upscaled x2 on the right


The algorithm handles short lines well and long lines less-well. It rounds corners and when summing all possible matches in each 3x3 neighborhood, adds a satisfying "bleed" around joints:


Custom line scaler result


Comparison with nearest neighbor and xBR


If we just wanted a higher resolution line we'd be done but in Obra Dinn's case pixels carry information about wireframe color (inDarkness or not) separate from the wireframe on/off channel. This means that the changes to the wireframe channel need to be back-applied to the other channels. That's again a fairly simple pass that updates the subpixel colors based on neighboring wireframe values.

All told, the custom method is much faster than xBR and looks better for this special case. I have a hunch the technique could be modified to handle full color data and used as a general-purpose pixel scaler. Maybe I'll play around with that after the game is done. So, never.


Putting It All Together

Combining the higher resolution dither pattern with the custom line scaler makes a big difference. There's still swimming during motion due to the low resolution input data but it's way more comfortable to look at. The old display mode will remain as a selectable option and this new business will probably be the default.

I'm gonna gently close the book on this again. The final result:




Old/new comparison


Moving
13  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: October 18, 2017, 09:48:50 PM
FWIW (unless I'm confusing things completely) Subject-Verb-Object would be [Person B] [shot] [Person A]. The phrase [Person A] [was shot by] [Person B] is passive voice (Object-Verb-Subject).

You're right and it's actually worse than that, as I've got both "[Person A] [was shot by] [Person B]" and "[Person A] [shot] [himself]" as fate options for the same guy. So I guess it's less "subject" and more like the "topic" you see in, at least, Japanese grammar. I don't want to think about it too much or I'll go changing things again.


Please, i need this desesperatelly...  i need to make a huge city and Unity Lightmapper takes ages (literally)

I touched on this a bit via Twitter, but the Lightcaster isn't production-ready for any case but mine right now. For one it's Mac-only. The shaders don't work on Windows for some totally great reason and I won't have time to figure that out until the game has shipped. For another, it's probably not ideal for huge levels. In any case it will eventually be released but I suggest finding another solution for your situation. Even for Obra Dinn I'm using a dynamic shadow-casting directional light for the moon/sun light so maybe you can try something like that for sharp cartoony shadows.


Schedule

Coming off PAX West, there was a scenario brewing in my mind where I could finish the game this year. It would've been a struggle but doable. Unfortunately there's not really a good time to release it between now and the end of the year, and I've got a few things on my plate that would really suffer from a dive into crunch. So I've decided to push any potential release until 2018 at the earliest. The less exact I keep it, the happier we'll all be I'm sure.


Currently

My next big post should be about the script-finalizing and voice-casting process. You know, gettin close to the end - show some progress. There's a few interesting tidbits in there even though it's not mesmerizing. But no, let me instead talk about some endless tweaking and wheel spinning. Stay tuned.
14  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: August 12, 2017, 06:05:57 PM
It is great to see an update on Obra Dinn cataloguing all the issues you have come across and your solutions to the problems you identified seem very elegant. I think the corpse hunt mode is stunning. Best of luck finishing the last few cutscenes and getting the dialogue recorded. I look forward to the next post.

Thanks!

Wait, maybe I've missed this in the past updates, but have you started to use different dithering algorithms for different sections? The book cover is clearly pattern dithering, the rest looks like a kind of noise diffusion. Did you make any cool updates to the dithering approach in general?

In 3D, most of the screen is pattern-dithered with bluenoise. There's one shader that can switch between bayer and bluenoise+diffusion dithering based on a texture channel. It's mostly used for the characters. Bayer dithering reproduces shades best, which works well for the clothes, and diffusion reproduces high-contrast details best, which helps the faces. I'm using the same shader on the book as a stylistic thing.

In 2D, there's more flexibility for which areas of the screen are dithered or sharpened. I actually don't use it that much but, for example, the deck maps look better with pattern dither and the sketch looks better with sharpened diffusion dither.

15  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: August 11, 2017, 08:41:28 PM
Time to dust this thing off.

@BartsBlue: Semi-answered below
@Austinwoodmedia: I'll be in touch!

The game is progressing along. I hit alpha way back on May 15th but unfortunately it was the "notice severe design problems" kind of alpha instead of the kind that lets you sleep at night. This all came to light when I watched an experienced game designer friend play through the alpha build.

The main issue is that the game not only doesn't hold your hand, it breaks both arms at the wrist and zip-ties your pinkies together. The story itself is relayed in such a limited way, and the player is given so little guidance, that it's natural to A) get totally lost and B) not care. 

None of this was a huge surprise. I could feel it coming for a long time but there's always been an excuse not to tackle it right away. Clearing alpha put the issue(s) at the top of the pile.


Problems

The Manifest



Flipping through the manifest's 5 pages.


The manifest was designed as the main mechanism for deciphering people and events on the ship. The lack of context and bare presentation of were supposed to add an interesting level of sleuthing to the game. That would've worked fine with fewer characters and a shorter story. Unfortunately 60 characters, 10 disasters, and 48 flashback scenes is just too much and the structure of the manifest only adds to the confusion. A prudent solution would be to cut the characters/story way back but I liked those more than the manifest.


Interactive Objects


Interacting with a lantern


Picking up the manifest


There are four types of interactive objects in the alpha: Doors, the Watchbox, Lanterns, and the Manifest. Doors are fine, everyone knows how those work. The watchbox is explicitly called out and gated. You can't proceed without opening it. Lanterns might be fine except that you have to look up to interact with them. The game goes out of its way to teach you that you shouldn't bother trying to interact with small things so having to hunt around for a small lantern switch is just bad business. The manifest is the only collectable on the entire ship, required for meaningful progression but not hard-gated, and easy to miss. Classic game design BS. This set of interactive items grew mainly from the need to find and pick up the manifest. In the game's logic, the manifest is in the Captain's possession and so naturally you need to board the ship and find it. My mind was totally wrapped up in that premise and it's only when I changed the player's central motivation that I could work out a fix.


Corpses Within Flashbacks


A corpse within a flashback


In order to progress beyond the flashbacks accessible from skeletons on the ship, you have to find bodies within flashbacks and "pull" them to the current time, at which point you can view their death flashbacks. This is a neat system but it's one unexplained system too many. If you played the game at PAX Aus you would've been treated to numerous popup messages with graduated hints and clues about how you're supposed to advance since this concept is not introduced well. Nobody read the hints and so most people got stuck. I personally really hate getting stuck in games so this was a tall nail.


Fixes

I'm in a pretty tight spot with what I can do to fix this stuff. The game is totally married to the concept that you only get bits of story through flashbacks at moment-of-death, and you only access these flashbacks from the corpse of the deceased. So to tell a complete story, there need to be long unbroken chains of dead bodies reaching into the past, and gated areas of the ship to start off new chains with a skeleton here or there. Coming up with a story to fit these restrictions definitely took the longest time and has had the largest resource expenditure, so it can't really be changed at this point. Restrictions are good though so I had some structure to come up with fixes:


The Book


Oh look there's a book in the watchbox *



Table of contents, visible at the start


Selecting certain elements unrolls a closeup


Revealing one page of the book after visiting a corpse's flashback. Cued with music.


The Book takes over all the duties of the manifest in addition to explicitly listing chapters and every death in the entire game, initially as blank pages. As you find corpses and visit their flashbacks, pages are filled with information to help you assign fates and understand clues. The linear layout also makes explicit the flow of time, something which is totally lost otherwise as you're finding bodies in a very scattered chronological order. The Book's design grew from the idea of naming the flashbacks with chapter headings. Once I started thinking about those I was able to see the entire meta-narrative from a different and more interesting perspective. The big question of why there's a blank book with all the deaths is explained in the book's preface, and the handling of the book ties all the way into the game's ending. This is a big change from the previous "zero context" presentation but I think it's an improvement. And once again I've built some form of (really big) document in one of my games so, situation normal.

* Spot the UK/American English typo


Fewer Interactive Objects


Door and lantern status carried over from visited flashbacks


Now that the book replaces the manifest, and it's found within the same box as the watch, there's no need to pick up any items from the ship. That solves a major "item-importance" design problem that plagued the game since the beginning. I extended this even further and now the lanterns are no longer interactive. Instead, they behave like the locked doors and are magically carried over from their state in visited flashbacks. This removes some player choice but I consider lantern status to be pointless gameplay-wise and it leaves everything looking worse if the player never bothers/figures to switch them on.


Corpse Hunting


Corpse hunting within a flashback


Instead of expecting players to implicitly understand that corpses within flashbacks are themselves special, there's now an explicit "corpse hunt" mode shoehorned in there. After visiting a flashback for the first time, as the music ends, you're put in a mode where the environment is reduced to wobbly outlines and any outstanding corpses are highlighted clearly. Walk up to a corpse, use the watch, and you're done. Some flashbacks contain multiple corpses and you need to find them all to proceed. Once all the corpses are pulled into the watch, you'll return to the current time where a ghostlike effect emanates from the watch and leads you directly to where the freshly-pulled corpses will appear, ready for their flashbacks to be visited. This whole process feels a bit uncomfortable with its modality but it so neatly draws the player along that I like it. Now it's possible to hintlessly progress through the game while piecing together its internal logic and story flow at a much more natural pace.


Etc

There were a lot of other small changes leading up to alpha and since. A couple I can remember:

Fate Validation

The central mechanic of the game is to determine the fate of everyone onboard the ship. You do this by filling out a little sentence describing how they died or disappeared. It's always been up in the air how the player would know if these fate guesses were correct. None of the previous builds deal with it at all. One option is to just wait until the end of the game and tell the player how many fates are correct. I prefer something more immediate just for player satisfaction, but there's a problem that immediate feedback can be cheated. If I tell them their guess was correct right away, it's trivial for them to just try all the combinations and boom, game skipped. The solution I ended up with is to basically make it really hard to try all the combinations. The game now tells you when any set of 3 fates are correct. After entering the third correct fate (from any fates within the entire set of 60), there's a little fanfare reveal and those pages in the book are locked from editing. Cheating one fate is easy but cheating three fates requires just enough work, intent, or both that you'd be better off solving it the right way.

SVO Fates

At some point I standardized all the fates to use a Subject-Verb-Object format. So instead of saying [Person A] [was killed by] [Person B] [with a gun], it's now [Person A] [was shot by] [Person B]. This makes matching fates easier and is friendlier to localization, where sentence structure can be shuffled. It also lets me create more naturally synonymous fates, which was trickier before. Seeing how someone dies doesn't necessarily mean you can agree on how they died. Are they being crushed by falling rigging, or crushed by a terrible beast who pulled down the rigging? The fate system allows each death to have multiple correct fates so hopefully players won't get stuck by entering something they thought was correct but wasn't flagged as so.


To-do

44 of 48 flashbacks are in the game as either complete or roughly complete. Some require a little work, some require a lot. I'm finishing up the script just now so most of the dialog/audio isn't recorded yet. I've only written 5 songs; I need 10 more. The ending is designed but not built. ~4 rooms on the ship need filling out. Assuming my fixes above actually hold, the sailing should be pretty smooth from here since it's no longer a design task but a production task within a functioning pipeline. Hopefully I can get this thing done before the end of the year but we will see.


PAX West

I'll be showing the latest build at PAX West this year in the Indie Minibooth area, Sept 1st and 2nd. Come by if you're around!
16  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: April 20, 2017, 06:32:05 AM
Can't you expand and than contract the 2d collision pane to avoid places to get stuck in? (instead of removing the chairs legs)
All passages should be quite a bit wider than the player and stay open and thin edgees or points don't get smoothed off/away.
edit: a player in a 2d hamster ball would do the same  Cheesy

I like your thinking. That end result looks great. IIRC, the original Quake actually does this exact thing in 3D so that collision testing can be done with points/lines instead of spheres/capsules. It generated something like 3 different fixed sizes (point, player, shambler) of collision data for each level. So if you wanted a solid dynamic object that collided with things, it had to be one of those sizes.

I do expand the shapes a little bit but don't contract afterwards since I want some separation between the player and the walls. The player is modeled as a circle, not a point, and currently the basic 2D circle/poly collision response is smooth enough at keeping the player out of small gaps that I haven't had to take it farther. Basically, yeah, a 2d hamster ball.
17  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: April 18, 2017, 01:40:20 PM
If I understand correctly that dust particles are always single pixels, this technique should, I think, have the advantage of the cloud "naturally" thinning in the foreground, as the visual space between particles should be greater in the foreground than the background.

That's exactly right. It mostly has the effect of obscuring things in the distance. Up close the particles effectively disappear.

Quote
Hmm... If the particles are always single pixels, what do you intend to do about changes in resolution changing the apparent density of the dust cloud? Or does the game work in only a single resolution?

Right now the game is limited to just 640x360 as a stylistic choice. A little arbitrary but everything so far has been designed against that and some things (mostly character models) don't hold up well at a higher resolution. Dust pixels are always scaled to a 640x360 screen so when I do test something like 1280x720 each dust particle is 2x2 pixels. Also doesn't look that great and another reason I'm trying my best to make it all work at 640x360.
18  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: April 17, 2017, 04:28:23 PM
[...]the only buggy thing I could mention from this demo was that if you're in a flashback and pause the game, the current sound clip continues playing, where I think pausing might be nicer? [...]

Good catch. I fixed this recently by stopping the music and having the last bit of sound echo/decay for a few seconds. Just fully stopping the music sounds too abrupt so this works a little better.

Super Foggy in Here

If you've played any of the public builds or read this devlog you may have noticed the "dust" effect I'm using in flashbacks.


Dust particles


These are implemented as static single-pixel points, making something like a point cloud. I like the effect since it can be used to suggest movement and atmosphere, which sets the scene apart from present-day wandering around the ship.


Point cloud modeled in Maya


Creating dust clouds is a little laborious. I basically just create a model in Maya, import that into Unity, then generate a dust pixel for each vertex in the mesh. That works fine for showing movement; not so well for atmosphere.

Dust Planes

One thing I tried for atmosphere is "dust planes", subdivided planes with painted vertex colors. On import dust points are generated based on the interpolated color of the surface.


Manually-created dust plane

This works ok, but it's labor-intensive and with so many scenes (a constant problem on this game) I really need something more automated. Also, without a lot more work, there's no consideration for occluded points. Some points are created inside other geometry and never seen.

Fog Maps

With the recent obstacle map work in the 2D collision system, my mind was exactly in the right place to think about this again. It turns out that the same system for detecting obstacles for player navigation can be used to build a fog map. Instead of vectorizing the shapes, I keep the map in a texture and run a few GPU processing steps on it to get blurred fog. The fog map is then dithered to 1-bit and serves as instructions for where I should create a dust pixel. Because the map is 2D, I randomize the height to give the fog layer some depth.


Building a fog map from an obstacle map. This fog layer is close to the deck.


Like the collision maps, these obstacle maps cover a certain range of distances above a floor plane. To get a variety in the fog coverage, I can adjust the resolution, plane height, and processing steps:


A fog layer much higher above the deck.


Dust particles in-game: ground fog layer + high fog layer + rain


I won't show the whole scene to avoid spoilers. Trust me that it adds some quality atmosphere. Here:


Easier to see in motion


My only worry now is that I've gone too far. Working on a game for ~3 years, it's easy to grow tired of how it looks and want to snazz things up. Going completely overboard with fog/dust is my snazz. This particular scene is during a storm so it makes some sense here. I tone things down for the calmer below-deck scenes. Hopefully it works out ok.
19  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: April 07, 2017, 07:39:05 PM
Amazing update! I'm a huge fan of the custom system posts you do, because they really detail the entire process of solving a problem in an interesting and satisfying way.
Regarding the default Unity collision[...]

Thanks! I think it's definitely possible to get Unity's built-in solutions much closer to what I want. Writing a custom collision system is definitely overkill. One of the big reasons I enjoy making games though is being able to solve interesting technical problems. Unity's great because unlike when writing your own engine from scratch, you can pick and choose which battles are worth fighting. In this case I enjoyed writing a separate system and I especially appreciate the peace of mind it gives me about player movement behavior.


I think it's worth noting that nobody reads hints… at expos.[...]

This is definitely true. Everyone plays games differently when people are watching them. But I've also found a lot of value in treating these situations as canary-coalmine tests. There are people that won't read important text in any situation, and I want the game to work for them. I've made a point so far to not ask the player to read a lot and putting gameplay-critical information in onscreen text is just pre-expo panic. It can work if the game is structured that way and the player understands this structure. But so far Obra Dinn wasn't/isn't like that so dropping major learning in an onscreen hint didn't feel right.

In any case, figuring out how to fix this specific problem led me to a much better solution that I think actually adds a significantly cool element to the game. I'll try to get a post up about it later.

Quote
[...]I have to admit I'm extremely excited for this game to a level that's a rarity. [...]

Thank you! I hope the final game doesn't disappoint.
20  Community / DevLogs / Re: Return of the Obra Dinn [GDC 2016 Demo Build] on: March 20, 2017, 07:23:28 PM
The time it took you to write all that was worth it!

Thanks CT and everyone else!


Jittering: Could it be that friction was the problem here? If so, did you try to play with removing friction on the player?

I was using a non-physics based FPS controller (CharacterMotor), so there was no friction to tweak. The jittering mostly comes from imperfect colliders that, for example, bump the player away in one frame directly into another collider that bumps it back on the next frame. You can normally just fix these jitter-causing colliders manually but I have too many scenes to worry about for manual fixes.

Quote
Unexpected collisions and scene rotation woes: Did you try using physics layers and setting values in the layer collision matrix?

I briefly looked at using layers, but Unity's layer system for 3D physics is shared with general GameObject layering which kinda sucks. In the end, the problem is the behavior of the movement against rotated colliders, not that I want to disable them completely.


Did consider using Unity's navmesh system to define/generate your obstacle maps? That might be able to produced similar results.

Yeah my first thought was definitely to use Unity's navmesh. Navmesh generation is insanely fast which is nice. In my case though I want to define the walkable area explicitly based on a floor surface. This is different enough from how navmesh generation interprets the general 3D soup that I couldn't make the two match up well.

Navmeshes don't cleanly solve the "it's all walkable slopes now!" problem in the tilted scenes, and they don't fully represent animated collision (doors). So it would've been harder to completely unhook the movement from 3D colliders. When I started thinking about visualization, the idea that everything could be both visualized and run in 2D was enticing enough that it felt worth pursuing.

Pages: [1] 2 3 ... 20
Theme orange-lt created by panic