Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 28 Feb 2011
Offline Last Active Today, 08:06 AM

#5222599 preventing system crash or power outage from wiping savegame: best methods

Posted by Bacterius on 11 April 2015 - 08:20 AM


But really, that's overkill.


yeah, probably, but what can i say? i'm a one percent-er. just because the engineering products we develop are for entertainment purposes doesn't mean we should become complacent and not try to deliver as solid a product as possible to the consumer. loading and saving files in a manner that can handle power outages and other crashes is not that difficult.



I think the point people are making here is that the environment of a typical PC gamer's computer is not controlled enough to be able to 100% guarantee that data will not be lost anyway. You may be able to get something incredibly reliable by using the atomic swap idiom on certified hard drive hardware/firmware/drivers with code that's been shown to be bug-free by a theorem prover, the whole thing being backed up by a triple redundant storage system inside a shielded, radiation-hardened nuclear bunker with its own power source.


But the average gamer has a basic hard drive with generic drivers and consumer firmware (which is probably lying to you anyway when asked whether it has actually flushed data to disk) and a power supply that can go out at any instant, not to mention the possibility for your program to simply be killed by a bluescreen or a hard freeze of the system, or the hard drive failing just as you finish writing to it, or a cosmic ray to flip a critical bit in memory that causes your program to malfunction and write corrupted data to disk without even being aware of it.


This is a bit reminiscent of Amdahl's law; you seem to be under the impression that you can achieve 100% reliability by simply writing "good code" when writing savefiles to disk, that there exists some sequence of statements that essentially guarantees that no player progress will ever be lost. But it turns out that you don't control all the variables, many environmental factors are independent of your program and will still find a way to screw up the process *no matter* how good your code is. In other words there is an upper limit to how reliable you can get the process given those factors, this is effectively what you have to "work with". It might be 95%, 99%, or even 99.9% for the everyday user (this depends on what your program does, the assumptions it makes and what it ultimately runs on) but it's not going to be 100% because there are way more bizarre things that can happen than conveniently timed power outages (with increasingly low probability, thankfully).


In short, don't spend too much time trying to solve issues which have underlying causes that you have no control over, instead work with what you have to produce something that works almost all of the time under normal circumstances and, should failure occur, gives the user a chance to recover in most cases, again under normal circumstances. In this particular instance the usual trick of writing the savefile to a dummy temporary file and "atomically" moving it to the right place when everything has been written works pretty reliably on today's systems, and in the unlikely event that something does go wrong (something well-defined at the level of your program that your program can detect and respond to in some way such as "execution halts while writing to temporary file, garbage was written but temporary file was not renamed to a proper savefile") the player will hopefully still have his before-last savefile to continue on, and maybe a notification that something has gone wrong with the last save, instead of being presented with a corrupted save. So this is a good, cheap and easy solution that seems to work well, and indeed it has been used for many years with very few problems.


If you do want to do even better than that (should "better" exist on at least some system/hardware that you are targeting), then, like people said before, instead of rolling your own you may want to look into how high-reliability software like databases have solved the problem, and do not be surprised if you find that the way they do it is actually not that much better than yours practically speaking when you have little to no control over the environment your program runs in; in general it might address a few more corner cases, have special code for various hardware combinations, and be more conservative overall in how it handles data, for correspondingly rarer failure cases (this is not to say that databases are unreliable, this is just to point out that the less control you have, the less guarantees you can make, the less you can do).

#5221294 What C# Library/Framework to make games

Posted by Bacterius on 04 April 2015 - 05:07 AM

I believe that MonoGame has everything that SlimDX has (is it maintained still?) and then a bucketload more smile.png


SharpDX may be a more up to date version of SlimDX, I believe. Note the two projects are not related as far as I know, but the API they expose is basically identical since they are both plain D3D wrappers.

#5221059 GCC -malign-double

Posted by Bacterius on 02 April 2015 - 10:00 PM

As I understand it this flag doesn't really do much on most x86_64 ABI's since long longs and doubles are already aligned on a two-word boundary. However if that is not the case then you must be very careful what you apply that flag to, because if any non-PhysX structure declarations (in library/system headers and so on) get affected by that flag and their layout suddenly differs from the layout expected by their implementation, which does not expect malign-double, there's no telling what might happen, but it will almost certainly end with stack corruption, an eventual segmentation fault of your program, and lots of tears.


I would recommend controlling the usage of this compiler flag as strictly as possible, in other words limiting it to the PhysX headers (or wherever they are needed) and nothing else.

#5220334 The Gamination Company

Posted by Bacterius on 30 March 2015 - 05:53 PM

Why'd this topic get moved to beginners? This is not a beginner topic, even though I am a beginner, it doesn't correlate...
This belongs in the Indie Projects, because it IS an official indie project

It's not, it's a recruitment thread, and as such belongs in the Classifieds as Hodgman said.

#5220155 Increase power of light in a Pathtracer

Posted by Bacterius on 30 March 2015 - 04:29 AM

The RGB color of my light is already at 255 and it is still too dark.

Sorry, I meant 50/100 as in floating-point values, that would translate to 12750 and 25500 in "integer" RGB values. Basically color is not really limited from 0 to 255, that's an artificial limitation of your display hardware. Most raytracers work in floating-point colors that can range from 0 to infinity (in principle) and then apply tonemapping to the final render to bring them back to a range where they can fit in an RGB color to be displayed.

#5220153 Increase power of light in a Pathtracer

Posted by Bacterius on 30 March 2015 - 04:22 AM

I have a recoursive Trace function which checks on intersection if the hitObject is a light source, if so it returns the object color.

So the object color in this case (for light sources) is essentially its intensity for R, G and B channels. Increase the value of those channels, and your light will become brighter. It's not unusual to have values for the "color" of a light source that are greater than 50 or even 100. And then tonemap when your renders start to become oversaturated (= washed out).

#5219649 Global Consts

Posted by Bacterius on 27 March 2015 - 10:20 AM

The thing is, there's no "magic" in this number.  If you're drawing quads you expect to see the number 4, or a multiple of 4, and by having it in-place you immediately get to do a visual/mental sanity-check on the code rather than having to go scoot off to a header file somewhere else.  In this case 4 is not a magic number.


There's a related discussion over at http://programmers.stackexchange.com/questions/266717/are-all-magic-numbers-created-the-same which I'm sure many of you will have already read... and personally I agree. Normally only a small part of your program needs to know that a quad has four vertices, and I'm pretty sure that number isn't going to change without the "quad" part changing as well. But if naming it VERTICES_PER_QUAD or whatever the case may be gives you warm fuzzies...

#5218211 Tiny .ini parser

Posted by Bacterius on 22 March 2015 - 02:23 AM

"Assuming you're on Windows.." does not imply that it is cross platform.


I was saying that because Acharis asked for a cross-platform solution in this post... these things can be easy to miss, and it seems gratuitous to lock yourself to the Windows API when (a) there are plenty of drop-in libraries that are already cross-platform and (b) you can write your own basic parser anyway in under ten minutes if you really wanted to. Also, ini files aren't Windows specific, they just happen to be found more on Windows, you can certainly store your settings in any format you like on any system you like (let's face it, key-value stores aren't exactly an uncommon format).


Having a library that abstracts the actual configuration data from its storage sounds like a useful thing to have though.

#5216399 String: How to find the most common character occurrence.

Posted by Bacterius on 14 March 2015 - 12:56 AM

I was super confused as to what language you were using. "string" is small so I thought C++, but then I saw you're using "public static string" which smells like java. Then I noticed your function name is capital camel case and your braces aren't Java-like, which could make it C++ again, but most string and array operations are Java again. :S


It's C#, given that stitchs has been asking about a C# linked list implementation review in a previous topic.. that and the string.Format() call is a dead giveaway tongue.png

#5215215 C# Linked List implementation review

Posted by Bacterius on 07 March 2015 - 05:57 PM

Also worth noting that using uint indices may not be in your consumers' best interest, the reason being that the de facto type for indices in C# is int, not uint (yes, I know, that makes no sense, and there is no viable size_t-like type either, but that's the way it is) which together with C#'s type system means you are going to be inflicting a lot of tedious casting to people who will want to use your interface in any nontrivial application. Furthermore, using uint's in the interface makes it impossible for .NET languages without an unsigned type to make use of your linked list class.


This is mostly irrelevant for a linked list implementation, of course, but I thought I'd point it out as a design flaw (to users).

#5213850 What are the recommended places to store save data?

Posted by Bacterius on 02 March 2015 - 02:54 AM

I wish asking the user where to save was the standard.

Where would you store the path to which to store save data? laugh.png

#5213475 Give me your Java and Python code

Posted by Bacterius on 28 February 2015 - 06:09 AM

A useful resource for requests like these is the Github search bar. Type in "language:java game" or "language:python game" and browse a bit smile.png

#5212417 Subtraction Problem in Java

Posted by Bacterius on 23 February 2015 - 03:49 AM

In math, 0.39999999999...(repeating to infinity) is equal to 0.4


While this is true, the floating-point approximation shown in the OP doesn't repeat to infinity, e.g. if you kept asking for more decimals you'd eventually get something like 0.3999999761581420898437500... (float) or 0.3999999999999999111821580... (double) depending on what the particular result happens to be.


Still, close enough cool.png

#5211780 OpenCL for both AMD and NVidia graphics cards with MinGW?

Posted by Bacterius on 19 February 2015 - 05:45 PM

The AMD APP libraries work just fine with MinGW, what is the problem? You will not be able nor want to link statically with the backend - amdocl.dll in this case - for obvious reasons but you can link against the ICD (OpenCL.dll) just fine and work with the headers provided (cl.h and friends) and from there query installed platforms such as the AMD runtime, the NVidia runtime (I suppose) and so on. What issue are you having?


Or do you mean you have an NVidia card and can't use the AMD APP to work with your graphics card? I wouldn't know then for I've never used the NVidia SDK, but if it's like all the others they just provide a generic OpenCL.dll, more or less generic OpenCL header files, a back-end DLL registered somewhere in the registry that actually implements their OpenCL runtime, and you just link against the OpenCL.dll provided and start using the NVidia platform. No Visual Studio required.


Can you add more details?

#5210813 Exclusive maximum in random functions

Posted by Bacterius on 15 February 2015 - 07:18 AM

Thanks for the link! It's pretty much what I expected. I agree with that SO reply, but I'm not really sure if it applies to the interface of a random number generator. Expressing "I want a dice roll between 1-6" as Random(1, 6) just seems more natural to me.


Ah, but the thing is that random number generators are not exclusively written to simulate dice rolls. When you are writing a random number generation library you usually want to go as generic as possible with your API in order to give the user the flexibility he needs to implement his own logic off of your random number generation routines. That can mean a generic Random(min, max) with the usual min/max convention which has effectively nothing to do with dice rolls. But you can implement dice rolls on top of that by writing a RandomDiceRoll(numSides) function that uses those Random functions, e.g. via Random(numSides) + 1. In and of itself, that Random() function has no relation to dice rolls, and indeed what you find "natural" for dice rolls will feel "unnatural" for things like selecting an array element at random, e.g. for shuffling a collection. That's because the function isn't designed for any specific task, and a min/max convention ultimately had to be picked.


In short, that the Random() function does not "favor" dice rolls is not a design flaw, it just means that you are meant to implement a dice rolling function using it instead of directly treating it as a dice-rolling function (because it isn't one).


And on that note, really, any random number generation library worth its salt should divide its API into a low-level random bit generation module (deterministic random bit generator, DRBG), a distribution API on top of that to generate different types of distributions like discrete [A, B) distributions, reals from 0 to 1, normally distributed numbers and so on, and finally perhaps (if applicable) a convenience API that performs some common tasks such as dice rolls, uniform choice from a set of values, shuffling, etc, etc. In that regard, I don't consider the System.Random class a particularly shining example of good design, but then most users are happy with a seed and a nextInt() function, so...