Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Blizzard

Pages: [1] 2 3 ... 40
Sea of Code / Another reason why WinRT is shit
« on: May 11, 2017, 11:13:20 AM »
So today I had to work with WinRT again. It was with sockets and WinRT has their own socket implementation. So no c-style sockets are allowed.

The main first issue is the problem that WinRT can't handle reading an "endless" stream from a socket. The problem point is the IInputStream::ReadAsync() method (because everything in WinRT MUST be async). Once you run the method, you can a special AsyncOperation object. You can assign a "Completed" delegate to that object and once WinRT reads at least one byte from the socket, that delegate will be called. Now, the issue here is that if there are no bytes available for reading, WinRT will wait an undefined period of time. This can be a timeout of apparently 180 seconds (somebody mentioned that information somewhere on Stack Overflow, I don't know if it's correct) or basically indefinitely. The catch is that there is no way to ask WinRT whether there are any bytes available for reading. So if you want to keep reading for a while or are wrapping sockets into a higher level system, you are fucked.

Now hold on. Yes, this is nasty, but this is only the introduction into the probably biggest async API design flaw I've seen in my entire life. Prepare yourself for a next-level fuck-up of multi-threaded programming.

So I kept thinking about this issue and an effective way to circumvent it. And I came up with something. I decided to use a buffer which I would then check for data in my main thread method call where I want to receive the data while I just keep calling ReadAsync() and let it do its thing.
Since we're working with async calls here and shared data between what appears to be separate threads (waaaaaait for it...), obviously this data needs to be protected with a mutex (this is a locking mechanism that prevents threads accessing the same data at the same time since threads are undeterministic). So I did that. But suddenly I would keep getting deadlocks sometimes (this is when an already locked mutex is locked in the same thread again and basically means freezing of the thread). I was surprised how this was possible. And then it hit me. I did some testing to confirm my theory and I was right.

You see, usually that "Completed" delegate callback should be called from a different thread. So using a mutex to protect data is absolutely necessary. There is no other way. And most of the time that's exactly what WinRT does. Except when it doesn't. It's possible that ReadAsync() actually finishes before you assign the "Completed" delegate. And you know happens when you finally do assign it? The callback gets called immediately IN THE SAME THREAD WHERE "Completed" WAS ASSIGNED! So if you locked a mutex before assigning "Completed" and then you have to lock that mutex withing the delegate that was assigned to "Completed", you will get a fucking deadlock! Fuck you, Microsoft! Fuck you!

The good news is that I was able to resolve the deadlock by unlocking the mutex before assigning "Completed". But fuck Microsoft and their asynchronous-but-sometimes-it-isn't API. >:(

Here's the final code so you have an easier understanding what I've been struggling with. I added a few comments to make it easier to understand

Code: [Select]
// this workaround is required due to the fact that IAsyncOperationWithProgress::Completed could be fire upon assignment and then a mutex deadlock would occur
hmutex::ScopeLock _lockAsync(&this->_mutexReceiveAsyncOperation); // ScopeLock makes sure the mutex is unlocked when this method finishes (very useful when throwing exceptions, etc.)
bool asyncOperationRunning = (this->_receiveAsyncOperation != nullptr);
_lockAsync.release(); // has to unlock that mutex again...
if (!asyncOperationRunning)
this->_receiveBuffer = ref new Buffer(this->bufferSize);
this->_receiveAsyncOperation = inputStream->ReadAsync(this->_receiveBuffer, this->bufferSize, InputStreamOptions::Partial);
this->_receiveAsyncOperation->Completed = ref new AsyncOperationWithProgressCompletedHandler<IBuffer^, unsigned int>(
[this](IAsyncOperationWithProgress<IBuffer^, unsigned int>^ operation, AsyncStatus status)
if (status == AsyncStatus::Completed)
IBuffer^ _buffer = operation->GetResults();
Platform::Array<unsigned char>^ _data = ref new Platform::Array<unsigned char>(_buffer->Length);
DataReader^ reader = DataReader::FromBuffer(_buffer);
hmutex::ScopeLock _lock(&this->_mutexReceiveStream);
this->_receiveStream.writeRaw(_data->Data, _data->Length);
hlog::errorf("OK", "async data: %d", _data->Length);
catch (Platform::OutOfBoundsException^ e)
hmutex::ScopeLock _lock(&this->_mutexReceiveAsyncOperation); // ... because this lock here might as well happen in the same thread as the one at the beginning of this code and cause a deadlock
this->_receiveAsyncOperation = nullptr;
this->_receiveBuffer = nullptr;
catch (Platform::Exception^ e)
return false;
... // down here I lock this->_mutexReceiveStream and read from this->_receiveStream, but it's not relevant to this issue

General Discussion / Reboot Develop 2017 "Making a better RPG"
« on: May 09, 2017, 08:53:51 AM »
Tim Cain from Obsidian Entertainment talked about RPGs this year at Croatia's Reboot Develop. It was a pretty great talk. And you're lucky! They recorded it. xD

There are some really good points for everybody who wants to develop RPGs. One of the points that really resonated with me was avoiding numbers which seems counterintuitive since numbers are kind of a core thing in RPGs. But the thing is: they are not. I haven't watched the video so I hope you can see the slides properly since there are some important visual things that he shows.

BTW, the actual talk is less than an hour even though the video is 2 hours long.

EDIT: Quickly glanced through the video and yes, the slides are properly visible. Have fun!

New Projects / MOVED: Heroes of Shaola (English)
« on: March 18, 2017, 01:02:41 PM »

General Discussion / Make it juicy
« on: February 26, 2017, 11:45:23 PM »
This is a pretty good video that explains why the finishing polish of your game matters.

Advertising / King of Booze: Never have I ever
« on: February 26, 2017, 10:54:00 PM »

Platform: Android (iOS coming soon)
Category: Casual, Drinking, Social
Number of Players: Unlimited

Available on:

Never Have I Ever is a fun drinking game for adults that can be used in all alcohol fueled gathering. It's a simple formula.

More people = More fun

Rules are simple:
  • 1. Sit in a circle (or stand, or don't be in a circle, who cares).
  • 2. Read the sentences out loud.
  • 3. Everyone who did it, drink.
  • 4. If you've never done it, don't drink.

That's about it.

The sentences/challenges are divided in 7 different categories. If you don't want to talk about dirty stuff, or relationship stuff you simply don't use that deck.

With that being said keep in mind that this is the game for ADULTS, if you're too young or easily offended this is not the game for you.

If you like the game show your love by rating it.

If you don't like the game and you're mad at it, and offended, and you want to share it with someone, don't, keep it your little secret.

If you wanna join other party monsters and see what else we got find King of Booze group on FB or IG.

Thank you for calming your ADHD for a minute and reading all of this.

Hope you have a blast.

Please drink responsibly.

Visit our website:
Like/Hate us on Facebook:
Like/Hate King of Booze on Facebook:
Follow King of Booze on Instagram:

Tutorials / MOVED: [MV] Armonic effect
« on: February 07, 2017, 04:05:22 AM »

Role Playing and Interactive Story Telling / CP - The Soap Opera (Season 3)
« on: February 05, 2017, 11:29:11 AM »
Go join our Discord group to join in on the fun. The forum hasn't been too active as far as role playing stuff goes, plus we can make it more chaotic this way. Feel free to leave your character summary here still.

What happened so far - Only god knows. I'm not gonna try to piece together the info from the previous topics, especially considering how much of a clusterfuck season 2 was. xD
Season 1:,7250.0.html
Season 2:,13971.0.html

What do we do now - Let's put together some context about who's who and how we'll start off.

How we play it - Everybody adds a paragraph or two of his own character. What he does, what he feels, etc. and then waits for somebody else. You can add more than that, but if it's too long, people might not read it and get discouraged to join. Besides our own characters, we will have "dummy characters" that no players really control. Instead we can "use" them in our stories. e.g. Maybe you make up a love interest as a dummy character. The easiest way to explain this would be the start of season 2: "I SLEPT WITH ZEXION'S WIFE." In this example the dummy character was Zexion's wife. We did kinda establish a real person to be Zexion's wife later, but you get the idea.

Any additional rules - Let's just use season 1 rules. I see no point to complicate this if it's just for fun.
There are not much of rules here. You are allowed to develop your own character and keep your story going on. There is no need for sign-ups, this is the thread where it all happens. Get into dialogs with people and uncover the dark secrets of CP. :O Just keep it "civilized".
Any maybe let's try to keep it "realistic" to a degree. xD

We'll set the story several years later from season 2 (which it literally is). I'll derive my story from the real world.

Blizz: "I love game development, but recently that passion has been fading. I think I need a break." So Blizz sells his gamedev company and buys a night club. He wants to try out how that works out for him.

I found this article about optimizing some code that would completely have the opposite effect in a multi-threaded environment. It's very good, because it gives you a good understand how one approach can be great in a single-threaded environment, but completely fall apart in a multi-threaded environment (as far as performance goes).

Programming / Scripting / Web / One of the most bizarre bugs I ever "fixed"
« on: November 25, 2016, 08:39:10 PM »
So, today I "fixed" a very bizarre bug.

We're using etcpak, an open source piece of code for conversion of images to the ETC1 format (all other implementations are much slower). It only had libpng so I integrated libjpeg in there as well since we kinda need it (it's especially useful since ETC1 is only RGB anyway). We made a container format called ETCX that uses 2 RGB images where the second (optional) image is the alpha channel and then we merge it all together in the shader. This is because we need texture compression for our newest game, but not a lot of devices support ETC2 yet.

I was batch converting images today and it would keep crashing on JPEG images. After I found the bug and fixed it (a race condition with data that libjpeg uses), it seemed to work fine. Well, except for those how_to_play_X.jpg images (X going from 0 to 9, we have 10 images). And it would keep crashing and crashing.

So I pull out the source again, compile, nothing. No crash. O_o I try the release configuration, no crash. O_o But etcpak.exe it crashes every single time when called from 2 layers of python (the main script calls a utility script as another process which then again calls etcpak for conversion before merging 2 ETC1 images into ETCX).

I start removing the libjpeg code, still keeps crashing. In the end I completely removed every trace of it, it still crashes. Then I removed the fopen() and fclose() calls and it suddenly stops. There is no threading problem here, the file is opened and closed in the main thread. And then I start suspecting the JPEG files themselves. There has to be some nasty corruption going on, but the images seem fine.
I open them in GIMP, just resave, nothing else and it works. It stops crashing. O_o

Long story short: "Corrupted" JPEG files would cause fopen() and fclose() would cause an exe to crash when it's done regardless of whether the exe had any JPEG code for handling or not. Merely accessing the file would cause the exe to be doomed to crash. And I was able to reproduce it consistently on another PC that pulled the JPEG files via SVN client. So it was definitely the files.


New Projects / MOVED: [XP] Elemental Fragment
« on: November 14, 2016, 03:16:46 PM »

New Projects / MOVED: [XP] Daath Origins
« on: September 10, 2016, 10:28:40 AM »

Video Games / Pokemon GO GPS Spoofing on Android
« on: July 14, 2016, 07:09:39 PM »
There's no way you haven't heard of it yet. It's the new overnight success Pokemon GO. The game allows you to walk around in the real world and with GPS tracking you can find and catch pokemon on your mobile phone, find items in Pokestops, evolve them, make them stronger, compete in gyms and more!

Before I explain anything I want to warn you: GPS Spoofing is against the TOS of Pokemon GO and can results in soft ban and even permanent bans of your account. The game is meant to be played by going outside. I cannot be held responsible for any damages to your phone, your account, your reputation or any other damages if you decide to use this guide.

I'll get right to the point. Why would you want to spoof your GPS location in the first place? While some people might have more "honorable" reasons like not being able to move the house or being handicapped, others are just plain lazy. Like me. Well, it's not the laziness factor here that's the problem to be honest. The current version freezes on me so often that it keeps draining my time without providing me the actual fun. So I decided I'll just cheat. Fuck it. (Though I don't cheat all the time. Usually only when I'm home. I use it legit when I go to work, etc.)

What do you need to know about GPS spoofing? It's basically faking your GPS location so you can simulate that you are walking around in order to be able to do all the things you can do in the game. There are a few things you need to know before settings things up.

1. Your Android phone has to be rooted. There is no way around this. To get this done, make sure to find a guide for your phone model. (Keep in mind that rooting your phone could void your warranty. Make sure to check and know the risks.)
2. Download and install Lucky Patcher.
3. Download (but DO NOT install) Fake GPS Location Spoofer. Put it on your SD card.
4. Run Lucky Patcher and give it super user access. One-time or 10-minutes only is fine.
5. Open the last tab Rebuild & Install, select the downloaded Fake GPS Location Spoofer APK from your SD card and select Install as system app.
6. After a reboot, open Fake GPS Location Spoofer, go to Settings and turn on Expert Mode.

You can avoid the whole thing with Lucky Patcher by purchasing the Pro version of Fake GPS Location Spoofer. Your phone still has to be rooted, though.

That's it as far as the technical part goes. But there are a few more things you should know:

  • Don't use Android's Mock Locations feature. Pokemon GO detects it, even if you try to mask it and it won't work.
  • Don't set your GPS to GPS only / Device only. Pokemon GO won't work like that.
  • Don't move around while using GPS spoofing. The cell tower triangulation seems to kick in and messes with your location if you move too much. These jumps in your location could make the server aware that you're trying to cheat.
  • Don't do huge jumps in too short amounts of time. I did 5 km (about 3 miles) jumps without problems within just maybe 10-15 seconds, but I did get soft-banned when I tried a 300 km (about 187 miles) jump. This might be because you have to switch between apps when you use Fake GPS Location Spoofer. So you get some sort of grace period. I once got soft-banned for doing a 300m jump, but it was probably because I moved around the cell tower triangulation kicked in.
  • Try to simulate moving or maybe riding a bike and do smaller jumps (e.g. 100m) at a time. That's your safest bet. Though I usually have no problems with jumps of 1km.
  • I recommend in Fake GPS Location Spoofer to turn on GPS Move Location and set the Timeout in seconds to 7 and The distance to move around to 10. It helps a bit in location and slightly moving around for a bit without having to change your location again.

About soft-bans:

Soft-bans are usually lifted after a time, but "smaller soft-bans" (e.g. if you tried smaller jumps) can be fixed by killing the game in the task manager and restarting it. Or maybe it was just the server being shitty on me, IDK.
You will know that you're soft-banned if all of these things happen to you:

  • Every pokemon flees after your first pokeball throw.
  • Pokestops always say "Try again later"
  • If you try to fight in a gym, the game lets you set up your party all the way (sometimes even the battle start animation finished) and then throws your back to the gym view screen.

And here's a special section on hatching eggs.

You will have a hard time hatching eggs with GPS spoofing. There is different information on the Internet. Some say the game uses GPS and the pedometer to make sure you are walking while some claim it only uses GPS. There appears to be a maximum speed at which you are allowed to move so that the distance counter increases and I've seen people estimate the speed anywhere from 10 km/h (about 6.25 mph) all the way to 30mph (about 48 km/h). From my personal experience, the distance on the eggs increases sometimes while I spoof, disregarding whether I keep shaking my phone or not so I assume that the pedometer isn't used. But it's far from reliable. I maybe get a few hundred meters for spoofing over a distance of 5km step by step. Walking or something slightly faster (slow bike ride, skateboard, etc.) seems to be the only reliable way. Though, I have to admit it's ruggish as well. I walk for like 2km and only get maybe a bit above 1km on my distance.

To add to this, while using the tidbit below and using FakeGPS to move around your fake location, you are able to hatch your eggs and increase the distance just fine. In fact, read below to see a great way to auto hatch your eggs. ~ gameus

Pages: [1] 2 3 ... 40