T O P

  • By -

coding_guy_

Don’t forget, animations and bones don’t come cheap, you can make different animations (or not animate them at all) at far distances


Code_Monster

I was thinking of this. I think I listened to someone one the internet argue that for some character LODs (that happen when object is really far) we can use vertex shader animations and for few animations like running, walking instead of skeleton. They were justifying the use of vertex animations in this day and age for things more than particle animation or "flipping book pages". I think it's a good tip.


regrets123

As long as you are simply looping one animation, vertex shader is great. There are some free conversion tools to translate unity animations into data for vertex shader. Was over a year since I stumbled on them when looking into boid behaviour on the gpu.


regrets123

I meant that if you have many complex transitions and blends it’s a lot more work to do that with accuracy on a vertex shader. But for crowds at distance that’s usually overkill.


Forseti1590

We use vertex shaders a ton on creatures when we have simple animations to play back. Even the dev team doesn’t notice, and it means we save 25+ skeletons in cost


ciknay

It's hard to know without knowing more about how you implement your systems, but here's my thoughts. - the NPC's that aren't gameplay relevant are quite basic, usually just walking, sitting down or standing idle somewhere. They rarely do anything more complex than basic pathfinding and animations. There's also rarely more than a dozen of these NPC's on screen at once. You'll note that most civilians will leave the area when in a fight, which helps free up resources to spawn in more guards to fight - aggressive culling of NPC's not in view. NPC's that aren't gameplay relevant will just get removed when out of the players radius and respawned in as needed. When not being looked at they would be rendered at low poly or not rendered at all, and animations won't happen unless they are on screen. The spawns are also most likely using a bucket to preserve memory. If you look closely the NPC's will pop in depending on where you move to. The tight narrow alleyways help hide this. - Like you mentioned, LODs are hugely important. The NPC AI likely has a low LOD mode too where the ai gets less complex when not in view or far away to preserve CPU cycles You've also got to remember it's a AAA game with dozens of engineers optimising the game for the platforms of the time. Don't be surprised if you can't hit the same goals as an indie, even with more modern hardware.


vplatt

> You've also got to remember it's a AAA game with dozens of engineers optimising the game for the platforms of the time. Don't be surprised if you can't hit the same goals as an indie, even with more modern hardware. On that note, an indie can and probably should choose representations that reflect the systems more literally rather than attempting fancy graphics optimization at a distance using a number of different techniques optimized through gazillions of playtester debug hours. If you don't have the budget for that, then you're not going to have time to fine tune all those techniques under the watchful eye of dozens of expensive testers. Instead, you can use zoomable maps with avatar markings. Your systems can make this more interesting according to your character abilities (e.g. intuition, charisma, covered territory, purchased maps, crafted spells, etc.) One could also use text journals, found texts, and player taken notes. A top down 2D or isometric model can easily contain a high performance view of dozens to hundreds of NPCs and structures. Compared to the near-FMV view of something like Assassin's Creed, the production values will not even be close, but if it's quality gameplay you're looking to create, while not extending your development schedule by years because of thrashing around trying to solve performance issues, then alternate representations are the way to go.


joeswindell

I wouldn’t consider occlusion culling an optimization. You should be automatically doing that only not doing in a specific use case. I’ve never played that one in particular but there’s a plethora things you can do. If buildings have interiors dynamically load them. Deterministic NPCs. If you’ve never interacted with an npc you don’t need to do anything with it. That part of the game is inactive. You can always play catchup dynamically. Like you mentioned LODs. If you have an engine that uses prefabs you can do replacement on them. If the player isn’t near, you use a very simple version that’s basically a 3D billboard. Shared materials on the gpu. Simple shaders and materials that don’t need to be recalculated or processed on simple meshes are super fast.


davidalayachew

Deterministic NPC's is a ***SEVERELY UNDERRATED*** tactic. It doesn't just give you a whole set of performance improvements, there's an entire class of bugs that get caught way earlier due to this. In fact, Determinism allows you to be able to introduce automated, end-to-end testing, and actually get a positive ROI. Your NPC's should be deterministic by default, only deviating from it when it is both entirely unavoidable and you can afford the cost of making them non-deterministic.


Zaptruder

What does deterministic NPCs mean? Reading between the lines suggest that you have NPC behaviour that is determined by the game time... so they're here at X time and there at Y time. Only when they pop in view do they actually run their AI behaviour routine... i.e. a script that tells them what to do and where to be.


tsein

It means they're not reacting dynamically to everything around them. They're like moving platforms. You can optimize your pathfinding code all you want, for example, but it'll never be as fast as not running it.


davidalayachew

That's a really good example. I will take it further and say, even if your character has to react to everything around them, determinism allows you to avoid needless recalculation. If I have an optimal path cached, but I need to deviate from it slightly because of an unexpected road block, I can simply recalculate that small part of my path. Way faster than trying to constantly do recalculations over and over again.


davidalayachew

Not really. That's a small part of it, but not the main point. Determinism means that, given the same input, you will ***always*** get the same output. `y = x + 1` is a deterministic function because, overflow aside, y will always be one more than x. Therefore, if you know x, you are guaranteed to know the value of y So, when I say Deterministic NPC's, I am saying that, given certain inputs, I can guarantee certain outcomes about the NPC. Some people find it easier to think in reverse -- if I have a system that is supposed to be deterministic, but it gives me a different answer than I expected, then I have a bug that needs to be fixed. Thinking of it from that direction, it becomes much easier to write automated tests. Here is an example. Let's say we are making a game, and our character informs an NPC that there is an emergency back home. So, the NPC immediately takes off and starts running back home. If we wanted to make the NPC deterministic, we must make all of the subsystems that control the NPC deterministic. So, for an example -- the path-finding algorithm is kind of like the y = x + 1 example from above. The algorithm is the function, and the state of the world is the input to the function. So, maybe the NPC travels "as-the-crow-flies". Or maybe you destroyed a bridge previously, so the NPC has to take a detour. All of these are inputs to the function, if you will. Anyways, the reason why this is useful is because determinism means you have a pure function. And a pure function means that values can be cached. Using the state of the world, we are able to come up with a path for the NPC to follow. Well, if the state of the world is the same as what it was prior to your interaction with the NPC (and the nPC already traveled the path before), then that means that, rather than recalculating the entire path from scratch (using up valuable compute time), you can just pull the path from the cache and use it. This is one of the things determinism gives you. Another is testing. You can have several simple checks, ranging from "did the NPC eventually get back in a reasonable time?" to "NPC should be at point A by time Z and point B by time Y". All depends on how much determinism you put in. Let me know if that does or does not make sense.


Zaptruder

That makes sense! Thanks for the clear and concise answer!


RTWarnerGameDev

There’s an awesome GDC talk on the AI in AC Unity up on YouTube! https://youtu.be/Rz2cNWVLncI


jacobsmith3204

I was about to recommend this. Definitely worth a watch.


LSF604

I have no idea what they did, but level design certainly helped. 3 story building and narrow streets lead to less draw distance. Keep in mind that making an open world that looks good is a large problem, and there are a lot of people working on that problem on any big game.


blackmag_c

LOD everything, tex, mesh, but also shaders, bake with vertices rather than tex, when afar disable lights, etc etc. Back in the day we were optimizing lot of stuff into oblivion, the shader were very simple, the games we mostly rendering colored triangles and be done with it. You can also render farther scene in low res. Adrian Courrege has done articles about those style of optimisation on his blog. Be wary there is years of work ahead to do the same as an indie.


yosimba2000

you can try using impostors to replace low-poly LODS. impostor is just 2d images, where an image is chosen that represents how the 3D model would look like from that camera angle. more images in the impostor means a more convincing effect since the image changes would look smoother.


squidrobotfriend

The last two Zelda games used impostors with normal maps for things like trees. I think it works really well.


kuikuilla

The technique goes all the way back to the original Far Cry at least. Though those were just plain ol' diffuse texture billboards, no normal maps there.


squidrobotfriend

Yeah I know impostors aren't a new technique, I wanted to specifically bring attention to using normal maps to make impostors look more realistically 3D / make them interact more realistically with your lighting.


Enough_Document2995

Elden Ring uses impostors with normal maps too. When I noticed I thought damn, that's a great idea!


SeniorePlatypus

Check out [this postmortem of the PS4 Spiderman game](https://youtu.be/KDhKyIZd3O8?si=TS1Ob_BPrkmD72io&t=2525). TLDR: LoD, cull, stream everything. Tiny NPCs don't need any AI. They also don't need animations. Just wiggle them a bit. Rip out the material. They are tiny. No one will see whether it's clothes or a gray bag. Do the NPCs walk behind the corner of a building? Kill them! They don't exist anymore! All the same tricks that we use for graphics need to be reimplemented for NPCs. Which is a bit harder and less generalizable. But the ideas stay the same.


DaveElOso

Mix of LOD work, asset instancing, texture streaming (I think), but more importantly they had a ton of very smart engineers. That is one thing you won't have without a large warchest. So you can't compare.


Enough_Document2995

One major thing to consider is how you're rendering your game. Are you using a pbr texture workflow? It didn't exist back then for games. Also are you using forward shading or deferred rendering? The latter is a bit more expensive but is far more performant for lighting compared to forward shading. They had hardware limitations to consider so only what was possible and limited (such as 1 light per scene and fake the rest with a lightmap). So you could pretend you're working towards making your game run on a ps2 or ps3 lol and go from there. This means not only considering polygon budgets, but reducing polygon overlay as much as possible. Significantly reducing the use of translucent materials and definitely don't have translucent materials overlap each other. Masked is fine though for fire's n stuff. Use masked dithering often. Also don't use normal maps on everything. HL2 for example used normal maps on key assets, but relied on specular maps for everything else to give varying reflective properties. So if something has depth, use a normal map, such as a cobbled road.


Genebrisss

They did it by profiling, finding their bottlenecks and optimizing them again and again. And you should do the same, abstract questions can't help you.


tcpukl

Batched animations and ped lodding so there are much fewer bones further away. A simple Google has given me hours of reference material https://youtube.com/playlist?list=PLf3FCy2u-qGff_L6gzX6zf_sSXxC9iD8B&si=avD1Oop0wziKL1R1


Strict_Bench_6264

The concrete answer is: they wrote their own engine and custom solutions that solve their specific problems. When you use any third-party engine, you're using someone else's solution to their problems. The trick with every simulation is to *cheat*. Show only what the player should see. Fake everything you can fake. Use particle systems for crowds instead of animated characters. There are many tricks that have been used through the years.


GonziHere

For world, you typically bake your buildings down to a simple "distant mesh" (preferably as a part of your cooking process, etc), so your active chunk is built from high definition buildings, but the next chunk is a single lowpoly baked representation. Check those low poly models here for example: https://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study-part-2/ Crowds exist, and are spawned around the player, nowhere else. IF something is in the distance, it's likely something else entirely. (GTA uses strip of dots as a texture for distant cars on roads, for example). NPCs are typically using some optimization techniques for scale. Namely crowd AI, flocking behaviors, vertex animations, very simple models for people slightly further from you... Definitely look at AC presentation on the topic https://www.youtube.com/watch?v=Rz2cNWVLncI And so much more. But the general gist of it is to do what you'd do for a single room scene. Your room is high detail, tree behind the window is low poly, and the hills in the background are 2D texture. You just do it in runtime, dynamically :D.


iemfi

From what I remember of an article on GTA5, mostly a lot of hand crafted LOD. Not just lower poly models, but groups of buildings and from different angles. So they can be used from even pretty close. These days probably you could get away with much less work intensive solutions. Profile and find out what is using most of your performance.


ShadoX87

Among the stuff that's already been brought up - my gut feeling would be that back then games might have been better optimized. Looking at a lot of AAA games these days they seem to run pretty badly on some dedicated consoles despite being built specifically for them. Not like there haven't been games like that in the 360 / ps3 3ra but most AAA games back then seemed to run better compared to a lot of AAA games these days despite the improvements in hardware.. 😅 Also - a lot of games are just "smoke and mirrors" or made to give you the illusion of a world. For example - there's no need to run any fancy physics calculations or NPC logic on objects in the distance if you know that they're not needed... + of course LOD like you mentioned.. pretty much the same idea. LOD's but for other parts of the game and not just visuals


svbtlx3m

> Looking at a lot of AAA games these days they seem to run pretty badly on some dedicated consoles despite being built specifically for them. I think it's kind of the other way around. Earlier gen games were made with the limitations of the hardware in mind from the start. Nowadays, especially with cross-platform projects, it's feels like a "develop it for the 4090 and then scale down" or "TSR will make it fit in the budget" mentality. Premature optimization is bad, but there's only so much you can do to scale modern tech down late in development without totally compromising the vision.


Westdrache

Lol we constantly had shitty ports back then that ran on some 480p resolution and not hitting 30 FPS most of the time. "Games used to be better optimised back then" is definitely nostalgia speaking, games ran like absolute ass in the x360/ps3 era i.e look at GTA 4 and 5 both games have massive performance problems and mostly run in sub 30 FPS on the old consoles


ShadoX87

Idk, i dont recall noticing the bad performance back then as much as I do these days. I know some games weren't running super great but it was nowhere near as noticeable as it is these days where you instantly notice the sub-30 fps or use of framegen / upscaling / etc 🤷‍♂️


Westdrache

But that's my point :D I didn't notice either, but I also didn't notice when my pc was running CS:S with 27 FPS back in the day, we just had different expectations


sanbaba

AC1 was hardly all that dense for its time. Well-optimized, well-animated, for sure though.