Search Unity

Games Scraps: Modular Vehicle Combat - Vehicle combat with buildable vehicles

Discussion in 'Works In Progress - Archive' started by Nition, Dec 8, 2012.

  1. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Awesome, someone solved the above issue for me. Having the whole wall as one big mesh and being inside that mesh on the map was messing up the sort order!
     
  2. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,461
    I was going to post this in the other thread where you were discussing graphics with James, but though your WIP thread was a better place to comment:

    While I do like the simplistic style of Scraps, I do think there are areas you could improve the look of the levels without resorting to over using post process and losing the visual distinction you already have. Right now the best visual element you have is the cars. They are simple in texture, but complex in geometry. This is the style of Scraps. This style that I think you should consider extending to the rest of your levels.

    Instead of shooting for semi-real, or traditional textures, softly blended across an amorphous height map, push the slider the other way! Go for simple but more contrasted textures on a geometrically complex level. Carved out the areas where combat will occur, give the players multiple interesting paths to moving between the areas, then fill the spaces between with interesting geometry. Cliffs that feel like cliffs and can't be driven up.

    The freeform roaming element of scraps is a great idea, and I know you'll be weary about doing anything to infringe this, but you could still achieve the same feel within a more 'designed' level, whilst gaining a lot more visually. Your latest map 'RiverRift' already has a good example of how this change could affect the look, and gameplay, with the long distinct wall section you have. Riding along the top path whilst raining fire down on the people fighting below? Glorious.

    Of course you would probably have to move away from using the Unity terrain system* to do something like this, but that might not be a a bad thing. Performance wise it's pretty bad at times. With a simple grid system, PVS, and vertex blending shader, you could probably knock out a more complex level with more triangles in a single call, and still end up with better performance!

    Anyway, love the game and sorry for addled ramblings. I was going to do a quick sketch to try and show WTF I'm talking about, but no time at the moment :)

    *big assumption moment!
     
  3. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Yeah, a lot of the terrain look is limitations of the Unity terrain. The default Unity terrain is good in the sense that it's easy to edit and import/export heightmaps, automatically scales LOD for distance etc etc, but for instance the vehicles use hard edges but the terrain calculates its own smoothed normals, so it never looks as crisp. Although for that specific example I'm pretty sure it'd be possible to create a shader that just ignores the er, normal normal data, and calculates its own on-the-fly.

    And yeah Unity's terrain performance is just OK, it's certainly not amazing. The grass performance is fairly terrible which is why I don't use that much.

    I totally agree that the map look doesn't match the vehicle look well. My main problem is just time. Making maps with complex 3D detail takes ages - more time than making maps with more detailed textures but less modelling detail.

    As for map design, RiverRift is me getting better at it. Hopefully I can keep doing more interesting layouts in future maps.
     
    NomadKing likes this.
  4. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Scraps v0.5.2.15

    This update is mainly lots of bug fixing and code cleanup behind the scenes. I also did a smaller v0.5.2.14 update that I didn't make an update post for earlier, which improved CPU performance.

    The specifics:

    2015-12 - 0.5.2.15
    - Added heavy armour part
    - Better support for XBox 360 controller on Mac and Linux. Separate default key bindings keep actual inputs the same on all platforms
    - Engine sounds with multiple of the same engine work together better
    - Removed an annoying ridge in the RiverRift terrain
    - Added some subtle fades between scenes
    Bug Fixes:
    - Fixed occasionally coming back from testing vehicles to the build screen and your vehicle has flown off into space somewhere
    - Removed more false positives and not-really-bad words from the swear filter
    - "Open save folder" button now working on Linux
    - Fixed the loading screen getting stuck if your vehicle spawned in right as a round ended
    - Fixed visual glitch between light beams and edge wall glass
    - Fixed screen staying white if your vehicle was destroyed right at the moment of evac completion
    - Fixed game modifiers (low gravity) not being unapplied on connected clients if the server shut down
    - Fixed SkinnedMeshRenderer errors being generated in-game (in the background) if a vehicle had no moving parts
    - Lots of refactoring and fixing issues with chassis, propulsion systems and their hit points and other values
    - Tooltips for chassis select now include the extra HP gained from the wheels (so they show the actual full chassis HP now)

    2015-12 - 0.5.2.14
    - CPU performance improvements due to physics and rendering optimisation work
    - Tweaks to the RiverRift map layout
    - Swedish translation update

    Have a good Christmas everyone. Thanks everyone who reported bugs that are fixed here.
     
    NomadKing likes this.
  5. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    It's been a bit longer than usual since the last Scraps update, so I just want to give some reassurance that I'm still working hard on things. There was a little time off over Christmas and New Years, but recently I'm working on something that I've alluded to a little in the past: A major new single-player game mode. My thoughts are that it should help a lot to flesh out the game content whether or not Internet multiplayer numbers pick up. I won't go into details of how it'll play just yet because I'm still testing things out myself, but I will in the near future. I think it'll be a lot of fun.

    The new mode is pretty major, and is going to take several months to finish completely. I'll attempt to get some stuff out to try earlier, but I'll also keep doing some smaller game updates in the meantime regardless. The next game update will be next weekend but it'll be mostly bug fixes and minor improvements. Still, things are happening, and I'll have more to show soon.
     
    Last edited: Jan 24, 2016
    RavenOfCode and NomadKing like this.
  6. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,461
    Mysterious new game mode... Ooooooooooooooooo! :)
     
  7. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    The latest Scraps release is again focused on fixing bugs and generally making the core game better. In the background I've also been working on the new Singleplayer mode, but that's not ready to show off just yet.

    0.5.3.0
    - More efficient shader/material usage for environmental stuff
    - Bigger shockwaves move faster (just looks better)
    - Some new destruction FX
    - Fixed some lightmapping glitches and improved some normal maps on terrain
    - Added some new stuff on the test map that I've been creating for the upcoming singleplayer game mode
    - Using the lowpassed music track in the lobby instead of the full one, it's more chill
    - Added an additional vertical adapter block
    Bug Fixes:
    - Fixed multiple issues where games could get stuck at Dropship In Transit when starting games. Please let me know if this happens to you after this update
    - Fixed AI sometimes being lazy and just hanging out until being destroyed for the first time, causing it to henceforth spring into life
    - Fixed game start failing if scrap limit was changed lower, then deploy clicked right away, causing the limit to lower and make a vehicle selection invalid
    - Fixed some incorrect cube weights on the Test Map
    - Fixed shockwaves sometimes not showing up when they should

    Two Dropship In Transit bugs - one that happened on going from menu to lobby, and the other while going from lobby to game - were horrible timing bugs that only occurred when the stars were aligned just right. The issues I found are definitely fixed now, but please let me know if you still get stuck at a loading screen in the future. Of course, report any bugs you find - I do try to fix things!
     
    NomadKing and RavenOfCode like this.
  8. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    0.5.3.1

    Today's Scraps update doesn't change anything exactly, but the install size of the game is now almost half what it was!

    Basically there was a lot of duplication between the main game and server components. This was OK when the game was very small anyway, but it's been getting steadily bigger, so I've refactored things so there's no separate server app at all anymore. Now a server is just the main game with a server flag passed in, and all the duplication is gone. You can still host a game and play on it at the same time.
     
    NomadKing and RavenOfCode like this.
  9. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    The last couple of weeks of dev have been a bit frustrating. I came up against an engine feature that I wanted which - my mistake - I had thought was in Unity 4 but was actually only introduced in Unity 5. Scraps has been halfway converted to Unity 5 for a while so I did a bit more on that conversion, tested the stuff I needed, and realised it still wasn't going to work anyway. Not a real loss of time because I'll most likely need to move the game from Unity 4 to 5 eventually anyway, but annoying because I want to get new content out as much as the next person.

    I can actually show some work on content rather than code for once though. You may have seen the new pile of crates and barrels on the Test Map in the last update:



    In the editor the crates look like the left image, but when the game is run they take on some random colour variation to look a little more interesting. Giving them all different Materials with different tints would blow out the amount of draw calls in the scene, so instead they all share the same Material, and the tint colour is set via the vertex colour on the mesh itself. Pretty simple code:

    Code (CSharp):
    1. void SetTint(Mesh mesh) {
    2.     // Tint is set via mesh vertex data rather than in the shader properties,
    3.     // so that we can still use the same shared single material instance on everything!
    4.     byte colour255 = (byte)(Random.value * 255);
    5.     Color32[] colors = mesh.colors32;
    6.     for (int j = 0; j < colors.Length; j++) {
    7.         colors[j].b = colour255; // Setting the blue channel
    8.     }
    9.     mesh.colors32 = colors;
    10. }
    The meshes are simple so running through the array is super fast - but it only runs once on level load anyway. Then in the surface shader I use the blue vertex's blue colour channel value to do whatever - it's really just a way of getting information from the game to the shader.

    Code (shader):
    1. // Any extra tint stored in BLUE channel  
    2. // fmod is % (mod). Using it to map all possible RGB values
    3. float4 tint = 0.7 + float4(IN.color.b, fmod(IN.color.b * 2, 1), fmod(IN.color.b * 4, 1), 1) * 0.3;
    4. if (IN.color.b > 0) {
    5.     c.rgb *= tint;
    6. }
    You may wonder why I set just the blue channel and then calculate a colour tint based on that rather than setting the whole vertex colour RGB and setting the tint to that value.

    The reason is that a lot of things in Scraps are actually done this way - heat effects on vehicle parts, damage texturing on everything, and how shiny vehicle parts are (specularity) are all specified by modifying the different colour channels in the mesh vertex data, so that each vehicle can be shown with one Material and the environment can be drawn with another. So I need the red and green channels for other things. Otherwise every time something got damaged or heated up, it'd have to use its own Material and have its own draw calls, making graphics performance a lot worse.



    I also made these barrels. The red one explodes of course. I wrote a generic script that I can attach to any world object to make it explode when destroyed and damage surrounding stuff.



    Driving a vehicle by ScrapsEnthusiast there. Yesterday I also added subtle air control to the game, so that'll be in the next update. It's tuned more for gameplay than being realistic, but you can at least pretend it's created from the torque of the wheels spinning in the air.



    And I made some light beam/forcefield-style walls that I can use to create more subtle level borders for some levels. Functionally they work the same as the current walls.



    For the next game mode I need lots of terrain, so I've been improving my terrain creation workflow. I can now take a basic low-detail terrain and put it through my Scraps-specific World Machine setup to get out a terrain fairly quickly with erosion and varied texturing.



    OK, the bottom one still doesn't look amazing yet, but that's without any grass, fog, sky, etc etc. It's a lot better than the top one considering the minimal manual effort involved. One thing that's not obvious in the screenshot is that the "after" terrains also have more fine detail - so I can map out a fairly low-res base terrain and then run erosion on it to make it into a more fully detailed one.
     
    NomadKing and RavenOfCode like this.
  10. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,461
    The force beam borders look great! :)
     
    Nition likes this.
  11. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thanks NomadKing. :)

    The latest Scraps update adds a little air control, a save format upgrade, tweaked weapon hit forces, and a terrain graphics upgrade.

    Full changelog:

    2016-3 - 0.5.4.0
    - Terrain graphics upgrade. But no more switching to greyscale terrain when in low grav mode I'm afraid
    - Magically, vehicle save files are now also PNG image screenshots of the vehicle itself
    - Separated weapon recoil and hit force, so they don't have to be the same anymore. Reduced hit forces in general - should help with Medium Cannon spam in particular
    - Rewrote the weapon movement range calculation AGAIN. More bugs fixed with it. Hopefully very correct and consistent now
    - Added a little air control: Pitch = Throttle forward/back. Roll = Throttle + Steering. More engine power gives more control
    - Finally the test map side road is actually 100% flat, right up to the ramp
    - Updated uLink and Steamworks.NET to their latest versions
    - Added grass density graphics option
    Bug Fixes:
    - Tooltips now update their text to match language changes without requiring a restart
    - Fixed mass from held wreckage not being subtracted after wreckage was offloaded on evac
    - Stopped evac pad ambient sound from playing when the pad is turned off (Test map)

    Air control


    I showed this off in the last update, but now it's live. You can control your pitch with throttle and your roll with turning. You can't control yaw - it's a car, not a plane OK? Practising in Low Gravity mode is a nice way to get the hang of it.

    Recoil
    Weapon recoil and hit forces used to always be the same, which was arguably more realistic, but it meant that if I wanted a big kick on a weapon it also had to have a big hit. Often because of hit angles and multiple shots hitting in one spot, the hits would end up even worse than the recoil.

    I've changed it so that I can set them separately, and reduced some hit forces. Hopefully there's less of a problem with Medium Cannons and Plasma in particular throwing vehicles around now. Of course you can still push your enemies around to some extent.

    Save Format


    Those are actual save files. When you save vehicles now they'll end up in a new format, which is also a png image - so now it's easier to see what a vehicle is if you're sharing it around.

    The easiest way to see your vehicle saves is probably to open the Save/Load dialog in the game and click the button at the top right which takes you straight there.

    Hosting these on an image host will most likely break them - you can try, but you're probably better off using a file host of some sort. Anything that won't try to modify or re-encode the image file.

    Dev note: There are several ways to do something like this. Gimbal has awesome image saves, as does the Spore creature creator. One potential method is to use the image's metadata fields to add your custom data, although sometimes those have size limits. Another method is to use something in the image itself that's invisible or hard to see, like something in the alpha channel or the least significant bits. Or even just extend the image to have the data encoded in an extra part of it, using all the available colour data.

    However, I've done this with the dumbest and simplest method possible: Just dumping all the save data at the end of the file! It was one of the options I've read about so it's not totally unheard of. Sure image hosts will probably break it but all those other methods get broken by image hosts anyway. Seems like as long as you still end the png part of the file properly (works for JPEG too!), every PNG reader that I've come across reads the files with no problem. Scraps just ignores the image part and looks for my special marker, then starts reading the save from there.

    Graphics
    Scraps' terrain graphics have always been pretty meh, and I wanted to get a better system for new stuff, so I've also back-ported that to the existing maps.





    What's actually better? Well, there's nice perlin shadowing on things (how much there is varies with the terrain texture):



    Although I had to get rid of the black outline FX on terrain.

    Bumpy stuff is... bumpier:



    And you can see there that the grass is better too, not just denser. The default Unity grass shader is a simple cutout thing: It takes a texture and says OK, if the alpha value is above whatever, I'll show that pixel, otherwise I won't show it. That gives really crisp but jagged looking grass. It also means that when the terrain engine tries to fade out distant grass, instead of getting semi-transparent grass you get grass that sort of gets cut down more and more at the edges.

    I did a literally one-minute edit to the grass shader to make it do "proper" transparency, and the difference is huge!



    I don't think Unity has updated their grass shader for a long time. There's a comment about Mac OS 10.4 in there. I was sure I must've killed performance as a tradeoff, but if anything the grass performance seems to be slightly better. Here's my replacement WavingGrass.shader and WavingGrassBillboard.shader if any Unity devs want them, it's like jumping from 2002 to 2012 in one fell swoop.

    There's also now texture blending based on heightmaps:



    What's happening above is, when there's a mixture of two different terrain textures, it used to just blend, but now it'll show the higher parts of the texture first (based on a greyscale height map I supply it), so the new texture sort if "raises up" out of the other one as it increases in opacity. For Unity devs, most of these new features come from using Tomasz Stobierski's Relief Terrain Pack (it's not exactly drop-in-and-your-terrain-looks-amazing, but it is very good once you bend it to your will).

    I also wrote some custom terrain editing tools of my own to let me make stuff faster:



    The heightmaps and splatmaps (texture layout) used there are pre-created - my tools aren't that amazing - but it automates a whole bunch of stuff that was previously tedious. It also means I can edit heightmaps and splats and basically just click to update. Without much more work a terrain like the one above starts looking pretty good:



    Still working on a new single-player mode.
     
    NomadKing and RavenOfCode like this.
  12. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    - Main Menu layout changes
    - AI players now show in the server info
    - If an AI player gets kicked from a game by a human player joining with no free slots, when a slot is free again they'll now come back... for revenge
    Bug Fixes:
    - Fixed rotation range calc bug
    - Fixed "aim sphere" rotation range visual bug
    - Fixed null reference exception that occurred on dedicated servers in no-GUI mode with the new terrain
    - Fixed music player playing the wrong track if the track was changed and then changed back to the original track while the original track was still fading out

    The main menu looks different, but it's actually the same functionally. The main aim is just to sort of encourage starting games that other people can join, but it also makes room for introducing a new game mode later.

    Equivalents:

    Playing single-player:
    Old: Singleplayer
    New: Play->Start A Game, have "Allow other players to join" unticked.

    Joining an Internet game:
    Old: Multiplayer->Internet->Join A Game
    New: Play->Join A Game

    Joining a LAN game:
    Old: Multiplayer->LAN->Join A Game
    New: Play->Join A Game, select the LAN tab

    Hosting an Internet game:
    Old: Multiplayer->Internet->Host A Game
    New: Play->Start A Game, have "Allow other players to join" ticked, and set to Internet

    Joining a LAN game:
    Old: Multiplayer->LAN->Host A Game
    New: Play->Start A Game, have "Allow other players to join" ticked, and set to LAN

    "Allow other players to join" is ticked by default, but it remembers what you last set, so if you always play Singleplayer for instance it'll stay unticked once you've set it that way.
     
    NomadKing and RavenOfCode like this.
  13. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    I just wanted to do a small fix-up update today to tidy some things up:

    2016-3 - 0.5.4.2
    - Some performance improvements, mainly on CPU (the previous terrain graphics upgrade made CPU performance worse)
    - Added some grungy texture to scene objects in general
    - No more lag spike (one-frame FPS drop) the first time wreckage spawns
    - Added a little help dialog thing when first playing a game to point out adding AI players
    - Added hover tooltips to the server list that show the full game name, in case it doesn't fit
    Bug Fixes:
    - Got rid of grass growing through evac pads on the test map
    - Missing button click sounds added to lobby screen
    - Fixed AI info in the server list going away after 30 mins when the lobby refreshed

    By the way, I'm also aware that running the game in DirectX 9 mode (if you don't have a DirectX 11 compatible graphics card) at the moment causes some issues with how the terrain looks. I'm looking into it.
     
    NomadKing and RavenOfCode like this.
  14. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Super secret new content preview, #1/10.

     
    NomadKing, Karearea and RavenOfCode like this.
  15. Venryx

    Venryx

    Joined:
    Sep 25, 2012
    Posts:
    444
    Wow. Yeah, I can see that playing a bit differently than the other maps.
     
    RavenOfCode likes this.
  16. Karearea

    Karearea

    Joined:
    Sep 3, 2012
    Posts:
    386
    Rimutaka map!
     
  17. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Funnily enough that particular stretch of map is actually loosely based on the terrain at Arthur's Pass.
     
    NomadKing, RavenOfCode and Karearea like this.
  18. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Scraps got through to be one of the games in the Play By Play exhibition in Wellington later this month.

    Play By Play is a new little games expo this year, started by a few locals: http://playbyplay.co.nz/schedule/

    It should be a pretty cool showcase of locally-made games. Stuff like Swordy, Poly Bridge, Automation... and there's an Australian games section too!



    Scraps please don't crash because I won't actually be there to check on it.
     
    Last edited: Apr 11, 2016
    RavenOfCode and NomadKing like this.
  19. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    RavenOfCode and NomadKing like this.
  20. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,461
    Is the super secret content an open world RPG mode? Do we get to fight dragons and equip swords on our vehicles?!?!?! :p

    Congrats on the Play By Play exhibition, hopefully it went by with minimal crash related issues ;)
     
  21. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Oh man, an open world vehicle combat RPG would be awesome, but it'd take a team to make!

    Anyway, didn't win at PlayByPlay but that's all good; here's

    --Super secret new content preview #2/10--​

    I made some stationary gun turrets to use for the currently-in-development new game mode.





    I've also written some simple AI for them.

    Note that generator and those heat-sinks: They also have inter-dependent functional parts like vehicles. Here's a demo video of everything where I explain what's going on:



    By the way, I didn't really mean to take two weeks between super secret new content previews - subsequent ones may be closer together. I managed to reproduce a stack overflow crash that I've been seeing sometimes come up in automated error reports, but haven't been able to reproduce myself until now. So I've been looking into that as well and it's been a bit of a rabbit hole.

    At the moment if you run Scraps for more than an hour or two in one game (without quitting to the menu and starting a new one), and there's heavy action like seven AI all fighting, it might occur. It shows itself in a way where the game will still be running but it'll be behaving strangely and weapons won't seem to do damage anymore.

    It's proven very elusive and frustrating to track down. The stack overflow doesn't include a stack trace or any additional information with it. I think it's related to a memory leak but the memory leak itself is proving very difficult to find. A leaked object like a vehicle mesh would be easy to detect, but instead it's data on the heap and the Unity engine allows me no way to see what's on the heap, just that the heap size keeps growing. I've spent too long trying different things and checking old versions already so I'm going to keep working on new content by day, and hack apart a branch when I've got time in the evenings, until I've unveiled the culprit there as well.
     
    RavenOfCode likes this.
  22. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    This week I made a flying drone enemy type.



    They track you, zip around the place, and are fun to shoot.

    Initial tests were interesting, almost boids-like:



    I found that for the drones I could use a surprising amount of the same code I used for the turrets which was nice. Apart from the actual flying code, a drone is pretty much a turret that moves. And similarly to the turrets I showed last week, they're made of functional parts just like vehicles. Here's a group of them where the one on the right has lost its heat sink and is starting to overheat, and another gets it heat sink shot off:


    (sorry for the huge gif! Webm support will get better one day...)

    I gave the drones some basic AI. I won't claim it's anywhere near as interesting as Dave's vehicle AI but it doesn't need to be in this case. They don't "fake" their flying though, they thrust around with real physics, so of course you can shoot or crash into them to throw them off. Hitting stuff way up in the air is tricky and not really good fun, so I've designed them to hover along close to the ground.

    You can see the physics at work in this scenario when I first gave them weapons...



    Yeah so, standard recoil is a bit much for them. Hence I must confess they are cheating a little now: It was either spend ages writing some smart AI that'd attempt to counter weapon recoil while flying somehow, or just let them have less recoil on their guns. I hate it when AI gets to cheat (vehicle AI never cheats by the way, it only sees what it can actually see and collects only scrap that it really collects) but the pragmatic choice here was obvious. So the drones you see elsewhere in this post are using specially engineered reduced-recoil MMGs.

    See you next week.
     
    NomadKing, HakJak and RavenOfCode like this.
  23. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Just dropping by to say I'm in love with your project. Keep up the great work!
     
  24. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thank you!
     
  25. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Super Secret New Content Preview #4/10



    Scraps vehicles so far always ostensibly have a human driver in a cockpit. Even if they're actually controlled by the AI, there's a cockpit that a person can fit in.

    I wanted some mini vehicles as a sort of starter enemy, more like a ground-based fancier version of the drones I showed earlier. Easy enough to code because they're still vehicles, but different. Instead of a human driver in a cockpit they have a Brain CPU.




    It's still a key component of the vehicle so the vehicle is lost if it's destroyed, like with the standard cockpits.

    I made it a micro chassis to use, that'd be too small for a normal cockpit.



    To be clear, the CPU cockpit and micro chassis aren't player usable, at least not with my current plans. They're just for fighting against. Look how cute it is though.





    I'm going to be away on family business for a few days next week (actually I'm already away now!) so I'm not sure if Super Secret New Content Preview #5 will make it on on schedule next weekend. But I'm hoping I'll get enough work time in that it will.
     
    NomadKing and RavenOfCode like this.
  26. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Super secret new content preview #5/10: Road Encounter

    A small taste of things to come.

     
    NomadKing and RavenOfCode like this.
  27. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Super secret new content preview #6/10: Less of a preview, more of a discussion

    For the first couple of days this week I was working on something that I then decided against. I've got other work done but it's not really ready to show, it's mostly just code that doesn't visibly do anything yet. So let's talk about the other thing I was working on because I'm interested in what people think as well. I do apologise that this isn't much of an interesting "preview."


    Part Wreckage
    Ever since I started working on the scrap wreckage system for Scraps, I intended there to be two types of drops. When you destroyed parts, you'd be able to collect general wreckage that was like cash you could spend on parts during a game, after using an Evac Pad. That part's in the game now. But there was also meant to be a chance that a whole part would drop when you destroyed one on an enemy. They'd have some amount of damage already applied like say 0-50%.

    This got left out initially just so I could get the game out a bit sooner, but I wanted it for the new game mode. Some code was there, and I started adding the rest to get it all working. I got as far as having the part wreckage spawn, but not as far as making the interface for you to spend it, before I changed my mind.



    My original idea was that if you picked up a part, it'd now be a free part to use on the Build screen (if you used an Evac Pad - if you died you'd lose it like with wreckage scrap). And so you could end up with a conglomerative scrap creation built of all sorts of scavenged parts, and I figured that'd be cool. But I weighed up the pros and cons again as I was restarting work on it, and I came up with:

    Pros:
    • Interstate '76 did it and it was cool. At the end of each mission you'd get salvage parts you could use to slowly upgrade your car. They'd have damage to repair as well. And it was fun.
    • It'd make enemy drops basically like a loot system in an RPG, which is a time-tested effective system. General scrap drops are like coins and part drops are like gear/items.
    • It'd encourage interesting builds and often it is limitations that end up inspiring real creativity. Plus it'd provide more variation to the game in general. Work with what you've got, try new things, and building ridiculous vehicles out of a bunch of scavenged parts is well within the Scraps philosophy.

    Cons:
    • Interstate '76 is a different game to Scraps, and while it worked well there, you couldn't buy parts at all – it was all salvage. So the parallel doesn't quite apply.
    • It could prevent interesting designs as much as it might encourage them, forcing people to use certain parts rather than follow their ideas. I've seen that Robocraft (a game with a similar concept to Scraps) recently switched from a money system to a loot drop system, and everyone hates it, because they can't build what they want. Part drops would similarly stop people from building what they want.
    Ultimately I'm thinking it's actually a better idea to leave things as-is. If I did do it, I'd certainly make it optional in melee mode (the current game mode). If I really want some special weapon to drop from some special vehicle, it could instead drop a "token" that simply unlocks that special part as available to build normally (i.e. buy it with scrap).
     
    Last edited: Jun 6, 2016
    NomadKing and RavenOfCode like this.
  28. RavenOfCode

    RavenOfCode

    Joined:
    Apr 5, 2015
    Posts:
    869
    Dropping a blueprint for buying the new parts would seem to be a good way between these to ideas. Still keeping it the way it is is fine too! :)
     
  29. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Someone reminded me about selling parts. Selling parts is another complication. If you put a part on your vehicle and then delete it, you get its current value back. But if you can sell salvaged parts for full value then the feature is almost pointless! - the only benefit vs. just getting scrap directly would be that you can't buy damaged parts so maybe you could use something that you couldn't afford new. If you can't sell scavenged parts for their full value, that's gonna be confusing if you're removing things from the vehicle to get scrap back. Not to mention complicating the code. I think this feature was a dumb idea from the start.
     
    NomadKing and RavenOfCode like this.
  30. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Super secret new content preview #7/10: "Procedural and hand-crafted"

    This update is going to end up giving away a bit about the new game mode but that's OK, I'll explain everything at preview #10 and that's not too far off anyway.

    So, in the new game mode I wanted levels that are a bit different every time. Each one short but always something new. The standard solution to that is to use procedural generation, and have the code create something that's different every time. But procedural can also mean bland, generating the same things with the same rules in different places, and for every game where it works well there's one where it doesn't.

    I'm taking a sort of a hybrid approach here which with some luck will almost give you the best of both worlds. Here's a complete map for one "world":



    That's big - it's over 7km long. But when a level generates it just takes a small chunk of that complete terrain, starting anywhere along it, and putting travel in a forward or reverse direction. I'm still tuning the exact length that'll be, but it's in the region of 1.5 or two kilometres.



    Then within that area, things get more complicated.

    Throughout the whole level the road is your guide.



    Spawn on the road, leave on the road.

    Within the level I can hand-place scenery, walls, turrets, enemy vehicles etc. A lot more stuff than the level will actually need. Then I tell the level generator OK, spawn some stuff in the level for a total of about x amount of scrap, and about 60% of it (or whatever) should be in stuff that attacks you, and the rest should be harmless (like crates). It then looks at all the groups of things and probabilities within the selected section of the map and decides what to spawn.

    I've set it up so I can pack the entire contents of the level up so instead of having a bajillion things spawned in the world and then deleting most of them (which would waste a bunch of time and RAM), everything in the level is stored only as information about that thing, and then only what's selected is spawned. Everything can be unpacked (basically, spawn everything) so I can edit it, and then packed again for in-game use. In Unity engine terms it basically stores the prefab used, the position and rotation, and then any other custom information that particular thing needs to configure it.

    But the key feature is that I've also set it up so I can create everything in groups with custom spawn probabilities. Here's an example of one group of things that could be selected to spawn:



    This whole thing - the roadblocks, the turret, and the two crates - has a "normal" chance of spawning so it has about as much chance as anything else to be selected. If it's too close to something else that's already selected, or its scrap values don't work out with what the level needs, then it probably won't be chosen.

    But within the group itself, it can choose different subsets of things to spawn as well. This subset will be chosen as soon as the level generator looks at it, so that it can know exactly what scrap value it'll have.



    The roadblocks in the middle are set to always spawn the concrete barriers OR the wooden walls, but but never both. So it'll never actually look like the above in-game.

    Neither the crates nor the turret are guaranteed to spawn at all, even if the group is chosen - you could get just the roadblocks. But somewhere between zero and all three will be chosen, with one of the crates in this case being a rarer spawn than the other. I could also set it to only spawn one thing out of three, or 1-3, or 0-2 or whatever. And the spawners can be nested so one of the choices could be another spawner with its own mix of guaranteed things and sub-choices.

    But even as it is there are 16 possible combinations of just that one small set.

    For AI vehicle spawns, I can now define patrol paths so they can patrol around, or just sit and wait.



    Right now most of the code for level generation is done, as is most of the stuff to put in the levels, but I still have a lot of work to do in actually populating levels and in the actual framework of the new game mode. Sometimes it feels like things are progressing at a decent speed, sometimes it doesn't, but rest assured that I'm working on it.

    See you next weekend.
     
    Last edited: Jun 6, 2016
    RavenOfCode and NomadKing like this.
  31. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,461
    Drones, Turrets, CPU's and Generated levels... I'm looking forward to trying out the single player mode! ;)
     
  32. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Super secret new content preview #8/10: Desert landscape

    For the new singleplayer game mode I need three maps to start off with.

    You've seen the initial Gorge map:



    Desert Map
    Now I've started on a desert map. In my mind I have this basic idea of the four classical elements - Earth, Wind, Fire, Water - where the gorge map is Earth and is sort of the starting Green Hill Zone of the thing, and the desert is Fire. Artistically though I was inspired by the real Desert Road here in New Zealand:



    Photo credit: Nicolas Leroy.

    So not a sandy desert, but more of a tussocky one left barren by volcanic activity.



    I'm still working on the look of this but here are a couple more shots:





    Other Part-Time Work
    Something else I want to let you know about in case it affects development times (I do realise I'm not churning out updates fast as it is - I really try, but doing everything yourself always takes a while). I've got some other part-time work starting this week. I've been working on Scraps full-time for years now but it's never made the sort of money one could live off. That's fine, I'm making this game because I've wanted to play it since the 90s and not because I want to be rich, but I'm going to have some other work to do on the side.

    Please don't let this worry you about Scraps ever being left unfinished. I've been wanting to play this game forever, it's taken longer than I hoped but it's really starting to look like the game I've always wanted, and unless I die suddenly I'll be working on it and it's getting made.
     
    Mister-D and RavenOfCode like this.
  33. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    No special preview this week I'm afraid, but there is a game update.

    I didn't intend to do an update right at this moment but I've finally, finally fixed a memory leak on the Scraps server that I've been trying to track down for months. I've been looking at it on and off in the evenings so that it didn't impact development on the game, but I've also really wanted to get it fixed. If you ran a game, even a single-player one, for a long time with lots of vehicles being spawned and destroyed, it'd eventually mess up and weird things would start to happen - like all damage would stop registering. It also meant that dedicated servers needed much closer supervision than they should have needed.

    In the meantime while I've been working on the new game mode I've also been fixing other things, so there are some other bonus changes here as well.


    Changelog
    2016-6 - 0.5.4.4
    - Added partial Polish translation
    - Adjusted collision damage down a little
    - Adjusted AI targeting a little. More shots at parts, less direct chassis shots
    - AI aiming calculation now takes the shooter's velocity into account as well as the target's. Be afraid
    - Made the in-game chassis colliders more detailed. Previously there was a box that could end up "protecting" some low components like small engines, with the chassis taking damage instead of the hit part
    - Adjusted some sounds and volumes of various things
    - Removed wreckage size scaling as it spawned since it looked dumb and was dumb
    - Had to exclude screen resolutions that don't match your monitor's aspect ratio due to a bug in the Unity engine. On Linux resolution reporting is too fickle to limit: If a chosen res doesn't look right, just try another one
    - Added visual indicator to health bars to help show when damage is done
    - Wreckage pickup is far more performance-efficient. No more slowdown when complex vehicles drive over wreckage.
    Bug Fixes:
    - FINALLY tracked down a memory leak on the server that was causing trouble when running the game for a long time
    - Fixed a couple of bugs with bullet spread. Machine-guns were more accurate than they looked visually (they match the visuals now)
    - Projectile trail FX angle fix

    2016-4 - 0.5.4.3
    - Improved AI pathing quite a bit
    - If AI gets stuck persuing in a circle, it'll eventually break out
    - Updated the vehicle/environment shader look a little
    Bug Fixes:
    - ATI cards that didn't support DirectX 11 had some issues with the new terrain shader. Disabled some features if ATI+DX9 is detected to help the look


    Info on the leak
    The Scraps server was slowly using up more and more RAM, until eventually the whole thing would crash with a stack overflow exception. But the stack wasn't the problem - it was the heap.

    I knew that it was the heap because looking at the Unity profiler, it appeared that all objects were being garbage collected just as they should be, but the thing that grew was Other->ManagedHeap.UsedSize. In other words things on the heap were getting allocated and not deallocated, so the heap had to keep growing when new things were made.

    Unfortunately in Unity it's impossible to inspect the heap, although it is now possible on platforms that use IL2CPP. Being able to inspect the contents of the heap would have solved this much faster.

    I fairly quickly worked out that creating and destroying vehicles was the problem, but the profiler reported that everything on the vehicles was successfully destroyed. Yet the leak implied something big was being held onto. There had to be a reference somewhere to something on a vehicle from something outside of the vehicle, that never got freed.

    My eventual discovery after slowly hacking pieces of Scraps apart was that it was an event subscription to an event on a static class.

    Scraps parts have a Health class that's a MonoBehaviour, and Health has a non-MonoBehaviour class that acts as a sub-component to do different things depending on whether this is a client or server machine (remember that this leak only happened on the server).

    When the health script was created, the member class subscribed to a static tick event on a static clock class that the server has. When the health script was destroyed, it run its explosion effects and all that, and also told the member class to unsubscribe from its event... most of the time.

    The problem was that the Health script's call to the member class wasn't in its OnDestroy, it was in another method that did all the destroying actions for the part and then called Destroy() itself - and that method didn't get called in every situation. Thus sometimes the event never got unsubscribed, and the reference to the member class was held by the static clock class forever, preventing it from being destroyed.

    Much more was being retained on the heap than just that one class, so my theory is that Unity was managing to remove the vehicle's data on the C# side, but not in the C++ back-end. Thus the profiler would show that every object was destroyed successfully, but in fact the static clock class' reference held onto the non-MonoBehaviour class which in turn was holding onto the whole vehicle part with its memory-consuming mesh and textures.

    To fix the issue for certain I basically just moved the cleanup code into the OnDestroy of the Health script, guaranteeing that if the script is destroyed, its member class gets cleaned up as well.

    TL;DR: If your heap is growing forever and you aren't leaking any objects, one thing to look for is events that mightn't be being unsubscribed. And don't think that a GameObject being gone means it's necessarily really gone.
     
    RavenOfCode likes this.
  34. Venryx

    Venryx

    Joined:
    Sep 25, 2012
    Posts:
    444
    Thanks for the explanation. I love reading about tough problems being solved/figured-out by other game-devs.
     
    Nition likes this.
  35. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    So do I! The Return of the Obra Dinn thread on TIGSource is really good for that sort of stuff. It's a Unity game.

    I've been working on the third and final terrain type I want for the initial release of the new singleplayer mode. To complement the existing Earth/Fire worlds, the next element is Water. Cold water.





    Slippery ice.





    Tune in next weekend and I'll properly explain what the new game mode actually is!
     
    Mister-D and RavenOfCode like this.
  36. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    RavenOfCode likes this.
  37. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Since I’m being slow with the next update post, here’s a sneak preview.

     
    RavenOfCode likes this.
  38. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    The first week after I made the Gauntlet announcement post was a bit of a mess and I didn't have a lot of time for Scraps work. It was getting near time for an update post and I was left wondering what I could make the next one about. What could I do in a couple of days or so? I didn't really want to do another small Gauntlet mode work post because that's all I've been doing for a while.

    So my decision was, you know what, it's time to take a short break from the new game mode work and put something new in the game, for the players.

    I looked through my figurative bag of potential parts to add and the Plasmanator came out.




    Changelog for v0.5.5.0
    - Added Plasmanator weapon
    - Replaced uLink closed-source version with uLink source code
    - Reduced network bandwidth use a little


    Plasmanator facts
    • Area effect weapon like super a Plasma Artillery.
    • Charges up. Holding down the Fire button charges it, and releasing actually fires it.
    • Drains lots of power while charging, and some power while sitting at full charge.
    • White smoke and a change in audio indicate full charge.
    • More charge = more damage and force on hit.
    • Unlocks at 4700XP.
    More charge also used to mean a faster bullet, which was nice conceptually but made it horrible to aim because you could never really get a feel for it unless you always waited for full charge. So the firing force is constant, but the hit force does increase with charge. There are bigger bullet and hit FX for the weapon for bigger charges.



    I wasn't sure how a charged weapon should handle the "R" key aiming mode where weapons only fire if they're aiming inside the circle area. It's just not a great weapon to use in that mode really - and you can of course turn it off. Currently it works the same as any other weapon, which means that the firing state cannot be active for it when it aims outside the circle. Since it charges while "firing", it will charge while inside the circle if you're holding fire, but if it goes outside the circle while being charged it'll fire off a shot since the "firing" state is turning off.

    I also wasn't sure how the AI should use it. Well, conceptually I was, but algorithmically... well, I wish I could just tell it to "behave like a human." I'd given Dave an assignment to look at it sometime but then I ended up doing it myself today. Basically I told the AI that if it's firing a charged weapon, it should release Fire momentarily to let off a shot IF:
    • Its aiming is going off-target OR
    • The weapon is fully charged OR
    • Power levels are very low (which would suggest that it won't be able to charge any higher)
    What I sometimes find is that in my code I'll go maybe a little overboard trying to find the perfect solution that covers every possible case, whereas Dave will code something super fast that's simple and yet more often than not turns out to work fine. Sometimes it'll need some tweaks and changes later, but usually the fact that it's simple at first means it's also easy to change. I feel like I might have managed a bit of a Dave-style solution here for once where I was worrying about how the AI was going to handle all these complex weapon scenarios, I ended up just adding a few simple rules, and actually it seems to do well enough to fool me that maybe the AI could even be somewhat intelligent.

    Of course as always if you find any bugs with things, please report them.

    This video was in my sneak preview update but here it is again. If you want to see something new with it, just load up the game - the Plasmanator is in the game right now!



    P.S. Take note of where your shots hit. If you don't seem to be doing much damage, you may be hitting in front of the enemy instead of directly on them. The bullets drop fairly fast so aiming a little above the target is key.
     
    RavenOfCode likes this.
  39. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    This week I fixed some bugs with the Gauntlet mode level generation and I've been testing my level generation out.

    I looked at two things that I noticed were an issue:

    Issue: A need for cover in the early game
    In Gauntlet you start with a small and cheap vehicle, and I found that you'd end up shooting a machine-gun turret with a machine-gun and it lacked much room for strategy. You can sneak up to some extent but often you crest a hill or something and you both have line-of-sight and you might as well shoot or get shot. I can beat the levels easily enough but I've been playing Scraps for years - you shouldn't have to take x amount of damage every time.

    Solution: I'm just going to add some taller barriers around the place basically, so there'll be more opportunities to approach from a strategic angle.

    Issue: Searching for that last crate
    You want to shoot crates to collect scrap, and if crates might be out in the wilderness somewhere, you're going to want to scour the wilderness to make sure you find them all.

    I knew that would be a bit of a chore, so I made most things spawn along the road that goes through every Gauntlet level. But it doesn't fix the problem because there's still some chance that things will spawn out in the middle of nowhere, so you end up going looking anyway. And removing that chance entirely would mean no reward ever for exploration, so I wouldn't do that.

    RPGs have had this problem for a long time. The theory is of course that when there's somewhere out-of-the-way to explore, you get something cool to reward your exploration. And having something there is probably better than exploring and finding nothing. But it also means now you have to explore every boring side-passage because you might miss something cool.



    Image credit: Possibly Adrian Chmielarz.

    Solution: I've added a radar mini-map so you can automatically know there's something out there from a good distance. I don't think I'd add a radar in melee mode/multiplayer because having a radar map would remove a player's ability to surprise the enemy. But in singleplayer I think it'll be fine.



    Enemy units are yellow crosses, non-threatening objects that contain scrap are blue squares. Trying to think of the colour-blind in these design choices.
     
    Last edited: Jul 30, 2016
    RavenOfCode likes this.
  40. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Weekly update time. This week I've continued working on level content and generation. I added some more content to the Earth level, and added the remaining features to the level gen that I needed:
    • Since Gauntlet levels can be played in forward or reverse direction, I added an option to include level content in one direction only (so I can do stuff like have walls that are always behind something no matter whether you're playing in "forward" or "reverse").
    • Added an automatic rotation option to mirror the direction of things in reverse mode. So I can do stuff like have turrets automatically flip to face the other way.
    • Added a specifier to have things not spawn until a certain level. Since each world (each map) will have 2-3 levels played within it, I can say something like "OK, don't have drones appear until level 2" and they won't spawn in World 1-1.



    Hopefully that's now every feature it needs. I'll really try to stick to that because I know in gamedev it's all too easy to get stuck working on the "engine" forever and never actually make the game. I also think the level gen is all working correctly now (it's a pretty serious probability-processing machine at this point), it just needs some adjustments.

    I added some giant arrows in the sky for myself in the Unity editor so I actually remember which way is the world's forward direction...



    Unity devs, call this from your OnDrawGizmos to get dumb sky arrows like me:
    Code (CSharp):
    1. void DrawGizmoArrow(float xPos, float zPos) {
    2.     Gizmos.color = Color.green;
    3.     float arrowHeight = 300;
    4.     Vector3 arrowStart = new Vector3(xPos, arrowHeight, zPos - 200);
    5.     Vector3 arrowEnd = new Vector3(xPos, arrowHeight, zPos + 200);
    6.     Gizmos.DrawLine(arrowStart, arrowEnd);
    7.     Vector3 crossLineStart = new Vector3(xPos - 50, arrowHeight, zPos + 50);
    8.     Vector3 crossLineEnd = new Vector3(xPos + 50, arrowHeight, zPos + 50);
    9.     Gizmos.DrawLine(crossLineStart, crossLineEnd);
    10.     Gizmos.DrawLine(crossLineStart, arrowEnd);
    11.     Gizmos.DrawLine(crossLineEnd, arrowEnd);
    12. }
    Oh and I modelled some of those "taller barriers" that I mentioned were needed last time.



    Gauntlet mode release TODO status:
    Bold = currently working on.
    • Finish up the level generation system - All features now in. Some adjustments still to do.
    • Populate the three maps with lots more content for the level generator to choose from - Working on map 1.
    • Finish up the desert and snow terrains
    • Write the framework around the new mode – handling game start, game end, scoring etc
    • Make some more vehicles for the AI to use
    • Add leaderboards? Or initial release might just give you a local score, and add online leaderboards later
     
    RavenOfCode likes this.
  41. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    2016-8 - 0.5.6.0
    - Reduced XP required to unlock some later parts a little. Final unlock is at 4000XP versus the previous 4700XP
    - Added eight stationary turrets to the test map to facilitate testing armour etc
    Bug Fixes:
    - Fixed several null reference exceptions that could occur when vehicle parts were destroyed
    - Players with laggy connections could still get incorrectly kicked for "cheating". Threw out that code for now: It won't kick you anymore but still needs some work later
    - Various small fixes



     
    RavenOfCode likes this.
  42. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Changelog
    0.5.6.1
    - Revamped the code that shows other player's vehicles in multiplayer. Their movement is now smoother, while not being any more delayed
    - Much improved vehicle collisions between laggy players as well. No more flying across the map!
    - Reduced some unnecessary network traffic
    - Added option to have a radar in melee games
    - Minor GUI adjustments
    Bug Fixes:
    - Hover effect no longer shows on Melee mode button while an overlay is up
    - Fixed real-time shadows not matching up with baked shadows at low graphics settings on the Test Map
    - Fixed a timing bug on joining multiplayer games that could get you disconnected with a vehicle build error



    Radar in Melee games
    I said in a previous post that I wouldn't add the radar I designed for Gauntlet mode into melee mode, because you should be able to hide from other players. But I figured it may as well be a custom option. Tick it at the lobby to enable it for everyone in the game (except AI - they still need line-of-sight to see you).




    No more inadvertently flying across the map
    This week I managed to fix an issue that's been plaguing Scraps multiplayer since it was first released, and that I actually I thought might be impossible to fix. Something that might not seem very important at the moment while Internet multiplayer is quiet, but still a relief to conquer.

    Scraps has always had an issue where sometimes, if you collided with another player and the latency between you was high, you could end up flying across the map. Like at 1:43 in this video where I'm playing from New Zealand on a US-based server:



    It was... "fun", sometimes, with quotes as necessary around "fun". It was definitely not how things should work, particularly since you could end up taking mega collision damage as well.

    To set the scene:
    • In Scraps, each client PC is in charge of the physics for their own vehicle.
    • The server also runs its own physics, but for movement it's just checking what the client said (for most other things it's the authority).
    • Other vehicles you see are sending you their positions - they're not running their own movement physics on your machine.
    • Having said that, they still need collision boxes and momentum so that you can collide with them.
    So each vehicle is doing their movement physics on their own machine, and getting sent the positions of everyone else. Since the "fly across the map" problem got worse as your latency got worse, I theorised that the problem was as follows:
    1. You and an enemy vehicle collide.
    2. Latency means that although your vehicle bounces back right away, they keep moving forward for a moment because both of you are seeing each other a little in the past, and you're only doing physics locally for yourself.
    3. They therefore clip their vehicle's collision boxes into your vehicle further than they should, sending you flying across the map due to the physics engine's repulsion force that tries to keep things apart.
    Basically their ghost invades your personal space and your vehicle tries to get away. And that would be potentially impossible to fix.

    But it turned out that wasn't the problem!


    The Real Problem part 1: How games show other players
    Let's look at how a game shows other players' positions first.



    The above applies to any real-time multiplayer game. You simply cannot know where other players are right now, because there's always some latency between your computers. There are two typical ways to handle this: Extrapolation and Interpolation.



    With extrapolation, you say OK they were here half a second ago and going this fast in this direction, so they're probably here now. But extrapolation sucks: In Scraps and especially in FPS games where players can change direction even faster. If players always ran in a straight line at the same speed extrapolation would be great, but it's just a guess and often it turns out to be a bad one -meaning once the next real position update comes through, you'll see things rapidly correct themselves to a new position.

    So usually interpolation is the way to go, in Scraps and in other games. You show the other player a little in the past (1s in the diagram above is a big exaggeration just for easy numbers. Quake 3 used 0.1s for instance), so that you can have real data on both their past and future positions, and then show a smooth movement between them. No more guessing. There can still be some issues like the "bouncing ball problem", but that's getting picky.

    Fun fact: Scraps actually dynamically modifies the interpolation delay to compensate for the latency of each player, so I can keep things smooth while also having as little delay on other players as possible. Scraps can also extrapolate a little bit, but only if it has to.


    The Real Problem part 2: The real problem
    Anyway, that's all fine and good. But in your average FPS game the other players are just a set of colliders that have no actual velocity or momentum. I mean, they "move" around, but it's more like they teleport each frame to a new position. Whereas in Scraps if an enemy vehicle collides with you they should be able to knock your vehicle away - not just keeping you out of their collision boxes but really pushing you with force based on their current velocity. They need to be actual physics objects working with the physics engine, while also just being data fed in from other PCs.

    Scraps uses a networking library called uLink, and along with uLink came an example script for just this sort of thing. They had an interesting system, and I used the same sort of system for Scraps. It worked like this:



    It only looked at the most recent data coming in from the other player, and it set their vehicle up with a velocity that would get it to that point at the right time. Therefore you had a vehicle with real physics that nevertheless always moved exactly where it was told to.

    But what I noticed last week, and what I should really have thought about in the past, was that unreliable data could cause big velocity variations (of course this is also a lesson in trusting other people's code...). For instance if you didn't get any data from the other player for a bit, their vehicle would keep moving wherever it had been going for a bit and then suddenly have to do a big correction, giving it a big velocity - whether or not it actually had a big velocity on the other player's PC (although really big corrections would just teleport instead, it wasn't that dumb).

    I noticed that the velocity actually fluctuated all the time, and I wondered why I hadn't just tried doing what a normal FPS would do, but interpolating the velocity as well as the position, like so:



    So I did that - and it works really well! Why didn't I try that in the first place? Velocity is now interpolated along with position, rotation etc. The vehicles have real physics but still go where they are told to go, and the flying-across-the-map problem ended up fixed as well. And there's no additional delay in where you see the enemy - the interpolation is set the same amount in the past as it was before. Turns out it must have been velocity fluctuations that were causing it, and what I thought was a problem with higher latency was actually a problem with less reliable connections.

    You will still see a delay on high-latency connections in the other player getting pushed back in a collision. You hit them, you bounce back, they seem to stay still for a moment, then they bounce back too. That's just because you're only doing physics for yourself, so you're waiting for the new collision to get sent out and then some back to you. The good thing is, everyone gets pushed back the right amount!

    The bad thing is... no more exciting unplanned flights into orbit?
     
    RavenOfCode likes this.
  43. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    This week I've been mostly placing content in Gauntlet mode levels. I did make an SMG drone as a less deadly version of the the existing MMG drone:



    I also made a little Unity editor prefab placer script which I'll share.



    It lets you spawn arbitrary prefabs with the buttons, and it automatically raycasts to the ground and places things there. You can show a visual indicator for placing invisible prefabs, and there's an option to give things a random starting rotation. You could also rotate the selected object with the keyboard like in the gif above, but for some reason it often ran at like 1fps and was horrible to use, so I've removed that feature.

    The code isn't anything special because it's just meant for my personal use in the editor, but I'll share it here as I think it could be useful to other unity devs. If you're using it, read the code comments as there are some changeable things within, but it should work as-is as long as you replace the paths in LoadPrefabList with your own:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using UnityEditor;
    6.  
    7. // GUI editor interface for easily placing a set of hard-coded prefabs on a map
    8. public class SimpleThingPlacer : EditorWindow {
    9.     // Set in inspector. Have this enabled to give prefabs a random starting rotation
    10.     [SerializeField]
    11.     bool randomYRotation = true;
    12.  
    13.     // Got prefabs that don't have a visual model? Put their GameObject names here to see a visual indicator when holding them
    14.     readonly string[] prefabsThatNeedVisualIcons = {"VehicleSpawner"};
    15.  
    16.     // Your prefabs can be assigned to categories you define here, and will show up in these groups in the editor window
    17.     enum Categories { NonEnemy, Enemy, Group }
    18.  
    19.     Dictionary prefabs;
    20.     GameObject curHeldPrefab;
    21.  
    22.     // #### UNITY INTERNAL METHODS ####
    23.  
    24.     protected void OnGUI() {
    25.         if (Application.isPlaying) return;
    26.         if (prefabs.IsNullOrEmpty()) LoadPrefabList();
    27.  
    28.         EditorGUILayout.BeginVertical("Box");
    29.         randomYRotation = EditorGUILayout.Toggle("Random Y rotation: ", randomYRotation);
    30.         EditorGUILayout.EndVertical();
    31.  
    32.         // This is pretty basic - could be modified to auto-set NUM_PER_ROW based on window width
    33.         const int NUM_PER_ROW = 3;
    34.         const int ENTRY_HEIGHT = 64;
    35.         const int ENTRY_WIDTH = 80;
    36.         foreach (KeyValuePair category in prefabs) {
    37.             bool isInRow = false;
    38.             EditorGUILayout.BeginVertical("Box");
    39.             EditorGUILayout.LabelField(category.Key.ToString(), EditorStyles.boldLabel);
    40.             List p = category.Value;
    41.             for (int i = 0; i ();
    42.  
    43.         // Replace these with the paths to the assets you want to show up
    44.         // Or these hard-coded paths could be replaced by automatically loading all assets in a folder etc
    45.         // Or maybe create an interface in the editor window itself to add/remove prefabs
    46.         AddPrefab(prefabs, Categories.NonEnemy,  "Assets/Prefabs/Environment/SinglePlayerPhysicsDamageable/Walls/WoodenWall.prefab");
    47.         AddPrefab(prefabs, Categories.NonEnemy, "Assets/Prefabs/Environment/SinglePlayerPhysicsDamageable/Walls/ConcreteBarrier.prefab");
    48.         AddPrefab(prefabs, Categories.Enemy, "Assets/Prefabs/EnemyNonVehicles/Drones/MMGDrone.prefab");
    49.         AddPrefab(prefabs, Categories.Enemy, "Assets/Prefabs/EnemyNonVehicles/Drones/SMGDrone.prefab");
    50.         AddPrefab(prefabs, Categories.Group, "Assets/Prefabs/GauntletSets/GauntletEarthRoadblock1.prefab");
    51.     }
    52.  
    53.     // Path should start with the Assets forlder, e.g. "Assets/Textures/texture.jpg"
    54.     void AddPrefab(Dictionary prefabDict, Categories category, string path) {
    55.         GameObject prefab = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
    56.         if (prefab != null) {
    57.             ISpawnedThing ist = prefab.GetComponent(typeof(ISpawnedThing)) as ISpawnedThing;
    58.             if (ist != null) {
    59.                 if (!prefabDict.ContainsKey(category)) prefabDict[category] = new List(1);
    60.                 prefabDict[category].Add(prefab);
    61.             }
    62.         }
    63.         else {
    64.             Debug.LogWarning("Couldn't find prefab at: " + path);
    65.         }
    66.     }
    67.  
    68.     void CreatePrefab(GameObject prefab) {
    69.         curHeldPrefab = (GameObject)Instantiate(prefab);
    70.         // Remove any automatic "(clone)" designation
    71.         curHeldPrefab.name = prefab.name;
    72.         if (randomYRotation) {
    73.             Vector3 eulerRot = curHeldPrefab.transform.eulerAngles;
    74.             eulerRot.y = Random.Range(0, 359);
    75.             curHeldPrefab.transform.eulerAngles = eulerRot;
    76.         }
    77.         Selection.activeGameObject = curHeldPrefab;
    78.     }
    79.  
    80.     void ReleaseHeldPrefab() {
    81.         curHeldPrefab = null;
    82.     }
    83.  
    84.     // Returns true if the input transform or any of its parents, grandparents etc have the specified tag.
    85.     static bool HasTransformInAncestors(Transform trans, Transform match) {
    86.         if (trans == match) return true;
    87.  
    88.         trans = trans.parent;
    89.         while (trans != null) {
    90.             if (trans == match) return true;
    91.             trans = trans.parent;
    92.         }
    93.         return false;
    94.     }
    95. }
    96.  
     
    RavenOfCode likes this.
  44. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Last week I got a nice job offer that I've accepted, but it had to be a full-time position, so it's not going to leave much remaining time for Scraps unfortunately. It's an offer that I would be silly to ignore in favour of my obscure little game that I've already been working on for years without much success (income-wise anyway). Of course Scraps could take off in success after Gauntlet mode is added, or after it leaves Early Access, but historically that's very rare: Almost always if a game's sales are slow at first during Early Access, they remain a small-time thing at full release.

    So I'm going to stop the current weekly news updates since development is gonna get real slow. I'll post whenever I have interesting new stuff to share instead.

    Here's what I did in my last week of freedom:

    I made some more level content. Yeah, I'm still on world 1, because I keep making things like tools for level building or things to put in the levels rather than actually putting things in levels. Subsequent maps should be way faster to populate, like how the terrains for worlds 2 and 3 were done much much faster than the terrain for world 1.


    A thing I did this week in that vein was make a new type of vehicle spawner. I already had vehicle spawners that I could place on the map with a list of vehicles they could spawn. Looked like this in the editor:


    When playing, they'd randomly select a vehicle to spawn from the list, and that worked OK. Gauntlet mode is sort of half procedural, half hand-placed, and it's important to be careful with how procedural it is. Fully hand placed would make it exactly the same every time, which would get boring fast. But fully procedural almost always ends up boring as well - a million variations on the same thing. No Man's Sky is the procedural game du jour to complain about, but there are many.

    However, in this particular case I realised that there were many scenarios where I really just wanted a vehicle spawner that would spawn any vehicle I had that was appropriate for the current level. Same potential set for every spawner. On top of that, really the vehicles should get harder as you progressed to another level within the same world, but to do that currently I'd have to place multiple spawners and limit them to just the level they were intended for.

    So I made a vehicle library that loads up all the vehicles I've put in a folder, and lets me select them with filters. For instance if I wanted a vehicle in a certain price range with only cheap weapons on it I could do:

    Code (CSharp):
    1. vehicleLibrary.GetVehicle(VehicleFilters.TotalCost(minValue, maxValue),
    2.     VehicleFilters.EachWeaponCost(weaponCostLimit));
    Or for a vehicle in a certain price range with a small chassis:

    Code (CSharp):
    1. vehicleLibrary.GetVehicle(VehicleFilters.TotalCost(minValue, maxValue),
    2.     VehicleFilters.ChassisType(VehicleData.ChassisOptions.Small));
    "But writing code every time? That sounds like even more work than placing two spawners." Well yeah, it would be, but I made a new vehicle spawner that automatically detects which Gauntlet level the player is on and sets the appropriate filters. So there's no vehicle info to set in the interface at all:


    And I can still use the old spawner type if I want specific vehicle options.

    In other news, at one point I also accidentally broke everything in a fun way:

     
    RavenOfCode and Venryx like this.
  45. Venryx

    Venryx

    Joined:
    Sep 25, 2012
    Posts:
    444
    Sad to hear (as a fellow Indie), but makes sense I suppose.

    Despite that, congrats on making a quality game pretty much on your own, and releasing it on Steam for the world to see. : )

    You've already made it much farther than most, and there's plenty of time for you to make more attempts in the future. (I think so anyway; you looked pretty young in the pictures on your blog (or wherever) from what I remember. Haha, now's where you correct me and tell me you're actually 80 and on your death bed...)
     
  46. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Nah, I'm not a kid but I'm not ancient. Scraps is my first major game project and hardly anyone has a super successful first commercial game. It's just life really. I wrote a bit more in-depth about what I'll keep doing Scraps-wise in the version of my post that's on scrapsgame.com: http://www.scrapsgame.com/weekly-update-semi-bad-news-scraps
     
    RavenOfCode likes this.
  47. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    You guys will know that Unity's terrain system has a special system for trees, separate from the one for placing glass and other detail stuff. Your trees must use two specific built-in shaders. Your trees must reside in a folder with the text "Ambient-Occlusion" in the name. They may have colliders, but other components on them will be ignored.

    I tried the tree system out, I haven't used it before. It's got some nice features - for instance it'll automatically turn your trees into billboards at long distances to save rendering work (much like Jurassic Park: Tresspasser did way back in 1998). Although even that has its quirk - the billboards have a slightly different perspective to the meshes so they do some weird bending as they switch over.

    I had it all working actually quite well, but the killer was the lack of support for custom components. The trees would have to be permanent; immovable. Scraps with indestructible trees? It wouldn't do.



    Look at that realistic tree-smashing action (pls don't destroy trees IRL).

    So anyway I added some trees.



    (not to SandyBridge - I was just testing them there)

    They're not using the special tree system. They're just meshes with a couple of LODs. LODs being levels of detail - showing the lower LOD at far distances. Works fine.

    The trees I have actually came with two LODs already, but I wasn't exactly impressed. Does this look like a seamless transition to you?



    The branches are fine. The leaves not so much. So I made my own low LOD versions that aren't particularly great either but everything looks OK.



    I'm still adding level content. Each "world" in Gauntlet mode is big - but at least it does get reused for three levels. My new job is taking up a lot of time as I knew it would, but I'm still managing to get a little Scraps work done. See you next time.
     
    RavenOfCode likes this.
  48. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thank you for your extreme patience as I continue to bumble along with this game in what spare time I have. Last update, I suggested that I'd get Gauntlet mode's World 1 finished, and then work on the framework for Gauntlet mode iteself. In the end I decided to get the first two worlds done first, since both will be needed for a playable release of Gauntlet anyway. I've now got the content for the first two worlds complete.

    The Gauntlet mode worlds will be loosely themed on the classical Greek elements: Earth, Water, Wind, Fire. Earth and Water now have all their content, and if I give them three levels each, that'll be enough for an initial release of the new game mode that you can try out. As in an actual game update, not just more progress news like this. What I still need to do first is write the framework around the new mode: How you enter levels, progress through them, repair between levels etc. It's stuff that's mostly in the game already but it needs to be strung together correctly and have some new concepts added. At the moment to test Gauntlet mode, I use dev tools to select a vehicle and drop into a level manually. I'm afraid I don't have a release time estimate because the amount of time I have for Scraps currently varies a lot week by week. It'll get done.

    I've also been making a few other changes to the game as I go, that'll make it in when Gauntlet launches. One I can show off is a new primary firing mode:



    It's something that was brought up in the forums a while ago. People were carefully building vehicles that didn't have quite enough power supply for their weapons, so the weapons would end up dropping down into a sequential firing mode instead of all firing at once - meaning less recoil, and more spread out power and heat. Now that mode can be automatic, but the old mode is still there as well. There isn't really any additional complexity to worry about for the player - left-mouse will be the new mode, or right-mouse will fire using the all-at-once mode that's in the game now.


    Some new screens of the Gauntlet worlds I've been making
    EARTH is sort of the Green Hill zone of the thing. It's grassy hills and rocks and trees, and combat is against lewer-level enemies: Basic machine gun turrets, mostly micro vehicles, hover drones.



    WATER is snow and ice. AI vehicles are more expensive and more frequent, turrets are more powerful, and drones are less common. But your vehicle will be more powerful too.

     
    RavenOfCode likes this.
  49. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    I'm going to try and post news about what I'm working on a bit more often again. Here's my list of what I need to do for an initial Gauntlet mode release:


    Gauntlet tasks to do before initial release
    - Get local games fully working - DONE
    - Object for holding game state in Gauntlet mode
    - Auto-repair system + vehicle swap ability
    - Gauntlet game flow from menu to end
    - Score system
    - Level generation tweaks
    - Update scrap drop system
    - Item unlock system
    - Update How To Play screens
    - Test and balance gameplay
    - Music?

    Looks a bit long and scary, and yes it is rather a lot, but not all of those things are major. I thought the first one was pretty major and I've already got it done. What I'm going to do is, each time I complete one of those, I'll make a post and talk about that line item in more detail. When they're all done there'll be a real game update.

    Let's talk about "Get local games fully working".

    Local Singleplayer
    I'd like to start with Minecraft as an example here. When Notch originally made Minecraft, the singleplayer and multiplayer components of the survival mode were separate. Bugs would often appear in one but not the other - usually multiplayer because networking is hard, man. A lot of work had to be done twice, in the singleplayer game and also in the multiplayer one. I read an interview somewhere where Notch mentioned that one thing he'd have liked to have done differently was going fully multiplayer from the start, and having the singleplayer just run on a local server. Eventually that's exactly what happened: The game was changed to be always multiplayer behind the scenes, and that's why anyone can easily join your singleplayer game on LAN now if you choose to open it up.

    When I built Scraps I decided that likewise, having one networked system that everything used was the way to do. In the interests of simplicity, the Melee game mode always runs a separate server. That's why it was easy to add the "Allow other players to join" option to singleplayer games. Whether you host a multiplayer game or whether you start a singleplayer game, a local server starts up and you silently connect to it.

    I don't think I made a mistake in doing it that way because it works well, but there is an effect on CPU performance because some calculations have to be done twice (the graphics card gets away free here because I run the server with no graphics). For Gauntlet mode I want to have good performance on moderate PCs even on later levels with big vehicles, and getting rid of the need for the server is an obvious win there. Plus I'd done a lot of the work already as I'd needed it in the past for testing. The changes basically entailed writing new paths for things when there was no network present, so what usually had to wait for server confirmation etc would do its own thing.

    Now, converting a singleplayer game to multiplayer is always a big job, sometimes such a major change it's just about impossible. But converting a multiplayer game to singleplayer has been a lot easier! Not least because things always get simpler rather than more complex. This class structure in Scraps:



    becomes this:



    I've actually still got a couple of minor issues to fix but it's basically all working. As a bonus, when the Gauntlet update comes out you'll also be able to play the Melee game type in a true local mode - I've got that working as well - if you have "Allow other players" unticked:



    That should give a bit of a performance boost for people with low-spec CPUs (to be clear, you won't see this performance boost now, it'll come with the Gauntlet update).
     
    MD_Reptile likes this.
  50. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    The "Object for holding game state in Gauntlet mode" list entry is done, but the news post I did for it has a lot of pretty basic technical stuff that actual game devs on these forums probably already know. I'll just link it from here for those interested rather than including it all: http://www.scrapsgame.com/gauntlet-game-state-object-technical-rambling