Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Ranzear
Jul 25, 2013

I'm reminded of this game I rented once and never saw again until I just now googled it up:

https://www.youtube.com/watch?v=Nu4-IhV--Ww&t=543s

Seems this game is half naval battles and half load screen though unless you're playing the weenie boat to drag things out, lol

Ranzear fucked around with this message at 01:08 on Mar 15, 2020

Adbot
ADBOT LOVES YOU

Ranzear
Jul 25, 2013

ChocNitty posted:

I don’t know how many people share my opinion, but I think the writing in 99% of games are trash. Even most games that people say has really good writing like Halo, I could have disabled the dialogue and enjoyed the game no less. The writing is almost always cliche, and bland, instead of being inspired and thought provoking.

But thats okay with me for most genres of games, because I enjoy them to be immersed in the games world, and to be engaged by the gameplay, being challenged by puzzles, and hooked in with item collecting, and to enjoy other things like the score, and visual style, etc.

Wouldn’t it be a good idea of game producers and publishers contracted acclaimed authors from outside the gaming industry to write some of these games? Or do this more often? The reason Witcher 3 has an outstanding story and writing is because it came directly from an excellent novel.

Or is it just a matter of cost? They don’t have the budget to hire Steven King to write the next Telltale game.
Non-gaming authors wouldn't know the first thing about writing stories for games. It's a huge variance in agency and presentation. Just to illustrate, what if you asked G.R.R. Martin to write a Choose Your Own Adventure? You'd get six pages describing a single table at a feast and a choice to eat the bread pudding or the creme brulee. One of them was poisoned, you die, game over.

That's why a lot of game writing is kinda lazy and disconnected from actual gameplay, because writing against actual mechanics is hard and as Hughlander points out it can also be constraining as development goes on. "Acceptable" writing in games more or less just sets a backdrop for the game to take place against, like Halo for instance, or takes an existing story and very carefully adds points of agency and gameplay without the narrative dictating the mechanics, ala Witcher.

Truly good writing in games, however, is like good CGI: You don't goddamn notice it! It blends in instead of sticking out. Prime example: Hollow Knight. The entire proper story takes place across maybe a dozen one-sided conversations, but the agency to explore the world, learn the history, find the macguffins, and punch the baddie is all writing in the end, it just doesn't seem like it because you aren't actively reading dialog or having stuff narrated at you. Showing, not telling, is still writing.

Nonlinear writing, agency versus constraint, and ludonarrative consistency are all special skills independent of classical writing chops.

Ranzear
Jul 25, 2013

They who makes the concept makes the game, no matter how hard they beg coders and artists make it for them.

Ranzear
Jul 25, 2013

There's certainly a difference between cooking up a concept and then sitting on it for a rainy day versus cooking up a concept that is far beyond the skills you can obtain yourself or even from others.

For instance, I have a long-pondered passion concept for a four-way asymmetric third person hardcore-teamwork shooter, but it's 90% art 10% coding. Making four vastly different teams with three or four units each in 3D is just beyond me currently, but I might have the people and resources for it later. I could dump time into it to make a prototype, but I'd be redoing all that work in some different engine instead of forcing something like Godot or esoteric homebrew garbage onto any artists I obtain. That game also screams for Unreal Engine in the back of my mind, but I've become a Rust snob since.

I could actually make some weird suggestion that, from a pure skillset and resources perspective, procrastination is better than prototyping. It's too easy for temporary solutions to become permanent hobblings. Generalize your work instead: Look at all the concepts you want to make and write the code that enables some small part of as many as possible. Build up your own little toolkit of libraries and tricks and classes until you realize you've already written 90% of something and can bang out the detail work to finish it. You'll produce way better code and likely way better games that way.

Ranzear
Jul 25, 2013

TooMuchAbstraction posted:

It sounds like you're saying "build the idealized form of the utility you need, that can be adapted to any future requirement."

Nah, the suggestion was more about looking at one's current list of things one might wanna make and figure out what overlap one could write some reusable code for, not even for future application. When one finally gets halfway into one of those ideas and realizes it's kinda poo poo, one can still turn around and repurpose that modular part. It just gets ahead of trying to reuse something not intended to be reused. Still technically procrastinating on most of your projects by avoiding working on any one in particular?

I'm super weird and write netcode first in almost every case, because all of my games are client-server and how one shoves stuff between those dictates almost every data structure. After moving to Rust and basically having a clean sheet, my first major chunks of code have been serialization and barebones netcode just to get most anything off the ground. My fastest way out of a funk is to just write anything, and being non-committal to any particular idea helps. I can agree that this approach might be uncommon.

If it isn't good coding practice, it's at least good coding practice.

Triarii posted:

Yeah, it's a pet peeve of mine that a lot of programmers I've worked with are in the mindset of "give me a detailed specification of everything The System needs to do, and I will descend into my cave for three months before emerging with it complete and perfect." Then whenever someone wants to try something new that wasn't predicted in the specification (because you can never predict everything you're going to want to do) they get shot down with "no, we can't do that. The System doesn't support it."

I have a related but egregious peeve with this which I don't expect is limited to gamedev: On the design side, one might say 'hey, every unit has these six stats'. If the programmer just puts their head down and makes a unit class with six named unsigned integers for those stats, they're a moron. Nobody codes that blindly in reality, I hope, but a lack of coders engaging with the design work and designers not expecting questions or pushback before implementation is a very much experienced nightmare for me. Emphasis on 'expecting' communication back too - if I were purely on design I'd be mondo concerned if anything I gave the programmer was implemented without a word thrown edgewise.

My Hallmark Personalized Version of Hell is the designer wanting content changes scheduled on a weekly basis. Turn that over in your head for how "the week containing Cinco de Mayo" might be handled. How about like Mario levels; Is it 5-1? Or is it 4-4 because this week started last Sunday which was still April, so we're currently scheduling Month 5 holiday content in Week 4-4? By the way there will be a week 5-5 at the end of May. Week 16 of the year? Starting from Jan 1 or the Sunday before again? Which days of 2020 are Week 46, off the top of your head? What week is Easter 2021 in? Now the designer wants stuff to change on the first of the month as well, and that weekly stuff should alter itself to reference the current month at the same time. Take this bat and beat me over the head now, please.

Communication and mutual understanding of both obstacles and goals is hugely important.

nielsm posted:

A while ago I read some advice to not write reusable code, but rather write replaceable code. If it's easy to rip out any part of the code and replace it with something new, you're also flexible. Also not be afraid of copy-paste for chunks that need partial reuse. Refractor the code later when it's more clear which parts make sense to have shared among modules.

I like this a lot. It gets at what I idealize but wasn't phrasing right: Isolation of code.

I said generalizing, but it's 90% to do with isolation. Fast trashy code that is isolated enough to be replaced later is good, it just so happens that if one has a ton of free time and is writing something common to all their backburner projects one probably might as well write it okay-to-good and still well isolated in the first place. Isolation is always good, no matter how perfect the code inside it is perceived to be, because it works as a testing boundary too.

That's my beef with prototyping. I see it as the blind head-down coding spree that produces an exact self-contained solution with no isolation of major structures. I have some horrific monstrosities that came about from 'just prototyping', we're talking 1460 lines of code with nine comments, because everything is just temporary, right? I had to put a prohibition on ever touching that project again, because it's too big to rewrite and too integrated and forgotten to fix. I still play it now and then just to remember the things I learned from it.

On the other hand with all of this: Aphantasia. I am confirmed to be a weirdo, especially in designing with concepts instead of visuals. I also figure Rust is forcing me into a ton of strong isolation patterns too. It will almost automatically kick you in the balls for trying to copy and paste some piece of code into a slightly different place.

Ranzear fucked around with this message at 18:05 on May 3, 2020

Ranzear
Jul 25, 2013

Maybe you thought I was a designer making that statement, but I'm putting fellow programmers on blast there. Instead of listening to the designer who very exactly said 'land this 747 in Chicago', you could land at the airport nearest Chicago that supports heavy aircraft? I'm just spitballing here, but I fully expect the programmer to know capability better than the designer and take some responsibility for it.

And good communication is making it clear to the designer that one should only land a 747 at an airport. I'm sure they'll get the idea.

One doesn't get to declare all provided design will be inadequate and then hide behind the inadequacy of design for why their code can't accommodate at least some changes in the plan. That's just being a dick and I hope mine and Triarii's peeve examples don't actually exist.

Ranzear fucked around with this message at 17:33 on May 4, 2020

Ranzear
Jul 25, 2013

It's especially true on smaller teams where one is likely to take ownership of an entire system. Again hoping these people don't exist, but I figure that 'blind' coding tendency could come from school environments, where every problem presented has an obvious solution and no complications. Treating gamedev work like homework is never gonna cut it.

Hell, I find myself questioning my own design when it involves implementing a bidirectional map for a full graph of distances between objects instead of just putting them on a 2D coordinate, but I want a logical distance between those objects to fit better with moving towards or away from one-another in a turn-based system. I'm gonna keep trying to think of a way to cluster them or something, but the actual memory/network cost isn't prohibitive of the brute force solution because there won't ever be more than twelve or so, which is 78 edges.

Ranzear
Jul 25, 2013

And now I'm down a rabbit hole about how Shrek for Xbox was the first game with deferred shading.

https://www.youtube.com/watch?v=j-ijgJNFAD4&t=466s

Apparently this was made by a team later known as ... DICE? :smug:

They seem to disavow it though.

Ranzear
Jul 25, 2013

Coffee Jones posted:

Had an interview the other day for a server side developer position.
One of the questions they'd asked me:
"How would you design a match making lobby for an FPS like Halo or a CCG like Hearthstone?
This Game is distributed across multiple sites in the world, but you need to find the best possible match for several waiting players ASAP."

I'm gonna read between the lines that they intended the question to be about the differences in matchmaking between those two titles.

For Halo, you might have some stat tracking or ranking, but almost exclusively you're gonna group players by nearest server because ping is critical. Fill matches to a minimum player count and then level them with remaining players (better to have four 7v7s than three 8v8s with eight players left hanging).

Hearthstone is the complete opposite. What server is connected to doesn't really matter, even regarding localization. Players should be matched by a strong MMR or ELO system. There should be some minimum waiting time in case a better match comes along, but also considerations toward maximum waiting time.

Matchmaking is a hellish nightmare of no solution ever being good enough because the expectations of any system are plainly impossible. There will always be waiting times because a short wait is worth a better game experience.

Ranzear fucked around with this message at 07:33 on Aug 2, 2020

Ranzear
Jul 25, 2013

Don't get me started on some hypothetical about mild pay-to-win in the game so top rankers are always top spenders, so keeping their match times low and "letting" them curbstomp others is a big loving can of worms someone always wants to crack open.

Ranzear
Jul 25, 2013

dads friend steve posted:

You’re right, I gave way too much decision making power to clients

The correct amount of authority to give the client is zero. Don't even fully trust the inputs you do allow.

Ranzear
Jul 25, 2013

Mild rant ahead.

I would almost argue that a turn based game with no chat doesn't strictly need regional servers but global connectivity sucks more and more lately. Even just Japan to West Coast will completely poo poo the bed twice a week for hours at a time. It's still better to have the combined pool of players from the start in that case. Splitting the pool into regions, when unnecessary like a turn-based game, is rarely a good idea because then you're even more prone to time-of-day slumps in activity affecting both match time and match quality.

Non-gameplay UX, like deck management, can still suffer from bad ping more than gameplay does, so I've flip-flopped on regional servers a lot. Regional servers with a shared PvP pool is an ideal I've been working out recently though, since my current project falls cleanly into the mentioned category. It just depends entirely on how portable your matchup data and client connections are. Matchmaking should be able to tell any set of clients to meet up on a best-case gameplay server.

I just don't like regional servers being completely isolated islands, even in ping-critical games.

Ranzear
Jul 25, 2013

Nah, been like that for a long time. Fremont to Tokyo will just randomly be like 10mbit tops, from both Linode or Digitalocean (dunno if they're not just in the same datacenter though). Entirely throughput for that matter, latency stays pretty normal.

Ranzear
Jul 25, 2013

ChickenWing posted:

Tangentally off the server question, how does game server communication actually work? My dev career so far has been exclusively RESTful CRUD servers with like 200ms response times and I've always wondered what the paradigms are when your job is to be responsive at the reflex level rather than at the "waiting for a web page to load" level. I know vaguely that you're sending the absolute minimal client deltas (at least that's how they explained it in the source engine video I saw), and I'd guess you're doing the absolute barest minimum serialization/deserialization at the communications layer, but beyond that it's one hundred percent black box.

Web APIs dominate a lot of stuff. Most mobile games just have PHP backends. Beyond that I guess I'll essay and summarize:

For actively synchronized games, it depends entirely on the game. A lot of AAA titles are hilariously liberal with their netcode and that's how you get stupid easy see-through-walls hacks and whatnot. A lot of the mentioned 'minimal deltas' concept relies on giving the client way too much information in the first place. If you have a very simple arena game with no 'hidden' information like Splatoon this is generally okay, but some free weekends of Call of Duty were a good time to play with some of the tools and see how it lacks any sort of server side culling or input filtering; the client knows the position and facing direction and even movement inputs of every other player likely because the dedicated server was the exact same code as their ad-hoc with just a dummy client as host.

There was a tank game called Tanarus way back that did pretty well to hide cloaked tanks from appearing in the netcode, but it would still have an object for the engine sound because players were supposed to be able to listen for it if one was lurking very close. Of course this engine sound was given away no matter how distant, so there was a hack that would just automatically fire artillery at any unassociated engine sound.

That's the first slice in my framework of netcode: My comment about trusting nothing from the client was only part of a whole shtick about treating the client like a hostile adversary; give it minimal information and accept only exact inputs in return. It's my anticheat paradigm. No amount of machine learning spyware nonsense is gonna keep the client from abusing information that the server readily provided. It's so common I wonder if that's just some repeated misinterpretation, where the instruction to send 'minimum information' leads to minimizing the bandwidth cost and full state updates, when in reality it was about gameplay information all along and those optimizations work entirely against hiding information. Bandwidth is indeed a consideration, but you know what costs a lot of bandwidth? Sending information the client isn't supposed to use in the first place.

The next slice of stuff that varies based on application is server versus client simulation. The client has to have some simulation capability just to interpolate between server updates, and the server should be doing some simulation just as the barest protection against nefarious clients. This is a huge slider in almost all cases and the Tanarus example I gave comes up again. Tanarus was an entirely server-driven game and went at least as far as being able to cull tanks from client vision but still provide unassociated sounds to play at some location. Tanarus is long gone for me to know too much more than that, particularly how much client sim it did, but I do remember that network loss would have a tank continue driving/turning aiming as it was before disconnecting, so there was at least the minimal simulation on the client. That's the barest gist of netcode: Keep the simulation state of the server and client from diverging, hopefully with minimal data and effort but also with consideration for hidden information remaining hidden.

There is this paragon ideal I chase where the server does 100% of simulation and logic for the game, and the client is turbo-mega-dumb and receives state and raw metadata (velocity, acceleration) for what an object will do until the next update rather than fully simulating anything at all. The client's only job is to blend each state transition with whatever it was last displaying.

That leads into the third slice, and perhaps the hardest to really pin down: Latency compensation. By the time the server tells the client something, that information is already dozens of milliseconds and multiple display frames old, but one of the best functions of a well-simulating client is to take that state information and the known delay from the server and 'forward simulate' to be in at least temporal parity with the server. This is where culling state information gets tricky, because it might delay the visibility of someone walking around a corner by a step or two and they'll seem to pop into existence. There are several more advanced topics here about how the server can look back at the state when a client gave inputs and retroactively change the current state, but the idea is that simulation lends to aligning things temporally as much as spatially and mechanically.

This is another ideal I chase where the server has three complete gameplay states it operates on: A past state that takes user inputs and applies them in proper timing to produce the present state, the present state which is the canonical state of the game and becomes the past state, and a future state which is used for information culling to prevent 'pop-in' and also gives some version of that contextless 'forward-sim' metadata I mentioned before.

So yeah, that whole 'black box' thing you encounter isn't entirely for reasons of complexity or proprietarity, but probably just raw disgusting shame at how much information they leak to the client and how abusable even AAA netcode tends to be. Their best anticheat method is usually being console exclusive, which is why you see spyware/rootkit nonsense get slapped on the PC ports or, hell, even whole new PC releases. Looking at (and never playing) you, Valorant.

This idea that the server can do a lot more of the work in keeping the game secure is someone reliant on VMs getting cheaper and cheaper though, the paradigm is just really slow to shift. Used to be a game server was some ten-thousand dollar 1.2ghz dual socket four-core expected to run a dozen instances, but now a decent VM is easily more powerful than any single client (without needing to do graphics at all) and costs a whole forty bucks a month tops and is still spun up only when needed.

So anyhoo, in summary: Netcode considerations depend on how much information you want to hide from the client, the distribution of work between the client and server to keep information hidden or interpolate state, and how precisely you need to keep the client(s) and server in sync temporally. Bandwidth cost and server load are almost red herrings compared to those factors, and either of those becoming a major factor is probably indicative of bigger problems.

The easiest netcode to implement is literally just serializing and shoving the whole game state to clients. That's also probably the best place to start. From there it's all about paring off the parts one doesn't need, but in some priority or order that follows those factors I described:

  • Rather than serializing the whole state, do a pass by team and filter out things that team doesn't see.
  • Instead of taking any kind of simulation-embedded input, like dictating the vector of their gun barrel, just get an abstract 'aiming here, pressing these buttons' input object from each client and let the server sort out what it means and/or just pass it along to other clients for forward-sim.
  • With input mappings or other simple enumerations, let the client do the legwork figure out what animation is supposed to play or other strictly visual things. Have the server handle a system, like sounds, when you want that system of things to break through the 'fog of war'. Server-controlled visibility is also great for information layers, like if you had some kind of 'sonic sensor' to let a player see footsteps through walls - one needs to cull these footstep sounds unless the player has that sensor. Splitting gameplay objects into sets and layers is fantastic for this and even simplifies the team-based vision in some cases.
  • Interpolation is a good friend, and the server should run way slower than any of the usual 'display' framerates one might think of. This is when one gets into deep time slicing, as if to have a bullet fired at some particular time between updates, and as much as I've read about time slicing it always ignores the amount of isolation of any given object required to really pull it off; simulating the whole state at any arbitrary slice is silly. Anything that operates in arbitrary time should be well isolated. What this really looks like is producing a bullet already simulated to the position it'd be at as if it had been fired at that arbitrary time, but that gets into hitscan vs particle jank. I could write half a book on doing broadphase with temporal bounds to solve that but I think you get the idea. Just run the server as slow as one can get away with.
  • As much as one can, let the server and the client run the same code. My ancient gnarly jankfest netcode-prototyping four-course-spaghetti-dinner Caliber uses node.js for the server and has all the client scripts double as node modules, so all server and client sim is absolutely 1:1.

Something that floats around conceptually for me is having the "server" be a standalone/portable thing and the client is running a local instance that stays in sync with it and does all the basic state transition and temporal work, then the visual part of the client is able to freely poll it for arbitrarily interpolated state without any worry for updates or interpolation. That way even local play has a 'server' and this enables ad-hoc connections and stuff too, while also hugely simplifying development with not needing to maintain or restart an active server on every change of interacting code. It'd be like a state negotiation model, and leads to some ideas like having a game 'upgrade' to ad-hoc by one or two players joining and doing round-robin authority and then 'upgrade' again by migrating the state to a dedicated server when even more players join.

tl;dr You're doing better than 90% by just shoving serialized state around but leaving out parts the client shouldn't know. The rest is just temporal fuckery to prevent jank and promote fairness despite lag. Your game has to have a hilariously overburdened state to need any of the crazy decades-old delta stuff and modern VM servers kinda negate the tradeoff anyway.

Ranzear
Jul 25, 2013

Rodney The Yam II posted:

My game involves a very non-deterministic AI controller that animates the game entities.

What's making it nondeterministic? My only guess is RNG, but you could throw a seeded PRNG behind it instead and change the seed every so many timesteps to prevent prediction. That will let you forward-sim on the client.

Ranzear
Jul 25, 2013

In terms of raw state-pushing, the best idea I've had is to implement both state and edges, edges being strictly a transformation between states. Optionally, multiple edges can be chained from one state to produce some new state, but the basis is about edges being simple transformations that take a state in and put a state out. They really are just delta differences I guess.

From there, one can use two different kinds of updates in their netcode. This was something I explored but never fully implemented in Caliber. There is a 'static' update that is the most recent full state, obviously supplied to joining clients and would be as complete as a save file, and dynamic updates which are just the transformation edges between states. From there, multiple edges on a single state are additive, meaning one can also produce an edge that makes corrections, like if some player's laggy input changed an outcome and their position should be adjusted to compensate.

The clever bit with this is letting objects be identified mostly by anonymizing hashes. Then one can do something like the team-vision based culling I mentioned before, giving a limited state object to limit information to each client, but then throw the same complete edge updates to all players. The final trick is to shuffle all the hashes on each full state update, so no continuing edges for a given object can still be associated with that object. The edge updates are useless without an associated object in the main state update, while not culling edge updates makes those updates fast enough to crank way up in frequency.

I just never got around to implementing the edge updates or hash shuffling for Caliber, because full state updates weren't pushing more than 500kbps for thirty plus visible players (i.e. spectating, no culling) and the server starts to eat itself for many other spagettiriffic reasons long before tick rate becomes an issue. I was leaning toward full state updates as slow as 4hz, and edge updates as fast as 100hz. The other weirdness was that it shouldn't even matter if edges arrive out of order, just apply them as received, so UDP is an option. Even mild packet loss would be quickly corrected by the main update.

Theory is not implementation though. Even just calculating the edges between states and ideally trimming out 'unchanged' stuff is probably too big a tradeoff to beat out big simple state shoving.

Ranzear
Jul 25, 2013

Ping jitter is far more noticeable and harder to correct for than raw latency. A client that wildly swings from 20ms to 80ms latency likely has a far worse experience than a client that is consistently 120ms. The biggest problem with gaming on wifi isn't latency or loss, it's jitter.

Ranzear
Jul 25, 2013

I don't know of any socket library I've looked into lately that doesn't use TCP_NODELAY by default, because most are doing their own buffering. Rust's does at least.

Sounds more like UDP if packet loss was causing it to implode. Somebody pour Hughlander a drink.

Ranzear
Jul 25, 2013

Fixed point is good for consistency but a pain in the butt to actually implement. I ended up just trimming floats all the time, but it did save a lot of raw bytes in my JSON streaming. Outside of extreme cases, like Kerbal Space Program before the origin centering patch, nothing needs full precision floats. Hell, few things need more than three digits of decimal, which would be millimeter precision in Unity.

Don't rely entirely on determinism either, just have a periodic re-sync of clients and reduce desync as much as possible. OpenTTD is an outlier probably for being too broad a simulation to throw a complete state around and that level of lockstep also relies on complete information to all clients, which is an already discussed no-no in games with mechanics reliant on hidden information. I also presume OpenTTD is built for multiple players potentially interacting with the same objects, which doesn't really come up in other games.

As for implementation of input, make it something parallel to or inserted into the game state. A very simple struct as what Vino mentioned, just a set of raw input values that are tied to and fed to some particular game object. It's also not a directive like "I aim my turret 30 degrees left" but instead an intent like "I want my turret to be pointed 127 degrees absolute" which lets both the server and client determine how much the turret turns independently in real time, forward-sim time, or inter-update frame time. When abstracted this way, the client just plugs the more current local input object in for forward-sim until the next update, which makes local input immediate and smooth, but the server also just passes along inputs on other player controlled objects instead of needing to do any 'baking in' of those inputs for forward- or inter-update- sim. This also makes it easier to have bots, because they just produce the same input object as a regular player and don't need to process as much state.

This is how Caliber runs 120fps+ on the client, but a variable tick rate based on player count server-side. Everything is delta time and any precision loss or collision damage weirdness is just chalked up to server load.

Eliminating 'instantaneous' input is nice all around, like my turret-aiming example. I don't have anything against games with instantaneous snap aiming, but I like the physical realism of not having instantaneous perfectly accurate inputs, and it makes everything easier to synchronize and keep smooth between updates. Instantaneous direction changes from client input are hard to reconcile in netcode because they're hard to reconcile in physics and reality, but an intent and a known timeframe to achieve that intent can be executed in many different temporal offsets and granular simulation steps at once. It's also a mild anticheat method because the client has zero authority over the absolute precision of an input.

Ranzear
Jul 25, 2013

With upcoming AMD cards that support a more open-source-ish raytracing library it should pick up a little more steam beyond gratuitous tech demo. Even just throwing in one quick raytrace pass for global illumination (and sticking to faster methods for reflections and other junk) is huge.

Adbot
ADBOT LOVES YOU

Ranzear
Jul 25, 2013


The Imp and Pinkie sounds too.

The one I never miss is the Chronoshift sound from C&C:Red Alert.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply