stream of a consciousness
Writings on personal projects, politics, religion, society, education, and what ever other rants cross the mind of cgranade.
Monday, December 30, 2013
Sunday, September 15, 2013
Hacking Up Map Tiles for Tabletop RPGs
This post was written in collaboration with Ben Criger.
We want to make tabletop gaming more fun. That means removing tedium and headaches, making games more visually gripping, and giving gamemasters the tools they need to quickly construct worlds for their players. As it stands, this world-building has to be suspended whenever combat breaks out. Too much time is spent to track what combantants are where, what the environment is like, where important objects and effects are, etc. This motivation is part of why we have previously tackled projects like hero_init, which removes from gamemasters running HERO System games much of the burden of keeping track of initiative orders and of communicating combat numerics to players.
Today, though, we'd like to look at another part of the picture: the combat map.
The map serves as a visual language for roleplaying combat; it represents the environment shared by the players and narrators. For games that are entirely about the map, such as war games, maps are lovingly prepared with all manner of props and decorations, at great cost (both in money and time).
For RPGs, however, the tool of the trade is often a wet-erase mat on which map features are drawn at game-time, slowing down combat and exploration. If a GM is well-prepared, they might have eschewed a wet-erase mat for a map predrawn on paper, but that presents its own problems (how does the GM reveal map details "on the fly," for instance).
Many elaborate tools and solutions exist and are being developed, including ones based on projectors, flat-panel TVs, augmented reality, etc. These ideas are not yet generally applicable, though, if only because of cost, preparation time, and the specialized knowledge needed to make them work well.
Our approach is to use a combination of rapid prototyping tools (in particular, 3D printers and laser cutters) to manufacture physical objects that help in quickly building and annotating rich environments in which minifigs can be readily placed and moved. The first step in this approach is to make tiles that can support minifigs, markers for annotating characters and locations, and that can be quickly connected and rearranged. By adding pegholes to these tiles, environmental details can be added around minifigs. 3D-printed risers together with pegholes in the tiles allow for the map to be quickly extended into the third dimension, as is useful, for instance, in superhero games with flying characters.
By making tiles from readily-available acrylic, we can prototype these ideas quickly and effectively using equipment found in hackerspaces like KwartzLab (thanks tp help from our good friend Catherine Holloway). The tile shapes are generated procedurally by a Python library, while the 3D printed parts are generated using OpenSCAD. This allows for rapid customization and manufacturing, and keeps costs low. More importantly, we will soon be making the software implementing these procedures open source, so that gamers can make their own map tiles and accessories without having to ask for permission, and can remix and extend our ideas in new and interesting ways.
Our first batch doesn't have the pegholes, due to a DXF error that has since been fixed, but with what we have right now, we can already confirm that our designs can be connected and disconnected quickly. Moreover, we can start making marker accessories for things like character numbers (useful for mooks!), grenades, status (slow, poisoned, etc.).
Eventually, we'd like to have the design down enough that we can sell tiles and accessories for those players and game masters that either don't have access to time, equipment and expertise to manufacture their own, or that prefer to buy them pre-made. Towards that goal, we'd like to offer readers of this blog a set of our map objects to use in their own games, so that you can let us know how you like them. If you're interested, please let us know!
We want to make tabletop gaming more fun. That means removing tedium and headaches, making games more visually gripping, and giving gamemasters the tools they need to quickly construct worlds for their players. As it stands, this world-building has to be suspended whenever combat breaks out. Too much time is spent to track what combantants are where, what the environment is like, where important objects and effects are, etc. This motivation is part of why we have previously tackled projects like hero_init, which removes from gamemasters running HERO System games much of the burden of keeping track of initiative orders and of communicating combat numerics to players.
Today, though, we'd like to look at another part of the picture: the combat map.
Hero Game, 8one6. Used under Creative Commons BY-SA 2.0 license. |
The map serves as a visual language for roleplaying combat; it represents the environment shared by the players and narrators. For games that are entirely about the map, such as war games, maps are lovingly prepared with all manner of props and decorations, at great cost (both in money and time).
Dark Angels Meet Orks on Warhammer Armies, Steve Goeringer. Used under Creative Commons BY-ND 2.0 license. |
A Riverboat In the Swamp, MockLogic. Used under Creative Commons BY 2.0 license. |
Our approach is to use a combination of rapid prototyping tools (in particular, 3D printers and laser cutters) to manufacture physical objects that help in quickly building and annotating rich environments in which minifigs can be readily placed and moved. The first step in this approach is to make tiles that can support minifigs, markers for annotating characters and locations, and that can be quickly connected and rearranged. By adding pegholes to these tiles, environmental details can be added around minifigs. 3D-printed risers together with pegholes in the tiles allow for the map to be quickly extended into the third dimension, as is useful, for instance, in superhero games with flying characters.
By making tiles from readily-available acrylic, we can prototype these ideas quickly and effectively using equipment found in hackerspaces like KwartzLab (thanks tp help from our good friend Catherine Holloway). The tile shapes are generated procedurally by a Python library, while the 3D printed parts are generated using OpenSCAD. This allows for rapid customization and manufacturing, and keeps costs low. More importantly, we will soon be making the software implementing these procedures open source, so that gamers can make their own map tiles and accessories without having to ask for permission, and can remix and extend our ideas in new and interesting ways.
A few tiles from our first batch. |
Eventually, we'd like to have the design down enough that we can sell tiles and accessories for those players and game masters that either don't have access to time, equipment and expertise to manufacture their own, or that prefer to buy them pre-made. Towards that goal, we'd like to offer readers of this blog a set of our map objects to use in their own games, so that you can let us know how you like them. If you're interested, please let us know!
Friday, September 13, 2013
Free Speech, Pervasive Harassment and a Stopgap Effort
The Internet can be a very unkind place; more specifically, it can be home to some very unkind people. If you are a woman speaking up on about feminism, for instance, harassment and taunting can quickly become a terrible norm. There are entire communities (I will not link to them, even with nofollow) that seem to be dedicated to the use of harassment, taunting, stalking and spamming to silence people on the internet that speak up for themselves and those they care about. As bad as all that is, it's even worse if you openly identify as trans* or an ally.
The technology that delivers such harassment, however, can also be used to try and recover some peace. Any worthwhile social media network in existence today allows users to block anyone they wish without giving cause. Importantly, no one needs to justify to others whom they wish to separate themselves from. We get to set our own boundaries and shape our own social environments. That said, the sheer volume of harassment directed at some users can be daunting enough that manually blocking individual harassers becomes onerous and triggering. Thus, tools like the Atheism+ Block Bot for Twitter are used to help curate lists of repeat harassers so that users looking to make a quieter and more welcoming social environment for themselves have the tools to do so.
Of course, the Block Bot is rather unpopular in certain crowds, to say the least. It is derided as everything from an expression of groupthink to a violation of Twitter's terms of service. One truly disgusting aspect of many objections is how the concept of free speech is invoked to oppose any attempt to filter out or curtail the flow of such harassment online. There is practically a pocket industry to misunderstanding what freedom of speech means when it comes to harassment, discrimination and bigotry (most recently, I would categorically object to Mathew Ingram's characterization of the response to Pax Dickinson's hateful Twitter habits), so let me be very clear on this point: speech has consequences. Freedom of speech does not mean that anyone else is obligated to listen to what you say, to condone it, to broadcast it on your behalf or (as is relevant in Dickinson's case) to continue employing you when your speech compromises your ability to do your bloody job. In particular, other people have the right to talk about you when you use your speech to harass, intimidate, annoy and otherwise bully another person. If what they decide to do is to warn others that you may not be worth spending time and emotional effort interacting with, then that is a consequence of your speech that must be accepted in order for freedom of speech to have any useful meaning whatsoever.
All that aside, there has been (and I stress that this is my opinion, informed in part by my own privileges and biases) a single objection to the Block Bot that rings true: that the nature of the block lists offered by the Block Bot so far is not transparent. It is not easy, for instance, to determine which admins added which users to the block lists and why. Rather than use this objection as an excuse to remove from people their ability to quickly filter their social environment, however, I wish to address the objection at a structural level. In particular, I would like to build a blocking tool that does not in any way build in my own values or views, but is a tool that can be used in a transparent way by me, by my friends, by my detractors or anyone else that desires to.
That is, I want the process of building, disseminating and applying blocklists to be decentralized. I do not want to be the arbiter of anyone's social media environments, nor do I want anyone else to be. Rather, I want people to have access to the tools they need to usefully employ social media networks without the constant threat of harassment and bullying.
Thankfully, the web is already decentralized in precisely this way. A blocking tool that simply fetches lists from various websites is thus abstracted away from the particular motivations of those running such websites. Moreover, transparency can be achieved by using standard tools common in the open source movement, such as Git, which track the history and contributions to a given file in a robust and decentralized manner. Thus, using this approach, one would pick blocklists curated by users that they trust, each hosted in Git repositories that track metadata and history in a rich and reusable manner.
With all due respect, then, to the authors and maintainers of The Block Bot, I have taken my own stab at the problem based on these principles. I have developed a userscript (that is, a small JavaScript library that runs inside your browser and modifies websites that you view on the fly) that modifies Twitter to block users based on one or more killfiles of your choice. This userscript is itself open source (under the AGPLv3, one of the strongest copyleft licenses available), such that it can be modified, reused and repurposed without my approval or even my awareness.
Instructions on how to use this userscript are available at the GitHub repository where it is hosted. If you are interested, please use it and let me know what you think and how it can be improved. With your help, I hope we can take the next step towards making social media a tool we can all use safely and productively. This isn't the end of the story, and we must continue to work for making a better Internet, but I think it is, at the least, a useful stopgap that can help mitigate the worst of what many users currently have to go through in order to participate.
The technology that delivers such harassment, however, can also be used to try and recover some peace. Any worthwhile social media network in existence today allows users to block anyone they wish without giving cause. Importantly, no one needs to justify to others whom they wish to separate themselves from. We get to set our own boundaries and shape our own social environments. That said, the sheer volume of harassment directed at some users can be daunting enough that manually blocking individual harassers becomes onerous and triggering. Thus, tools like the Atheism+ Block Bot for Twitter are used to help curate lists of repeat harassers so that users looking to make a quieter and more welcoming social environment for themselves have the tools to do so.
Of course, the Block Bot is rather unpopular in certain crowds, to say the least. It is derided as everything from an expression of groupthink to a violation of Twitter's terms of service. One truly disgusting aspect of many objections is how the concept of free speech is invoked to oppose any attempt to filter out or curtail the flow of such harassment online. There is practically a pocket industry to misunderstanding what freedom of speech means when it comes to harassment, discrimination and bigotry (most recently, I would categorically object to Mathew Ingram's characterization of the response to Pax Dickinson's hateful Twitter habits), so let me be very clear on this point: speech has consequences. Freedom of speech does not mean that anyone else is obligated to listen to what you say, to condone it, to broadcast it on your behalf or (as is relevant in Dickinson's case) to continue employing you when your speech compromises your ability to do your bloody job. In particular, other people have the right to talk about you when you use your speech to harass, intimidate, annoy and otherwise bully another person. If what they decide to do is to warn others that you may not be worth spending time and emotional effort interacting with, then that is a consequence of your speech that must be accepted in order for freedom of speech to have any useful meaning whatsoever.
All that aside, there has been (and I stress that this is my opinion, informed in part by my own privileges and biases) a single objection to the Block Bot that rings true: that the nature of the block lists offered by the Block Bot so far is not transparent. It is not easy, for instance, to determine which admins added which users to the block lists and why. Rather than use this objection as an excuse to remove from people their ability to quickly filter their social environment, however, I wish to address the objection at a structural level. In particular, I would like to build a blocking tool that does not in any way build in my own values or views, but is a tool that can be used in a transparent way by me, by my friends, by my detractors or anyone else that desires to.
That is, I want the process of building, disseminating and applying blocklists to be decentralized. I do not want to be the arbiter of anyone's social media environments, nor do I want anyone else to be. Rather, I want people to have access to the tools they need to usefully employ social media networks without the constant threat of harassment and bullying.
Thankfully, the web is already decentralized in precisely this way. A blocking tool that simply fetches lists from various websites is thus abstracted away from the particular motivations of those running such websites. Moreover, transparency can be achieved by using standard tools common in the open source movement, such as Git, which track the history and contributions to a given file in a robust and decentralized manner. Thus, using this approach, one would pick blocklists curated by users that they trust, each hosted in Git repositories that track metadata and history in a rich and reusable manner.
With all due respect, then, to the authors and maintainers of The Block Bot, I have taken my own stab at the problem based on these principles. I have developed a userscript (that is, a small JavaScript library that runs inside your browser and modifies websites that you view on the fly) that modifies Twitter to block users based on one or more killfiles of your choice. This userscript is itself open source (under the AGPLv3, one of the strongest copyleft licenses available), such that it can be modified, reused and repurposed without my approval or even my awareness.
Instructions on how to use this userscript are available at the GitHub repository where it is hosted. If you are interested, please use it and let me know what you think and how it can be improved. With your help, I hope we can take the next step towards making social media a tool we can all use safely and productively. This isn't the end of the story, and we must continue to work for making a better Internet, but I think it is, at the least, a useful stopgap that can help mitigate the worst of what many users currently have to go through in order to participate.
Sunday, March 24, 2013
Python, MATLAB and legacy interop.
I promised that this space would see more of my side projects and random recreational efforts, so today, I'd like to introduce another of my stray software libraries: pymex. This library embeds the CPython 2.7 interpreter into MATLAB using MEX, so that Python software may be integrated into legacy MATLAB applications. (I realize I'm showing my bias here, but I consider MATLAB development to be so badly broken as to be legacy, irrespective of when a MATLAB application was made.)
In particular, pymex exposes Python to MATLAB via the py_eval.m function, which evaluates a MATLAB string as a line of Python as if passed to Python eval() inside the embedded interpreter's __main__ module. Moreover, MATLAB code can access the Python __main__ module by using py_eval.m and py_put.m; the resulting Python objects are abstracted within MATLAB by the PyObject.m class (currently very incomplete), which translates MATLAB operators and methods into calls to the corresponding CPython API functions.
If the called Python code needs to execute something back within MATLAB, then this can be accomplished by importing the pymex extension module exposed by pymex_fns.c and calling pymex.mateval(). The pymex extension module also exposes other functionality, such as pymex.get(), which allows Python code to dynamically extract variables from MATLAB workspaces.
Of course, all this leaves the question: why bother? With more and more hardware being exposed not just through C APIs, but also with Python modules, pymex can help in getting legacy MATLAB applications communicating with cutting-edge hardware. For example, I have recently discussed Galvant Industries in various places— their GPIB/USB adapter ships with an impressive array of Python modules for controlling common instruments.
The other main advantage of embedding Python into MATLAB is that legacy MATLAB applications can then gain access to the wealth of scientific Python code that has been written as of late. For example, I hope to bring tools such as the excellent SciKit-Learn and QuTIP2 libraries into the world of MATLAB. I have before collaborated in the creation of Python-language scientific tools for use in quantum information, including QuaEC and Qinfer, that also could potentially be of use to those developing MATLAB applications.
While none of this is anywhere near done, polished or even well-documented yet, I thought I'd share a bit of my software hackery with the world. With a bit of luck, this project will help make interop nightmares a bit less pronounced and increase the range of tools available for scientific development and hardware control.
In particular, pymex exposes Python to MATLAB via the py_eval.m function, which evaluates a MATLAB string as a line of Python as if passed to Python eval() inside the embedded interpreter's __main__ module. Moreover, MATLAB code can access the Python __main__ module by using py_eval.m and py_put.m; the resulting Python objects are abstracted within MATLAB by the PyObject.m class (currently very incomplete), which translates MATLAB operators and methods into calls to the corresponding CPython API functions.
If the called Python code needs to execute something back within MATLAB, then this can be accomplished by importing the pymex extension module exposed by pymex_fns.c and calling pymex.mateval(). The pymex extension module also exposes other functionality, such as pymex.get(), which allows Python code to dynamically extract variables from MATLAB workspaces.
Of course, all this leaves the question: why bother? With more and more hardware being exposed not just through C APIs, but also with Python modules, pymex can help in getting legacy MATLAB applications communicating with cutting-edge hardware. For example, I have recently discussed Galvant Industries in various places— their GPIB/USB adapter ships with an impressive array of Python modules for controlling common instruments.
The other main advantage of embedding Python into MATLAB is that legacy MATLAB applications can then gain access to the wealth of scientific Python code that has been written as of late. For example, I hope to bring tools such as the excellent SciKit-Learn and QuTIP2 libraries into the world of MATLAB. I have before collaborated in the creation of Python-language scientific tools for use in quantum information, including QuaEC and Qinfer, that also could potentially be of use to those developing MATLAB applications.
While none of this is anywhere near done, polished or even well-documented yet, I thought I'd share a bit of my software hackery with the world. With a bit of luck, this project will help make interop nightmares a bit less pronounced and increase the range of tools available for scientific development and hardware control.
Labels:
imadeathing,
legacy,
matlab,
programming,
python
Friday, February 22, 2013
hero_init: Closing the gap between tabletop and CRPGs.
My projects haven't always worked out so well, especially where gaming is concerned. That said, I do think there's some real opportunities to improve upon what we think of as tabletop gaming by bringing ideas and tools from computer-based RPGs to the, well, table. Others have done an excellent job of challenging the idea of what it means to have a map, and of bringing tabletop mentalities into the realm of web-based gaming, but there's a lot of areas yet to be explored. In particular, what does it mean for gaming when every player brings to the table a tiny device with a huge screen that is constantly connected to everything around it (that is, a smartphone)?
Enter hero_init. This latest project is an attempt to answer this in a bit less ambitious of a fashion than Project Umbra (though I would like to get back to that at some point). At first blush, hero_init seems to be a straightforward scriptable initiative tracking tool for HERO System 6th Edition, but there's a bit more to it than that.
The DM's view of hero_init, but not the complete story. |
While there's a lot of utility to offering DMs nice tools to manage combats in an orderly fashion, that's hardly too innovative. Where hero_init starts to flesh out my ideas, however, is in that little status display at the top, tauntingly reading out "Server Status: Offline." Type in the command "server start", and the GUI changes to show a link that the DM can give to players that will provide them with extended information about the combat.
The hero_init DM console after enabling the server. |
That's right, hero_init embeds a primitive webserver. This server tells players when it's their turn, how much health and endurance they have left and when their next turn will be.
Seems like it's Alice's turn! |
Incremental as this might be, I think that there's some real potential to this small proof of concept. By reducing the amount that DMs and players have to think about managing rules and communicating statistics, the focus of the game can change to more interesting things, like story-building, role-playing, world exploration, tactics and even lighthearted banter. Less bookkeeping means more freedom to explore the game itself.
More dramatically, when computing is brought to the table, new kinds of rulesets become feasible that were previously not reasonable. Here, for instance, powers that allow combatants to slow and speed up other combatants by manipulating time become more tractable, offering more creative choices to DMs and players alike. With more sophistication, hero_init could allow for still more creative play by freeing DMs from having to track the myriad kinds of damages and statuses that would normally result from the inclusion of strange and esoteric powers.
Once we've asked how computers can help augment the games we already play, the next question naturally poses itself: how can computers help us make new kinds of rules and game structures altogether? Take, for instance, that a hallmark of the modern J-RPG is to play around with initiative systems. Final Fantasy is famous for its Active Time Battle system (and its many variants) that allows characters to be differentiated based on not just strength, dexterity and magical prowess, but also on raw speed. What Final Fantasy X player hasn't just shined with delight as they cast Hastega, throwing the entire party into double-time? While tabletop systems like HERO allow for this to some extent, they still lack the sheer expressiveness of Grandia II's rich initiative system, which allowed for players to specialize party members in different combat actions such that some characters could nearly instantly use items while others could cast spells as quickly as the animations would allow. Why not, then, take the next step and design a tabletop RPG that draws more heavily from the rich history of C-RPGs while still putting all of the world-deciding power in the hands of humans?
In this way, I see hero_init as asking a question of the gaming community. That question has as many exciting and wonderful answers as there are talented storytellers ready to play.
By the way, I should mention that hero_init is open source (AGPLv3), portable (written in Python, depending only on PySide and Qt4) and oh-so-forkable (GitHub for the win). Please feel free to play around with it. The code's a bit of a mess, it being a proof of principle so far, but I would love to see what people can do with it!
A return and reorientation.
It's been a long while, and a lot has happened since I last tried my hand at blogging. The time has come for me to return to it, though, albeit with a few changes. While I do plan on still ranting occasionally, I would like to take the opportunity afforded to me by returning from a long hiatus to reconsider what this blog is about. In particular, I would like to take some more space to talk about the personal projects that occupy my spare time these days. By doing so, I would like to present more of what excites and motivates me, rather than focusing on talking solely about the problems that society faces. That is, I'd like to show the web a bit more of a complete view of me and what I do than I used to.
These changes notwithstanding, I plan on leaving all of my old posts intact; my words are there, however misguided they might be in retrospect. Moreover, I still plan on airing my rants on occasion. Rather, I intend to make sure that such ranting is not to the exclusion of all else.
To start things off, I will soon be posting about a new gaming project (yes, another one). Thanks for hanging in there!
These changes notwithstanding, I plan on leaving all of my old posts intact; my words are there, however misguided they might be in retrospect. Moreover, I still plan on airing my rants on occasion. Rather, I intend to make sure that such ranting is not to the exclusion of all else.
To start things off, I will soon be posting about a new gaming project (yes, another one). Thanks for hanging in there!
Subscribe to:
Posts (Atom)