Saturday, August 20, 2016

AxiDraw circles in Python

So, I got an AxiDraw 2-axis plotter (or, as I prefer to refer to it, "DrawBot") from Evil Mad Science - ordered it a while ago, just arrived about a week ago.

I drew several of the sample figures that came with it, including Barack Obama and Taylor Swift's signatures, which will be useful when I want to forge the signatures on the Obama-Swift treaty I'm writing up.

And then, me being me, I dug into the Python code to draw some test figures.

My first attempt was using the axidraw-xy code, which connects to the CNCserver node.js server, which yielded not entirely satisfactory results.



It seems that the AxiDraw's stepper motors need to be driven together or opposing to get axis aligned steps, and at equal magnitudes. CNCserver imposes some scaling and some clamping. I spent a little time trying to reverse those transformations, but decided that it was easier to take the Inkscape extension code and kill off the Inkscape-specific bits and make a standalone bit of code.

The results are promising:



The code I was working with provides functionality for starting from a stop, accelerating along the path, and decelerating to come to a stop at the end. So, for my circle drawing, I just draw a bunch of short segments, which means the head is lurching along the entire time. It seems like it wouldn't be too hard to pass in a set of points to connect, and base the exit velocity of one segment (and entrance velocity of the next) on the angle between the segments - for basically colinear segments, maintain full speed - for perpendicular or sharper angles, drop to a stop.

Still, it's satisfying to have a little bit of Python producing tangible results:



or, if that doesn't work: https://goo.gl/photos/fmmXhqagCtpUrCLZ9



If you want to mess around with this, first buy a plotter DrawBot, then grab my code from GitHub: https://github.com/tsmaster/axidraw/tree/master/inkscape%20driver



Monday, August 1, 2016

More-onoi


More thinking about Voronoi regions, and using them to generate irregular game tiles.

Actually, I haven't done a lot of new thinking, but I've been meaning to jot down some notes and open questions, so when I get time to work on this, I'll make sure I'm not missing things.

Before the questions, though - maybe you want to hit this link:

http://bigdicegames.com/TheTwenty/IVor/index.html

And hit 'R' after things settle down to restart it.

What that tool is doing:
  • places some number of "sites" (gray dots) on the screen, with a random radius from 24 to 40 pixels.
  • for each pair of sites A and B, constrains them to be no closer than the sum of the two sites' radii
  • for each site, constrains it to remain onscreen
  • repeat the above until there's no remaining movement
  • generate a voronoi diagram for the resulting locations
  • draw the diagram, leaving out line segments to infinity
Simple stuff. I'm using https://github.com/jceipek/Unity-delaunay for my voronoi generation, which seems adequate. I tried some other (downstream) forks of that code, and couldn't get stuff to work. I may fiddle with this version and upload my own unmaintained fork, because we need more of that.

So, some thoughts about what I see in that demo:
  • It's fast enough that I could probably regenerate the voronoi diagram every frame.
  • The caption says "interactive", and aside from pressing 'R', it's not.
  • I'm not entirely satisfied with the site topology - if you look at the bottom center of the picture above, you'll see one tallish thinnish tile with a bunch of sites clustered around it like a horseshoe or a little bit like the Saint Louis Arch. Maybe not very much like the Saint Louis Arch. It doesn't feel like the kind of connectivity I want. I suspect that if I get the Lloyd Relaxation step in, that kind of clustering might go away.
  • I'm not defining what's wrong with the horseshoe/arch clustering. I'm not sure I have a good definition. I think what's bothering me is the short edges. You can see other short edges elsewhere, and they bother me, too.
  • There are long edges in the diagram, like ones that go off the edge of the screen. I don't really care about those, as I intend to be generating these maps at larger than screen resolution.
  • There are occasionally places where a tile will be drawn, but the gray dot won't be drawn. That's almost certainly a bug in the way that I'm drawing my gray dots. I'm using Vectrosity for my line and dot drawing, and I like it, but it's a "retained mode" API, and I think I'm updating the dot list incorrectly, leading to some dots getting lost.
  • I generate all the dots at once. I could generate them adaptively, putting dots in areas that aren't densely filled.
  • I want to stick in some obstacles (walls, trees) and terrain types (open, rough, water) and plop a player-controlled character on there to get the feel of walking around. I meant to do that a week ago, but have got distracted with other stuff.
Ok, so that's what I've done. The point of the post was meant to be what my concerns and open questions are about this whole approach, what I'm trying to answer with these experiments.
  • This is a whole lot of work, is it worth it? That's the big question. I think most of the rest of the questions feed in to this one.
  • How do you handle straight-line effects? There's two parts of this, and maybe they have different answers. Let's think of two spell effects that one might have: Explosive Fireball and Ray of Embitterment. The fireball's effect might be centered somewhere in a tile, and effect everything "nearby". Is "nearby" defined in terms of tiles? Probably not. In order to feel right, I suspect that I want to draw an actual circle in screenspace (or in cartesian worldspace, not tilespace) and use that as my area of effect. Similarly for the ray, I'll want to trace out a long, thin rectangle, and use that. These aren't hard to do for a computer game, and could be approximated for a miniatures game using rulers and whatnot. Seems like it can be done. A variant of this is how to handle flying movement, but that's really the same thing, I think.
  • If the tiles represent different movement effects, what about directional effects like "uphill/downhill"? I think that I'm going to have to handle certain effects on a case-by-case basis. A short list of these features: uphill/downhill, rivers (going with, against, across the current), roads (some vehicles will be able to move at good speed as long as they stay on a road, that's logic inside the vehicle, not inside the map).
  • How does one meaningfully author a map like this? For regular tiled grids, or "continuous" maps, you can use a tiled map editor or a 3d terrain editor. For this stuff, it feels like the editing pipeline is going to be hard to use. Right now, I'm guessing that the world will be laid out as vector features (a road is a spline with a width, a forest is a polygon) which will then be used to generate the grid.
  • How does "facing" feel? One reason that I think that people like hex grids is that if your game mechanics takes facing into account, a hexagon provides a reasonable level of fidelity. Better than a square, and... well, there aren't a lot of other regular options to work with. I want to get some code running to really answer this for myself, but my feeling right now is that with short edges, facing will feel fiddly. With more uniform edges, maybe it'll feel better.
  • Do the adjacent tiles feel close enough for tactical combat? In this demo, tiles are supposed to be pretty close to the same size, though even now, it's not entirely working. If I have a melee unit in a small tile, and the neighboring tile is 3x as big, does that feel unrealistically far away? Or, if I'm standing in a large tile, maybe I have a lot of nearby small tiles (in a horseshoe arch cluster, perhaps) - are they all able to engage me in melee?
  • If a tile is large, should it permit multiple units inside it? Does that break the whole notion of tiles? I think I'm going to have to play around a lot to get the feel for this. Maybe with good smoothing, the problem goes away. I don't know yet.
  • Supposing I want units of different sizes, ranging more than one order of magnitude - is that a problem? What if the units aren't roughly circular in footprint? I'll almost certainly have small creatures in the game. Rats, or spiders, or something suitable for an annoying first encounter in the basement of the first building you walk into. But I think I'll also want a rock giant. Maybe some colossal creature striding through the ocean that you encounter. There's lots of possibilities. I also have this half-baked idea of segmented monsters, a little like the dragon in "Space Harrier", or the tentacles in games like R-Type. It's maybe weird to think of using those kinds of approaches for a tiled, tactical, turn-based combat RPG. Maybe not. My current thinking is that a giant unit would have a center point that moves just like any other unit, so maybe there's nothing special about a giant. And segmented serpents might just have a sequence of adjacent tiles that they occupy. Now that I talk about it, there's a pretty good canonical segmented creature already in gaming.
  • One thing that discrete tiles offer is a manageable set of choices, fighting analysis paralysis. Does getting rid of regularity work against this? Maybe. I'm hoping that with good UI, it'll be easier to decide where I'm going and be able to make a good selection.
  • But keyboard control is basically out, right? Probably. If there's somewhere between 4 and 8 neighbors of each tile that you visit along your move, there's unlikely to be good key-bindings to select the correct neighboring tile.
  • But let's say that some places you want regular tiling, can you support a square grid or a hex grid? Would it be possible to smoothly go from chaotic irregular grids to regular grids? Probably. A while ago, I did some experiments with this question, and the results weren't immediately successful, but I think there's potential.

Ok, so given all of those questions, I think my TODO list includes:
  • make a map with some obstacles and some different terrain types
  • put a character with facing on that map
  • build a UI that allows movement (with facing) on that map
  • put some other creatures on the map to "fight" with
So, yeah, basically make a game to figure out if this is how I want to make my game.

Saturday, July 23, 2016

Going Back to the Voronoi Well


I like hex maps. There's something pretty about them, and one of the first "serious games" I played - by which, I suppose I mean a game involving thinking, made for grown-ups - was on a hex grid. (That game was Outdoor Survival, derided as one of the worse Avalon Hill games, made on a bet, or a dare, or some other poor form of boardgame design inspiration).

I also dig maps with irregular spaces. Look at the spaces on the Risk board. OK, those are countries. How about the spaces on a Gammarauders board: https://boardgamegeek.com/image/118956/gammarauders?size=medium (still not a terrific game, but relevant to this discussion. Oh, and they're within larger hex tiles, to make layout interesting).

A while ago, I was doing some fiddling with using Voronoi Diagrams to make irregular polygonal tilings, with an itch to see if a computer RPG might use those as an interesting "grid" for a map.

Let's say your unit has a move of 8 spaces. And maybe the spaces are of different sizes, smaller on rough terrain, larger where it's smoother / flatter / clearer / easier. You can count out an 8 space path on the grid, and it's all easy. My barbarian guy only has a move of 6 spaces, and so he's not going to catch up to you, so long as you're trying to escape.

Irregular grids feel a little more natural - like something that'd be created by some natural process. Regular grids of squares or hexagons are obvious abstractions, lines laid down by some divine geometer.

One reservation I have with an irregular grid is that it assumes a single mode of travel - let's say walking. But what if your birdman unit wants to fly across the map? Seems like he would disregard surface terrain considerations (but he might have his own wind current issues to consider).

The above image is a Voronoi diagram of a bunch of vertices laid out in concentric circles. I've rotated each circle a random amount, to keep things from getting too regular, but you can still see regions where the spaces are nearly a square grid and others that look pretty close to a regular hexagon grid.

I'm considering implementing Lloyd's Relaxation algorithm to try to smooth out some of this, but it requires computing a centroid per tile, which is more work than I really care to do right now. I could do Laplacian relaxation, which is simpler, and might be just about as good.

I really just wanted to post the pretty picture.

Thursday, May 19, 2016

Ceviche’s CafĂ©

Not a blog post about food - though that sounds good right about now.

Instead, this is more about griping about technology, which is more in line with what I usually write.

The 2016 Seattle International Film Festival has just opened as I write this. 25 days of upwards of 300 movies. I was told upwards of 400 movies, but I'm not sure about that. The biggest film festival in the United States.

In years past, I've got the big fancy catalog to flip through to decide what I wanted to see. There's a PDF of a smaller catalog, which is also helpful. And on SIFF's website, there's a "My SIFF" feature which allows you to keep track of the stuff you have tickets for. Or, for the folks who buy a series pass, you can still register your interest in specific showings.

It doesn't (as far as I can tell) export to useful things like Google Calendar for easy reference on the go.

So, in addition to cursing the darkness, I set about to put things into a more useful format. I didn't get explicit permission from SIFF for this, so I'm not advocating that you do what I have done. I wrote a Python script that uses urllib(2) and Beautiful Soup to pull down and then interpret web pages. With a little bit of poking around, I was able to interpret individual movie pages, to figure out where and when the showings are. There are a lot of venues and a lot of screenings going on.

After collecting that information, I proceeded to push the movies up onto Google Calendar, which you can see here: https://calendar.google.com/calendar/embed?src=tbbr77hpo9aqi5b98qdr2el2ls%40group.calendar.google.com&ctz=America/Los_Angeles

I actually did most of that last year for SIFF 2015. This year, I discovered that some of the movies some friends wanted to see weren't showing up on the Google Calendar. I poked through the debug log that was generated when I wrote the data to the calendar, and it turned out I was detecting some sort of error condition on certain movies, skipping them, and continuing on.

As I dug deeper, I determined that the error condition had something to do with Unicode encoding and/or decoding. Oh, joy.

One thing that was an interesting issue is that some of the URLs that SIFF uses have non-ASCII characters in them. It's OK, as long as you encode those characters properly. For example, http://www.siff.net/festival-2016/ceviche%E2%80%99s-dna has the right quote (not part of 7-bit ASCII) properly wrapped. If you try to get urllib2 to download the URL that you see in the browser address bar, it'll choke.

Maybe there's a better way to do this, but I ended up just finding the last slash and hitting the part of the URL after that with an encoding pass, because my efforts to encode the whole string led to the slashes being converted, which isn't any good.

Ok, so I can handle right quotes, maybe.

There's a bunch of other characters that show up, like in the opening movie, "Café Society". My tool took several passes, writing and rewriting title text, using the title as a key when storing the movie information in the python "shelve" format, reloading it, and somewhere along there, unicode titles were getting mangled, and I was having a hard time making sure that they got re-encoded or re-decoded, or encoded and decoded or something. I kept throwing more random layers at the problem, and it still wasn't really working for me.

In the end, I realized that I could grab the title text as ascii for the purposes it already served (particularly being a key for shelve) and then also grab a Unicode version of it alongside for generating the calendar entries.

Which ended up working really well. I'm astonished I didn't think of it earlier.

I also added in a pass where if I found '&' in the text, I'd convert it to '&'. Again, there were fancier, probably better ways which I tried and had a hard time with. So, I did a simple replacement specifically targeting that one character.

In the end, it works pretty well - I've got several things that I might change about the script before 2017, but in a lot of cases, my life would be easier if SIFF exposed an API to pull movie information from. I know that SIFF isn't in the API business, so maybe if I contacted them, they'd refer me to the company that handles their web presence, and maybe that'd be a useful conversation.

Or, maybe what I've got is good enough for a while.

Sunday, February 14, 2016

Now with more intentional pew pew, and randomly driving into stuff that doesn't need to be driven into


What's in there that you didn't see last time? A few things.

  • I added in a raycast to determine if the shot that a box takes is occluded (by a static box, by a moving box, by a dead box), which makes things seem more purposeful.
  • Not that you'd notice it, but there were several bugs in my collision code. One made the physics boxes twice as wide as they should have been, but only for dynamic tests, like for the paths of bullets and moving boxes. Thus the "corridor map" was out of sync with things that moved.
  • Boxes target nearby boxes sometimes, they randomly pick places to patrol to sometimes.
  • Boxes target nearby boxes, which may lead to one or more of them shooting them up (which, I know, you've seen that bit) or it may lead to them getting stuck in an embrace of, I want to say "death", but it's just an embrace of hostility - they're trying very hard to move into the location of the other box, which is simultaneously trying very hard to move in the opposite direction. I've seen two and three boxes get in these cycles. I could put some special case logic in there to say "oh, no, what you really want to do is engage at this ideal radius for this weapon", but I want to come back to that later, possibly with a different approach altogether.
It's getting to the point where the stuff I want to do next is largely falling under the category of "activity selection", like choosing to search for a better path for several ticks, or choosing not to patrol when a box discovers an enemy box. Also, there's stuff here I'll call "aggregate behavior" that I'd like to do, like allowing boxes to call for help, and flank their targets.

It feels like I've done a lot, and after spending a bunch of time refactoring just to fix bugs, working on this doesn't feel quite as exciting as it did before that, but things are in a better state, so that's good. I recently heard Jonathan Blow use the term "code morale" which matters on real projects and screwy little tech demos like this.

One thing you don't see in that movie is a piece I added in where I can hit a key to cycle a "selection" marker from colored box to colored box, which draws them with a little highlight, but more interestingly (to me, I don't want to speak for you good people), it dumps a bunch of debug spew to the console for just that one box. Hm, potential feature for approximately never: create debugging facilities that are keyed on the box, and a debug console that can select what feed to watch.


Saturday, February 13, 2016

Now with random Pew Pew


The first thing here is that I'm experimenting with MP4 movies of my progress - I'm using ffmpeg to capture the video, since my previous method (using byzanz to create animated GIFs) had an upper limit of less than a minute. Maybe you get enough of all of this in 15 seconds, but I, for one, need more box-moving-around-time than that.

Also, I split the teams up finer. Now, we have 6 teams of 2 boxes each, in festive colors. Were the people demanding that? Festive colored boxes seems good.

Also, they can shoot at each other now. There's no intelligence involved - each tick, there's a 1% chance that a box will spawn a bullet in a random direction. Bullets check for collision with the moving boxes and the static boxes. If they hit a moving box, they apply damage. If they hit anything, they deactivate themselves.

Boxes that lose 4 points of damage become inactive.

You can almost root for boxes to survive, if you want.

TODO:
aim more intelligently
retreat from threats (when wounded?)
track weapon heat
call for help
flanking
particle effects when bullets impact

Friday, February 12, 2016

Boxes not hugging the other boxes




What you see here is the introduction of a "corridor map", a network of navigation landmarks that the boxes use to find their way around obstacles. It's an improvement over yesterday's behavior of getting stuck on walls, in that the boxes are somewhat aware of the obstacles now. They can still get stuck, so there's room for being more aware of not making progress on a plan and bailing out to try something different.

Thursday, February 11, 2016

Boxes not overlapping


Adding to yesterday's demo, the boxes are now a couple different colors, still moving around. Now they bump into each other and use a simple constraint system to ensure that they don't overlap.

Also, I added some fixed boxes in the world that boxes might move around. Except they're not really smart enough to do that yet. Sometimes, they knock each other loose.

TODO: make stuff smarter.

Wednesday, February 10, 2016

Something a little different


This doesn't tie in to my previous posts, really. Just screwing around, getting a PyGame / OpenGL framework up and running.

There's a few boxes moving around the screen. So, that's something.

Friday, February 5, 2016

Spaceship Flying In Space

Back in college, before I knew much about anything, I gave a resume to a tiny little company called HDC Computer Corporation. That name kind of pegged them (constrained them?) to be a Microsoft Windows development house.

They managed to get some of their stuff bundled into Windows-286, if I recall correctly, including a little space shooter game called "HDC Rocks". Yes, it was about shooting rocks in space. Also, the title was a gag and tongue-in-cheek motto.

The Internet doesn't seem to remember that little nugget, but maybe it will now.


What you see here is the rebuilt version of as far as I had got on my "Space Rocks" demo - a little space ship moving around on the screen, rendering in OpenGL 2.1, with a window provided by SDL2.

Nothing's particularly exciting about it - the pathfinding, if you can call it that, is "move horizontally, then move vertically". There's no real obstacles. It doesn't have a lose condition.

But it's running again, OpenGL commands, as issued from my language, sent through a C shim to a vanilla OpenGL implementation.

As I mentioned in my previous post, I had lost a file (failed to check in my work) called gl_tools.c, which contained that layer, so the effort necessary to reproduce it was simply(?) a matter of exporting GL calls down into my library.

Sort of. The time management code is coming from SDL, so that took a little more attention. The initialization of an OpenGL context isn't quite as simple as I had recalled. I made use of Lazy Foo' Productions' SDL/OpenGL tutorial to figure out what bits I really had to rebuild inside my shim library.

And there you go, it's working again. And checked in, besides.

I even made myself a little convenience tool that launches the program, records frames of it rendering, then compresses that into an animated GIF all in one handy script. I could make it slightly cleverer, by forcing the window to open up at a particular point on the desktop, which would keep you from looking at my emacs window in the background. But maybe emacs makes you comfortable. I wouldn't want to deprive you of that.

The cursor, though, not so sure about that. I could easily suppress the cursor.


So. The demo is back up and running, and the thing I was running into back in July when I last checked stuff in (I don't remember this stuff, but GitHub does) was that I wanted to have a solid story about what I was doing with arrays of complex objects (like structs, say, like you might need to have for a bunch of asteroids floating across your screen). Would arrays have to be statically allocated? What's initialization like? Am I going to have pointers to these things? Python and Java don't have pointers, except that they do, but you don't see them. Is that what I want?

I want to avoid copying complex objects except by explicit deliberate action. It feels like there are a few other choices that can come as a result of that, but I haven't really meditated deeply enough to make it obvious how things ought to work. Perhaps the next step is to try some stuff, and be prepared to roll back if I don't like how things are working.

Wednesday, February 3, 2016

Setbacks, and starting not from scratch

So, it's been a while since I've posted about my compiler project. Projects being what they are, you don't always have steam for everything.

And then, a few months ago, the laptop where I had been doing my development was taken. I can curse the darkness, but it's not as bad as it might have been - I had most of the project checked in to two offsite locations. So, that's nice.

At the risk of Pollyanna, this is an opportunity to verify that I don't have hidden dependencies that I wasn't aware of. So, I'm starting on a new machine, and hopefully, I'll be back to productivity soon.


I've added a Prerequisites page to my development Wiki. (Is that external? I forget. Probably not, or I'd link here.) It's the stuff you'd expect:

  • LLVM 3.6
  • libedit-dev
  • enum34
  • llvmlite
  • PLY
  • emscripten
  • SDL

Ok, maybe not all of that is expected. I think llvmlite's dependencies could be tidied up. And maybe I don't need SDL for everything, but for the Pong sample app, I did.

Once I got stuff installed and cloned the repo down onto my machine, I built the pong demo as a local executable, and it worked great.

I haven't yet rebuilt the web version, but you can play it here, if you like: http://bigdicegames.com/BDGRT/Pong/pong.html - I just link it because I keep forgetting where it is, so this is a bookmark for my own purposes. Also, I notice that that doesn't play nicely with my (current) version of the Chrome browser, but it does in Firefox.

Looking back through my checkin log, I see that I had been doing work on my Asteroids tribute sample, but when I try to build it, it looks like gl_tools.c never got checked in, so I get to rewrite that. How hard can that be? Just wrapping stuff like gl_begin and gl_color3f. I should be able to knock that out in short order, maybe tonight.

I'm also noticing that building emscripten targets (like the web version of Pong) is failing, probably due to not having installed certain bits of emscripten.

But, I'm delighted to say that my little test programs for computing factorial and Fibonacci stuff worked just fine.