My hobby prior to RCM

Re: My hobby prior to RCM

Postby teh_leet_haxor » Thu Sep 12, 2013 6:12 am

So I haven't had much time as of recent, pretty much due to working on RCM 3.0 (which will launch... very, very soon :D), to do much other than scour font-websites that have a filter option with 'free for commercial use'. This came after Edge pointed out that we need to avoid using fonts for RCM that don't have a free license, so I figured that I might as well do one big sweep for non-sucky fonts to build up a single shortlist collection useful to either/any project.

Here's what I'm now using:

Image

The actual font was more standard in terms of character width, so I squashed it with a transform. I think the result looks probably as similar to the old font as I'll get; it's not quite so STYLISED, though it does make up for that in legibility.

*

Speaking of Edge, he also gave me another idea the other day, related to optimisation / clean coding. He made some casual mention of how there are a lot of bad C# programmers, writing games using the Unity engine, who freely instantiate a ton of objects in their game loop which then get abandoned at the end (and, of course, re-created less than 1/60th of a second later, 60 times per second).

To invent an example of my own, consider that I need to clock the total distance moved for every unit, every update, for proximity testing.
  • Bad: Create a new HashMap every update, which maps Unit object references to a number.
    Run a loop to fill it with zeros.
    Clock the distances into it, do the proximity tests, then discard the whole object.
  • Not so bad: Place an extra member variable into the Unit class and just use that to store the total.
    Make the code for the proximity testing reset it to 0 when it's done with it.
Obviously that uses more memory per unit spawned, but it's much cleaner than allocating memory for 60 new HashMap objects per second which all just get left for the GC to de-allocate, assuming your crappy code hasn't kept a reference somewhere (which would be what we call a memory leak).

In any case, this got me doing some thinking and self-assessment. I think my stuff is fairly clean for the most part, including with the above example, but I can't deny that some parts of the code do instantiate the occasional vector object for temporary use. It does actually copy an object reference when it can, but it occasionally needs a clone which it can proceed to modify without harming the original. Of course, a single vector is way smaller in memory so the scale of the inefficiency will be almost nothing, but the principle still applies and I think I can do it a little better and cleaner.

When I mentioned that I create the occasional temporary vector, Edge suggested reviewing where it occurs, and doing something similar to the not-so-bad example above. That would even involve just static vectors added to a few classes, as opposed to being an object property which gets duplicated (e.g. per unit spawned in the game). However, since the objects in question are literally all vectors, I've decided to take that idea to the next level and build in an RPN calculator for vectors, with a fixed number of 'registers' in a stack.

Information: an RPN calculator does things in a different order to a standard (or 'algebraic') calculator, more suited to computers, though it also benefits humans who take some time to get used to it. If mathematical operations are like verbs in a language, RPN is to Algebraic as German is to English.
Here's how an RPN calculator would resolve the expression 3 - (4 - 5):
  • Input 3
  • Input 4
  • Input 5
  • Minus
  • Minus
Each input is entered into the stack, which rolls up by 1 each time something is added.
After the inputs, the stack is at {5, 4, 3}.
The first Minus looks up the stack, subtracting 5 from the 4 and rolling the stack down, leaving the stack at {-1, 3}.
The second Minus then similarly subtracts the -1 from the 3, leaving the stack at {4}, which is the answer.
If you've ever had to move a calculator cursor left and right all over the place to insert brackets around stuff you've already entered, because you're reading the expression from left to right instead of in the actual operation order, that is what RPN abolishes.

So back to the point, if I need to use a vector cross product for something (examples: FOV culling, billboarding, smooth camera rotation), the process would be...
  • Copy in the first vector
  • Roll the stack up by 1
  • Copy in the second vector
  • Cross
...and the stack would roll back down, containing the cross product.

No instantiation, and the registers are centralised and can be reused by anything that needs them.
User avatar
teh_leet_haxor
Site Admin
 
Posts: 610
Joined: Sat Mar 02, 2013 7:39 am

Re: My hobby prior to RCM

Postby Edge Damodred » Thu Sep 12, 2013 6:53 pm

teh_leet_haxor wrote:In any case, this got me doing some thinking and self-assessment. I think my stuff is fairly clean for the most part, including with the above example, but I can't deny that some parts of the code do instantiate the occasional vector object for temporary use. It does actually copy an object reference when it can, but it occasionally needs a clone which it can proceed to modify without harming the original. Of course, a single vector is way smaller in memory so the scale of the inefficiency will be almost nothing, but the principle still applies and I think I can do it a little better and cleaner.


This isn't aimed at Hax but programmers in general. It's usually not the amount of memory allocated/deallocated or in rendering how much you draw, but how often you tell it to allocate/deallocate/draw. Computers like things in batches. To use an old math story about Billy bringing home 15 cans of beans with his hands and how many trips it would take, it's more about the fact that he has to make 8 trips since he can only carry 2 cans per trip. However give Billy a bag and suddenly he can bring home more cans in a single trip, thus reducing the overhead of him going back and forth between the store. If you've got a function intended to work on a large data set don't have it take in a single element, take in the whole data set if possible(by reference of course). This reduces a lot of the overhead of calling that function 1000 times for 1000 elements and all the overhead of making those calls.

Now for those who are looking into Unity be aware that it is using an old version of Mono(open source version of .NET) due to the nightmare that is licensing, so its Garbage Collector is no where near as good as the current version of .NET or even the current version of Mono. So you should really take pains to avoid using 'new' at run time. Unfortunately a lot of the black box classes in UnityEngine don't follow this advice though they have made improvements over the years. Check here and here for tips on dealing with Unity's Garbage Collector(and possibly tips on other languages that use GC as well).
When in doubt, hit it with a bigger hammer.
User avatar
Edge Damodred
Rival
 
Posts: 535
Joined: Sat Mar 02, 2013 7:33 pm
Location: Somewhere in the Ford Galaxy

Re: My hobby prior to RCM

Postby teh_leet_haxor » Sat Sep 14, 2013 4:45 pm

The thing about Mono there surprises me; you'd think that the whole point of Mono was to be a license-free C#, and open source so if the trunk takes a bad direction it can still be forked. Edit: Unless I totally mis-read that, and it's just Unity not keeping up. Either way I know that equates to effort required, but Unity has to jutify its not-entirely-free license somehow, which won't happen by lagging behind like that.

About the vector instantiation, it's a good thing I did look into it, because a typical scene was creating around 4000 to 20000 vectors per frame, just to do general calculations. It now has its calculator, and almost all vector-returning methods which created a clone have been removed. When a clone is legitimately needed, such as when spawning a unit or a particle, the code to do that can man up and visibly say new Vector.

The number of vector instantiations per frame now actually hits a minimum of 0, typically with a few occasional spikes when particles are generated.
Projectile creation seems to spike 20 or so, and laser guides / hit detection creates temporary CollisionData objects which in turn create vectors (the world position, the normal of the impact, the direction of force etc). I'll be looking into cutting those down as well; it should be quite feasible for the code to re-use a single static CollisionData object.
User avatar
teh_leet_haxor
Site Admin
 
Posts: 610
Joined: Sat Mar 02, 2013 7:39 am

Re: My hobby prior to RCM

Postby Edge Damodred » Sat Sep 14, 2013 10:02 pm

Unity is still using the last version put out by Novell because the licensing terms were much more commercial friendly than the current version by Xamarin(using the LGPL and GPL license, this license can become problematic in mobile devices which is where Unity really gets a lot of use). Basically they've been trying to update their version as much as possible but it comes down to a matter of priorities. Right now their version of Mono works "good enough" and they need to keep up with the current trend in graphics and animation capabilities while maintaining their lead in number of deploy-able platforms. Unreal Engine 3 has been barking at their heels in the mobile space for the last few years and now that UE3 can natively be used on fairly compliant HTML5 browsers(right now this is pretty much just the latest version of Firefox) people can deploy 3D apps without the need for plugins at all.



You can probably remove the need for particles to instantiate new vectors by allocating an array for it with the maximum number of particles in the emitter. Just keep track of how many particles are active right now and when one dies you can swap it with the one on the "end" of the active number and decrement your active number by 1. If you need to have them sorted for drawing you can do all the calculations first and then do a second sorting pass before drawing. When the effect is over just pool the array until it's needed again. Of course now you'd have to manage a bunch of emitters based on specific effects.
When in doubt, hit it with a bigger hammer.
User avatar
Edge Damodred
Rival
 
Posts: 535
Joined: Sat Mar 02, 2013 7:33 pm
Location: Somewhere in the Ford Galaxy

Re: My hobby prior to RCM

Postby teh_leet_haxor » Mon Sep 23, 2013 8:47 pm

Edge Damodred wrote:You can probably remove the need for particles to instantiate new vectors by allocating an array for it with the maximum number of particles in the emitter.

Even better, the particle manager now places expired particles into a common pool to be re-used, regardless of what is trying to spawn them. After reading that, I did consider adding such an array to the Engine gadgets since they create an unending stream of particles, but it would be tough to nail the required number for each engine. They spawn more particles as the ship moves faster (actually placing them at constant distance intervals), and the speed cap is affected by stuff like the Afterburner. Special cases for that would work at the moment, but would likely bite me later because it uses a Status Effect system where some external gimmick could also grant a temporary speed buff (a system which I fully intend to use as part of mission and boss design). In any case, that thought evolved into the Particle Soup system.


Unrelated: Deployment with a bundled JRE was successfully tested on a machine without Java installed. It uses a lot of command line options which assume the burden of providing the necessary environment variables that let the VM find everything it needs, but it worked. Speaking of which, I should probably also extract a readout of the resulting runtime environment under those conditions.

I had been reading about (and experimenting with) the various tools available for compiling (ahead-of-time) Java bytecode into platform-specific machine code, particularly the GCJ option as part of the GCC. I gave up on this, after supplying MinGW with various dependencies it needed, when I found that I would have to divorce MinGW from its package manager and scour the internet for a version downgrade for the GCC Core to make it compatible with its version of GCJ. Also contributing to the lack of being arsed was the discovery that platform-agnostic Java bytecode with JIT compiling universally outperforms any AOT equivalent (even Excelsior JET, the $2500 solution) in everything except initial loading time. All such projects seem to have stagnated when the world was given a free license to bundle Java SE.
User avatar
teh_leet_haxor
Site Admin
 
Posts: 610
Joined: Sat Mar 02, 2013 7:39 am

Re: My hobby prior to RCM

Postby Gorione » Wed Sep 25, 2013 9:28 pm

I'm getting a 3D version of Asteroids vibe on those initial screen shots. Now mind you, I have read through this entire thread yet, but it's just my initial impression of your game there.

This will date me, but I remember when the Asteroids video game first hit my local 7-11 in 1979. I was 12 at the time and thought it was the greatest thing I'd ever seen up until that point. Yup, I've made 46 circuits around the sun so far.

I know I've heard Emp, Varyar and Highlander talk about their first video game consoles, most notably Emp with the Atari 2600. I'll go one further. My first video game console was the Pong console. Boring as hell in retrospect, but still fun at the time. Then some years later we got an intellivision. After that, we got a computer and I transitioned to playing games on an Apple II+.

It just amazes me how far technology has come and how just your average joe like you Hax can spend some time and write a video game that looks fairly decent fairly easily. Ah, to have the tools today back then....
Communism jokes are only funny if shared with everyone.
User avatar
Gorione
Veteran
 
Posts: 409
Joined: Sun May 12, 2013 9:14 am

Re: My hobby prior to RCM

Postby teh_leet_haxor » Thu Sep 26, 2013 12:37 pm

Gorione wrote:I'm getting a 3D version of Asteroids vibe on those initial screen shots

I'm getting an idea for a mini-game :)
Do keep looking through the pictures and videos though; the eventual vibe should hopefully be a mix of Elite and Freespace.

Gorione wrote:It just amazes me how far technology has come and how just your average joe like you Hax can spend some time and write a video game that looks fairly decent fairly easily. Ah, to have the tools today back then....

I'd say it takes a bit more mathematics and programming than the average study, but in as much as one person can do it, absolutely.
It doesn't use any actual engine, which would have the potential to look current-gen with very little time spent, but it does enjoy use of various frameworks that do handle the most basic tasks:
  • OpenGL of course; a lot of geometry/rasterisation/lighting is done automatically. I still have to provide the coordinates of every vertex of every face and tell it which direction it's facing and which location on the texture it should represent, which sounds like a lot, but is actually quite negligable overall.
  • OpenAL; again, I just have to buffer the sounds and give each sound source properties such as position, velocity, gain, pitch etc, and it handles all the processing/mixing and communication with the sound device.
  • Java itself; it's just more refined than C++, presents fewer problems in general, and the burden of porting it between Windows/Linux/MacOS is already done.
  • LWJGL, which provides the crucial interface between Java and the native OpenGL functions. Also, like Java, it too comes with native libraries for all the platforms, and automatically loads the one it needs. The fact that the natives are compiled from C++ and accessed via JNI sounds a bit daft and will arouse the C++ purists into mocking it*, but all I see is 'functional', 'cross-platform' and 'ease of development'.
  • JInput gets a lesser mention. It does do much of the work of interfacing with controllers, but I still have to do a lot of management myself.
There's also a few other minor things that it does use but which don't really contribute to the ease of development. JOrbis comes to mind, which lets it load the game audio from OGG format as opposed to large WAV files (MP3 does not have a free license).


* Thankfully, 100% of C++ purists use Linux, and they shut up when I point out that it gets an automatic, working Linux port.

Joking and fabricated statistics aside, I do respect C++ for its potency and its pivotal role in the development of everything we have now, it's just a bit clumsy/inelegant and I'm quite sure the world wouldn't miss it if it was only ever used where it's really necessary (for drivers and such).
User avatar
teh_leet_haxor
Site Admin
 
Posts: 610
Joined: Sat Mar 02, 2013 7:39 am

Re: My hobby prior to RCM

Postby teh_leet_haxor » Thu Oct 17, 2013 10:47 am

Big overhaul of the unlock system in the last few days, which is another thing holding up mission progress now somewhat out of the way.

It was using the player's save file to seperately record mission progress and items unlocked, which was a breeding ground for mess and inconsistency whenever I change stuff. It now only records mission completion, and uses that to determine what stuff the player should have at any given moment. That way I can add/remove items or change requirements without worrying about an existing save file containing items that shouldn't be there or lacking items that should.


Also, new interface feature for it:

User avatar
teh_leet_haxor
Site Admin
 
Posts: 610
Joined: Sat Mar 02, 2013 7:39 am

Re: My hobby prior to RCM

Postby teh_leet_haxor » Sun Nov 24, 2013 8:11 pm

So from the very start, network play has been one of the big 'nope, not planned and will likely never be' items, firmly placed within the figurative zone of feature creep. However, as features go, it's the one thing I get asked about a lot and would definitely like for it to have, so I decided to give it a go following a fair bit of thinking over how it might work internally.

That was about a week ago; since then I've got it to transmit the game world and have the client player spawn in the world of the host. There's not yet any communication of ship gadgets, and the host does not update the clients, but it's a start and a milestone moment for which I grab some footage for the collective log. Lower image is the host, upper image is the connecting client.

Also don't mind that the enemies are slaying each other; the aggro system is currently mid-overhaul to accomodate a few additional concepts.

User avatar
teh_leet_haxor
Site Admin
 
Posts: 610
Joined: Sat Mar 02, 2013 7:39 am

Re: My hobby prior to RCM

Postby koiseptember » Mon Jul 24, 2017 9:44 pm

Mostly during missions, including tutorial missions. I had planned for one main voice as a commander-type role, one voice for a small part towards the end, and could also fit in an optional secondary role as the base computer (similar to EDI or Jarvis (actually I found out yesterday that Jarvis is a real character, but I still thought it was an AI for ages)).

goldenslot
koiseptember
FNG
 
Posts: 4
Joined: Mon Jul 24, 2017 9:29 pm

Previous

Return to Listener Side Projects

Who is online

Users browsing this forum: No registered users and 1 guest

cron