January 16, 2017

Blue Asterisk Instead Of Red Cross

I noticed this article on Kotaku about the developers of Prison Architect running into trouble when they used the Red Cross to denote health.  We encountered something similar back when we were developing SiN Episodes: Emergence.

If you play SiN Ep, you may notice that all of the health containers have a blue asterisk and have the initialism F.T.R.C. emblazoned on them (standing for the Freeport Trauma Recovery Center).

What you may not know was that this was a response to me forwarding an article from GameIndustry.biz to management (link to summary), and the artists deciding to put in a response that a) lined up with the color of the healing spray, b) was not in any way able to be mistaken for a red cross or red crescent, and c) was a subtle way of putting in an initialism for "Fuck The Red Cross."

December 31, 2016

Why Valve (Possibly) Stopped Curating Steam

Please note that the following is purely conjecture, but I do think it explains a lot.

I back Jim Sterling on Patreon. I enjoy his Best of Steam Greenlight Trailers series and hope that none of my upcoming projects ever appear on that particular series, I do happen to agree that ever since the floodgates opened with Steam Greenlight, the amount of crap that has gone onto the service has increased at an alarming rate.

Mind you, it wasn't always like this.  Back when I was working on "SiN Episodes: Emergence," Valve had a severe interest in curating games that could appear on the service.  Now, though, unless a game is likely to be rated AO or be considered pornography in certain markets, pretty much anything can get on Steam. 

What changed?  It's not the surfacing of first-party launchers like Origin or UPlay.  It's not the resurgence of the indie game developer.  It's not the rise and/or fall of indie portals.  I think what changed is that Valve started to fear antitrust litigation.  Let me explain.

Valve both owns Steam, the number one portal for computer game software digital distribution, and develops it own games.  For better or worse, they are the major marketplace.  If you aren't on Steam, you aren't visible in the eyes of most digital download consumers.

Back when Steam was only Valve's software, a case could be made that nobody else had a right to be on the marketplace.  Even with a few select titles on Steam, Valve could easily say that this was part of a publishing deal with Valve, and therefore they weren't picking winners and losers.  Up until they started allowing other publisher catalogs to appear on the service, it was still a "Valve is publishing these titles, therefore it's still a Valve product in a sense" service and could be defended as such.

The moment other publishers could put stuff on Steam, though, everything changed.  At that point, Steam was no longer a publishing platform, but a storefront with negligible distribution costs and virtually unlimited shelf space...and they not only controlled who got what position on the shelves, but they also were stocking their own product there as well so they could be seen as having a conflict of interest.

Because Steam is now a storefront as well as a developer, Valve can't be seen to be picking winners and losers.  If they say that product X can't be on Steam, if another game with a similar theme or quality bar gets on the service, the developer of product X could potentially sue.

Valve created Steam Greenlight specifically to get the "curation" part of the marketplace out of their immediate control.  The assumption was that people visiting Greenlight would take their responsibility seriously and so Valve could allow the best submissions onto the service and still have some level of quality control on the service.  Unfortunately, it's fairly obvious that Greenlight has been gamed to no end and the floodgates of shovelware and asset flips have been opened onto the service.

There are algorithmic solutions to some of these problems.  Rating games that you own on Steam will do a good job of helping to quickly bury crap games.  Using Steam refunds for absolutely horrible games will also help, because refunds also cost Valve a small amount of money in transaction fees and I'm sure that Valve factors refunds into how aggressively they shift products out to search purgatory.

However, there's only one thing that will guarantee that Valve is able to effectively run Steam without running into lawsuit bait as part of curation: spinning Steam off from Valve.  The moment Steam is independent, Steam can easily start acting like a storefront only and not have to worry about conflict of interest.

Is it going to happen?  Probably not.  Hopefully Valve is able to find a way to more effectively curate their storefront without conflict of interests being shoved to the forefront...but I'm not holding my breath.

December 17, 2016

RomTerraria and v1.3.4.4

If you are using the test version of RomTerraria for v1.3.4.3 and above and are experiencing water not rendering, please repair your Terraria installation, launch the game once, exit, then repatch.

If you are using the patch and the map is not coming up or you are stuck in a lower lighting mode, it means that an exception has been thrown.  I need to know the resolution you are trying to run at.

I'll be spending time tomorrow working on any reported issues.  Today I have to go finish my Christmas shopping and try to ignore the fact that today would have been my twenty-second wedding anniversary.

[Removed three weeks worth of outdated information]

Update 1/8/2016 12:03pm: I'm still getting reports of water and lava not properly rendering.  If you have deleted your config file, reset your resolution, then restarted the game, and you are still having issues, look in your Documents/My Games/Terraria folder and look for a file called CrashInitTargets.txt and post the contents of that.

Update 1/9/2016 7:30am: I received a CrashInitTargets.txt that showed a NotSupportedException creating the waterTarget RenderTarget.  That's really odd because that particular exception shouldn't be thrown by the RenderTarget2D constructor.  Will research when I get home tonight.

Update 1/9/2016 6:45pm: Okay, I just made a change that should free up an extra 140-210MB of RAM.  Water is working using the following values in config.rt.json (I game RomTerraria its own config file to help keep things simple:)

  "SmartCursorToggle": true,
  "MapEnabled": true,
  "InvasionBarMode": 2,
  "AutoSave": true,
  "AutoPause": false,
  "Language": 1,
  "PlacementPreview": true,
  "GoreVisualsAllowed": true,
  "VolumeSound": 1.0,
  "VolumeAmbient": 0.75,
  "VolumeMusic": 0.75,
  "UseExperimentalFeatures": false,
  "Fullscreen": true,
  "WindowMaximized": false,
  "WindowBorderless": false,
  "DisplayWidth": 3840,
  "DisplayHeight": 2160,
  "GraphicsQuality": 0,
  "BackgroundEnabled": true,
  "FrameSkipMode": 2,
  "LightingMode": 0,
  "LightingThreads": 0,
  "Parallax": 0.88,
  "ShowItemText": true,
  "LastLaunchedVersion": 188,
  "UseSmartCursorForCommonBlocks": false,
  "UseSmartAxeAfterSmartPickaxe": false,
  "UseSmartWallReplacement": true,
  "DisableLeftShiftTrashCan": false,
  "HighlightNewItems": true,
  "HidePasswords": false,
  "ReverseUpDownForArmorSetBonuses": false,
  "MouseShowBuildingGrid": false,
  "AllowUnfocusedInputOnGamepad": false,
  "LockOnPriority": 2,
  "InvisibleCursorForGamepad": true,
  "GamepadDisableInstructionsDisplay": false,
  "SettingsUnlock_WorldEvil": false,
  "SettingsEnabled_MinersWobble": true,
  "UseStormEffect": true,
  "UseHeatDistortion": true,
  "WaveQuality": 3,
  "MouseColor": {
    "R": 255,
    "G": 50,
    "B": 95
  "MouseBorderColor": {
    "R": 0,
    "G": 0,
    "B": 0,
    "A": 0
  "QuickLaunch": false,
  "CloudSavingDefault": false,
  "FilterLimit": 16,
  "FilterPriorityThreshold": "VeryLow"

I'm packaging up the build now.

Update 1/9/2016, 6:54pm: Here is my update. The big change here is that I eliminated depth buffers for all of the render targets. Users of Terraria will see this result in ~210MB of RAM being saved. Users of RomTerraria will see this result in ~140MB of RAM being saved (I used to reduce the depth buffer to 16 bits instead of 24 bits). Again, this is an EXPERIMENTAL RELEASE. Have fun.

December 7, 2016

Ten Years Out

I left the games industry in December 2006.

I've looked back, and while there are things I miss, I won't be going back into games full-time until I can go back on my own terms.

November 23, 2016

The Method Rewrite Post

While I was taking my Uber back from the Postmodern Jukebox concert, I figured out how I was going to "fix" Terraria and allow myself to release an update for RomTerraria at the same time: I'm going to rewrite the method that is introducing the issue.

I've patched bugs in the base game before. For the longest time, if you didn't have a My Games/Terraria folder in your Documents folder, the game would crash when trying to create the settings file.  I patched that with the original releases of RomTerraria.

Fortunately, I've got a good place to handle injecting my replacement method.  LiquidRenderer.PrepareDraw just calls the internal method.

I'm going to do this patch in two phases.

Phase one will be out tomorrow on Thanksgiving assuming nothing else blows up and will simply make PrepareDraw be a no-op.  This will allow everything else to work as is EXCEPT for the new water effects.

Phase two will take significantly longer.  I'm going to rewrite LiquidRenderer.InternalPrepareDraw.  It's a bit over 400 lines of, well, not good code.  I mean, it's dereferencing to memory before a pointer.  If I was going to be a total dick, I could craft a world file that could potentially turn into a native code exploit.  Fortunately, I'm not a total dick.  This will take me a lot longer to do and may end up moot if they fix the issue before my rewrite is done.

I've only got this weekend to do this, so here goes nothing.

Update 11/24/2016, 11:57am: Well, it's not going to happen this morning, but I am working on it...

Update 11/24/2016, 12:20pm: I've gotten the replacement class building as a standalone DLL.  I've got to do IL-patches to replace 14 instances of the class in six methods in two classes.  I'm going to try to get that done before I have to leave for my afternoon social obligation.

Update 11/24/2016, 4:38pm: I'm back from my social obligation and am resuming my coding.  I've almost got the replacement working.

Update 11/24/2016, 9:57pm: Stopping for the night.  I've got my replacement class patched in and am working on debugging, but I'm exhausted.  That said, making PrepareDraw a no-op has other side effects and isn't a good solution, so I'm dropping that part of the plan.

Update 11/25/2016, 12:18pm: Taking a lunch break.  Since I'm afraid I'm going to have to do this kind of thing again in the future, I've created a general purpose class replacement system. Will resume testing once I am fed.

Update 11/25/2016, 1:03pm: I'm now able to reproduce the crash inside my custom class inside the debugger.  Should help me fix it.

Update 11/25/2016, 1:09pm: Well, it's good that I made the class replacement system generic, because the crash is NOT caused by the code I suspected.  It appears that something else is running amok around memory.  Give me a bit of time to figure out the appropriate memory layout so I can figure out which object is immediately before this one in the heap.

Update 11/25/2016, 1:30pm: I've got a 1.2GB memory dump that I'm manually going through.  I'd be going faster, but the .NET memory tools require a minimum .NET version of 4.5 and Terraria is compiled to 4.0.

Update 11/25/2016, 2:25pm: Good news: managed to stop the game from crashing. Bad news: filled blocks of water aren't rendering.  Still going.

Update 11/25/2016, 3:53pm: I've checked my current code into Github.  Still trying to figure out why full blocks don't render.  Note that this doesn't truly fix the memory overwrite, but it leaves the old 160KB object around as a "safety buffer."  I'm going to try for another hour, then call it a day.  I've still got work to do around the house.

Update 11/25/2016, 5:51pm: Part of the problem is that the version of Telerik JustDecompile that I'm using doesn't properly decompile unsafe code evidently.  Testing a fix now.

Update 11/25/2016 6:00pm: Adding padding around the wave bank let me run with water effects for almost ten seconds before the game crashed in a spectacular fashion.  Looks like something is hardcoded with a max resolution and when you go above that resolution, it starts walking over memory it shouldn't.  Dinner shortly, then more research

Update 11/25/2016 6:09pm: Here's a test version.  This is not guaranteed to work, but appears to be working in my limited testing.  Please let me know if it crashes for you.

Update 12/6/2016 1:13pm: v1.3.4.4 was just released.  The test version was compiled and tested against v1.3.4.3, and may not work with v1.3.4.4.  I'm at work for several more hours.  Let me know if I need to address anything after the fix.

Update 12/19/2016 9:35pm: Added LAA support code.  Trying to fix an issue with rendering water that surfaced at certain resolutions for v1.3.4.4 before releasing an update.

Update 12/25/2016 3:58pm: Build for v1.3.4.4 here.  You'll have to set up your settings again.