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 ... 41
Lexima Legends IV - Chaos Project / Chaos Project BETA
« on: September 02, 2017, 10:01:53 PM »
The time has come. It's a few days short of 6 years since I started working on this. Initially I wanted to add 2-3 additional hours of gameplay with the "Beyond Epic" game mode, but it kinda mutated into 5 hours. I wanted to make it story-driven and glue the gameplay onto it. That didn't happen. Instead they grew together. I added even some other things like 60-FPS support through XPAce, fixed a lot of minor bugs, rebalanced some minigames and the entire monster arena, added more game modes etc. The normal game experience remains mostly unchanged with the exception of some special tweaks (and 60 FPS obviously), but the additional content will blow your mind.

You might be thinking "Blizzard, you ass, you've been promising this thing now for almost 6 years. It's never going to be done." Well, that's just it. The open beta release date is tomorrow. No, this is not a joke. No, this is not a shitty estimation. I literally have to do one more thing for the game to be a beta version: Finish balancing the final boss fight in the "Beyond Epic" game mode. That's a few hours of work. Sure, there are a few bugs around that I'm aware of, but they are mostly graphical. So besides the boss balancing there's nothing else to be done for the beta.

So, what's new then?

Beyond Epic game mode

  • the ultimate post-game challenge
  • Rivy joins your party to kick some ass
  • max level 1000 with insane stats and no grinding necessary (which doesn't mean you can't grind if you want)
  • new awesome Meta States, play the game like never before
  • beyond epic damage, beyond epic battles, beyond epic music, beyond epic bosses
  • an unexpected closure to the canon storyline
  • unlocked by beating the game in any mode and getting the "good" ending
  • about 5 additional hours of gameplay!

Zero Hero game mode

  • a low-level challenge for those who can handle it
  • enemies drop double gold, but only bosses give EXP

Soul Rage game mode

  • a special challenge for those deeply familiar with the game mechanics
  • normal abilities are not available
  • SR costs are halved
  • Meta Limit costs only 50% SR
  • enemies drop double gold

running at 60 FPS

  • smooth animation with improved engine
  • more custom optimizations to provide an even smoother experience
  • 50% increased movement speed, no more slugging around

supporting XBox 360 compatible controllers for input

  • no more keyboard-jockeying if you want the full old-school experience

all-new Revive Charm accessory in many item shops

  • provides a one-time Auto-Revive until it's used up

improved pet monster battles

  • higher chance to increase stats during battle
  • higher stat increases during battle
  • higher chance to gain stat boosts during battle
  • lower chance to lose stat boosts during battle when hit
  • high stater increases with the items
  • less grind, more fun

more battle BGMs

  • added a new default battle BGM (and left the old one as well)
  • the rest are available automatically in any game mode except "New Game"

improved font installation

  • no more missing text
  • no more hassle installing fonts

new boss-dying animation

  • more unique and fancier than ever

better audio

  • updated a lot of tracks with higher quality audio

changed Mandora Prison

  • for each completed room, you get a reward
  • you can skip rooms
  • reduced difficulty to match the 60 FPS glory

minor bug fixes and improvements

  • graphics
  • dialogs
  • audio timing
  • brand new battle transition
  • improved battle status display
  • game now saves and loads faster
  • added more save points throughout the game to allow for shorter play sessions
  • changed how some skills and enemies work

reworked some dialogue and plot points

  • now Endout is a bit better fleshed out in the earlier story segments

more fun with game modes

  • beating "New Game" will now unlock "And Again!", "Warrior", "Zero Hero" and "Soul Rage" all at once
  • beating "Warrior" or "Zero Hero" will unlock Exerion
  • with so much more new mode craziness going on, the number of save slots is now 12

Sea of Code / Randomness and distribution
« on: June 14, 2017, 08:06:33 PM »
Those of you who worked with C or C++ probably know that on Win32 systems that the macro RAND_MAX is only 32,767 (0x7FFF). This causes problems if you want random values higher than that since due to the distribution, there are values that you will never get.

e.g. You want 1,000,000. 1,000,000 / 32,767 ~= 30.52. That means that you can get a 0 or a 31, but never anything between these two numbers.

Now, you could take two numbers and sum them up or multiply them, but that breaks the equal distribution of numbers and some values will happen more often than others. It's easiest illustrated with a few small values. Let's take a range from 0 to 2 inclusive. All possible combinations:

0+0, 0+1, 0+2
1+0, 1+1, 1+2
2+0, 2+1, 2+2

If you take a close look at all possible combinations, you will notice that the results are not equally probable. 0 and 4 appear only once, 1 and 3 appear both twice and 2 appears 3 times as a result.

The only way to really handle this issue is to combine the values in a way that preserves the equal distribution. If we simplify the entire thing and say it's only possible to generate 1 bit randomly, we can get the values 0 or 1. Now if we do this procedure N times, we can get a number that consists of N bits and all numbers generated in such a way will always be equally likely to appear and the distribution will be preserved. Since we already have 15 bits (32,767) at our disposal to be generated, we can just generate this value twice and then just combine them by shifting one of the numbers to have a 30 bit value.

I implemented this in our foundation library, you can take a look here at line 46 and 47 (or just find "#define HRAND()" if the code has changed since this post was made):
I do casting to int64_t, because I have multiplication and division with another 32-bit int so nothing breaks. Incidentally I think this is the same reason why Microsoft limited RAND_MAX to 32,767 in the first place.

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 »

Pages: [1] 2 3 ... 41