Weekend refactor

I’m not sure how I will feel on the day it’s time, but the weekend might be for a little bit of work; coming in and getting some housekeeping done would be nice. Not having a clock is good and bad. The latter, I think, comes or may come in other places; for lacking that immediacy here – not being of the revenue-generating sort – is a sort of relief. To have as my earlier jobs more laid back than a comparable startup elsewhere is almost a blessing.

It blows my mind that the average income here for my work is so high. I guess a lot of that goes into doing things you are forced to do or to push things that don’t stem from ghost specs and autonomy. Out of a page, a prototype; out of emails, iteration. Maybe I am still naive about both my ability and of brilliant betters: my GitHub is still pretty empty.

I’ve reached a local maxima with my tech stack. It’s time to learn something like Ruby on Rails or to get deeper into perl. Game programming has been primarily about vectors – it doesn’t feel like programming, though. Just parroting concepts, no execution of ideas.

Programs are written to solve problems, and maybe that’s what I need: some motivation for a physics toolbox, a logic solver – applications to aid my rote exercises, efficiency without the expense of ink.

We the [group] privileged

In Access 2007, group is a reserved word; so wherever you refer to it, surround it in brackets: [group]. Otherwise, you will get errors.

One app controls approval perms via groups and users. Users are added to groups, and group membership determines privileges. Unofficially – because it’s not an explicit database field – the owner of a created object is the first person in the object’s state history.

Maintenance is done out-of-band; that is, separate programs. A cPanel would be nice, but it’s easier to throw widgets onto a coordinate canvas. The backing store is a database, so SQL is our “agnostic” language.

Separating administration from the web view decreases process management on the server. The administrative program is its own thread on a remote machine. This tradeoff isn’t worth the security risk of distributing a standalone root executable, though. In either case, knowing the authentication credentials is sufficient.

Top two queries in Access

My two most important queries with Access are

  • get the latest event of a record’s history
  • insert with nested select

The first is useful to prevent extra bookkeeping tables. You lean on the declarative nature of SQL to let the engine figure out your need: sort it for me, pick out the top one, thanks.

select tbl1.event_id, event.name, status.name
  (select tbl1.event_id, 
    (select top 1 id 
    from eventhx as latest,
    where tbl1.event_id = latest.eventid
    order by timestamp) as latest_hx_id
    (select eventhx.eventid as event_id
    from eventhx, status
    where status.name = 'UPCOMING'
    and status.id = eventhx.statusid order by recordstamp desc) 
    as tbl1) 
  as tbl2, eventhx, status, event
where tbl2.latest_hx_id = eventhx.id 
and tbl1.event_id = event.id
and status.id = eventhx.statusid
and event.id = eventhx.eventid

Here is an insert with nested select:

insert into emp (firstname,lastname,genderid)
  select 'susan', 'gray', tbl1.genderid
    (select top 1 id from gender where name = 'female') as tbl1

Quick web apps for effective longevity

Dramatica espouses the “timelock” and “optionlock”: constraints on the characters to pace and contain the narrative.

I implemented a personal bulletin board inbox that tracks status changes of little messages. Everyone’s time is tracked now. It’s like Gmail measuring your productivity. Hilarious. Hopefully it sees widespread use, because I’m sort of proud of it – not because of its technical execution, but because programmers write programs to be used, not to be ignored.

I abuse Mojolicious::Lite in the worst way: it’s all MVC, but it’s all pipes and opens. It’s not scalable, but I like to think this is what Rails looked like before a thousand lines. My next step is to learn tcl and Expect to test the database and driver.

SQL queries got me to thinking about game mechanics. You can either make everything data in the table, or you can construct queries that leverage the existing information. Ideally, every query is an ordered join among the minimum necessary tables, but I have seen some monstrous queries: a half-page diagnostic of a failed one, mercilessly smooshed together into a wall of text.

Capability hesitance

At work I challenge myself to implement solutions, but at home I’m like, “Well, that’s already been done before.” If it’s only about monetary compensation and caring about stakeholders, I should be addicted to freelancing. From a capabilities perspective, I ought to make my own toy engines for

  • an adventure game
  • a side-scrolling platformer
  • a non-scrolling, dynamic action game (Tetris clone)
  • a card game
  • an RPG

And all this before 3d.

Two other concepts that are hugely important TODOs: sound and networking.

I’ve at least framed it; now to get to it.

Little founder

Continuing software development has justified hiring another programmer for in-house projects. This is really cool, because my contributions helped management consider the position of dedicated app-creators instead of only application support folks. It lends legitimacy to my efforts, that we can solve problems with new software and not only more people.

Collaboration means we need to lean on more tools: namely, source control and unit testing (at a minimum). I want to be able to use existing code whenever possible, so having a canonical codebase will free us to experiment and integrate as requirements dictate. Hopefully, we will not get into arguments about one approach being better than another.

That’s one of my primary concerns: whether the new person wants to build a monolithic empire, a one-sized framework, stretched pieces across a single language membrane. I like small tools and pipes, I/O streams and operating system-assisted asynchronicity. I pick the language for the job and glue programs with the shell. It’s a natural fit, and not one I would willingly give up.

Windows in windows

I’m pretty close to just working on an RPG engine. You have to start somewhere. RPGs use separate windows for managing inventory, so let’s look at arbitrary, draggable rectangles. (gif)


I’m on the images chapter; I should be exulting in images. I need to demonstrate snapping though. That’s important for inventory management. And the windows themselves should only be movable from the title bar, while their innards are content.

What I ought to be doing is iterating completed works!

Division and ordinals

Division by two numbers with the same units, canceling those out, produces a naked quotient. This has two meanings: the first is the number of ticks which can be marked along the (longer) numerator, each of length equal to the denominator; and second, it is the farthest ordinal of the collection.

For example, you have a 10-foot plank. Dividing by 2 feet, you get the number 5. That means you can have five 2-foot planks, but it can also mean “the 5th position of these demarcated planks.”

This concept is demonstrated in snap-to, where you want to find the pixel position of the nearest logical coordinate to move an object such that it aligns with a grid. Up to a deviation of half the width of the smallest default tile, find the leftmost position in pixels given x in pixels.

In the calculation, you would go from the given x position in pixels to the nearest logical coordinate and then back to pixels for moving it there. Up to a certain point, floor(x/2) from 10 to 11.9 is 5.

Bordered game board II

I was wrong before: the border is incidental based on our parameters:

  • the width of game board
  • the width of the smallest piece
  • the number of pieces per row

That last part was where I stumbled. I assumed a larger-width table and the border thus, but the border’s width is incidental to the dimensions of your piece, not determined before.

So it’s the width of the game board, large enough, subtracted by the width of the smallest piece times the number of pieces per row, halved: that will equal the width of each border.

We expect the border to vary from game to game depending on the size of the smallest piece and how many pieces go on each row.

An array[][] could be mapped onto a two-dimensional scrolling screen. If we treat the array indices as the logical positions, the upper left tile of our view would be

view_x_offset / tile_width = logical_x // or array index [x][]

Although this feels like a reverse lookup, graphical to logical…

Grid offset

In the previous post, we figured out the width of the borders around a game board. Now, if we know the width of the smallest piece – or that of a single tile – we can determine the x- and y-position to draw it, even though we only establish a screen-independent numbering.

bbb| (0,0) | (1,0) | (2,0) |...|bbb

The “bbb” stands for the width of our border or 15px.

We can multiply by the x-coordinates 0, 1, 2, etc by the width of the smallest piece and add on the length of the border to get the position at which we can draw. Assuming our piece width is 10px,

pair  x-coord  draw at
0,0   0        0 * 10 + bbb (15) = 15px
1,0   1        1 * 10 + 15 = 25px
2,0   2        2 * 10 + 15 = 35px

That’s our spacing. The money is that if we make bigger tiles, the mapping to screen x- and y-positions is automatic!

   ^ 15px ^ 25px ^ 35px ...

This is really helpful because Brackeen’s fifth chapter features tile offsets plus parallax. Armed with these details may give us a fighting chance.