log

August 8, 2010

A semi-useful, half-done JavaScript 2D game engine (featuring Streets of Rage 2 characters)

In mid-April this year I got inter­est­ed in play­ing with the Can­vas ele­ment in JS. Back in the dark ages I used Visu­al Basic 6 (!) to make a few sim­ple 2D & 3D par­ti­cle and game engines, and so those were the first things trans­lat­ed to JS. A sim­ple point sphere demo and this basic par­ti­cle engine were the result. Hilar­i­ty and/or hor­ror will ensue if you look at the physics code btw.

I took that par­ti­cle engine and start­ed build­ing objects to man­age images and ani­ma­tion, draw­ing, sound, key­bind­ings, input sequences, actors con­trolled by a pro­gram­ma­ble state machine, basic (read: incor­rect) physics and bound­ary col­li­sion. The end result is the incom­plete Streets of Rage demo.

What’s missing

  • There’s no col­li­sion between char­ac­ters, so you can’t attack any­thing yet.
  • Load­ing infor­ma­tion of any sort. This is easy to do, and I just haven’t got­ten to it.
  • Addi­tion­al plumb­ing to allow mul­ti­ple players.

I haven’t real­ly worked on this in a month or two (as usu­al, I got dis­tract­ed by real life and work) but today I fixed some of the out­stand­ing glitch­es and reviewed the todo com­ments through­out the code. There’s plen­ty more to do yet.

Technical overview of features

For pro­gram­mers out there inter­est­ed in the inter­nals, here’s a quick break­down on what each sys­tem does:

image­Store:
  • han­dles the dynam­ic load­ing and stor­ing of image files, with the option of pro­vid­ing or gen­er­at­ing coor­di­nates for each inde­pen­dent image in sprite sheets and a call­back for load complete;
  • dynam­ic cre­ation and stor­age of flipped-axis ver­sions (to avoid using hor­ri­bly slow trans­forms dur­ing Can­vas drawing);
  • a draw func­tion that knows about indi­vid­ual sprites in an image and auto­mat­i­cal­ly sam­ples the cor­rect coor­di­nates from the source image;
  • a pars­er for com­pressed info about graph­ic files and sprite sheet coor­di­nates that can also gen­er­ate the coor­di­nates when giv­en the width and height of each sprite in an image.
ani­m­Store:
  • han­dles ani­ma­tion sets based on the sprite frames from imageStore;
  • has basic ani­m­Start, ani­m­Stop and getCur­rent­Frame func­tion­al­i­ty to make it easy for your game to know which frame to draw;
  • a pars­er for com­pressed ani­ma­tion info.
input­Store:
  • han­dles the col­lec­tion of key­board events such as keyup and key­down (real key­down, not affect­ed by the key­board repeat rate);
  • trans­lates raw key­board events into cus­tomis­able game key-mapping;
  • match­es key-map sequences such as “down, down-for­ward, for­ward, jab punch” to game actions like “jab fire­ball”. The sequences are cus­tomis­able and very sim­i­lar to Mugen’s ‘D,DF,F,x’ style, includ­ing charged attacks such as ‘~20D,U,ab’ (an EX Flash Kick). This is the sys­tem I’m most proud of;
  • a pars­er for com­pressed input sequence data (again, quite sim­i­lar to Mugen’s).
actor­Store:
  • han­dles the cre­ation of game actors (char­ac­ters, agents, what­ev­er you call them);
  • cre­ates instances of actors with physics prop­er­ties, ani­ma­tions, audio, state machine info etc unique to each instance;
  • a pro­gram­ma­ble state machine to affect a char­ac­ter’s state based on input, physics, cur­rent state and state tim­ing, ani­ma­tion etc;
  • state machine can switch to new char­ac­ter states, ani­ma­tions, sounds, affect physics etc
  • a con­ve­nience func­tion for build­ing a draw queue list (see below) for every actor instance.
physic­s­Store:
  • stores basic physics infor­ma­tion for each actor or par­ti­cle such as posi­tion, veloc­i­ty, mass, elas­tic resti­tu­tion etc;
  • restricts actors to a cus­tomis­able 3D bound­ary box
  • con­tains the most bro­ken grav­i­ty and drag cal­cu­la­tions you’ll ever see;
  • No actor/particle col­li­sion yet.
audio­S­tore:
  • han­dles the load­ing and stor­ing of audio files (very sim­i­lar to imageStore);
  • detects brows­er sup­port for the <audio> ele­ment and pro­vides the brows­er with the appro­pri­ate file;
  • con­tains workarounds for pop­u­lar brows­er bugs.
drawQueue:
  • han­dles the draw­ing queue for the game, so that oth­er func­tions can just pass a list of sprites to draw;
  • drawQueue will sort every­thing by z order before run­ning an opti­mised draw loop;
  • the result from actor­Store’s getInstance­DrawList() can be passed direct­ly to drawQueue.

In the Streets of Rage demo, all the above sys­tems are stored in xlib4.js, and the game-spe­cif­ic parts (such as sprite and ani­ma­tion lists, audio and input set­tings, etc) are stored in xsor4.js. There’s still a huge amount of work to do, but there’s a pret­ty clean divide between sys­tem and game logic.

The source code is licensed pret­ty lib­er­al­ly, and feed­back, com­ments and patch­es (!) are wel­come. Check the license at the top of the files before using or sam­pling from the code though, just to be safe.

posted by Andrew

An increase in State-funded school chaplains

We may have an athe­ist leader but she sure does­n’t shy away from buy­ing votes from the reli­gious wing. I would much pre­fer any state-fund­ed pro­grams to be estab­lish­ing ratio­nal thought in schools, not the opposite.

The Depart­ment of Unpro­nounce­able Acronyms pro­vides a FAQ on the pro­gram includ­ing this inter­est­ing answer about school chap­lain faith, although I find the answer on why the gov­ern­ment funds this pro­gram more telling. There’s no real ratio­nale apart from “Chap­lains play[ing] a sig­nif­i­cant role in… sup­port­ing the well­be­ing, val­ues and spir­i­tu­al­i­ty of young peo­ple”; a high­ly debat­able state­ment at best. Noth­ing a ded­i­cat­ed youth work­er or coun­sel­lor could­n’t do, prob­a­bly with a lot more frank­ness and pragmatism.

Dur­ing my high-school years I have fond mem­o­ries of avoid­ing the week­ly reli­gion class through any means nec­es­sary. Even at 13 I under­stood the absur­di­ty of those class­es being explic­it­ly opt-out instead of opt-in; con­sid­er the par­ents and car­ers who don’t think about reli­gion and thus aren’t like­ly to know their child is being deliv­ered a dose of Arbi­trary Belief Sys­tem™ each week. From my per­spec­tive it’s an ill-fit­ting cog in a ratio­nal, sup­pos­ed­ly-sec­u­lar edu­ca­tion sys­tem, and I’ve no inter­est in main­tain­ing what church lead­ers con­sid­er the ‘spe­cial reli­gious edu­ca­tion sys­tem’. Eek.

posted by Andrew

August 6, 2010

When jounalists inject misinformation

In iTWire’s ‘The inter­net fil­ter is dead! Long live the fil­ter!’ James Riley writes:

Despite the nar­row focus of the gov­ern­men­t’s pro­posed fil­ter, despite its tech­ni­cal fea­si­bil­i­ty and despite a series of trans­paren­cy and account­abil­i­ty mea­sures that were to be put in place, the fil­ter sim­ply unnerved peo­ple. And a great many sim­ply said the fil­ter would not work.

Mis­in­for­ma­tion ahoy. The focus of the fil­ter has and will always be vague, mean­ing­less trite in the style of ‘save the chil­dren’, with a creep­ing scope and absolute­ly no account­abil­i­ty. Wit­ness how the leaked URL list blew out to include cur­rent­ly legal porno­graph­ic mate­r­i­al, infor­ma­tion about euthana­sia and a Wik­ileaks page. Google et al have spent the last two years com­plain­ing that the scope is ill-defined, sub­jec­tive and hard to enforce.

On the mer­it of its tech­ni­cal fea­si­bil­i­ty, where are the con­crete sta­tis­tics on the effect of trans­fer speed, reli­a­bil­i­ty and false pos­i­tives? Where is the inde­pen­dent study? Why was the Gov­ern­men­t’s report so delayed? Again, iiNet and oth­er ISPs whose exis­tence does­n’t depend on con­tin­ued gov­ern­ment con­tracts force­ful­ly opposed the tech­ni­cal imple­men­ta­tion for a wide swathe of reasons.

Beyond the tech­ni­cal imple­men­ta­tion prob­lems there’s also the fact that the fil­ter is incred­i­bly sim­plis­tic and inef­fec­tive; any­thing based on URL lists is prone to bypass via proxy, tun­nelling and encryp­tion (to name just a few tech­niques). Two min­utes after this thing goes live a thou­sand Yahoo Answers pages will list ways to bypass it. And who’s like­ly to have the tech­ni­cal knowl­edge to do so already? The very peo­ple you’re ‘pro­tect­ing’ or ‘stop­ping’: the tech­ni­cal­ly-mind­ed new gen­er­a­tion and any­one else who’s ever stepped off the main­stream web. No, seri­ous com­mer­cial pae­dophiles would not be stu­pid enough to use unen­crypt­ed web traf­fic, and the fil­ter won’t block their content.

I’d love to see the size of the URL list should the gov­ern­ment start block­ing pages that describe how to work around the filter.

And no James, there is no ‘tech­ni­cal trans­paren­cy and account­abil­i­ty’. The gen­er­al pub­lic don’t know how the sys­tem works, can’t review it from a tech­ni­cal or source-code lev­el, and have no con­trol over the blocked address­es even as a mat­ter of peri­od­i­cal pub­lic or inde­pen­dent review. A telling part of the quote above is “[…] a series of trans­paren­cy and account­abil­i­ty mea­sures that were to be put in place” (empha­sis mine). Note the “were”. They had­n’t been dis­cussed pub­licly, or reviewed, or imple­ment­ed, or stress-tested.

The inter­net fil­ter is about get­ting a black-box into every ISP to estab­lish a base­line sys­tem for block­ing arbi­trary con­tent at the Gov­ern­men­t’s whim. Noth­ing more. It will not pro­tect you, your kids or your dog. If you think it will then you are an idiot.

But the Howard Gov­ern­ment end-user fil­ter­ing pol­i­cy was a dis­as­ter (if you define dis­as­ter as a pol­i­cy that costs mil­lions but is near­ly com­plete­ly ineffective.

Labor’s inter­net fil­ter has cost mil­lions already (just for test­ing!) and will be com­plete­ly ineffective.

Under for­mer Com­mu­ni­ca­tions Min­is­ter Helen Coo­nan, gov­ern­ment spend tens of mil­lions of dol­lars on its end-user fil­ter pol­i­cy – includ­ing $15 mil­lion on an advertising/awareness cam­paign to make sure par­ents knew the fil­ters were available.

One Gov­ern­men­t’s bad­ly-man­aged project does not pre­clude a lat­er Gov­ern­ment from attempt­ing to do a bet­ter job. Also, how the hell do you spend tens of mil­lions of dol­lars on fil­ter­ing soft­ware devel­op­ment? You know, it’s not that hard, derr. I could give you the name of quite a few free projects the Gov­ern­ment could adapt to fit with the help of two C++ pro­gram­mers and a few weeks. Unless said project decides to invest a few mil­lion in gold-plat­ed chairs or a new build­ing full of point­less super­vi­so­ry staff.

At its peak, about 30,000 peo­ple had tak­en up the gov­ern­men­t’s offer of free fil­ter soft­ware. 30,000! From an Aus­tralian sub­scriber base of 12 mil­lion or more!

Believe it or not James, not every­one with an Inter­net con­nec­tion has kids, has kids of a the appro­pri­ate age, requires new fil­ter­ing soft­ware (oth­er soft­ware exists, includ­ing stuff ISPs offer already), or shares your obvi­ous polit­i­cal posi­tion on carte-blanch filtering.

Fur­ther, despite the noisy oppo­si­tion to the ISP-lev­el fil­ter­ing pro­pos­al, par­tic­u­lar­ly from the tech­nol­o­gy sec­tor, Mum’s and Dad’s were gen­er­al­ly in favour in Gov­ern­ment fil­ter­ing the kind of con­tent that the RC cat­e­go­ry is applied to.

Wrong, and a total­ly slant­ed sta­tis­tic. Again, we’re not all par­ents, and we don’t all have kids, and we don’t all want the same arbi­trary restric­tions as those who are par­ents. You’re miss­ing a fun­da­men­tal point here: why are you apply­ing a “solu­tion” meant for a select tar­get audi­ence to all of us? Your use of the col­lo­qui­al ‘Moms and Dads’ instead of nam­ing a spe­cif­ic demo­graph­ic also reeks of loaded lan­guage.

The fact that the oppo­nents of manda­to­ry fil­ter­ing qui­et­ly accept­ed the vol­un­teer ISP fil­ter­ing by the nation’s three largest ISPs – which will block child abuse sites – is just strange.

Wrong. We expressed dis­sat­is­fac­tion and frus­tra­tion that those ISPs caved in with­out con­sid­er­ing the ram­i­fi­ca­tions. We do not accept their deci­sion. Where are you get­ting this idea from? And again, you’ve tied that sen­tence in with a sim­pli­fied ver­sion of the truth: ‘block child abuse sites’. This para­graph’s utter absur­di­ty is exposed when you write it hon­est­ly: … qui­et­ly accept­ed the vol­un­teer ISP fil­ter­ing by the nation’s three largest ISPs – which will block arbi­trary con­tent at the Gov­ern­men­t’s sole dis­cre­tion – is just strange. Does­n’t quite have the same effect as the slant­ed rhetoric of the oth­er ver­sion though.

All the die-hard anti-cen­sor­ship pro­test­ers and free speech lib­er­tar­i­ans were in effect say­ing that Gov­ern­ment fil­ter­ing (or cen­sor­ship in their lan­guage) indeed had its place in our soci­ety and that only dif­fer­ence they had with Gov­ern­ment was over pre­cise­ly where the line was drawn.

This is called a straw­man argu­ment. You may have heard of it. Don’t do it; it’s essen­tial­ly a manip­u­la­tive way to seed fear, uncer­tain­ty and doubt. If that’s your goal then you should­n’t been in journalism.

With­out the Lib­er­als sup­port, with­out the Coali­tion, Gov­ern­ment will not be able to get its manda­to­ry plan through the Sen­ate if it is re-elected.

What? I don’t know how to inter­pret this sen­tence; is it just a state­ment, a request to put pres­sure on the Lib­er­al par­ty, or polit­i­cal cam­paign­ing for Labor? I’m very confused.

Regard­less, even with the ad hoc vol­un­tary scheme, the account­abil­i­ty and trans­paren­cy mea­sures that gov­ern the black­list will need to be passed.

Wrong. Which sites a par­ent choos­es to block in a PC-lev­el fil­ter­ing pro­gram becomes a deci­sion for that par­ent alone. I don’t see the Gov­ern­ment pass­ing a black­list bill for my AdBlock sub­scrip­tion, so why this? Rec­om­men­da­tions are as far as this should go.

This debate has legs in it yet. Cer­tain­ly the inter­net fil­ter issue gen­er­at­ed more heart than any tech­nol­o­gy-relat­ed pub­lic pol­i­cy debate of the past 30 years.

Yet hard­ly any­one out­side the ISP and tech­ni­cal com­mu­ni­ties know how it works or the future reper­cus­sions of installing black-boxed fil­ter­ing machines. The main­stream media has­n’t dis­sect­ed the sys­tem for lay­men, and arti­cles such as yours con­tin­ue to pave over all the inter­est­ing tech­ni­cal and polit­i­cal detail and tote the ben­e­fits while ignor­ing the problems.

And so much mis­in­for­ma­tion was prop­a­gat­ed about how the fil­ter would work, and what kinds of con­tent that it would cap­ture that what passed for debate often descend­ed into per­son­al abuse and name calling.

And much of the vit­ri­ol was heaped on Com­mu­ni­ca­tion Min­is­ter Stephen Con­roy, who became a kind of light­ning rod for crit­i­cism on any­thing fil­ter related. 

Sure­ly you’re famil­iar with how dis­hon­esty from the Gov­ern­ment leads to dis­trust amongst the peo­ple. We dis­trust Con­roy and asso­ciates because time and time again they’re used inac­cu­rate lan­guage, mis­in­for­ma­tion and dem­a­goguery when describ­ing the fil­ter. Con­roy should­n’t have his post because he isn’t tech­ni­cal­ly com­pe­tent. The posi­tion, espe­cial­ly in this debate, requires explic­it tech­ni­cal knowl­edge which he does­n’t possess.

Per­haps we should put Fred Nile into the Com­mu­ni­ca­tion Min­is­ter posi­tion. I’m sure Mr Nile’s per­son­al views would­n’t affect the deci­sions he makes as part of his respon­si­bil­i­ty to reflect pub­lic opin­ion in a senior polit­i­cal posi­tion with the pow­er to lim­it the trans­fer of infor­ma­tion. Behold the sec­ond rea­son we dis­trust Mr Con­roy: deci­sions with seri­ous, long-reach­ing con­se­quences require a com­plete­ly objec­tive view­point, and that has­n’t been demonstrated.

The Coali­tion has enjoyed watch­ing Sen­a­tor Con­roy twist in the breeze over this pol­i­cy for well over a year. Final­ly they have announced which way they’ll jump on this issue.

That the Coali­tion has ten­ta­tive­ly grown a sin­gle ver­te­brae of a spine should­n’t dis­tract from the fact that their oth­er­wise jel­ly-like corpse has been silent­ly flap­ping in said breeze for two years. Their politi­cians wait­ed until polling group returns showed they could use the issue to boost per­cent­ages, not that they tru­ly believe what’s said in their media release. Pol­i­tics in this coun­try (at least for the two intractable par­ties) has devolved into vague promis­es of unique per­spec­tives and solu­tions while effec­tive­ly para­phras­ing the oppos­ing par­ty’s poli­cies and work­ing only to main­tain a sad and sor­ry status-quo.

——-

Arti­cles about poten­tial­ly cru­cial top­ics such as Inter­net fil­ter­ing require sta­tis­tics, frank lan­guage and the abil­i­ty to under­stand a deep, tech­ni­cal sub­jec­t’s con­se­quences in both the tech­ni­cal and soci­etal areas. If you have the van­tage of a jour­nal­is­tic soap­box and only have a fleet­ing grasp on the top­ic — or even worse a polit­i­cal­ly-biased view­point — you run the risk of turn­ing a com­plex argu­ment into a bunch of talk­ing points and sub­jec­tive gum flapping.

Come on guys, jour­nal­is­m’s core is objec­tiv­i­ty. Watered-down report­ing and opin­ion-seek­ing has drained the media of its abil­i­ty to present tan­gi­ble facts that actu­al­ly prompt read­ers to con­sid­er their posi­tion on an issue. Weav­ing in your opin­ion between facts com­pli­cates your read­ers’ abil­i­ty to analyse and make deci­sions since they first have to extract truth from fic­tion — and that’s sup­posed to be your job!

posted by Andrew

August 5, 2010

Proposition 8 sputtering

From news.com.au’s Cal­i­for­ni­a’s gay mar­riage ban over­turned:

Judge Walk­er was with­er­ing in his crit­i­cism of Propo­si­tion 8.

“Propo­si­tion 8 fails to advance any ratio­nal basis in sin­gling out gay men and les­bians for denial of a mar­riage license,” he wrote in his judgement.

“The state does not have an inter­est in enforc­ing pri­vate moral or reli­gious beliefs with­out an accom­pa­ny­ing sec­u­lar purpose.”

Although my favourite quote is def­i­nite­ly this baf­fling statement:

Lawyers for the back­ers of Propo­si­tion 8 made the case that lim­it­ing mar­riage to oppo­site-sex cou­ples is vital to pub­lic inter­est because it pro­motes pro­cre­ation, which is fun­da­men­tal to the sur­vival of the human race.

Indeed, because I know so many gay men and women who would ignore their sex­u­al­i­ty in the pur­suit of get­ting mar­ried. Oh yeah. What world are you idiots liv­ing in? We’re ask­ing for equal rights so that we don’t have to ignore our sexuality.

Adden­dum: anoth­er excerpt from the Judge Walk­er’s rul­ing state­ment.

posted by Andrew

August 4, 2010

Testing form submission locally in IE: an interesting bug/feature

A friend sent me a chunk of code with an inter­est­ing bug: on one par­tic­u­lar PHP script, IE would­n’t sub­mit the form. Every oth­er brows­er would. The first fix was rea­son­able, the sec­ond bizarre.

For the first fix, the offend­ing lines of code looked like:

   echo "<div class=\"form\"";   
   echo "<form action=\"index.php\" method=\"POST\">";

See it? The end of the first line does­n’t include a > to com­plete the <div> tag. The result in IE’s DOM:

   <div class="form" method="POST" action="PRMT_process.php" <form="">

The lack of a > caused the <form>‘s attrib­ut­es to be con­sumed by the pre­vi­ous <div>. Not sure how we end up with an attribute called ‘<form’ at the end, but it could be a quirk of IE’s pars­er stack that will­ing­ly con­sumes garbage char­ac­ters and coerces them into attrib­ut­es. Nasty. This meant there was­n’t a <form> tag open so the sub­mit but­ton had noth­ing to do.

But that did­n’t fix it. I ripped out the con­tents of the form and test­ed; no. Ripped out the code before the form includ­ing the boil­er­plate; no (inci­den­tal­ly, if a <form> is the first tag in the code — eg. no <body> — then the <form> is dropped on the floor by the pars­er). Even­tu­al­ly I end­ed up with this testcase:

   <body>
      <form action="index.php" method="post">
         <input type="submit">
      </form>
   </body>

Now at this point I was very, very con­fused. Dumb­found­ed. Espe­cial­ly since I’d looked at the file in hex-view to make sure strange Uni­code char­ac­ters had­n’t invad­ed then checked the encod­ing and BOM. I re-typed each line. Still did­n’t work.

I typed the con­tents out in a sep­a­rate file and copy/pasted over the top of the bro­ken one; still did­n’t work.

I copied the orig­i­nal file and opened the copy; still did­n’t work. I vis­it­ed ‘witch­craft’ on Wikipedia and researched human sac­ri­fice, per­formed a sacred rite involv­ing goats, 13-point stars and heavy breath­ing to the East; still did­n’t work.

I opened the prop­er­ties dia­log for the file on a whim:

Windows file properties dialog for the broken HTML form file

Were you aware that Win­dows auto­mat­i­cal­ly adds pro­tec­tion to a file that was trans­ferred from anoth­er PC, even if it was orig­i­nal­ly a .txt file? I cer­tain­ly did­n’t know it would dis­able form sub­mis­sion should the file be com­plete­ly renamed and opened in one par­tic­u­lar brows­er. Inter­est­ing. What kind of weird-arse check is being per­formed deep inside IE to do this? Is this relat­ed to why local AJAX does­n’t work?

I do see the point of this; Unknow­ing User #523 is sent a file and told to rename and open it in IE to receive a free pay­ment of five mil­lion Niger­ian pan­das or some­thing, and JS auto-sub­mits a form con­tain­ing infor­ma­tion from their machine. But what’s the dif­fer­ence between this file being on a web­site or run­ning local­ly? JS should­n’t have high­er priv­i­leges, and there’s no local-file access apart from <input type=‘file’>, and a file con­trol’s val­ue can’t be set in HTML or JS auto­mat­i­cal­ly. Is this a pro­tec­tion against secu­ri­ty bugs in the brows­er that the shell team devel­oped, which then required obscure changes to IE’s code­base any­way? Urgh.

Long sto­ry short: if your oper­at­ing sys­tem is doing funky, hid­den stuff to files that make them break in com­plete­ly unre­lat­ed sit­u­a­tions, show a bloody mes­sage some­where. IE6 gave us the yel­low bar when JS was dis­abled for local files — ter­ri­bly annoy­ing and arguably point­less, but at least it was a mes­sage. This is just arcane.

posted by Andrew

August 2, 2010

The Drum Unleashed: Political porn as the sun rises

Hilar­i­ous arti­cle by Cather­ine Deve­ny on the ‘debate’ between Fam­i­ly First’s Wendy Fran­cis and the Aus­tralian Sex Par­ty’s Fiona Pat­ten on morn­ing television:

Look out, up next, the inter­net fil­ter. Fran­cis played the ‘You’re either with us or with the child rapists card.” Pat­ten was forced to explain to Fran­cis that child sex abuse is ille­gal, the Inter­net will not stop it and that any­one involved in child sex abuse should be pros­e­cut­ed and sent to jail. Not allowed to continue.

See also this fine arti­cle writ­ten by Fiona Pat­ten on net cen­sor­ship and hypocrisy.

Please stop vot­ing the two prac­ti­cal­ly iden­ti­cal polit­i­cal par­ties into pow­er. Make a big, unavoid­ably notice­able dent in their vote tal­lies and give sen­si­ble, adult-fac­ing pub­lic pol­i­cy a chance.

posted by Andrew