00:00
00:00
Newgrounds Background Image Theme

decafpanda just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

The Flash 'Reg' Lounge

3,046,127 Views | 60,186 Replies
New Topic Respond to this Topic

Response to The Flash 'Reg' Lounge 2016-07-26 22:36:29


At 7/26/16 08:54 PM, MSGhero wrote: There's an option now to force your game to be served on https, which is cool. I'm not sure what the benefits are to not doing that, though. Seems like it should be the default.

Useless if insecure resources are still being loaded onto the page.
Good thought, though.


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-07-27 16:08:44


At 7/26/16 02:30 PM, Glaiel-Gamer wrote: get in the tube

https://www.youtube.com/watch?v=QTe5i-jEYTs

Wow. Crazy perspective.

Response to The Flash 'Reg' Lounge 2016-07-27 18:30:02 (edited 2016-07-27 18:51:21)


This should be fun.
Edit: Heh


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-07-27 22:11:09


At 7/27/16 06:30 PM, egg82 wrote: This should be fun.
Edit: Heh

Sounds like your troubles are over

Response to The Flash 'Reg' Lounge 2016-07-28 14:42:13


At 7/27/16 10:11 PM, GeoKureli wrote: Sounds like your troubles are over

Sounds like theirs have just begun. I've just signed them up for every spam service available.
http://www.mailbait.info/

This also looks like something I can play with. I love getting junk e-mail, it helps me sharpen my hacking skills :D

I don't think I ever had a MeetMe account, but alright.

Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-07-28 20:32:56


At 7/28/16 02:42 PM, egg82 wrote: I've just signed them up for every spam service available.
http://www.mailbait.info/

Meh, any spam email is guaranteed to be from a throw-away account. also I bet most junk filters can handle it anyways.

Response to The Flash 'Reg' Lounge 2016-07-28 22:28:22 (edited 2016-07-28 22:31:18)


At 7/28/16 08:32 PM, GeoKureli wrote: Meh, any spam email is guaranteed to be from a throw-away account. also I bet most junk filters can handle it anyways.

The intent is to make it incredibly difficult for them to sift through the junk e-mail to find the real responses. I try to find ways of making things as hard as possible for scammers because it's fun and it helps me find new and creative ways of doing things :)

Actually, I'm now thinking there might be an even better way of making things hard for "reply to x" scammers by sending them hundreds of thousands of fake replies with spoofed "from" headers. I'm sure I can build a program for something like that..


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-07-31 18:19:51


Have to redo most if not all pathing.

Ugh

The Flash 'Reg' Lounge

Response to The Flash 'Reg' Lounge 2016-07-31 20:35:49 (edited 2016-07-31 20:36:23)


At 7/24/16 07:06 PM, PrettyMuchBryce wrote: If you're concerned about rigid looking paths you could look into path smoothing algorithms.

I did a bit of research on path smoothing, but it seems like that requires what amounts to ray traces or convex casts, up to one per tile in the path, which is my current bottleneck and wouldn't be good with multiple enemies.

Looking at an algo called Theta* which can do angles in path planning. Might need to nix nape's raycast if this requires it though, and use a less granular less good approach.

Response to The Flash 'Reg' Lounge 2016-07-31 20:52:02 (edited 2016-07-31 20:52:51)


At 7/31/16 08:35 PM, MSGhero wrote: Looking at an algo called Theta* which can do angles in path planning. Might need to nix nape's raycast if this requires it though, and use a less granular less good approach.

I feel like something is fundamentally wrong, here, if you're saying pathfinding (raytracing, of all things) is slowing your game down. That may not be what you're saying, but it seems like it. If that's the case, finding an efficient algorithm isn't going to solve anything until you figure out what is actually causing the bottleneck - if MMOs can pathfind millions of NPCs at once on a server you can pathfind a few on a modern PC (The pathfinding itself may not actually be the problem)


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-07-31 21:57:01 (edited 2016-07-31 21:59:28)


At 7/31/16 08:52 PM, egg82 wrote: I feel like something is fundamentally wrong, here, if you're saying pathfinding (raytracing, of all things) is slowing your game down. That may not be what you're saying, but it seems like it. If that's the case, finding an efficient algorithm isn't going to solve anything until you figure out what is actually causing the bottleneck - if MMOs can pathfind millions of NPCs at once on a server you can pathfind a few on a modern PC (The pathfinding itself may not actually be the problem)

Ok when I said bottleneck I meant I don't like how many times the raytracer is being called given that so many edge cases still exist and that there is one fundamental edge case that cannot be solved no matter how many raytraces I use but I see it happen often enough that I want to fix it.

I *need* a new algo, and it just so happens that flash — which is not an MMO server — starts to visually tear when enough enemies start raytracing. They only do it 6 times per second, but that's enough to impact the visual framerate. I still run 60 fps just fine, but it doesn't look like it.

Plus, it's nape raytracing, not some 20 line snippet.

Edit: I sometimes draw the nodes during pathfinding, which actually impacts the framerate

Response to The Flash 'Reg' Lounge 2016-07-31 22:12:36 (edited 2016-07-31 22:16:14)


At 7/31/16 09:57 PM, MSGhero wrote: Ok when I said bottleneck I meant I don't like how many times the raytracer is being called given that so many edge cases still exist and that there is one fundamental edge case that cannot be solved no matter how many raytraces I use but I see it happen often enough that I want to fix it.

I *need* a new algo, and it just so happens that flash — which is not an MMO server — starts to visually tear when enough enemies start raytracing. They only do it 6 times per second, but that's enough to impact the visual framerate. I still run 60 fps just fine, but it doesn't look like it.

Not saying your code is bad or anything, just saying there might be something fundamentally broken. I've had this happen a lot to me, where I would try to fix something and go for workaround after workaround, and then I finally decide to go and fix the thing that was actually broken in the first place (or find it and then fix it) and everything works beautifully again.

Again, the pathfinding algorithm may not be the problem. Especially since it's NAPE, I assume it's not. I'm saying there might be something else wrong with the codebase that's causing things to slow down to a crawl and you might want to inspect other things that are going on. I don't expect AS3 to run an MMO server or anything, but at the same time it should be capable of handling some client + server-side code with pathfinding just fine (I've done it myself)

From what you're saying I think it might be an issue with Flash having everything tied to framerate. If you set two timers (one for drawing, one for updating) everything should be much smoother- especially if the update timer is tied to the sound card rather than the video card. There's a library for it on github somewhere, I just can't remember where exactly.

My framework also uses separate timers for update and draw functions, if you'd like to take a quick look at the StateEngine class?

Edit: Found the timer. It's called Metronome. There's a newer one that might be better, though, since it doesn't need a sound card to run. It's called Timekeeper. I haven't looked into that one much, but it looks interesting.


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-07-31 22:40:39 (edited 2016-07-31 22:43:06)


At 7/31/16 10:12 PM, egg82 wrote: Not saying your code is bad or anything, just saying there might be something fundamentally broken. I've had this happen a lot to me, where I would try to fix something and go for workaround after workaround, and then I finally decide to go and fix the thing that was actually broken in the first place (or find it and then fix it) and everything works beautifully again.

Ok bottleneck wasn't the right word to use in this forum haha. It's a memory leak* which is why the visual framerate is being reduced. I'm using less than 30% of my 16.7 ms every frame except for when I draw my pathing nodes. I generate an excess of nodes to try to mitigate the edge cases which exacerbates the memory usage (ray traces between all nodes), and edge cases still persist. So I need a whole new solution. If theta* uses ray traces, I'm probably going to avoid nape's implementation since I believe tracing over a 2d array is faster than tracing over polygon space.

*It's not really a leak, it's unavoidable memory usage due to reflection/enums with parameters. It might be avoidable with haxe macros, but I don't understand those well enough to generate functions at compile time. It would be baller if I do, though: faster execution and less memory usage. The leak is slow enough that the GC doesn't kick in in a reasonable amount of time, but fast enough that the visual tearing occurs after a while (which I've never actually understood). Things are dealloc'd properly I believe, just chilling.

Response to The Flash 'Reg' Lounge 2016-07-31 22:58:08 (edited 2016-07-31 22:59:15)


Knowing nape, though, raytracing there might be faster than tracing over a 2D array depending on the granularity. I have to assume nape is just doing 3 dot products and 3 bitwise ANDs per edge in the space.

Response to The Flash 'Reg' Lounge 2016-07-31 23:48:41


At 7/31/16 10:40 PM, MSGhero wrote: *It's not really a leak, it's unavoidable memory usage due to reflection/enums with parameters. It might be avoidable with haxe macros, but I don't understand those well enough to generate functions at compile time. It would be baller if I do, though: faster execution and less memory usage. The leak is slow enough that the GC doesn't kick in in a reasonable amount of time, but fast enough that the visual tearing occurs after a while (which I've never actually understood). Things are dealloc'd properly I believe, just chilling.

Ah, I see. You could try adding an "OOM panic" and manually force GC when mem hits a certain percentage used. Either call System.GC() or allocate a lot of memory really quickly and then release it.


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-08-01 03:39:48


Wanted to wait a while to share so I didn't end up with two posts, but I've been busy this weekend!

New website
New shirts: 1 2 3 4 5

Whaddya think? The website was done in less than a day, but I think it came out pretty alright.


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-08-01 10:18:40


At 8/1/16 03:39 AM, egg82 wrote: Wanted to wait a while to share so I didn't end up with two posts, but I've been busy this weekend!

New website
New shirts: 1 2 3 4 5

Whaddya think? The website was done in less than a day, but I think it came out pretty alright.

Website looks good, I like shirt 2 the best, and I promise people will ask you for webdev no matter what you say.

Response to The Flash 'Reg' Lounge 2016-08-01 13:54:10


At 8/1/16 03:39 AM, egg82 wrote: Whaddya think? The website was done in less than a day, but I think it came out pretty alright.

One small correction: Java is not an ECMAScript dialect. Not sure about C#, but I would double check. Site looks good!

Response to The Flash 'Reg' Lounge 2016-08-01 13:55:49


At 7/31/16 10:58 PM, MSGhero wrote: Knowing nape, though, raytracing there might be faster than tracing over a 2D array depending on the granularity. I have to assume nape is just doing 3 dot products and 3 bitwise ANDs per edge in the space.

The code for Nape is open source, right ? Does it make sense to dig into the code a little bit and learn more about what is actually happening in the engine ?

Response to The Flash 'Reg' Lounge 2016-08-01 14:15:14


At 8/1/16 01:55 PM, PrettyMuchBryce wrote: The code for Nape is open source, right ? Does it make sense to dig into the code a little bit and learn more about what is actually happening in the engine ?

Yes it's open source, no it doesn't make sense.

Nape is written in caxe, which is then compiled to haxe, which is then compiled to as3/js/cpp/etc. The caxe source is confusing and the haxe source is nigh impossible to debug (trust me). It would be better to test them out, but I'm pretty sure nape will be slower since the 2D array isn't explicitly dependent on the number of edges in the space.

Response to The Flash 'Reg' Lounge 2016-08-01 15:01:18 (edited 2016-08-01 15:25:18)


At 8/1/16 10:18 AM, MSGhero wrote: I promise people will ask you for webdev no matter what you say.

I know :(
I'm basically hoping someone one day will look at that small bit and go "oh, never mind then." - maybe. If I have to modify a template for my own portfolio you know for damn sure I don't have "an eye for design."

At 8/1/16 01:54 PM, PrettyMuchBryce wrote: One small correction: Java is not an ECMAScript dialect. Not sure about C#, but I would double check. Site looks good!

I was 100% sure Java is an ECMAScript dialect and 60% sure C# is. Whoops! That could potentially be fatal. I'll do some quick research and modify that sentence slightly.

At 8/1/16 02:15 PM, MSGhero wrote: Nape is written in caxe, which is then compiled to haxe

What the what? Okay, when did Haxe become this huge thing all of a sudden? I think I vaguely remember it not existing just a year ago, right?

Edit: I don't think I want to live in this world any more.
(This, by the way, implies a hulluva lot more than its original meaning. You can't have case-insensitive hash functions, which means what exactly for our passwords stored in that database?)


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-08-01 15:49:48 (edited 2016-08-01 15:52:09)


At 8/1/16 03:01 PM, egg82 wrote: What the what? Okay, when did Haxe become this huge thing all of a sudden? I think I vaguely remember it not existing just a year ago, right?

Haxe has been around for like 10 years, but no one cared about it until OpenFL and flixel showed up, with Ludum Dare bringing a lot of people in. Tbh before OpenFL, your cross platform game making options were limited if not nonexistent. Now there's luxe, kha, flambé, and others. Cartoon Network, Disney(?), Nickelodeon, TiVo, Zynga, etc all use haxe now. You can code unity projects in it as well as export to Python and Lua now.

Caxe lets you compile to haxe and to swc, to support the pure AS3 devs who can't do anything with hx source. Turns out haxe would add the ability to export to swc eventually. Now there's really no reason for nape not to be pure haxe other than it's way too big to change from caxe.

Response to The Flash 'Reg' Lounge 2016-08-01 16:14:52 (edited 2016-08-01 16:18:56)


At 8/1/16 03:01 PM, egg82 wrote: Edit: I don't think I want to live in this world any more.
(This, by the way, implies a hulluva lot more than its original meaning. You can't have case-insensitive hash functions, which means what exactly for our passwords stored in that database?)

I'm actually cool with this, so long as it makes a big deal to notify the users when they set up their passwords. In the end, case sensitivity impacts the users memory just as much as it deters a brute force hack. I absolutely hate it when sites make me use upper/lower, a symbol, a number and some japanese kanji in my password as though people will try ever to hack my Nintendo fan club account

EDIT: at least 90% of passwords capitalize the first letter only.

Response to The Flash 'Reg' Lounge 2016-08-01 16:36:16 (edited 2016-08-01 16:50:33)


At 8/1/16 03:39 AM, egg82 wrote: New website

I like it. good layout, slim. Honestly, not super helpful for getting exposure, though.

If possible, show interactive examples of your projects rather than just links to github. I've always sent my code source to interviewers, and no one has ever looked at them. No one wants to look at code samples, they want to see the final results of a project. If they do look at code, it's only after they deemed the final presentation 'acceptable' and it's still rare.

There's also no description of what those repos even do, either on the page or in the github repo info. and there's no description of you. The bullet points near the top of the page are more of a slim resume, you should start off by talking about you. Give a mission statement, followed by you in a nut shell. Be a bit candid, include personality, like it's an OK Cupid bio paragraph; ending that section with "Stop asking me for web design" or something, would likely be read more than the series of bullet points, seeing as how most people will probably not ever be looking someone with every single one of the skills listed there.

Response to The Flash 'Reg' Lounge 2016-08-01 16:58:42 (edited 2016-08-01 17:18:13)


At 8/1/16 04:14 PM, GeoKureli wrote: I'm actually cool with this, so long as it makes a big deal to notify the users when they set up their passwords. In the end, case sensitivity impacts the users memory just as much as it deters a brute force hack. I absolutely hate it when sites make me use upper/lower, a symbol, a number and some japanese kanji in my password as though people will try ever to hack my Nintendo fan club account

EDIT: at least 90% of passwords capitalize the first letter only.

I dislike restrictions as well. I would like it very much if every website had a list of "1 million common passwords" they checked against and that was all they did. I want to be able to enter my fully-randomized 16-character passwords in with my password manager and never have to deal with them again. Password restrictions force me to be creative with my password manager, which ultimately actually reduces my overall security instead of increasing it as intended.

But let's assume I wanted to brute-force your password. Most password range from 5-12 characters with the most concentrated being at around 8-10. With a full keyspace- letters count for 26 characters, numbers count for 10, and symbols (using a standard American keyboard) count for 33. Including uppercase letters, there's a whopping 95 possible combinations per character. In an 8-character password that's 6,634,204,300,000,000 total combinations (almost 7 quadrillion).

Let's assume for a second that the passwords stored in WF's database are hashed with MD5 (they wish they were) - a single GTX 1080 (~$600) will produce MD5 hashes at a speed of ~250,000,000 (250 million) per second. Modern hardware is quite impressive. Most password cracking stations are running about 4 of these in parallel. Four times the speed (~1 billion hashes per second) give or take a couple thousand. With a single 1080 you can break ANY 8-character password submitted with MD5 in ~307 days. Four GPUs (a regular, real cracking station) will net you all possible combinations in about 76 days.

Now let's remove the uppercase letters from the equation. We now have 69 possible combinations per letter giving us 513,798,370,000,000 (513 trillion) possible combinations. With one 1080 it will take 23 days. With four, it will take 5 days.

THAT is why having uppercase characters in passwords is good. Not that GPU cracking matters here, because if you manage to get your target's pet name and birthdays of their family members you can try all of 6 possible combinations and you'll get in. Uppercase letters would at least double that number of tries if nothing else.

Of course, all of this is moot if you're using MD5 with no salt anyway. Rainbow tables exist for a reason.

Good articles below:
https://www.troyhunt.com/our-password-hashing-has-no-clothes/
https://blog.codinghorror.com/speed-hashing/

Shameless plug:
Good password storage on Github

Edit: Hey @liljim - what's NG's password schema anyway? Bcrypt with a hash cost of 8?


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-08-01 17:18:28


At 8/1/16 04:14 PM, GeoKureli wrote: japanese kanji in my password

I have autohotkey set up to change "shrug" to ¯\_(ツ)_/¯ so that's less of a problem for me.

Response to The Flash 'Reg' Lounge 2016-08-01 20:24:14


This should be fun!


Programming stuffs (tutorials and extras)

PM me (instead of MintPaw) if you're confuzzled.

thank Skaren for the sig :P

BBS Signature

Response to The Flash 'Reg' Lounge 2016-08-02 16:55:25


At 8/1/16 04:58 PM, egg82 wrote: Shameless plug:
Good password storage on Github

You don't need to do this:

$retarr = array(); while($row = $statement->fetch()) { array_push($retarr, $row); }

Just do this:

$retarr = $statement->fetchAll(\PDO::FETCH_BOTH);

I also don't really know why you made a query() function and then made it use prepare and not use any of the additional features that prepare gives you.

This:

public function query($q) { global $logger; try { $statement = $this->connection->prepare($q); $statement->setFetchMode(\PDO::FETCH_BOTH); $statement->execute(); $retarr = array(); while($row = $statement->fetch()) { array_push($retarr, $row); } return $retarr; } catch (\PDOException $ex) { $logger->log("PDO", "ERROR", $ex); return null; } }

Can be simplified to this:

public function query($q) { global $logger; try { $statement = $this->connection->query($q); return $statement->fetchAll(\PDO::FETCH_BOTH); } catch (\PDOException $ex) { $logger->log("PDO", "ERROR", $ex); return null; } }

And why are you using PDOs but still manually escaping every input? Just use parameterised queries and not worry about that. You don't need to manually escape stuff like you would if you were using the procedural mysql_ functions (which should never be used for several reasons). Just use prepare and bind the values:

$stmt = $database->prepare(" SELECT `id`, `$user_field`, `$pass_field`, `$key_field`, `$iv_field` FROM `$table` WHERE `$user_field` = :user OR `$email_field` = :user; "); $stmt->bindParam(":user", $_COOKIE["user"], \PDO::PARAM_STR); $stmt->execute();

It's also rather redundant to be using the backticks everywhere, as they don't do anything if your table and column names don't have SQL keywords in them. But that's personal taste, I suppose. (I never use them unless I need them; they're ugly.)

And, like in that snippet, you don't need to concatenate your strings to include variables. There's no significant performance one way or the other in regard to using them, but using them makes your code hard to read and hard to change; I highly recommend plopping variables in the middle of double-quotes.

As for binding parameters: pretty much the only things that can't be bound are database, table, and column names, so you would still need to escape those if you wanted to add them to your query from an un-trusted source for some insane reason.

And, although I think encrypting the result of a hashing algorithm is rather pointless, you should use OpenSSL to handle encryption rather than mcrypt; mcrypt outdated and abandoned and all the other reasons listed here.

You also included a rather significant security risk with this:

if (count($result) == 0) { if ($this->prevent_user_enum) { // Preventing timing attacks. $this->check_pass("testing", [...]); echo("User/E-mail does not exist, or password is invalid!"); return; } else { echo("User/E-mail does not exist!"); return; } } if (!$this->check_pass($pass, $result[0]['pass'], $result[0]['key'], $result[0]['iv'])) { if ($this->prevent_user_enum) { echo("User/E-mail does not exist, or password is invalid!"); return; } else { echo("Password is invalid!"); return; } }

You should never be reporting that much information via a login dialog, as it would make finding existing usernames and emails significantly easier. There's no good reason to provide anything other than "invalid credentials" regardless of what actually failed.

And this is a pretty bad idea, too:

$security->set_cookie("encrypted_pass", $security->encrypt($pass, $result[0]['key'], base64_decode($result[0]['iv'])));

Passwords should only ever be stored as hashes, and only when it's absolutely necessary. There isn't any good reason to encrypt a plaintext password, let alone encrypt a plaintext password and store it as a cookie.

And, as I alluded to above, this just doesn't make sense:

$encrypted_pass = $security->encrypt($security->pass_hash($pass), $key, $iv);

What's the point of encrypting a hash? A correctly constructed hash doesn't contain any useful information.

All that aside, this is a rather bizarre mishmash of OOP and procedural code with multiple Main classes being used in a non-useful manner. I'm assuming this was never intended to actually be used in something (I hope so, at least) but it should still at least be a RESTful MVC framework; right now it's just a mess of spaghetti code.

Far from being even close to some of the horrible attempts I've seen at handling user management, but this is certainly not logging in and registration done right. The security problems not withstanding, this is the sort of web development style of coding that makes me want to rip my hair out when I have to work with it: it's, honestly, just a hard-to-read mess.

You should patch up those security holes; reorganise the code to be an MVC framework (pretty much the best paradigm for web development) and, if you feel like it, make it RESTful, which isn't super important but still not at all a bad idea; and read up on how to properly implement PDOs. Looks like you're trying to use PDOs the same way the deprecated procedural mysql_ functions were used, which is over-complicating your code.

Response to The Flash 'Reg' Lounge 2016-08-02 20:30:03


I just found out my company has a team using Haxe. If I switch, I would be transferring from the company's bread and butter game team, to some high risk department that works on some project I've never even heard of. On top of that, it might be harder to eventually move back to my hometown of Chicago, and still work for this company. On the plus side, I would finally be leaving AS3, and I'd get to work with a language I'm far more interested in. Alternatively I can stay on this team and eventually switch to Unity when the flashpocalypse begins. Though Unity is great, odds are the Haxe team is making a game I would enjoy more than my current project, which is literally my most hated genre.

Response to The Flash 'Reg' Lounge 2016-08-02 21:01:40


At 8/2/16 08:30 PM, GeoKureli wrote: Though Unity is great, odds are the Haxe team is making a game I would enjoy more than my current project, which is literally my most hated genre.

You can compile to unity with haxe if that makes you feel better.

switch
do it
I haven't been able to compile my game to cpp in 15 months, it's great
*cries crossplatform tears*