Muddler 0.7 released!

With the recent changes in package metadata there come new muddler releases. Muddler 0.6 was primarily concerned with adding support for the new package metadata items, and 0.7 added one I was missed in 0.6 (dependencies) as well as replacing the existing Ant output with my own. Also added error handling for situations I know may fail, such as parsing malformed json and the like. The result is a more unified output and more information for the package author at build time.

New metadata support

Mudlet 4.12 brought some big changes to packaging and what information you can bundle about your package. So naturally I had to make some changes to muddler to accommodate that!

The full list of keys supported in the mfile for filling out your package’s metadata are:

  • package
    • The name of the package. The original metadata. Same as it ever was
  • version
    • The version of the package. This was available previously, but now Mudlet displays it!
  • author
    • Your name in lights! Well, a text box in Mudlet’s Package Manager, but still it’s recognition
  • title
    • ‘Short description’ if using the Mudlet package exporter.
    • Shows up in the package manager next to your package name in the list of packages
    • as such best to keep it somewhat short
  • description
    • This is a longer description for your package which is shown only once your package is clicked on in the package manager
    • supports Markdown
    • if you have a README.md file in the project root then the contents of that will be used automatically
  • dependencies
    • Comma separated list of other packages which should be installed for yours to work
    • for example, “MDK,MMSolver”
    • no actual enforcement in Mudlet yet, but still a convenient way to include the information
  • icon
    • The name of the image file you want to use for your package’s icon
    • file should be in src/resources/<filename>
      • for example if you set “icon”: “computer.png” then the file should be in “src/resources/computer.png” in your project
    • file is copied into place for icon usage rather than moved, in case you want to use it for labels or such
    • Recommended size is 512×512 pixels, as this is what Mudlet will scale it to

More and better output!

Before, I did not really provide any of my own output. The things displayed in the terminal when muddler would run were mostly output by the AntBuilder it uses for moving and zipping files and such once it has transformed the filetree into a Mudlet xml file.

Now I provide all of the output, and attempt to do so in a consistent manner. I’ve also started handling errors for things like malformed JSON or file access errors, so that it will tell you where to look for the issue. This should aid greatly in troubleshooting failing builds.

Example of new output from a real package build

The GitHub action automatically selects the latest version unless you specify one, so there should be no need to explicitly upgrade if you’re already letting it handle that for you.

Always looking to improve

If you have any feature requests or find any bugs, please let us know by filing an issue. I won’t promise I’ll take every suggestion, but I do promise I’ll at least give each one serious consideration.

Mudlet 4.12 released

This release has some nice quality of life stuff in it, but a couple things specifically aimed at package developers and their users.

New Package Manager

One of the more obvious changes will be the package manager for installing and uninstall packages has changed a bit.

New Package Manager look

The new look is not only nicer, but it also paves the way for new functionality. You can include new metadata in your packages and also a custom icon for your package.

Package Manager showing a package with new metadata

New Package Exporter

Along with the new package manager is a new package exporter to aid in getting your package together and adding the metadata you want to it. The new metadata is entirely optional, though.

Picture from Mudlet release post showing new exporter workflow

The new metadata you can set are as follows:

  • Author: Your name here.
  • Icon: Image shown in the package list in the package manager. Scaled to 512px512px so something that size works best. The computer with horns in the Package Manager screenshot above
  • Short Description: This will show up in the package manager to the right of the package name. “The recognition maker” in Package Manager screenshot.
  • Description: The long description for your package. This supports Markdown and is the bigger block of text starting with the heading The RecogINATOR in the screenshot.
  • Version: The version of the package. Typically higher = newer.
  • Dependencies: A list of other package names which should be installed for your package to work. MDK,MMSolver in the example pic

In addition, it will timestamp the package with the date and time it was created, which can be helpful in confirming the version is the same one originally created as well.

File watching

Mudlet 4.12 also introduces the ability to watch a file and have an event fire any time the file changes. This is described with more details at https://wiki.mudlet.org/w/Manual:Lua_Functions?#addFileWatch but you use addFileWatch(“/path/to/file”) and it will then raise the event sysPathChanged with the path to the file as the first parameter after the event name. You can use this to reload a package when it changes on disk or to read configuration data from a file when it’s updated, things like that.

And more!

This was just a quick whirlwind flyover of the new features in Mudlet 4.12 which I think will benefit script authors specifically. As usual there were a lot of other fixes and additions included in the release post than I could go over here, and it’s worth taking a moment to look over the post.

Muddler has been updated to reflect the new package metadata as well and will be getting its own post before long as well!

New Build With Muddler GitHub Action

As part of my efforts to make Muddler easier to adopt and my general preference for automation in my own project I have created a GitHub action for building your project with Muddler. The action is on the GitHub action market HERE

What’s a GitHub action and why should I care?

GitHub actions are GitHub’s mechanism to build and/or publish your project. This is useful when you are working with others on a project especially, as GitHub can build your project and make the outcome available for testing without the other people working on it having to download and build it themselves.

Enough with the theory, old man. Concrete examples!

As part of developing the action to build a project with Muddler I set up my LusterniaChatTabs project to use it, even though I’m the only one working on it. Checking an action file into the .github/workflows directory of your project will cause it to be run by GitHub at the appropriate times, as defined by the file. In this case, the file is .github/workflows/ci.yml .

Configuration

Here’s what it looks like, with comments added for explanation.

# The name of the action, it is used for display in the actions view in GitHub
name: CI

# This section controls when the action runs. In this case, when code is checked
# into the main branch or when a pull request is made targeting the main branch.
# If your projects default branch is something else, such as 'development'
# then you would use that instead of main below
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

# Including this lets your run the action on demand as well
  workflow_dispatch:

# The jobs (collection of steps) for the action
jobs:
  # This collection is called 'build'
  build:
    # build on GitHub's latest ubuntu image
    runs-on: ubuntu-latest

    # The steps to follow for the 'build' job
    steps:
      # this step checks out the project repository to work on
      - uses: actions/checkout@v2

      # this is the step I made, which builds your project with Muddler
      # it will show up as "Muddle" in the GitHub web interface later
      - name: Muddle
        uses: demonnic/build-with-muddler@v1.2
      
      # This step uploads the artifact for you and others to download
      - name: Upload Artifact
        uses: actions/upload-artifact@v2
        with:
          # build/tmp/ is the directory muddler makes the mpackage out of
          # GitHub only allows you to upload zip files, so we let them
          # zip it up and upload it. That's all the .mpackage is anyway
          # just with a different file extension
          name: LusterniaChatTabs
          path: build/tmp/

In use

I will not go into detail on how to create a PR (Pull Request) in this post, there are a wealth of resources online which can show you how to do this, but if enough people ask for it I’ll make a post focusing on that. But I will show the workflow in action, via the artistic medium of captioned screenshots.

Newly opened Pull Request. CI workflow adds the check shown

By clicking on the ‘Details’ link (shown by the red arrow above) you bring up information on the workflow run.

Workflow information. Red arrow shows Muddle step

You can get further information on the Muddle step (so named in the ci.yml file above) by clicking the expansion arrow marked by the red arrow.

Screenshot showing the details of the build-with-muddler action

The build-with-muddler step determines the latest release of muddler and downloads it to use, unless you specify a version, and then runs it to assemble your package for you. Thanks to the “Upload Artifact” step we defined, the artifact is available to download and install in Mudlet for testing.

Screenshot showing where to find the uploaded artifact

Click the Artifacts expander and you can click on the artifact name (LusterniaChatTabs in this case) and it will download the zip file. This can be installed into Mudlet using Mudlet’s package manager.

If the action runs successfully, then it will clear the check for the Pull Request, and if not then the check fails and needs to be fixed before the PR is merged.

Screenshot of PR showing “All checks have passed”

And that’s it in a nut shell. I will make a post on setting up your Mudlet project for Muddler soon, but I was too excited about making it a GitHub action which I and others could use for automation and wanted to get this post put together to help get the word out.

Mudlet 4.11 highlights

Meatspace asserts itself always, but sometimes more than others. I’d meant to get this post out over the weekend but that didn’t work out for various reasons. Regardless, one of the things I’d like to do with this blog is highlight various features of the client which I think are either under-utilized or are new in an effort to get the word out. A lot of this is touched on in the release post as well but bears repeating or a bit more of a dive, and some of it didn’t make it to the highlights reel for that post but are worth a mention in my opinion.

So with that being said, here are some of the more exciting bits out of the Mudlet 4.11 release.

Italics/Bold/Underline in c/d/hecho

An oft-requested feature, finally these formatting options are parsed in cecho, decho, and hecho. I use the backtick (`) as my lua alias since I use it so often.

getWindowWrap(windowName)

Another small one, but when formatting text it can be super helpful to get the wrap width of a console.

Drag and drop URL installs

You have been able to drag and drop Mudlet packages onto the Mudlet window to install them for a few versions, but now you can drag and drop a url from your web browser onto Mudlet and it will download and install the package for you.

Named captures in perl regex triggers

Another one that’s been requested a few times finally makes its way into Mudlet thanks to the efforts of Mudlet’s newest member of the core dev team, Delwing. The release post includes some pictures, but briefly:

-- old way
-- regex pattern: ^The mystical magical aura around (\w+) turns a deep vermillion and you feel your blood boil, doing (\d+) damage$

-- code
cecho("Blood boiled by " .. matches[2] .. ":<red> " .. matches[3] .. "\n")
-- new option
-- regex pattern: ^The mystical magical aura around (?<attacker>\w+) turns a deep vermillion and you feel your blood boil, doing (?<dmg>\d+) damage$

-- code
cecho("Blood boiled by " .. matches.attacker .. ":<red> " .. matches.dmg .. "\n")

-- above code would also work with the following pattern, making it easier to combine patterns where the captures come in different order
-- regex pattern: ^You take (?<dmg>\d+) damage as your blood boils, a faint red mist rising from your skin and flowing towards (?<attacker>\w+)\.$

String interpolation (formatting)

One piece of syntactic sugar whose lack is often bemoaned is string interpolation. “What is string interpolation?” I hear some of you thinking. It’s a fancy way developers describe replacing things inside strings with their value. The version Mudlet uses is modified from the f-strings luarock, which is primarily aimed at Lua 5.2+ and had to be slightly modified to work in Mudlet. It replaces anything inside { } with the outcome of the expression. It may be easiest to show with a few quick examples.

-- You could rewrite the code for the triggers above like this
cecho(f("Blood boiled by {matches.attacker}:<red> {matches.dmg}\n"))

-- Lua allows you to call functions with a single string or table argument without the parentheses. This is usually considered bad practice, but this is one place I will often make an exception
cecho(f"Blood boiled by {matches.attacker}:<red> {matches.dmg}\n")

-- You can run functions as part of the string. Assuming you have written a function getDamageColor which returns different colors based on how much damage you took, you could run the echo as follows:
cecho(f"Blood boiled by {matches.attacker}:{getDamageColor(matches.dmg)} {matches.dmg}\n")

Save/load Mudlet map to/from JSON

Right now, the Mudlet map saves as a binary file, the actual map item in the code being serialized to disk. With the 4.11 update it can now save and load in the JSON format. This has several benefits, among them that it is human readable. This makes it much easier to manage inside Git for people who maintain crowd maps, providing manageable diffs and much smaller repositories due to the way git handles binary vs ascii files. Also provides an official JSON format to code against for things like the web viewer for Mudlet maps, or perhaps a future program which allows you to add/remove rooms from the json file without being inside Mudlet itself. We’ll see what people come up with =)

Conclusion

Mudlet 4.11 took a while longer than was hoped due to Travis CI essentially turning its back on FOSS with its new pricing model, but should hopefully get back to regular releases soon. The combination of string interpolation, named captures in regex triggers, and the addition of formatting codes for bold, underline, and italics to the c/d/hecho functions in particular will allow for much easier to read code when doing complicated string formatting and combining multiple patterns which do the same thing in your trigger editor.

Dev Environment – Linux

What we will try to accomplish

We’re going to walk step-by-step through setting up your Linux machine to use a development environment like the one I use.

This one is coming first primarily because I use Linux myself, and also because it’s one of the easier environments to get set up. I am using Ubuntu 20.04 as the example, but the steps for other distributions will be similar, apart from the system package manager steps.

What are we installing, actually?

  • basic build tools
  • Lua5.1
  • LuaRocks
  • Luaformatter
  • Visual Studio Code
  • docker
  • muddler

Let’s get started

I recommend doing this while your system is up to date, but it isn’t necessary. I used a virtualbox image from osboxes.org to ensure it works on a clean install and to get the screenshots, so the username will be osboxes throughout the demonstration.

Build tools and dependencies

# Make sure you have the latest package information
sudo apt-get update
# Install dependencies. Up to cmake are for luarocks/luaformatter. After that will be needed by docker's install later.
sudo apt-get install build-essential gcc git libreadline-dev lua5.1 liblua5.1-0-dev cmake apt-transport-https ca-certificates curl gnupg-agent software-properties-common
Installing system dependencies

LuaRocks

Next, we will install LuaRocks. We do not use the system version as it’s older, and Luaformat needs something newer.

# the wget is to download the archive file
wget https://luarocks.github.io/luarocks/releases/luarocks-3.9.0.tar.gz
download LuaRocks
# this extracts the file into its directory
tar zxvf luarocks-3.9.0.tar.gz
# Then we move into the directory
cd luarocks-3.9.0.tar.gz
# The provided configure script will determine where all the pieces luarock needs to build are kept on your system
./configure
extract and configure LuaRocks
# Then we build it
make
building LuaRocks
# And this installs the build files to your system
sudo make install
installing LuaRocks

After this you will need to edit your .bashrc file. If you are using a shell other than bash, this filename will be different, use the file appropriate to your shell. Add the following line to the end of the file, save, and quit.

PATH=$PATH:/usr/local/bin:$HOME/luarocks-3.5.0/lua_modules/bin

This adds /usr/local/bin and the luarocks directory in your homedir to your path, so that luarocks and the luarocks you install with it will be available in your path.

LuaFormatter

Close your current terminal and open a new one so the PATH change above will take effect before the next step.

sudo luarocks install --server=https://luarocks.org/dev luaformatter

It can take a moment, the series of pictures below gives you an idea of what you can expect. Do not worry about the attribute warnings, warnings are usually nothing to worry about.

LuaRocks will take care of downloading, compiling, and installing LuaFormatter for you when you hit enter.

I recommend you download my luaformatter config file, though this step is optional and you can format your code how you like, this will provide a starting place that has your code looking like mine, anyhow.

cd $HOME
wget https://raw.githubusercontent.com/demonnic/MDK/master/.luaformatter
downloading luaformatter config

VSCode

You can download Visual Studio Code from https://code.visualstudio.com/Download . Select the version which is right for your linux, in this case the .deb. Once it is downloaded, double click it to install.

Once it is installed, open it and go to the extensions tab.

First install sumneko.lua

Then install the koihik.vscode-lua-format

If you downloaded my luaformatter config file, hit ctrl+shift+p and type ‘settings’, then click “Preferences: Open Settings (JSON)”.

Open settings

This will bring up the settings file for vscode. You want to add the following line to it at the top, just below the first {, with <user> replaced by your username.

    "vscode-lua-format.configPath": "/home/<user>/.luaformatter",
Add config for luaformatter

The order of the entries doesn’t really matter, but this way it should definitely be in the right place and not accidentally nested in something else.

Docker

Add docker’s GPG key and ubuntu repository to your system

# Download and install the GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# add Docker repository to repository list
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# update package information
sudo apt-get update
Setup docker repository

Install docker

# install docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
# add docker group - this failed for me because the group
# already existed, but it doesn't hurt to run it if the group
# already exists, so I included it.
sudo groupadd docker
# and add yourself to it
sudo usermod -aG docker $USER

You can verify it’s working by running their hello world image. First, close your terminal and open a new one so it sees your new group membership. I have occasionally had to reboot my computer for this to take effect, so if the following fails, try adding ‘sudo’ in front of it. I recommend rebooting though.

docker run hello-world
hello world!

Muddler

Since we installed docker, this is now very simple

docker pull demonnic/muddler:latest
pulling muddler image

You can now use docker to run muddler to create your Mudlet packages. To aid in this, you may want to download the ‘muddle’ script and place it in your path.

wget https://raw.githubusercontent.com/demonnic/muddler/master/muddle
chmod +x muddle
sudo mv muddle /usr/local/bin
Installing wrapper script for ease of use

Congratulations! You now have everything you need to replicate the essential pieces of my development environment for Mudlet scripts. I opened up the MDK project so you could see what it looks like at the end.

emco.lua from the MDK in new dev env

For follow up, if you want to get rid of all the yellow squiggles you may want to follow the instructions HERE. And to save some typing, add the snippets for vscode for Mudlet I maintain HERE. But both of these steps are optional and while they will improve your experience they are not required.

First Project: The Questinator

We need a project

Why do we need a project? Well, because a big part of why I first decided to start this blog is I wanted to work through a project from start to finish in a way that people could hopefully learn from and make their own Mudlet development smoother/faster/better. I admit I’m biased towards my way of doing things, though, and the point isn’t to necessarily get people to copy me so much as to explain how I do the thing and why I do the thing that way.

So we need a project to work through together. And I decided it will be the Questinator.

WTF is a Questinator?

I’m so glad you asked! We can start right here with step one, definining what the project is!

the Questinator is a tool which allows users to document quests in their mud, and aids in completing them.

That’s great, but what does it mean?

Well, wouldn’t you know it that’ll be the next step! Time to start defining things on a more granular level.

If this is where you are expecting me to start talking about user stories, or UML, or the like… you probably don’t need this tutorial quite so much. And honestly I only sort of vaguely use any of that and don’t feel confident teaching it.

But I do think it’s important to think about what you actually want to accomplish, and at least the bare sketch of how up front.

So, Questinator will:

  • Present either a userwindow or adjustableContainer with its interface inside
  • Maintain a set of quests, each of which will:
    • have a list of ‘phases’ of the quest, which can be thought of as the general steps involved
    • have a list of areas each phase takes place in
      • the areas can and ideally will correspond to the area in the Mudlet mapper.
      • But ideally I want this to be usable for taking notes even if you are not using the Mudlet mapper
    • maintain a list of rooms involved in the quest
      • as with the areas ideally these will correspond to roomID and roomName in the Mudlet Mapper
      • But ideally I want this to be usable…
      • Each room will maintain information about
        • general notes… whatever you might want.
        • NPCs in the room related to the quest
        • Commands you might want to send in the room which relate to the quest. “kill porcupine” or “give porcupine to farmer”
        • the phase(s) of the quest in which it is involved
    • Be able to give the list of all NPCs from all rooms for each phase or the full quest
    • Same for areas and rooms
  • Provide for configuration of things like
    • font face
    • font size
    • function to use to go to a room
    • function to use to go to an area
    • single page or tabbed layout
    • create links?
  • Config is saved to disk and loaded on start
  • Provide a way to quickly configure functions for the generic mapper and the IRE mapper, since they’re the two most commonly used mapping scripts.
  • Should have its own commandline for interacting with it via the keyboard
    • this should be doable using aliases from the normal command line as well
  • But will make commands to send and rooms/areas to goto clickable is configured to do so

That uhh… seems like a lot

It can, when you try to take it all in at once. But thankfully it is not Athena and need not be born from our skull fully formed and ready to do battle.

In upcoming posts and videos we’ll get the dev environment fully setup and begin working on laying the project out, implementing the things we need a little at a time.

I look forward to our progress together!

Hello world!

Some traditions are worth keeping.

What is this?

This is the beginning of my blog. So let’s establish some goals

  • Present my workflow for working on Mudlet scripts
  • Provide instructions for setting up your development environment like mine
  • Walk through creating at least one package from start to finish (Questinator!)
  • Highlight some quick and dirty tips for working with Mudlet
  • Have fun!

What is this not?

  • The One True Way
  • Probably not even The Best Way
  • How to get rich programming
  • One weird trick to learn to code