• What Are You Working On? July 2015
    1,392 replies, posted
[QUOTE=krix;48268014]I don't seem to be able to play streams at 'Source' quality.[/QUOTE] My bad. It's fixed for good now.
[QUOTE=Darwin226;48267258]From a language design standpoint exceptions are a pretty huge hack, but not supporting them when you already decide to use a language that has them, and has grown around them seems very fishy.[/QUOTE] I disagree with the first part, but not the second (except for C++ because technically there's no standard in that regard there). They aren't a hack, you just have to implement a matching set of standards to semantically differentiate between fatal and non-fatal/expected errors. .NET's [I]Try...[/I] variant methods are a good example: - If a default variant (unexpectedly) fails, the exception provides a lot of information for debugging. - If a [I]Try...[/I] variant (expectedly) fails, you get [I]false[/I] without extra overhead. It sometimes gets a bit ugly when translating between different sets of standards though: For example unlike in .NET with its [I]Try...[/I] variant methods there's no separate mechanism for non-fatal errors in the Windows API (or basically anything written in C I suppose). This means that to wrap the various XInput versions in a way that doesn't have potentially terrible performance and still fails fast by default, I have to make one that fails on any error code other than zero, and one that only fails on error codes it doesn't recognise as non-fatal and otherwise returns either [I]true[/I] or [I]false[/I].
[QUOTE=Handsome Matt;48269091]It just seems absurd to me to use exceptions in something performance dependent as a game[/QUOTE] I'd still prefer exceptions to something that crashes each five minutes to irrelevant shit like GMod.
[QUOTE=Handsome Matt;48269091]It just seems absurd to me to use exceptions in something performance dependent as a game[/QUOTE] You know, you can have effectively zero overhead exceptions where all that junk only matters when an actual exception is triggered and propagated.
[QUOTE=Tamschi;48268101]I disagree with the first part, but not the second (except for C++ because technically there's no standard in that regard there). They aren't a hack, you just have to implement a matching set of standards to semantically differentiate between fatal and non-fatal/expected errors. .NET's [I]Try...[/I] variant methods are a good example: - If a default variant (unexpectedly) fails, the exception provides a lot of information for debugging. - If a [I]Try...[/I] variant (expectedly) fails, you get [I]false[/I] without extra overhead. It sometimes gets a bit ugly when translating between different sets of standards though: For example unlike in .NET with its [I]Try...[/I] variant methods there's no separate mechanism for non-fatal errors in the Windows API (or basically anything written in C I suppose). This means that to wrap the various XInput versions in a way that doesn't have potentially terrible performance and still fails fast by default, I have to make one that fails on any error code other than zero, and one that only fails on error codes it doesn't recognise as non-fatal and otherwise returns either [I]true[/I] or [I]false[/I].[/QUOTE] I don't disagree with any of your points. Exceptions that provide data for debugging are good. The [i]Try[/i] methods are also good. I would argue that using something like Maybe/Option is a better idea, and a more elegant way to handle these situations but I'm sure some people would disagree and this isn't a point I feel like defending at the moment. What is a hack is providing a catching mechanism. It breaks flow and encourages "I'm not sure what precondition to check for" mentality. The majority would probably agree that using exceptions as a flow control construct is a bad idea, yet catching a FileNotFound exception and reporting an error to the user is just that. If an exception is something your program can actually recover from than it's cause could have been anticipated at the call site and handled without destroying any kind of flow. If it isn't, then you SHOULD crash with an error log. .NET does provide a way to "do the right thing", as does Haskell for example. You have a crashing version and a "safe" version of a function. If you're unsure about weather the data you're pumping into a function is valid, you use the safe version that forces you to handle the result differently based on there being an error or not. If you're sure that everything is good then of course you should crash when it's determined that your assertions about the code are incorrect. That's a bug and you want to know about it and fix it.
I've been messing around with XInput since yesterday and drew something using the control sticks (GDI+): [thumb]https://dl.dropboxusercontent.com/u/5013896/forum/Facepunch/Programming%20WAYWO/7.2015/XInput.png[/thumb] Red is the left stick, blue the right one. It's a bit disappointing: - The wiggle rooms before you can feel push back (roughly the areas I coloured in the centre) are pretty large. - The round borders I pushed the sticks along don't register as particularly round. - Most importantly, the sticks clip significantly in the cardinal directions (which cuts of parts off the "circle").
the amount of c++ i use in my projects (usually) begins and ends with the file extension. i use c++ features only when they are outright better than the c counterparts (new/delete because i'm lazy for example). all i know is i've been told by multiple programmers who have been making games since before i was born that c++ exceptions are a joke. so i take their word for it.
[QUOTE=Tamschi;48269506]I've been messing around with XInput since yesterday and drew something using the control sticks (GDI+): [thumb]https://dl.dropboxusercontent.com/u/5013896/forum/Facepunch/Programming%20WAYWO/7.2015/XInput.png[/thumb] Red is the left stick, blue the right one. It's a bit disappointing: - The wiggle rooms before you can feel push back (roughly the areas I coloured in the centre) are pretty large. - The round borders I pushed the sticks along don't register as particularly round. - Most importantly, the sticks clip significantly in the cardinal directions (which cuts of parts off the "circle").[/QUOTE] I can see how the clipping can be useful for walking in a straight line.
[QUOTE=Ott;48269742]I can see how the clipping can be useful for walking in a straight line.[/QUOTE] I feel like it should be up to each game to implement that though.
[QUOTE=Darwin226;48269369]I don't disagree with any of your points. Exceptions that provide data for debugging are good. The [i]Try[/i] methods are also good. I would argue that using something like Maybe/Option is a better idea, and a more elegant way to handle these situations but I'm sure some people would disagree and this isn't a point I feel like defending at the moment. What is a hack is providing a catching mechanism. It breaks flow and encourages "I'm not sure what precondition to check for" mentality. The majority would probably agree that using exceptions as a flow control construct is a bad idea, yet catching a FileNotFound exception and reporting an error to the user is just that. If an exception is something your program can actually recover from than it's cause could have been anticipated at the call site and handled without destroying any kind of flow. If it isn't, then you SHOULD crash with an error log. .NET does provide a way to "do the right thing", as does Haskell for example. You have a crashing version and a "safe" version of a function. If you're unsure about weather the data you're pumping into a function is valid, you use the safe version that forces you to handle the result differently based on there being an error or not. If you're sure that everything is good then of course you should crash when it's determined that your assertions about the code are incorrect. That's a bug and you want to know about it and fix it.[/QUOTE] I agree for the most part, however the way exceptions are caught in .NET are normally "very unexpected but recoverable" cases that should travel up multiple stack layers. As an example, if you save a user-edited document there are normally a lot of possible failure locations unless you cache the whole file in memory first (which normally isn't the best idea), up to outright hard drive failure. It would be very inconvenient (and probably somewhat inefficient during normal execution) to handle and forward those cases manually everywhere. It makes more sense to put a barrier around the [I]Save[/I] method so an IO error (or anything else not critical, for release) doesn't bring down the rest of the application and causes data loss. The exception, even if unexpected, can also be used to display some information with hints to fix it to the user. (Of course it's better to provide actual friendly messages for expected cases, but Microsoft does a pretty decent job with localised error messages already.) (It would be pretty nice to be able to throw an exception-"light" without all the overhead of the stack trace. In theory it's very possible in native code and would lead to much tidier flow control in certain complex cases.) On the latter point: Can Haskell infer what you need based on the return type? Something that automatically decides whether to go with the tentative variant or the loud one would be useful in many cases to reduce implementation overhead... but then again you'd probably still want a mixture even if your current method returns a [I]Maybe[/I].
[QUOTE=Tamschi;48269793]On the latter point: Can Haskell infer what you need based on the return type? Something that automatically decides whether to go with the tentative variant or the loud one would be useful in many cases to reduce implementation overhead... but then again you'd probably still want a mixture even if your current method returns a [I]Maybe[/I].[/QUOTE] Yeah, you can probably do that, but it's not done. Handling Maybes is very simple in Haskell and very rarely actually involves explicit unpacking. A classic example is form validation [code] userData :: FormData -> Either String User userData form = do name <- readName form mail <- readMail form pass <- readPassword form return (User name mail pass)[/code] Here each of the read* functions also returns an "Either String something" and the <- unpacks them to get the something. If any of them return an error, the execution stops there and the whole userData function also returns that error. No explicit unpacking, no ceremony.
[QUOTE=Ott;48269742]I can see how the clipping can be useful for walking in a straight line.[/QUOTE] It's actually detrimental if not handled specifically by the program: [img]https://dl.dropboxusercontent.com/u/5013896/forum/Facepunch/Programming%20WAYWO/7.2015/XInput%20Clipping.png[/img] If you reach the clipping point on one axis, the vector is pushed further away from the cardinal direction than it would be otherwise. Also note that in the previous image the red "circle" isn't really clipping against [I]short.MaxValue[/I] unlike the blue one. Either there's sensor distortion flattening the circle or it just cuts off a little bit earlier. If you want really circular input you probably have to calibrate it (which can at least to some extent be done seamlessly during gameplay). It's unlikely to fix any distortion issues though.
Here "Either" is (in this example) just a fancy Maybe that carries extra info on what went wrong.
This is how programmers make trees [t]http://i.imgur.com/J8flS9C.png[/t] [editline].[/editline] [t]https://pbs.twimg.com/media/CKjQlsEXAAALE3T.png:large[/t] [editline].[/editline] [t]https://pbs.twimg.com/media/CKjeuwOUMAAqfwF.png:large[/t]
[QUOTE=Darwin226;48270112][...] No explicit unpacking, no ceremony.[/QUOTE] [I]Technically[/I] that is explicit though, isn't it? :wink: (I like this a lot, it's very concise for what it does.) Something I want to do at some point when I know more about it is to create a language that removes all the arbitrary limits you currently have with .NET compared to what the runtime actually can do. Something that by default is very safe but can be made a bit more malleable or just completely redone where convenient. [editline]22nd July 2015[/editline] [QUOTE=polkm;48270163]This is how programmers make trees [t]http://i.imgur.com/J8flS9C.png[/t][/QUOTE] There are rounding(?) errors near the back of some of them. It may be a good idea to risk a bit of overdraw if you can't just render them as quads with the right shader.
I am a bit late to the party but aren't exceptions in C++11 a lot less troublesome and a lot more efficient? What ever happened to crash hard crash fast?
[QUOTE=WTF Nuke;48270348]What ever happened to crash hard crash fast?[/QUOTE] Only on irrecoverable errors please.
Those are the only types of errors I generate baby.
[QUOTE=WTF Nuke;48270348]I am a bit late to the party but aren't exceptions in C++11 a lot less troublesome and a lot more efficient? What ever happened to crash hard crash fast?[/QUOTE] Interesting enough, some languages take it to another extreme and adopt a "Let it crash" type of philosophy, notably Erlang and actor-based frameworks such as Akka, where on error, you simply let the process crash and whoever is supervising the process handles the failure, and makes sure the worker starts back up. Supervision hierarchies where you have trees of supervisors and workers are usually used to handle this (it's cool, you should look at it if you like distributed systems). Practically avoiding defensive programming, instead opting for crash-handling at a higher level. This makes sense for Erlang due to it's green-threading system where you commonly have hundreds or even thousands of tiny worker processes spread over your machines cores doing the work, while the main worker process probably shouldn't crash, if a worker process performing a HTTP request crashes and is restarted, after which the process retries the request, it's not as big of a deal since the crash is handled properly and never actually causes the entire system to fall over. for those interested: [url]http://learnyousomeerlang.com/errors-and-exceptions#not-so-fast[/url] [url]http://c2.com/cgi/wiki?LetItCrash[/url] [url]http://lgiordani.com/blog/2013/05/30/error-handling-in-erlang-a-primer/[/url] [url]https://mazenharake.wordpress.com/2009/09/14/let-it-crash-the-right-way/[/url] [code] -module(store). -export([start/0, store/2, fetch/1, server/3, spawn_server/1, kill/0]). server(StoreMap, Replicas, Type) -> receive {store, {Key, Value}} -> ChangedMap = maps:put(Key, Value, StoreMap), [Name ! {update, ChangedMap} || Name <- Replicas], %%sends update to all replica nodes server(ChangedMap, Replicas, Type); {Sender, fetch, Key} -> Val = maps:get(Key, StoreMap, undefined), Sender ! Val, server(StoreMap, Replicas, Type); {add_rep, Name} -> %% adds new replicas for this process to distribute updates to server(StoreMap, Replicas ++ [Name], Type); {update, NewMap} -> %% updates the keyvalue store on this node to mirror the node it is replicating. server(NewMap, Replicas, Type); kill -> exit(kill) end. spawn_server(Name) -> Pid = spawn(?MODULE, server, [maps:new(), [], Name]), register(Name, Pid). %% gives it a name start() -> Master = spawn_server(master), Replica = spawn_server(replica), master ! {add_rep, replica}, Servers = [Master, Replica]. store(Key, Value) -> try_action([master, replica], fun(Name) -> Name ! {store, {Key, Value}} end). try_action([Server|Servers], Action) -> try Action(Server) catch _Exception:_Reason -> try_action(Servers, Action) end. fetch(Key) -> try_action([master, replica], fun(Name) -> Name ! {self(), fetch, Key}, receive Value -> Value end end). kill() -> master ! kill, replica ! kill. [/code] An example of a server which falls over to it's replica should the master fail, it's a rather naive example, but it shows what you can accomplish with Erlang. Receive being "pattern match on any message sent to this process", and "ProcessID ! message" being send a message to ProcessID (potentially on another machine entirely). Here the Master/Replica nodes are actually not linked to start up instantly afterwards, just a simple example of some sort of failover is demonstrated :v: It's a rather naive example, but I hope it's at least partially understandable, Erlang employs pattern matching for a lot of things, so that's what you see in the function arguments as well. For those who wish to poke into Erlang, i'd recommend "Learn you some Erlang" inspired by the Haskell book: [url]http://learnyousomeerlang.com/[/url]
Gotta up and move 47 servers from New Jersey to California. Which is easy until you get to the part where you need to reconfigure a fuckton of IPs, permissions based on IPs, DNS settings, etc. Fug.
[thumb]http://i.imgur.com/ekBkGZe.png[/thumb] Eh, i can't into user interfaces. Red one is disabled window, orange one is currently active window and gray one is inactive. Both smaller windows are actually contained within the big window, that's why it's not in the front.
[QUOTE=Tamschi;48270229][I]Technically[/I] that is explicit though, isn't it? :wink: (I like this a lot, it's very concise for what it does.) [/QUOTE] Yeah, this was just an example that actually unpacks the data into names. The same function could just be written as [code]userData form = User <$> readName form <*> readMail form <*> readPassword form [/code] or [code] userData form = liftM3 User (readName form) (readMail form) (readPassword form)[/code] [editline]23rd July 2015[/editline] [QUOTE=Tamschi;48270229]Something I want to do at some point when I know more about it is to create a language that removes all the arbitrary limits you currently have with .NET compared to what the runtime actually can do.[/QUOTE] I never understood that. For example, generic attributes are something that exists in IL, but C# simply forbids. wat
[QUOTE=geel9;48271055]Gotta up and move 47 servers from New Jersey to California. Which is easy until you get to the part where you need to reconfigure a fuckton of IPs, permissions based on IPs, DNS settings, etc. Fug.[/QUOTE] You have 47+ servers for scrap?
[QUOTE=Rocket;48273143]I assume they have a few VPSes for each of their services for load balancing, as well as a few for databases and logging. I don't think he means actual physical servers.[/QUOTE] I know they're not going to be physical. These days everything is virtual. Even still, 47+ for scrap, that seems excessive. But that's without knowing the load that the service takes I suppose.
Made a cover system a la Metal Gear Solid 1. [vid]https://miyuki.impulsh.moe/Ag5C1x[/vid] Running into a wall makes the character take cover. It knows if you're near the edge of a wall and moves the camera over accordingly.
[QUOTE=polkm;48270163][t]http://i.imgur.com/J8flS9C.png[/t][/QUOTE] That is the best looking 2D/pixel-art grass I ever saw.
[QUOTE=`impulse;48273424]Made a cover system a la Metal Gear Solid 1. [vid]https://miyuki.impulsh.moe/Ag5C1x[/vid] Running into a wall makes the character take cover. It knows if you're near the edge of a wall and moves the camera over accordingly.[/QUOTE] That's really cool, does it use the wall's normals to determine how to position the camera?
So, during the last month I worked on a ton of stuff - Saving players, chunks, loading them and streaming them online, collision and online lobbies before the game. Now I've returned to the terrain generation, tweaked it a bit: [IMG]http://i.imgur.com/ihdmJwJ.png[/IMG] I have encountered a problem, however. The rainfall map takes way too long to generate (Around 5 minutes for a 1000x1000 map, and I plan on bigger maps, so I need a new way to generate it). Does anyone have an idea how to 'smudge' values over an array quickly? I want to move the rainfall values across to the wind direction, but its slow as hell doing it one point after another...
[QUOTE=Megolas;48274165][...] I have encountered a problem, however. The rainfall map takes way too long to generate (Around 5 minutes for a 1000x1000 map, and I plan on bigger maps, so I need a new way to generate it). Does anyone have an idea how to 'smudge' values over an array quickly? I want to move the rainfall values across to the wind direction, but its slow as hell doing it one point after another...[/QUOTE] You could either thread it normally (sampling multiple targets for each destination with an iterative solution), or you could implement an iterative solution on the GPU to make it run even more in parallel.
its not good, but yeah. [video=youtube;ziOryRTYUH4]https://www.youtube.com/watch?v=ziOryRTYUH4[/video]
Sorry, you need to Log In to post a reply to this thread.