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.


Messages - Blizzard

Pages: [1] 2 3 ... 922
1
Resources / Re: problem to open mrmx-os
« on: June 23, 2017, 10:48:43 AM »
There is an issue with the input module that requires a newer RGSS DLL. :P

2
Resources / Re: problem to open mrmx-os
« on: June 23, 2017, 07:40:36 AM »
The Steam version / Humble store version and the official version from their website should work fine.

3
RMXP Script Database / Re: [XP] XP Ace Tilemap
« on: June 23, 2017, 07:39:36 AM »
Eh, it happens. I've uploaded tons of faulty demos in my time. xD

4
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): https://github.com/AprilAndFriends/hltypes/blob/master/src/hltypesUtil.cpp
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.

5
General Discussion / Re: How to Get Enterbrain's Software Free
« on: May 31, 2017, 08:10:13 AM »
Maybe we should even delete the topic.

This does NOT work anymore. Most (all?) of their software has been updated leaving this method unusable.


6
Nice work!

7
Script Requests / Re: Mrmx-os script to can use the keyboard
« on: May 17, 2017, 08:37:17 AM »
Maybe the input box is set to use a weird font. :/

8
Script Requests / Re: Mrmx-os script to can use the keyboard
« on: May 16, 2017, 07:39:40 PM »
That's weird. The base RMX-OS has a custom input module included there. It should work. I really don't know.

9
Script Requests / Re: Mrmx-os script to can use the keyboard
« on: May 16, 2017, 07:46:24 AM »
Did you click on the input box? There should be a caret blinking.

10
Chat / Re: Your Life Here
« on: May 16, 2017, 07:40:32 AM »
Congratz! :D I'm really happy for you! :D

11
Lexima Legends IV - Chaos Project / Re: Legion in Warrior Mode
« on: May 14, 2017, 12:40:03 PM »
So, I'm there again. >_> I'm testing Zero Hero and I' just beat Doom Caller. Reading my first post again I'm really not up for doing this at Jason 37, Endout 38, Lucius 35 and Ariana 41. xD I'll at least wait until I get Sydon or something (right now I arrive in Mandora). The EXP from the other bosses and the decent stuff I got from the rewards should be enough to keep me afloat at least until chapter 9. Phoenix Sword especially will be useful at the Mountains of Slumber.

12
RMXP Script Database / Re: [XP] Blizz-ABS
« on: May 14, 2017, 12:32:39 PM »
Your biggest challenge is actually the fact that a lot of keyboards have a limit to how many keys you can keep pressed at once.

14
Script Troubleshooting / Re: Problem with my pathfinder
« on: May 12, 2017, 08:26:37 AM »
Yeah, it performs faster because of its greedy nature. xD When it works like that, some paths will be faster, some will be slower depending on how straightforward they are.

I think that you shouldn't make it more general. Algorithms and generalizations are fine, but your should use the specifics of a problem to optimize the shit out of it. Since we have a Cartesian coordinate system and it's not likely to change, we should use that fact to make the implementation faster.

15
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)
{
try
{
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);
try
{
reader->ReadBytes(_data);
hmutex::ScopeLock _lock(&this->_mutexReceiveStream);
this->_receiveStream.writeRaw(_data->Data, _data->Length);
hlog::errorf("OK", "async data: %d", _data->Length);
}
catch (Platform::OutOfBoundsException^ e)
{
}
reader->DetachBuffer();
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)
{
PlatformSocket::_printLastError(_HL_PSTR_TO_HSTR(e->Message));
return false;
}
}
... // down here I lock this->_mutexReceiveStream and read from this->_receiveStream, but it's not relevant to this issue

16
Script Troubleshooting / Re: Problem with my pathfinder
« on: May 11, 2017, 10:35:30 AM »
This isn't really A*, but more of a modified Dijkstra.

That's what I meant.

You mean because of this?

Code: [Select]
key = request.open.keys.min {|a, b|
        a[2] > b[2] ? 1 : (a[2] < b[2] ? -1 :
        (Math.hypot_squared(a[0] - request.target.x, a[1] - request.target.y) <=>
        Math.hypot_squared(b[0] - request.target.x, b[1] - request.target.y)))}

I'm first checking the already known cost before checking the heuristic cost. So you think I should check them together?

17
Script Troubleshooting / Re: Problem with my pathfinder
« on: May 11, 2017, 07:51:47 AM »
That's true, I did optimize my script in such a way.

I think you're wrong about Dijsktra. The thing with a Cartesian coordinate system is that coordinate distances are consistent throughout the whole grid so technically the heuristic of the xy coordinate difference is actually not just an cost estimation, but a consistent cost. I used that fact to make the Dijkstra's algorithm implementation faster and that's basically what A* is. It just uses a heuristic like that to decide which nodes to check first.

18
Script Troubleshooting / Re: Problem with my pathfinder
« on: May 10, 2017, 08:35:32 AM »
I'd have to go in-depth with your algorithm to figure out what's wrong. xD

A* is actually just a modified Dijkstra's algorithm. Instead of going through all nodes, an x,y coordinate heuristic is used to check possibly favorable nodes first.

19
Script Troubleshooting / Re: Problem with my pathfinder
« on: May 10, 2017, 06:50:17 AM »
Actually looking up a different path finder might be a good idea since you can figure out how the other one is implemented.
That being said, I vaguely remember that you're supposed to use heuristic cost to the new node from the current plus the movement cost to the current node. I haven't taken a good look at your code yet though.

20
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

http://www.rpgcodex.net/article.php?id=10609

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!

Pages: [1] 2 3 ... 922