One of the most important things I find important when I design programs is the User Interface. I am a firm believer that things should just work the way you think they should.
When I was looking to put my own stamp on Unleashed Pixel Dungeon the first thing I noticed was that pressing on the Quick-Slot item brought up a targeting dialogue, but did not auto-select any of the available enemies. I wanted to make it so that if a previous (still living mob) has not been targetted it will randomly select a visible mob from those available to use as a default. Pressing the Quick-Slot item again (double tap) will auto-target that mob. You could always select a different mob if you prefer, this is just for convenience.
I started playing with the QuickSlotButton.java, visible enemies are stored in the Dungeon.Hero structure, so in the useTarget() function (which is called when we click the Quick Slot Button with something that uses targetting) we first check to see if we already have a target selected and it is one of the available targets, otherwise we iterate through the list of visible targets and randomly select one of them...
I guess we could select the closest, or the weakest, or the toughest, or the one that is awake... for right now I am just selecting a random target. The only thing left to do is save off that target so that we can continue attacking it the next turn. I am also saving the lastTarget off in the Hero structure so we can potentially link Melee attacks against the same target in the future.
It was a fairly painless mod to implement and a nice introduction (for me) into the code. The full fix is available on GitHub.
Enjoy,
David
Father Nature's Ramblings
Thursday, July 30, 2015
Unleashed Pixel Dungeon version 1
I have been meaning to learn Java better for quite some time now, which has led me to my latest project over the last month and a half: Unleashed Pixel Dungeon.
I am very excited about contributing to this Open-Source project. Basically, this is a Roguelike game where you control a single adventurer and explore a randomly generated dungeon, with a lot of the content randomly generated (scroll names, potion colors, etc...) in order to keep the game fresh and exciting. Food is generally scarce, and you will probably die a lot. But, if you are smart you can discover strategies to survive; each obstacle is a puzzle to be solved.
Unleashed is based on the wonderful Pixel Dungeon and Shattered Pixel Dungeon variants. I am hoping to spend a few posts talking about the specifics, but here is my current change log for the first version:
DSM-0000 Moved code into the Android Studio directory structure
DSM-0001 Fixes needed to get code to compile
DSM-0002 Place Unleashed stamp on the game
DSM-0010 Increase dungeon level size to 40x38
DSM-0011 Reduce Hunger impact
DSM-0012 Item drops in High-Grass
DSM-0013 Improved drops in Crypts and Treasuries
DSM-0014 Adjust drop tables
DSM-0020 Add five new dungeon levels
DSM-0021 New Mobs - Slimes/Assassins
DSM-0022 Level-up Buffs
DSM-0023 Max Hero Level is now 35 - effects mobs max levels
DSM-0024 Exp to Level tweaks to hit level 30 by depth 30
DSM-0025 Level to Power tweaks to make mobs more balanced
DSM-0026 new BURNT level type
DSM-0030 Save/Load Screens
DSM-0031 Allow saves only at Level Entrance Signs
DSM-0040 Item Level Caps
DSM-0041 Chance of Upgrade Failure
DSM-0042 Artifact Weapons
DSM-0043 Glowing Weapons
DSM-0044 Allow enchanted weapons to be upgraded
DSM-0045 Armor Glyph descriptions
DSM-0046 Auto Aim with Staff/Thrown Weapons
DSM-0047 Better MageStaff imbuing
DSM-0050 Altar Dungeon Feature
DSM-0051 Altar Room
DSM-0052 Altar Donations on drop
DSM-0053 Archway Dungeon Feature
DSM-0054 Prison Room - locked with bones
DSM-0055 Make the "SECRETS" level feeling less common
talk to you soon,
David Mitchell
I am very excited about contributing to this Open-Source project. Basically, this is a Roguelike game where you control a single adventurer and explore a randomly generated dungeon, with a lot of the content randomly generated (scroll names, potion colors, etc...) in order to keep the game fresh and exciting. Food is generally scarce, and you will probably die a lot. But, if you are smart you can discover strategies to survive; each obstacle is a puzzle to be solved.
Unleashed is based on the wonderful Pixel Dungeon and Shattered Pixel Dungeon variants. I am hoping to spend a few posts talking about the specifics, but here is my current change log for the first version:
DSM-0000 Moved code into the Android Studio directory structure
DSM-0001 Fixes needed to get code to compile
DSM-0002 Place Unleashed stamp on the game
DSM-0010 Increase dungeon level size to 40x38
DSM-0011 Reduce Hunger impact
DSM-0012 Item drops in High-Grass
DSM-0013 Improved drops in Crypts and Treasuries
DSM-0014 Adjust drop tables
DSM-0020 Add five new dungeon levels
DSM-0021 New Mobs - Slimes/Assassins
DSM-0022 Level-up Buffs
DSM-0023 Max Hero Level is now 35 - effects mobs max levels
DSM-0024 Exp to Level tweaks to hit level 30 by depth 30
DSM-0025 Level to Power tweaks to make mobs more balanced
DSM-0026 new BURNT level type
DSM-0030 Save/Load Screens
DSM-0031 Allow saves only at Level Entrance Signs
DSM-0040 Item Level Caps
DSM-0041 Chance of Upgrade Failure
DSM-0042 Artifact Weapons
DSM-0043 Glowing Weapons
DSM-0044 Allow enchanted weapons to be upgraded
DSM-0045 Armor Glyph descriptions
DSM-0046 Auto Aim with Staff/Thrown Weapons
DSM-0047 Better MageStaff imbuing
DSM-0050 Altar Dungeon Feature
DSM-0051 Altar Room
DSM-0052 Altar Donations on drop
DSM-0053 Archway Dungeon Feature
DSM-0054 Prison Room - locked with bones
DSM-0055 Make the "SECRETS" level feeling less common
talk to you soon,
David Mitchell
Back from Hiatus
Well, it's been a long time since I've posted on here. I had changed my email account, and then wiped my personal laptop so that I could work on Android Development.
Long story short; I am very grateful for the Blogger password recovery options.
I am very excited about some new projects I've been working on including my first Android - Google Play release "Unleashed Pixel Dungeon"!
More on that shortly,
David
Long story short; I am very grateful for the Blogger password recovery options.
I am very excited about some new projects I've been working on including my first Android - Google Play release "Unleashed Pixel Dungeon"!
More on that shortly,
David
Sunday, November 17, 2013
Adventures in Compiling - Notepad2
I've been using Notepad2 for awhile now at work since it is an approved tool, and it's somewhat useful. I like the single document interface and the syntax highlighting, but it has a few drawbacks; it doesn't support Bash or Cygwin scripting.
Long story short I decided to download a copy and make a few modifications.
1. Download a copy of all the source code.
The source can be found on the Notepad2 page, after unpacking it into a project directory you also have to download a copy of the Scintilla source and place it in the top level project directory (ex. Notepad2\scintilla).
Notepad2 Source Code
Scintilla Source Code
2. Choose your development environment.
Pleasant surprise - everything is in C++. Since I'm using a Windows XP machine, and I'm cheap I opted for the free Microsoft Visual Studio 2010. Download, Install, Register. According to the instructions a few things need to happen first though, we need to locate the "lexlink.js" script and run it (double click). This modifies the Catologue.cxx file to remove syntax files from the Scintilla build that we don't care about.
Open up the solution and convert it and we should be good to go.
Now before we make any modifications we need to make sure that we can get a clean compile, otherwise we'll be chasing false errors as we make changes. It's about now that I discovered that my computer doesn't have a copy of winres.h on my system. This isn't such a big deal, a few web searches later and I locate my Microsoft SDK - Include directory (for me it's in Program Files) and added a new file named "winres.h" with these contents:
#include <winresrc.h>
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1)
That was easy, now I'm getting clean compiles without too much trouble.
3. Making some modifications.
Basically what I want to do is add in Syntax Highlighting for Cygwin/Bash. I want comments Gray, Strings Green, Executed Commands Orange, Numbers Red, Keywords Blue, Variables light blue, and External Commands (from Cygwin) with a gray background. Kind of like this:
First we need to add support for our Bash files. That Catologue.cxx file gives us a pretty good starting point - we want to uncomment out this line: ("//LINK_LEXER(lmBash);") and while we are at it we want to add in lmBash to lexlink.js so re-running it won't mess it up again. And then we add in the lexBash.cxx file to our Scintilla\Lexers in our project.
Now we need to add in support for our new type... searching around we run across the Styles.cxx file, this is where all of our keywords and format defaults are created. We need to do a few things here:
- increase the NUMLEXERS variables in the header to support one more type.
- Add in our new KEYWORDLIST.
- Add in our new EDITLEXER.
- Add our new lexer to pLexArray.
I created a script in BASH to generate a list of shell built-ins and common commands. It was easy enough to do these steps, but I quickly discovered that the Bash lexer doesn't support External Commands... only Keywords. I added them in as a new type anyway which involved adding a new ENUM type (SCE_SH_EXTERNAL) in SciLexer.h and tossing it in as an additional case to LexBash.cxx. We'll get back to this in a minute.
A KEYWORDLIST is an array of strings. Our Bash Lexer reads these into wordlists for internal use.
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[2]; // we added this one.
Pretty straightforward, we add the keywords to the appropriate list. The list is handled in LexBash.cxx. We are using the first string for BASH keywords (there are a few special cases in the lexer, so they don't need to be added).
KEYWORDLIST KeyWords_SH = {
// "if elif fi while until else then do done esac eval for case select "
"alias bg break builtin cd command compgen complete compopt continue declare dirs disown echo enable exec exit export "
"false fg getopts hash help history jobs kill let local logout mapfile popd printf pushd pwd read readarray readonly "
"return set shift shopt source suspend test time times trap true type typeset ulimit umask unalias unset wait fc", "",
"awk banner clear df diff dirname du egrep env expr fmt fold free ftp g++ gcc grep groups gzip head hostname identify "
"import integer install ipcs join ln login look ls make man man2html mkdir mkgroup more mount mv nice od perl print "
"ps rm rmdir script sed setenv sh since size sleep sort strings stty su tac tail tar telnet tidy top touch tput tr "
"umount uname uniq unix2dos unzip uptime users vmstat watch wc whereis which who whoami xargs yacc yes zip basename "
"bash bc c++ cal cat chgrp chmod chown chroot cksum cpp crontab cut date factor file find flip flock",
"", "", "", "", "", "" };
Next we add in our EDITLEXER, the first line matches the ENUM token SCLEX_BASH, a string ID from Notepad2.rc (we added: 63022 "Bash Script"), the fourth field indicates the file types that will default to this type, and then we finally get to our styles.
Each style line gives us the ENUM cases (from LexBash.cxx) that we are applying the given style to, a string ID that describes the rule (press cntrl-F12 to change rules for Bash and this is the identifier that will show up), and our Coloring Rules in field 4. If you want to combine multiple ENUM types to the same rules you can combine up to four of them using MULTI_STYLE. The last line is an empty rule.
EDITLEXER lexSH = { SCLEX_BASH, 63022, L"Bash Script", L"sh; bash", L"", &KeyWords_SH, {
{ STYLE_DEFAULT, 63126, L"Default", L"", L"" },
{ SCE_SH_COMMENTLINE, 63127, L"Comment", L"fore:#808080", L""},
{ SCE_SH_WORD, 63128, L"Keyword", L"bold; fore:#0000C0", L"" },
{ SCE_SH_EXTERNAL, 63236, L"External", L"bold; fore:#4040C0; back:#C0C0C0", L"" },
{ SCE_SH_NUMBER, 63130, L"Number", L"fore:#FF0000", L"" },
{ MULTI_STYLE(SCE_SH_STRING,SCE_SH_CHARACTER,0,0), 63131, L"String", L"fore:#008000", L"" },
{ SCE_SH_OPERATOR, 63132, L"Operator", L"fore:#0000C0", L"" },
{ SCE_SH_BACKTICKS, 63229, L"Backtick", L"fore:#FF8000", L"" },
{ SCE_SH_PARAM, 63249, L"Variable", L"fore:#0080C0", L"" },
{ -1, 00000, L"", L"", L"" } } };
OK, so now we need to make some changes to LexBash.cxx to recognize External Commands.
In ColouriseBashDoc() we tell it to save off a copy of our External Keywords:
WordList &keywords2 = *keywordlists[2];
And we Added our new SCE_SH_EXTERNAL as an additional case in the same place we handled SCE_SH_WORD.
case SCE_SH_WORD:
case SCE_SH_EXTERNAL:
At this point we can compile and test... all we need to do now is seperate the behavior for EXTERNAL and WORD. We use the "sc.ChangeState(_ENUM_VALUE_)" to apply the rule, so we need to handle the two types. Scrolling down to the very bottom of this case we make a minor modification - when we were going to apply the INTERNAL identifier check to see if this is an external command, if so change to SCE_SH_EXTERNAL, otherwise do what we were going to do originally.
else if (cmdState != BASH_CMD_START || !(keywords.InList(s) && keywordEnds)) {
if (keywords2.InList(s) && keywordEnds) {
sc.ChangeState(SCE_SH_EXTERNAL);
} else {
sc.ChangeState(SCE_SH_IDENTIFIER);
}
}
Compile, Run, Test... everything looked good. This was surprisingly easy... I got the whole thing done in about two hours. I think I've documented all of the stumbling blocks, and I feel comfortable modifying the code now. I might try to tackle some other things in the code, we'll see. I decided to throw this together as a tutorial in case anyone wanted to add support for their own favorite languages. Enjoy.
Thanks to Florian Balmer for his excellent software, and for making it available to the world.
Long story short I decided to download a copy and make a few modifications.
1. Download a copy of all the source code.
The source can be found on the Notepad2 page, after unpacking it into a project directory you also have to download a copy of the Scintilla source and place it in the top level project directory (ex. Notepad2\scintilla).
Notepad2 Source Code
Scintilla Source Code
2. Choose your development environment.
Pleasant surprise - everything is in C++. Since I'm using a Windows XP machine, and I'm cheap I opted for the free Microsoft Visual Studio 2010. Download, Install, Register. According to the instructions a few things need to happen first though, we need to locate the "lexlink.js" script and run it (double click). This modifies the Catologue.cxx file to remove syntax files from the Scintilla build that we don't care about.
Open up the solution and convert it and we should be good to go.
Now before we make any modifications we need to make sure that we can get a clean compile, otherwise we'll be chasing false errors as we make changes. It's about now that I discovered that my computer doesn't have a copy of winres.h on my system. This isn't such a big deal, a few web searches later and I locate my Microsoft SDK - Include directory (for me it's in Program Files) and added a new file named "winres.h" with these contents:
#include <winresrc.h>
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1)
That was easy, now I'm getting clean compiles without too much trouble.
3. Making some modifications.
Basically what I want to do is add in Syntax Highlighting for Cygwin/Bash. I want comments Gray, Strings Green, Executed Commands Orange, Numbers Red, Keywords Blue, Variables light blue, and External Commands (from Cygwin) with a gray background. Kind of like this:
First we need to add support for our Bash files. That Catologue.cxx file gives us a pretty good starting point - we want to uncomment out this line: ("//LINK_LEXER(lmBash);") and while we are at it we want to add in lmBash to lexlink.js so re-running it won't mess it up again. And then we add in the lexBash.cxx file to our Scintilla\Lexers in our project.
Now we need to add in support for our new type... searching around we run across the Styles.cxx file, this is where all of our keywords and format defaults are created. We need to do a few things here:
- increase the NUMLEXERS variables in the header to support one more type.
- Add in our new KEYWORDLIST.
- Add in our new EDITLEXER.
- Add our new lexer to pLexArray.
I created a script in BASH to generate a list of shell built-ins and common commands. It was easy enough to do these steps, but I quickly discovered that the Bash lexer doesn't support External Commands... only Keywords. I added them in as a new type anyway which involved adding a new ENUM type (SCE_SH_EXTERNAL) in SciLexer.h and tossing it in as an additional case to LexBash.cxx. We'll get back to this in a minute.
A KEYWORDLIST is an array of strings. Our Bash Lexer reads these into wordlists for internal use.
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[2]; // we added this one.
Pretty straightforward, we add the keywords to the appropriate list. The list is handled in LexBash.cxx. We are using the first string for BASH keywords (there are a few special cases in the lexer, so they don't need to be added).
KEYWORDLIST KeyWords_SH = {
// "if elif fi while until else then do done esac eval for case select "
"alias bg break builtin cd command compgen complete compopt continue declare dirs disown echo enable exec exit export "
"false fg getopts hash help history jobs kill let local logout mapfile popd printf pushd pwd read readarray readonly "
"return set shift shopt source suspend test time times trap true type typeset ulimit umask unalias unset wait fc", "",
"awk banner clear df diff dirname du egrep env expr fmt fold free ftp g++ gcc grep groups gzip head hostname identify "
"import integer install ipcs join ln login look ls make man man2html mkdir mkgroup more mount mv nice od perl print "
"ps rm rmdir script sed setenv sh since size sleep sort strings stty su tac tail tar telnet tidy top touch tput tr "
"umount uname uniq unix2dos unzip uptime users vmstat watch wc whereis which who whoami xargs yacc yes zip basename "
"bash bc c++ cal cat chgrp chmod chown chroot cksum cpp crontab cut date factor file find flip flock",
"", "", "", "", "", "" };
Next we add in our EDITLEXER, the first line matches the ENUM token SCLEX_BASH, a string ID from Notepad2.rc (we added: 63022 "Bash Script"), the fourth field indicates the file types that will default to this type, and then we finally get to our styles.
Each style line gives us the ENUM cases (from LexBash.cxx) that we are applying the given style to, a string ID that describes the rule (press cntrl-F12 to change rules for Bash and this is the identifier that will show up), and our Coloring Rules in field 4. If you want to combine multiple ENUM types to the same rules you can combine up to four of them using MULTI_STYLE. The last line is an empty rule.
EDITLEXER lexSH = { SCLEX_BASH, 63022, L"Bash Script", L"sh; bash", L"", &KeyWords_SH, {
{ STYLE_DEFAULT, 63126, L"Default", L"", L"" },
{ SCE_SH_COMMENTLINE, 63127, L"Comment", L"fore:#808080", L""},
{ SCE_SH_WORD, 63128, L"Keyword", L"bold; fore:#0000C0", L"" },
{ SCE_SH_EXTERNAL, 63236, L"External", L"bold; fore:#4040C0; back:#C0C0C0", L"" },
{ SCE_SH_NUMBER, 63130, L"Number", L"fore:#FF0000", L"" },
{ MULTI_STYLE(SCE_SH_STRING,SCE_SH_CHARACTER,0,0), 63131, L"String", L"fore:#008000", L"" },
{ SCE_SH_OPERATOR, 63132, L"Operator", L"fore:#0000C0", L"" },
{ SCE_SH_BACKTICKS, 63229, L"Backtick", L"fore:#FF8000", L"" },
{ SCE_SH_PARAM, 63249, L"Variable", L"fore:#0080C0", L"" },
{ -1, 00000, L"", L"", L"" } } };
OK, so now we need to make some changes to LexBash.cxx to recognize External Commands.
In ColouriseBashDoc() we tell it to save off a copy of our External Keywords:
WordList &keywords2 = *keywordlists[2];
And we Added our new SCE_SH_EXTERNAL as an additional case in the same place we handled SCE_SH_WORD.
case SCE_SH_WORD:
case SCE_SH_EXTERNAL:
At this point we can compile and test... all we need to do now is seperate the behavior for EXTERNAL and WORD. We use the "sc.ChangeState(_ENUM_VALUE_)" to apply the rule, so we need to handle the two types. Scrolling down to the very bottom of this case we make a minor modification - when we were going to apply the INTERNAL identifier check to see if this is an external command, if so change to SCE_SH_EXTERNAL, otherwise do what we were going to do originally.
else if (cmdState != BASH_CMD_START || !(keywords.InList(s) && keywordEnds)) {
if (keywords2.InList(s) && keywordEnds) {
sc.ChangeState(SCE_SH_EXTERNAL);
} else {
sc.ChangeState(SCE_SH_IDENTIFIER);
}
}
Compile, Run, Test... everything looked good. This was surprisingly easy... I got the whole thing done in about two hours. I think I've documented all of the stumbling blocks, and I feel comfortable modifying the code now. I might try to tackle some other things in the code, we'll see. I decided to throw this together as a tutorial in case anyone wanted to add support for their own favorite languages. Enjoy.
Thanks to Florian Balmer for his excellent software, and for making it available to the world.
Saturday, September 28, 2013
Complete CMQA Access Dump
I've been doing a lot of work on Access Database Migration lately and a question came up about how we could provide CM/QA level auditing of the current database. And that is what led me to coming up with the following bit of code attached to a little button in our new database.
Private Sub CMQA_Audit_Button_Click()
On Error GoTo Err_DocDatabase
Dim dbs As DAO.Database
Dim cnt As DAO.Container
Dim doc As DAO.Document
Set dbs = CurrentDB()
Dim OutDir As String
OutDir = CurrentProject.Path & "\" & Format(Now(), "ddmmmyy-hhmmss")
MkDir OutDir
Dim Tbl As TableDef
For Each Tbl In dbs.TableDefs\
If Tbl.Attributes = 0 Then ' Ignore System Tables
Application.ExportXML acExportTable, Tbl.Name, , OutDir & "\tbl_" & Tbl.Name & ".xsd"
End If
Next
Set cnt = dbs.Containers("Forms")
For Each doc In cnt.Documents
Application.SaveAsText acForm, doc.Name, OutDir & "\form_" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Reports")
For Each doc In cnt.Documents
Application.SaveAsText acReport, doc.Name, OutDir & "\rep_" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Scripts")
For Each doc In cnt.Documents
Application.SaveAsText acMacro, doc.Name, OutDir & "\scr_" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Modules")
For Each doc In cnt.Documents
Application.SaveAsText acModule, doc.Name, OutDir & "\mod_" & doc.Name & ".txt"
Next doc
Dim QryAs QueryDef
For Each Qry In dbs.QueryDefs
If Not (Qry.Name Like "~sq_*") Then
Application.SaveAsText acQuery, Qry.Name, OutDir & "\qry_" & Qry.Name & ".txt"
End If
Next
Set doc = Nothing
Set cnt = Nothing
Set dbs = Nothing
Exit_DocDatabase:
Exit Sub
Err_DocDatabase:
Select Case Err
Case Else
MsgBox Err.Description
Resume Exit_DocDatabase
End Select
End Sub
I'm still not 100% happy with the output of the raw SQL code, but it does allow us to run Beyond Compare on the output and gives us all of the components (of our rather complex database) including VB Code, SQL and Form changes.
Private Sub CMQA_Audit_Button_Click()
On Error GoTo Err_DocDatabase
Dim dbs As DAO.Database
Dim cnt As DAO.Container
Dim doc As DAO.Document
Set dbs = CurrentDB()
Dim OutDir As String
OutDir = CurrentProject.Path & "\" & Format(Now(), "ddmmmyy-hhmmss")
MkDir OutDir
Dim Tbl As TableDef
For Each Tbl In dbs.TableDefs\
If Tbl.Attributes = 0 Then ' Ignore System Tables
Application.ExportXML acExportTable, Tbl.Name, , OutDir & "\tbl_" & Tbl.Name & ".xsd"
End If
Next
Set cnt = dbs.Containers("Forms")
For Each doc In cnt.Documents
Application.SaveAsText acForm, doc.Name, OutDir & "\form_" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Reports")
For Each doc In cnt.Documents
Application.SaveAsText acReport, doc.Name, OutDir & "\rep_" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Scripts")
For Each doc In cnt.Documents
Application.SaveAsText acMacro, doc.Name, OutDir & "\scr_" & doc.Name & ".txt"
Next doc
Set cnt = dbs.Containers("Modules")
For Each doc In cnt.Documents
Application.SaveAsText acModule, doc.Name, OutDir & "\mod_" & doc.Name & ".txt"
Next doc
Dim QryAs QueryDef
For Each Qry In dbs.QueryDefs
If Not (Qry.Name Like "~sq_*") Then
Application.SaveAsText acQuery, Qry.Name, OutDir & "\qry_" & Qry.Name & ".txt"
End If
Next
Set doc = Nothing
Set cnt = Nothing
Set dbs = Nothing
Exit_DocDatabase:
Exit Sub
Err_DocDatabase:
Select Case Err
Case Else
MsgBox Err.Description
Resume Exit_DocDatabase
End Select
End Sub
I'm still not 100% happy with the output of the raw SQL code, but it does allow us to run Beyond Compare on the output and gives us all of the components (of our rather complex database) including VB Code, SQL and Form changes.
Thursday, June 27, 2013
Automated Storytelling
One of the things that always fascinated me about AI was Automated Storytelling, or Emergent Narrative. This is the idea that a computer can tell a compelling story. There are a couple of approaches to this:
1. Fill in the blanks on a template-story; Think of this option as the Mad-Libs approach. A lot of webpages use a simplified version of this for automatic plot generators, etc... Very hit-or-miss and the computer has no real understanding of the story it is creating.
2. Using grammar-type rules construct a legitimate story the same way you would construct a sentence; pick a hero, pick a compatible mission, pick a compatible obstacle, etc...
2. Create a world and characters to inhabit the world, set things loose and look for an interesting story to develop. Think of this option as a Soap-Opera, or a Reality TV Show. Things are very open-ended.
3. Create a world and characters, pick compelling plot-arcs and then force the characters into situations to fulfill the plot requirements. This option can use sub-plots and back-seeding (changing previous portions of the story to support changes in the plot). An AI construct known as fate can be used to keep the story on track, while another AI construct works on making the story dramatic, or funny, or whatever the theme of the story is. I like to think of this option as a card game between two players (at least that's the way I'd implement it).
I've thought a lot about this topic over the years and I think I am ready to start trying a few things out. I have started by looking over my notes and simplifying the ideas, one thing I've learned from working on Decision Aid Systems, Expert Systems, Natural Language Recognition, and doing Automatic Report Generation is that complexity rarely leads to a better result.
So, I am consolidating my 46 traits in seven spheres:
MIND: crazy romantic sensitive clever creative funny logical critical
ACTS: lazy trusting careful perceptive secretive suspicious controlling sleazy BODY: weak klutz lazy strong tense abusive
TALK: quiet follower gossip charismatic
WORK: reckless selfish ambitious honest careful sacrificing
LOVE: unselfish-love friends-love logical-love game-love posessive-love romantic-love
LOOK: overweight dowdy plain athletic cute sexy glamorous exotic
into this:
MIND: ambitious, honest, romantic, player, possessive, planning
BODY: lazy, sexy, sleazy, reckless, abusive, addict
SOUL: crazy, leader, follower, gossip
I think that this offers sufficient variety, this also means Actors will have a limit of (up to) three traits each.
I'm narrowing in on a theme too, I'm going to go with deserted island (think Lost or Gilligans' Island) since it provides an easy sand-box (limited number of locations, don't have to worry about outside actors if we don't want to).
There are a number of other simplifications I'm making as well. My hope is that this will simplify the rules engine that guides behavior.
PS - Here is an old-style set of Actors, there are some Stats that are hidden behind them as well:
Name: ____________ Sex: female
DOB: 21 JUN AGE: YOUNG JOB: judge (second-job) Income: comfortable
lucky sensitive perceptive tense
healthy dowdy LOVE-STYLE: logical-love
Name: ____________ Sex: female
DOB: 21 JAN AGE: OLD JOB: accountant (cold-as-ice) Income: average
logical secretive strong quiet
healthy cute LOVE-STYLE: logical-love
Name: ____________ Sex: male
DOB: 21 AUG AGE: YOUNG JOB: bar-tender (ugly-betty) Income: comfortable
sensitive careful quiet
healthy plain LOVE-STYLE: friends-love
And, here is the new version:
Name: _____________ Sex: female Job: Engineer
Planning, Gossip
I'll post when I get a little further.
David
1. Fill in the blanks on a template-story; Think of this option as the Mad-Libs approach. A lot of webpages use a simplified version of this for automatic plot generators, etc... Very hit-or-miss and the computer has no real understanding of the story it is creating.
2. Using grammar-type rules construct a legitimate story the same way you would construct a sentence; pick a hero, pick a compatible mission, pick a compatible obstacle, etc...
2. Create a world and characters to inhabit the world, set things loose and look for an interesting story to develop. Think of this option as a Soap-Opera, or a Reality TV Show. Things are very open-ended.
3. Create a world and characters, pick compelling plot-arcs and then force the characters into situations to fulfill the plot requirements. This option can use sub-plots and back-seeding (changing previous portions of the story to support changes in the plot). An AI construct known as fate can be used to keep the story on track, while another AI construct works on making the story dramatic, or funny, or whatever the theme of the story is. I like to think of this option as a card game between two players (at least that's the way I'd implement it).
I've thought a lot about this topic over the years and I think I am ready to start trying a few things out. I have started by looking over my notes and simplifying the ideas, one thing I've learned from working on Decision Aid Systems, Expert Systems, Natural Language Recognition, and doing Automatic Report Generation is that complexity rarely leads to a better result.
So, I am consolidating my 46 traits in seven spheres:
MIND: crazy romantic sensitive clever creative funny logical critical
ACTS: lazy trusting careful perceptive secretive suspicious controlling sleazy BODY: weak klutz lazy strong tense abusive
TALK: quiet follower gossip charismatic
WORK: reckless selfish ambitious honest careful sacrificing
LOVE: unselfish-love friends-love logical-love game-love posessive-love romantic-love
LOOK: overweight dowdy plain athletic cute sexy glamorous exotic
into this:
MIND: ambitious, honest, romantic, player, possessive, planning
BODY: lazy, sexy, sleazy, reckless, abusive, addict
SOUL: crazy, leader, follower, gossip
I think that this offers sufficient variety, this also means Actors will have a limit of (up to) three traits each.
I'm narrowing in on a theme too, I'm going to go with deserted island (think Lost or Gilligans' Island) since it provides an easy sand-box (limited number of locations, don't have to worry about outside actors if we don't want to).
There are a number of other simplifications I'm making as well. My hope is that this will simplify the rules engine that guides behavior.
PS - Here is an old-style set of Actors, there are some Stats that are hidden behind them as well:
Name: ____________ Sex: female
DOB: 21 JUN AGE: YOUNG JOB: judge (second-job) Income: comfortable
lucky sensitive perceptive tense
healthy dowdy LOVE-STYLE: logical-love
Name: ____________ Sex: female
DOB: 21 JAN AGE: OLD JOB: accountant (cold-as-ice) Income: average
logical secretive strong quiet
healthy cute LOVE-STYLE: logical-love
Name: ____________ Sex: male
DOB: 21 AUG AGE: YOUNG JOB: bar-tender (ugly-betty) Income: comfortable
sensitive careful quiet
healthy plain LOVE-STYLE: friends-love
And, here is the new version:
Name: _____________ Sex: female Job: Engineer
Planning, Gossip
I'll post when I get a little further.
David
Wednesday, June 12, 2013
The Art of the Meeting
In any business there are a number of soft skills that are incredibly useful; a lot of people have talked about communication and technical writing, but I wanted to talk for a few minutes about another area that is often overlooked: Meetings.
A long time ago (when I was at Lockheed) everyone in our group was required to participate in Facilitator training (not just those running meetings), they believed that if everyone facilitates meetings they will run smoother. My experience was very positive with meetings when everyone had the training.
The idea was that the facilitator should do everything they could to prepare the meeting to run smoothly:
- scrub the list of required vs. optional attendees. (don't waste peoples time)
- ensure all required attendees are available for the meeting. (avoid rescheduling)
- send out meeting notices well in advance (1 week+).
- include the agenda for the meeting prior to the meeting (eg. with the meeting notice). (keep the meeting focused and on-track)
Everyone in the meeting was expected to work on keeping the meeting on-track:
- fill-in for any role as needed (eg. Note taker, facilitator if you have the expertise and the facilitator isn't available at the start of the meeting)
- keep good thorough notes for the meeting, the note taker should share the minutes to all attendees after the meeting (by the next business day).
- during the meeting keep the topic on the agenda items, other issues should immediately be relegated to off-line discussion.
- once an item has been decided by group consensus be prepared to move on.
General:
- Be on time for the meeting.
- Action Items should be re-capped at the end of the meeting to ensure they are accurate.
- Action Items should be descriptive enough such that someone not at the meeting will immediately understand what needs to be done.
- Minutes should be descriptive enough such that someone not at the meeting will understand what was discussed.
- Keep the meeting on-track, distractions such as side-bars or phone calls should not take place (or at the very least be moved outside of the room).
Facilitator:
- ensure all resources are available and you know how to use them prior to the meeting (projectors, podium, etc...)
- don't schedule meetings if an alternative is available and appropriate. (don't waste peoples time)
Phone Call (no documentation quick)
In-Person Talk (no documentation, quick)
Email Chain (provides documentation)
Scheduled Meeting (slowest option, meeting invite and distributed minutes/action items provide documentation)
I don't mean to champion etiquette, but I've been at companies where some of these items weren't followed and it makes it very difficult to be productive. Imagine discussing an Action Item from a month ago that says "Have Jake talk to the EP Group." or having a meeting scheduled and everyone preparing for it and then in the first five minutes of the meeting being told "we aren't going to be discussing that".
I've had it both ways; Facilitator training gets my vote.
A long time ago (when I was at Lockheed) everyone in our group was required to participate in Facilitator training (not just those running meetings), they believed that if everyone facilitates meetings they will run smoother. My experience was very positive with meetings when everyone had the training.
The idea was that the facilitator should do everything they could to prepare the meeting to run smoothly:
- scrub the list of required vs. optional attendees. (don't waste peoples time)
- ensure all required attendees are available for the meeting. (avoid rescheduling)
- send out meeting notices well in advance (1 week+).
- include the agenda for the meeting prior to the meeting (eg. with the meeting notice). (keep the meeting focused and on-track)
Everyone in the meeting was expected to work on keeping the meeting on-track:
- fill-in for any role as needed (eg. Note taker, facilitator if you have the expertise and the facilitator isn't available at the start of the meeting)
- keep good thorough notes for the meeting, the note taker should share the minutes to all attendees after the meeting (by the next business day).
- during the meeting keep the topic on the agenda items, other issues should immediately be relegated to off-line discussion.
- once an item has been decided by group consensus be prepared to move on.
General:
- Be on time for the meeting.
- Action Items should be re-capped at the end of the meeting to ensure they are accurate.
- Action Items should be descriptive enough such that someone not at the meeting will immediately understand what needs to be done.
- Minutes should be descriptive enough such that someone not at the meeting will understand what was discussed.
- Keep the meeting on-track, distractions such as side-bars or phone calls should not take place (or at the very least be moved outside of the room).
Facilitator:
- ensure all resources are available and you know how to use them prior to the meeting (projectors, podium, etc...)
- don't schedule meetings if an alternative is available and appropriate. (don't waste peoples time)
Phone Call (no documentation quick)
In-Person Talk (no documentation, quick)
Email Chain (provides documentation)
Scheduled Meeting (slowest option, meeting invite and distributed minutes/action items provide documentation)
I don't mean to champion etiquette, but I've been at companies where some of these items weren't followed and it makes it very difficult to be productive. Imagine discussing an Action Item from a month ago that says "Have Jake talk to the EP Group." or having a meeting scheduled and everyone preparing for it and then in the first five minutes of the meeting being told "we aren't going to be discussing that".
I've had it both ways; Facilitator training gets my vote.
Subscribe to:
Posts (Atom)