• What are you working on? v67 - March 2017
    3,527 replies, posted
[QUOTE=r0b0tsquid;52616167]Does anyone else have useful little commands like this in their aliases file [cpp]# Git ... alias fuckit="git commit -am 'fuck it'" alias FUCKIT="git add .; git commit -m 'FUCK IT'; git push origin --all"[/cpp][/QUOTE] No but I'm stealing that one for work
Proof of concept formatting for a terminal emulator. The first line is the text and the second line is the associated color. When I actually start working on the display part, each letter will be colored. It uses fmtlib under the hood so it has a lot of great formatting options from the get go. [img]http://i.imgur.com/n1AOYqr.png[/img]
[QUOTE=FalconKrunch;52615564]I like to use a combination of coroutines and delegates for my AI behaviours ...[/QUOTE] Yeah I'm doing it quite similar to that but breaking the behaviour into different classes, so there's a class for combat, a class for moving, and now a class for woodcutting. Here's my woodcutting: [code] public void Init(CharacterNPC npc) { _inventory = npc.Inventory; _movement = npc.NPCMovement; _combat = npc.NPCCombat; npc.AnimEvents.Attacking.Subscribe(value => { if (value && CurrentTree != null && _currentWood < _maxWood) { CutTree(); } else { if (CurrentTree != null) { CurrentTree.Disengange(gameObject); } CurrentTree = null; } }); } private void CutTree() { _inventory.AddItem(ItemId.Wood); if (CurrentTree.Health.Current.Value <= 0 && !CurrentTree.Cut) { var force = (CurrentTree.transform.position - transform.position).normalized; CurrentTree.Timber(force); CurrentTree = null; } } public Transform FindTree() { var transforms = Physics.OverlapSphere(transform.position, _treeSearchRadius, _trees).Select(x => x.transform).ToArray(); if (transforms == null || transforms.Length == 0) { return null; } var closestTransform = Vector3Utils.GetClosestTransform(transforms, transform); var closestTree = transforms.FirstOrDefault(x => x == closestTransform).GetComponent<ResourceTree>(); if (closestTree != null) { CurrentTree = closestTree; } CurrentTreeCuttingPosition = CurrentTree.Engage(gameObject, CurrentTree.DesiredPosition(transform)); return CurrentTree.transform; } public void TaskUpdate() { Vector3 treePos = Vector3.zero; if (ShouldFindNewTree) { FindTree(); } else if (MaxWoodReached) { IsCuttingTree.Value = false; } if (ShouldNavigateToTree) { _movement.NavigateTo(CurrentTreeCuttingPosition); } else if (ShouldTurnTowardsTree) { _movement.StopMoving(); _movement.LookAndDo(CurrentTree.transform, () => { _combat.InitAttack(CurrentTree); IsCuttingTree.Value = true; }); } } [/code] Also yes I see the point of coroutines but my experience is to avoid them and use something else like Observables from [url=https://github.com/neuecc/UniRx]UniRX[/url] instead. They're more powerful and less weird to wrap your head around. Enumerators for handling 'concurrent' tasks...? It's strange.
[QUOTE=FalconKrunch;52615564]I like to use a combination of coroutines and delegates for my AI behaviours. For example in unity [CODE] void Start(){ StartCoroutine(SimpleAILoop()); } Tree FindTree(){ //Tree finding code } IEnumerator SimpleAILoop(){ while(true){ Tree Tree = FindTree(); yield return StartCoroutine(WalkTowards(Tree)); yield return StartCoroutine(CutWood(Tree)); } } IEnumerator WalkTowards(GameObject Target){ //Walking code goes here } IEnumerator CutWood(Tree Tree){ //Cutting code goes here } [/CODE] Assuming all functions work properly, the AI actor will now walk towards a found tree, and start cutting it, in an endless loop. But this is pretty linear, so you can break it up by having WalkTowards fire a delegate, which you can then listen to and do stuff with. [CODE] delegate void OnArrivedAtTargetDelegate(GameObject Target); OnArrivedAtTargetDelegate OnArrivedAtTarget; void Start(){ StartCoroutine(SimpleAILoop()); } Tree FindTree(){ //Tree finding code } IEnumerator SimpleAILoop(){ OnArrivedAtTarget += (GameObject Target) => { if(Target == Tree)//simplified CutWood(Target); } while(true){ Tree Tree = FindTree(); yield return StartCoroutine(WalkTowards(Tree.transform.position)); OnArrivedAtTarget(Tree); } } IEnumerator WalkTowards(Vector3 Position){ //Walking code goes here } IEnumerator CutWood(Tree Tree){ //Cutting code goes here } [/CODE] Don't mind the complete lack of casts and stuff, can't be bothered to write that much, there's also issues now with the AI always walking towards a newly found tree, but this example is just to show you the general idea of what I mean. Now the code flow is a bit different, rather than always being linear, we can now check in a very isolated scope what kind of object we reached and what to do with that information. Delegates + lambdas in combination with coroutines is a very powerful tool in your programmer toolbox, so I suggest getting familiar with them as soon as possible.[/QUOTE] Have you considered using .NET 4.6 with Unity so you can use real async methods instead of the IEnumerable hackjob that it uses on the ancient Mono version?
Real async is also good, a step up from coroutines for sure. But it's not like reactive extensions though (?), you can't subscribe to things and do stuff like 'OnEveryUpdate'?
Denmark is having municipal elections in November, so I thought it might be interesting to look at the election data from 2013. When I did, I found a pretty clear difference between voting distribution in the poorer neighbourhoods in my city, and the wealthier ones, as well as between poor municipalities and wealthy ones. I thought it'd be interesting to make an interactive map of this, so it's been my project this weekend. This is what I have so far: [img]http://i.imgur.com/qRYXQyP.png[/img] I used Python to scrape the election data from [url]http://www.kmdvalg.dk/kv/2013/[/url] and fed the addresses into the Google Geocoder API to get LatLng points for every voting location within each municipality, and then used d3 to generate a voronoi diagram of these points, which I then overlayed on a Google Maps API map. When you click on a voting location it changes the display on the right to show you the information for that location. My plan is to have alternate views for it, so there's this per-location one. There will also be a per-municipality view. I also have a vague idea for showing relative voting presence of each party at all the locations, to see where the different parties are strongest, and to hopefully see clear divides within municipalities. My stretch goal is to collect some kind of economic data to compare with as well, but I have no clue how I'm gonna go about doing that. Bonus image of voronoi'd Denmark cause it looks kinda cool: [img]http://i.imgur.com/yqp1hcg.png[/img]
And now with more proof of concepting (using the shitty windows terminal coloring, had to enable it). [img]http://i.imgur.com/jC8fxf5.png[/img]
I want to do raycasting with variable sized walls. Maybe a tall building in the distance, maybe a short one up close. I figured I could do this by allowing rays to pass through walls, so that anything behind the wall that's larger than the current one will be drawn also. Add all vertical lines to some data structure and sort them based off of distance. further lines will be drawn first, closer lines drawn second. If, while sorting the DS, there are lines in the distance that are smaller than the ones up close (a building that is shorter than the one up close and therefore obscured by the closer building), drop them from the DS so as not to waste draw calls. I could make it some kind of max distance that the ray could travel, or I could make it simply so the ray travels to the edge of the map (or at least to the edge of the current partition of the map) before ending. I'll have to test it and see how it actually performs
Working on some specialised shaders for stylized rendering in Unity (also making a game prototype in the process). Lit + depth tested particles = volumetric explosions: [img]https://puu.sh/xlTEq.png[/img]
Serialisation can be a bitch so here's how I did it in one pass. This is a C++ project with pointers up the wazoo, cycles all over the shop. Pointers are non owning (except classes that manage pointers, which are a single digit number and represent memory management for major systems) so this isn't a code design issue, but it presents obvious problems for serialisation. I'm mostly sticking this here as c++ docs recommend a 2 pass approach, but I found it significantly easier to implement a 1 pass approach There's 4 main types of thing that you'll need to turn into byte form in C++ 1. Stuff that can be just straight up interpreted as bytes 2. Stuff that can't just be straight up interpreted as bytes, because it contains pointers or containers or whatever 3. Containers 4. Pointers So. 1. is fairly straightforward to serialise, you just take a char pointer to the struct and hide the bytes somewhere 2. is less straightforward. The solution I came up with is to make every non trivial class inherit from 'serialisable', which has a do_serialise method. This takes a serialise object which performs serialisation (and stores state), and a bool representing either encoding or decoding When implementing the do_serialise method for 2, it calls serialise_state.handle_serialise(object, should_encode) for each member (that you want to serialise or deserialise). This method figures out if what you're passing is standard layout and not a base of serialisable, in which case it does the byte representation method which accumulates into serialise_state. If its type 2 (and not a pointer). it recursively calls do_serialise. This is great and means you have a nice uniform api for dealing with stuff. It also figures out if its type 3/4 3. Containers. All containers have a size, and whatever ordering you pass in. So its fairly easy to stash the size on saving then dump the contents of the container by calling serialise_state.handle_serialise(element, should_encode). You can then simply load the size by doing the opposite Its important to use the uniform API here as it means that containers work regardless if they're holding standard layout simple types, or complex types that have a do_serialise method 4. Pointers are obviously the giant twat here, but this turned out to be much simpler than I expected Serialisation here will for me being used for networking as well, so there's a small detail here that each serialisable object knows who it was originally created by. So, massive caveat: Every object that has a pointer to it that needs to be serialised is a 'complex' object with a do_serialise method. This constraint is fine for me, but you could likely work around this. Every serialisable has an ID which is unique (simple increment) When saving a pointer, you look up its serialisation id. You stash this (and its owner) to a file. Then, you check if we've ever encountered this before by saving the pointer in a lookup table by its id (and owner). If we've ever encountered it before, you're done. If we haven't, serialise the data held by the pointer. This neatly handles cycles and references and ownership, and makes sure we never don't save something When you load an object that you expect to be a pointer, you simply lookup its owner and id. You then check the global state for whether or not we've found this pointer before. If we haven't (and the pointer isn't null, you have to check this manually), you allocate new memory and deserialise in the data that you know will be there (this means that it works with pointers inside containers due to it all composing nicely). Otherwise you simply copy in the pointer you found in your nice global table This has been by far the best implementation of serialisation I've done so far, because it does not require you to save any information about types, there's no giant switch statements, the whole thing is super straightforward and easy to use, and I only need to pass over all my data once. It will also work extremely neatly for networking, as I only need to then ensure that I disable the second part of the pointer lookup check (serialising the data within pointers) - the serialiser can be told pretty directly where every pointer is, and so I can easily send pointers over the network. Yay! This means that my save/load system works almost entirely, bar some more implementation I need to do. Whoop!
[QUOTE=war_man333;52618015]Real async is also good, a step up from coroutines for sure. But it's not like reactive extensions though (?), you can't subscribe to things and do stuff like 'OnEveryUpdate'?[/QUOTE] It's (in theory, at least) not particularly difficult to add that in an efficient way. C# async is partially duck-typed, which means that you can reimplement some of the core endpoint for your purposes. 'OnEveryUpdate' then becomes a loop with an await clause that will either fizzle out or throw (or return [I]false[/I] and throw on the next [I]await[/I], but that's a bit less nice) once the entity is detroyed. Both of this will currently be less efficient than using a normal event subscription though, unless you switch await suspension points often.
Playing around with visualizing data from my thesis with gnuplot, and this is something I came up with: [t]http://i.imgur.com/jg3OKgJ.png[/t] Too bad I can't use it. [editline]29th August 2017[/editline] [t]https://my.mixtape.moe/npjzdf.png[/t] Ok I'm done for today, time to sleep [editline]29th August 2017[/editline] [t]https://my.mixtape.moe/fazbhx.jpg[/t] please don't tell my mom I'm doing vaporwave
Between battling work, a cold, and the will to work on this project, I've done a bunch of world geometry stuff over the past couple of weeks. I wanted a world geometry system where the brushes could be quickly created and easily manipulated, but not overwhelming to the user and without being overly complicated; I didn't want to wind up remaking a model editor. In a nutshell, I made a system where world brushes are generated automatically from a point cloud, enforcing a convex hull. This algorithm is run whenever points are moved around so hulls can be molded quickly. Brushes can then be switched into concave mode at any time, which recycles the previous triangle data and prevents it from further auto-generating new data from the point cloud. Luckily, Bullet supports dynamic and static versions of both convex and concave meshes, so I set up special cases to support all these combinations. [t]http://i.imgur.com/vCIUKy7.png[/t][t]http://i.imgur.com/l0og0xd.png[/t][t]http://i.imgur.com/V7pgkOS.png[/t] [URL="https://en.wikipedia.org/wiki/Constructive_solid_geometry"]The next and last step is to figure out how to perform 'boolean brush operations' aka union, difference, and intersection[/URL]
[QUOTE=DrDevil;52624204][...] please don't tell my mom I'm doing vaporwave[/QUOTE] You mean post-punk/gothic rock, right? [sp]I took this off the wiki page for Unknown Pleasures. Please don't hurt me if I got the genre wrong.[/sp] [editline]29th August 2017[/editline] [QUOTE=DrDevil;52624204][...] Too bad I can't use it.[/QUOTE] Is there a specific reason for that?
This isn't really a visible change for obvious reasons, but the rendering system that I'm using for portals/mirrors finally supports recursion. Additionally, the whole project is undergoing a corporate design rework so everything is being ripped apart into modules and submodules to be used between assets, with a cert system that validates that you actually have purchased the features that you are trying to use (because I am a miserly asshole) [IMG]http://i.imgur.com/FXgXdV7.jpg[/IMG] [img]http://i.imgur.com/i6aGrl4.png[/img] It also uses up like 1/3rd of the vram that it used to, renders like 50% less fragments while recursing, and more.
[QUOTE=helifreak;52617969]Have you considered using .NET 4.6 with Unity so you can use real async methods instead of the IEnumerable hackjob that it uses on the ancient Mono version?[/QUOTE] I did not know this was a thing, I barely program in C# nowadays though. But I'll keep that in mind for the next time I use C#!
[QUOTE=Tamschi;52624791] Is there a specific reason for that?[/QUOTE] I want to show that the peaks on the returning points of the sine are higher than at the zero crossing. This plot doesn't really show it that dramatically.
[QUOTE=fewes;52623603]Working on some specialised shaders for stylized rendering in Unity (also making a game prototype in the process). Lit + depth tested particles = volumetric explosions: [img]https://puu.sh/xlTEq.png[/img][/QUOTE] Fucking hell can I click the rating I want ONCE please That's artistic as hell. Why does everything you do look so nice? [QUOTE=Karmah;52624762]Between battling work, a cold, and the will to work on this project, I've done a bunch of world geometry stuff over the past couple of weeks. I wanted a world geometry system where the brushes could be quickly created and easily manipulated, but not overwhelming to the user and without being overly complicated; I didn't want to wind up remaking a model editor. In a nutshell, I made a system where world brushes are generated automatically from a point cloud, enforcing a convex hull. This algorithm is run whenever points are moved around so hulls can be molded quickly. Brushes can then be switched into concave mode at any time, which recycles the previous triangle data and prevents it from further auto-generating new data from the point cloud. Luckily, Bullet supports dynamic and static versions of both convex and concave meshes, so I set up special cases to support all these combinations. [t]http://i.imgur.com/vCIUKy7.png[/t][t]http://i.imgur.com/l0og0xd.png[/t][t]http://i.imgur.com/V7pgkOS.png[/t] [URL="https://en.wikipedia.org/wiki/Constructive_solid_geometry"]The next and last step is to figure out how to perform 'boolean brush operations' aka union, difference, and intersection[/URL][/QUOTE] Also, this looks pretty cool. I don't think I've seen many indie engines with support for brushes. With CSG operations I guess the difficult part is optimizing the triangle output - I've used CSG engines where they recommended not to use the boolean operations because the output was pretty messy and suboptimal often times. For example, creating a doorway using subtraction would result in way too complicated meshes compared to just building the doorway with a few more brushes.
[media]https://www.youtube.com/watch?v=mdVE_4w3sh4[/media] Hooray! Save/load works almost entirely now, except for the event system which is going to be put in the bin for being badly designed
Some realtime painted material layering: [t]https://puu.sh/xmm0Q/8664aaf0a7.png[/t] Has some super incorrect image based specular now (no roughness taken into account, only metallic surfaces reflect the cubemap), which already looks quite nice.
[QUOTE=JWki;52625380] That's artistic as hell. Why does everything you do look so nice? [/QUOTE] Thanks! I really should give some credit to Unity's new Post Processing Stack though, that shit is godly. I managed to add some subsurface scattering to the clouds by rendering their backside depth to a buffer and calculating the difference in a shader. Looks pretty soft and cushy now: [img]http://puu.sh/xmph7.gif[/img]
You're embracing the polygons and it's looking great [editline]30th August 2017[/editline] Can you show us a gameplay/prototype video?
I doubt I can express thoroughly enough just how much I underestimated multiplatform application development: even if those platforms are just various versions of windows. I've spent the past week just fixing issues related to that stuff, which really sucked since most of the bugs just caused instant crashes with no missing dll errors, no log data created, and nothing really to go off of. I also forgot just how many simple features one can forget: I previously hadn't noticed that my rendering system + ImGui weren't communicating important functional key statuses like backspace, arrows, ctrl, shift, etc, until someone mentioned it. Same with double-click support being odd, mouse input acting oddly, and the lack of clipboard data support. I've added that stuff today, but christ I don't feel like it ever ends. My boss sorta-kinda gives me hell for being 6 months behind schedule, but I'm still figuring out this application/software development thing works, damnit :v [editline]edited[/editline] also someone just [I]had[/I] to request a progress bar so that'll be fun to implement, since the slicing backend launches on a thread independently of the rendering thread. i think std::atomic should make it suck less, but we shall see.
[QUOTE=paindoc;52630816]I doubt I can express thoroughly enough just how much I underestimated multiplatform application development: even if those platforms are just various versions of windows. I've spent the past week just fixing issues related to that stuff, which really sucked since most of the bugs just caused instant crashes with no missing dll errors, no log data created, and nothing really to go off of. I also forgot just how many simple features one can forget: I previously hadn't noticed that my rendering system + ImGui weren't communicating important functional key statuses like backspace, arrows, ctrl, shift, etc, until someone mentioned it. Same with double-click support being odd, mouse input acting oddly, and the lack of clipboard data support. I've added that stuff today, but christ I don't feel like it ever ends. My boss sorta-kinda gives me hell for being 6 months behind schedule, but I'm still figuring out this application/software development thing works, damnit :v [editline]edited[/editline] also someone just [I]had[/I] to request a progress bar so that'll be fun to implement, since the slicing backend launches on a thread independently of the rendering thread. i think std::atomic should make it suck less, but we shall see.[/QUOTE] Wait until you hit Linux. You're in for a ride especially with your Vulkan renderer from what I hear. WRT progress bars, idk about your specific use case obviously but a progress bar usually is a single producer, multi consumer thing - and who consumes it in what order doesn't really matter so you shouldn't need too much synchronization. A shared variable indicating the progress which is being updated by your worker thread usually works fine. Of course there can be more subtle issues that I'm missing due to having no knowledge of the greater system.
[QUOTE=paindoc;52630816]My boss sorta-kinda gives me hell for being 6 months behind schedule, but I'm still figuring out this application/software development thing works, damnit :v[/QUOTE] There was a quote somewhere that said something like if companies knew how long a project was realistically going to take, the majority of projects would never be started. I wouldn't let it annoy you, it's pretty common
Working on a Wolfenstein 3d remake in my own 3d engine [T]http://i.imgur.com/4RaEpKy.png[/T]
[QUOTE=JWki;52630893]Wait until you hit Linux. You're in for a ride especially with your Vulkan renderer from what I hear. WRT progress bars, idk about your specific use case obviously but a progress bar usually is a single producer, multi consumer thing - and who consumes it in what order doesn't really matter so you shouldn't need too much synchronization. A shared variable indicating the progress which is being updated by your worker thread usually works fine. Of course there can be more subtle issues that I'm missing due to having no knowledge of the greater system.[/QUOTE] Thankfully I don't think this whole application needs to be cross platform: the backend is, at least, since I've already tested compiling that with GCC+clang in the WSL. Haven't tried on an independent Linux install, but I'm not worried: I don't use very much platform specific code, and the little that I do is in filesystem stuff that is macro'd based on OS. also WRT progress bar, I tried using an atomic w/ an enum class to indicate the current stage, but it wasn't getting updated by the backend for some reason (despite using store(), oddly). Its nbd: not a high priority item, at all. Its back to crashing on start on W7 :v As for the renderer, I've started changing some of my code around to prepare for eventual cross-platform support. I'm kinda copying ImGui's approach to input handling: there's going to be an IO struct I can fill with values from whatever windowing/context system I'm using, and I'll get what I need from there. [QUOTE=djjkxbox;52630902]There was a quote somewhere that said something like if companies knew how long a project was realistically going to take, the majority of projects would never be started. I wouldn't let it annoy you, it's pretty common[/QUOTE] I used to be a lot harder on myself about this until I started keeping a todo list of tasks, and keeping completed pages around. Makes it a lot easier, primarily for me, to verify that I have been doing things and making progress. Same with my commit messages: I try to commit more often, and make it more clear what exactly I changed while doing so. I recently fixed a memory leak in my renderer that grew as nlog(n), where n was the number of window resize events. Oooops. That was a bit awkward. Not sure how it slipped under my radar for so long, either, but when dragging a window I noticed memory usage just go mental. Turns out the quantity of secondary command buffers I was allocating was growing per resize event D: [editline]31st August 2017[/editline] I really just want to get to work on a new contract, or be allowed to start cleaning up our radio code. the amount of same-line if statements I see is appalling. Our EE's don't like to read our code guidelines/style standards, lol
Working on this live map of transport lines in Oslo. Guessing the positions based on real time data from the transport company. The data says how many minutes until the arrival of the bus/tram/train. [video=youtube;P5JYAn6uW5k]https://www.youtube.com/watch?v=P5JYAn6uW5k[/video]
Ohh boy, here I go networking multiplayer games again! [media]https://www.youtube.com/watch?v=Ygjge3nstAI[/media] Things that work: Packet fragmentation, reliable packet delivery (mostly), packet sequencing Networking entire game state (very slow) AKA try massive packet Networking parts of the gamestate in a reduced way (very fast) AKA try mini packet Only networking parts of the gamestate involves defining a separate serialisation function just for stuff that needs to be networked, as well as informing the serialisation system that it needs to skip serialising pointers (as they only ever point to other serialisable datastructures that will be sent in a separate update) This is pretty rocking because it means the fundamentals are all there. The next big step is dynamic object creation/destruction, and ensuring that the clients gamestate doesn't go into invalid territory while we're updating it with packets. This will likely be fixed by requesting a big chunk of data when something gets destroyed and just waiting for it to all filter in Gamestate serialisation also needs to be done gradually rather than all at once, so when something major happens (new empire) and we have to sync tonnes of shit, the game doesn't just freeze. That's much later though
[QUOTE=Sam Za Nemesis;52635585]While I'm on a brain cool of my main hobby project I've worked on a quick physically based raymarching renderer with my friend [t]http://image.noelshack.com/fichiers/2017/35/5/1504231615-untitled.png[/t] Does anyone have any documents on generating good RNG?[/QUOTE] Perhaps not a direct answer to the question, but there were a number of good siggraph papers this year on sampling. [url]http://kesen.realtimerendering.com/sig2017.html[/url] Unfortunately the Wasserstein paper isn't publicly available from what I can tell. That said there's plenty of cutting edge blue noise algorithms out there ripe for picking.
Sorry, you need to Log In to post a reply to this thread.