Ported articles
This commit is contained in:
parent
6d0a0cae98
commit
f58a7cbf95
46
website/2016-04-11-doki-doki-densha-sekai.md
Normal file
46
website/2016-04-11-doki-doki-densha-sekai.md
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Doki Doki Densha Sekai
|
||||||
|
|
||||||
|
![A train has arrived at a station, as colorful cube-people
|
||||||
|
hustle.](/website/images/dokidoki.png)
|
||||||
|
|
||||||
|
**Nordic Game Jam 2016 People's Choice Awards finalist**
|
||||||
|
|
||||||
|
A relaxing exploration of a metro system. Put on a pair of headphones
|
||||||
|
and immerse yourself in a world of trains and cube people.
|
||||||
|
|
||||||
|
Made in cooperation with _[Sketchwhale](http://takunomi.space)_
|
||||||
|
and _[Astrid Sonne](https://soundcloud.com/a_sonne)_
|
||||||
|
|
||||||
|
Download on [itch.io](https://jmaa.itch.io/doki-doki-densha-sekai).
|
||||||
|
|
||||||
|
Original description:
|
||||||
|
|
||||||
|
> **Doki Doki Densha Sekai** is a first step to see when a world begins to
|
||||||
|
> form in the mind of the player. Try and visit all the unique stations
|
||||||
|
> such as complex __Inu-shibuya__, the religious center
|
||||||
|
> __O-biiru-no-mizu__ and curiously circular __Manko-mae__. If you miss
|
||||||
|
> either your ride or stop, don't worry about it. Relax and listen to
|
||||||
|
> the easy-going music while you wait. It might be a while.
|
||||||
|
>
|
||||||
|
> Was made for **Nordic Game Jam 2016**, by the following people:
|
||||||
|
>
|
||||||
|
> - [Sketchwhale](http://takunomi.space) made the design and the art.
|
||||||
|
> - [Astrid Sonne](https://soundcloud.com/a_sonne) created the music you'll hear throughout.
|
||||||
|
> - [JMAA](/) was stressed out coupling everything together.
|
||||||
|
|
||||||
|
## March 2019 Update
|
||||||
|
|
||||||
|
The game have been updated to fix several issues, and some minor
|
||||||
|
features have been implemented.
|
||||||
|
|
||||||
|
|
||||||
|
## September 2019 Update
|
||||||
|
|
||||||
|
The game has been updated once again, with following patch notes:
|
||||||
|
|
||||||
|
- The fonts have been reworked, removing some visual artifacts.
|
||||||
|
- An introductory main menu have been added.
|
||||||
|
- Xbox controller support has been added. Other controllers may
|
||||||
|
work, but as I only possess a Xbox controller, I am unable to
|
||||||
|
confirm.
|
||||||
|
|
91
website/2017-12-05-tigersay.md
Normal file
91
website/2017-12-05-tigersay.md
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
# Tigersay
|
||||||
|
|
||||||
|
## The dOvs Course ##
|
||||||
|
|
||||||
|
This last semester I've been following my university's course on
|
||||||
|
writing a compiler from scratch. The course uses the classic
|
||||||
|
[Modern Compiler Implementation in
|
||||||
|
ML](https://www.cs.princeton.edu/%7Eappel/modern/ml/), and thus our
|
||||||
|
input language is something called **Tiger**, a toy language designed
|
||||||
|
specifically for the book. The joke goes that Tiger is one of the
|
||||||
|
least used programming languages, but one of the most supported. It is
|
||||||
|
also weird. It's like if **C** and [Standard
|
||||||
|
ML](https://en.wikipedia.org/wiki/Standard_ML) had a deformed baby:
|
||||||
|
Mutually inductive data types and functions? Sure! Primitives for both
|
||||||
|
functional and imperative coding styles? Great idea! Type inference
|
||||||
|
for variables, but not for functions. Perfect! A way to determine the
|
||||||
|
size of arrays at runtime? No, absolutely not!
|
||||||
|
|
||||||
|
![A small piece of Tiger code, demonstrating an implementation of a
|
||||||
|
linked list.](/website/images/tiger-example.png)
|
||||||
|
|
||||||
|
The reason for these weird idiosyncrasies is obvious: nobody is
|
||||||
|
supposed to write actual programs in Tiger. The features of
|
||||||
|
Tiger are designed to illustrate how to implement them, not
|
||||||
|
necessarily to form a coherent whole.
|
||||||
|
|
||||||
|
That said, some of the features work together to allow a strange
|
||||||
|
elegance in the way some programs can be written. Recursive functions
|
||||||
|
and structure types allow one to express linked lists and maps using
|
||||||
|
relatively little code. See [the example
|
||||||
|
code](https://gitfub.space/Jmaa/tigersay/src/branch/master/tiger-linked-list.tig)
|
||||||
|
above, for an implementation of a linked list, and a function for finding the sum of
|
||||||
|
the list, using a recursive helper function. I could just as easily
|
||||||
|
have implemented it using an imperative style.
|
||||||
|
|
||||||
|
<!-- TODO: Include link to tests. -->
|
||||||
|
|
||||||
|
While following the course, my group used a testing framework,
|
||||||
|
containing many programs similar in style to the above code sniplet,
|
||||||
|
ensuring our compiler's compliance with the language. These
|
||||||
|
tests were small, and rarely tested more than a few features at once.
|
||||||
|
The question "Is our compiler actually capable of translating a _real_
|
||||||
|
program?" arose, and this lead me down the road of actually writing a
|
||||||
|
"real" program in Tiger, using its weird feature set.
|
||||||
|
|
||||||
|
## Tigersay ##
|
||||||
|
|
||||||
|
<!--start-->
|
||||||
|
|
||||||
|
![A badly drawn tiger explains its own existence: "Once upon a time,
|
||||||
|
there was a programming language named Tiger, and nobody used it. Then
|
||||||
|
some stupid student made a clone of cowsay, and that is how I was
|
||||||
|
born"](/website/images/tigersay-example.png)
|
||||||
|
|
||||||
|
**Tigersay** is an implementation of the classic Perl program
|
||||||
|
[Cowsay](https://en.wikipedia.org/wiki/Cowsay), written in the Tiger
|
||||||
|
programming language, a toy language originating from the [Modern
|
||||||
|
Compiler Implementation in
|
||||||
|
ML/C/Java](https://www.cs.princeton.edu/%7Eappel/modern/ml/) series of
|
||||||
|
books.
|
||||||
|
|
||||||
|
It does not come compiled, nor does it come with a **Tiger** compiler.
|
||||||
|
The only way to experience the wonder that is **Tigersay** is to use
|
||||||
|
your own **Tiger** compiler. (Or find one on the internet, but that's
|
||||||
|
cheating.)
|
||||||
|
|
||||||
|
<!--end-->
|
||||||
|
|
||||||
|
The standard version of Tiger is limited in its ability to interact
|
||||||
|
with the command-line, and as a result, so is Tigersay. The only way
|
||||||
|
to interact with Tigersay is to pipe the desired text into Tigersay:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "Hello World" | tigersay
|
||||||
|
```
|
||||||
|
|
||||||
|
Unfortunately this also means Tigersay only supports a single face,
|
||||||
|
the default tiger one, due to having no support for command-line
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
Tigersay responds to certain strings in silly ways, the most useful
|
||||||
|
ones being _help_ and _version_. Additionally it interfaces nicely
|
||||||
|
with [fortune](https://en.wikipedia.org/wiki/Fortune_(Unix\)).
|
||||||
|
|
||||||
|
![The badly drawn tiger exclaim: "I never made a mistake in my life.
|
||||||
|
I thought I did once, but I was wrong. -- Lucy Van
|
||||||
|
Pelt"](/website/images/tigersay-fortune.png)
|
||||||
|
|
||||||
|
If you'd like to play around with Tigersay yourself, you can find the source
|
||||||
|
code in the [Gitfub repository](https://gitfub.space/Jmaa/tigersay)
|
||||||
|
|
105
website/2018-02-06-infernal-interpreter.md
Normal file
105
website/2018-02-06-infernal-interpreter.md
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
# Infernal Interpreter
|
||||||
|
|
||||||
|
## The dComArk Course ##
|
||||||
|
|
||||||
|
My first semester of University (summer 2015) I had a course named
|
||||||
|
**Computer Architecture** commonly shorted to **dComArk**. It was a
|
||||||
|
standard course about the low level construction of modern computers.
|
||||||
|
It followed [Tanenbaum](http://www.cs.vu.nl/~ast/)'s classic
|
||||||
|
[Structured Computer
|
||||||
|
Organization](http://www.mypearsonstore.com/bookstore/structured-computer-organization-9780132916523).
|
||||||
|
The course itself was known for its [idiosyncratic
|
||||||
|
lecturer](https://twitter.com/nielsolofbouvin), and for being hard as
|
||||||
|
hell. Topics included registers, the stack, assembly code,
|
||||||
|
micro-code, and the architecture of processors in general.
|
||||||
|
|
||||||
|
Jumping directly from just having learnt Java, as a first programming
|
||||||
|
language, to suddenly having to understand and write low-level
|
||||||
|
programming languages such as
|
||||||
|
[IJVM](https://en.wikipedia.org/wiki/IJVM) and [X86-64
|
||||||
|
assembly](https://en.wikipedia.org/wiki/X86-64), was tough, and many
|
||||||
|
of my fellow students dropped out because of it.
|
||||||
|
|
||||||
|
My favorite assignment was the one where we extended IJVM
|
||||||
|
with a new op-code. You see, some processors are programmable, in
|
||||||
|
their own [highly restricted programming
|
||||||
|
language](https://en.wikipedia.org/wiki/MIC-1). Changing something you
|
||||||
|
think is set in stone - like the set of op-codes a processor has -
|
||||||
|
changes the way you see the world.
|
||||||
|
|
||||||
|
But this article is neither about IJVM, nor about micro-code. It's
|
||||||
|
about the course's fifth and final assignment. For this assignment we
|
||||||
|
were to write a recursive [fibonnaci
|
||||||
|
function](https://rosettacode.org/wiki/Fibonacci_sequence) in x86-64,
|
||||||
|
and then describe how it worked, with visualizations of the registers
|
||||||
|
and stack at every instruction.
|
||||||
|
|
||||||
|
![Example of the recursive Fibonacci function in x86, with
|
||||||
|
comments.](/website/images/infernal-interpreter-example.png)
|
||||||
|
|
||||||
|
[A friend of mine](https://christoffer.space/) spent an entire evening
|
||||||
|
on this assignment carefully drawing the [registers and stack into
|
||||||
|
Excel](/website/images/infernal-interpreter_christoffer-stack.pdf).
|
||||||
|
I decided I'd rather spend an evening programming, than messing about
|
||||||
|
with Excel, so I began writing a program that could generate code for
|
||||||
|
embedding into LaTeX. The program needed to emulate just enough
|
||||||
|
X86-64 to run the function, and no more.
|
||||||
|
|
||||||
|
## The Infernal Interpreter ##
|
||||||
|
|
||||||
|
<!--start-->
|
||||||
|
|
||||||
|
![Example of Infernal Interpreter output. Columns describe the
|
||||||
|
movement of data when executing x86
|
||||||
|
op-codes.](/website/images/infernal-interpreter-output-ascii.png)
|
||||||
|
|
||||||
|
**Infernal Interpreter** is an emulator and visualizer of a subset of
|
||||||
|
the AMD x86-64 ABI, using the GAS syntax. You give it a bunch of
|
||||||
|
symbolic machine code, after which it produces a visualization of the
|
||||||
|
running code, either to the terminal, or as a LaTeX file with Tikz.
|
||||||
|
|
||||||
|
It's old, written in Python 2, and for an incredibly specific purpose,
|
||||||
|
but I enjoy going back and looking at the output.
|
||||||
|
|
||||||
|
<!--end-->
|
||||||
|
|
||||||
|
There is something at once uncomfortable and fascinating about looking
|
||||||
|
at old code. Thoughts of "How could I ever write code this bad?" and
|
||||||
|
"Damned, I've gotten a lot better since then". While writing this
|
||||||
|
article I wanted some images that fits the style of my website, so I
|
||||||
|
added a `ascii` painting mode, that shows the trace in the terminal.
|
||||||
|
This was non-trivial, given the existing structures, which were
|
||||||
|
clearly designed to be as obscure as possible. Along the way the
|
||||||
|
frontend was updated to be more UNIX-like. The backend is a nightmare,
|
||||||
|
and has been kept without major changes.
|
||||||
|
|
||||||
|
If you'd like to take at look at it as well, you can find an [an
|
||||||
|
example of the tikz output
|
||||||
|
here](/website/images/infernal-interpreter_tikz-example.pdf).
|
||||||
|
Alternatively you can [download the program
|
||||||
|
itself](/website/images/infernal-interpreter_source-1.0.0.zip), or
|
||||||
|
[view the official Git
|
||||||
|
repository](https://gitfub.space/Jmaa/infernal-interpreter).
|
||||||
|
**Infernal Interpreter** requires **Python 2**, and will crash on
|
||||||
|
anything remotely complicated. Notably: it does not model the heap.
|
||||||
|
The source-code is available under the BEERWARE license, so you are
|
||||||
|
free to modify it as you like.
|
||||||
|
|
||||||
|
![Example of Infernal Interpreter output, with the Tikz painter.
|
||||||
|
Columns describe the movement of data when executing x86
|
||||||
|
op-codes.](/website/images/infernal-interpreter-output-tikz.png)
|
||||||
|
|
||||||
|
The program includes two example files in the `examples` folder, both
|
||||||
|
of which were part of my assignment, and has been included unaltered.
|
||||||
|
You can run them with a command like this:
|
||||||
|
|
||||||
|
./infernal
|
||||||
|
-i=examples/fibonnaci_recursive.S
|
||||||
|
--rdi=3
|
||||||
|
|
||||||
|
The `--rdi=3` argument is important, because it sets the `%rdi`
|
||||||
|
register to `3`, and thus tells the program to compute the 3rd
|
||||||
|
Fibonacci number. This writes ascii directly to the terminal. To
|
||||||
|
produce Tikz, simply change the painter: `--painter tikz`. The full
|
||||||
|
options can be found by running `./infernal --help`
|
||||||
|
|
175
website/2018-04-21-nijousatsujikenriron.md
Normal file
175
website/2018-04-21-nijousatsujikenriron.md
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
# Nijousatsujikenriron (AKA "The Elevator Game")
|
||||||
|
|
||||||
|
![Adrift on the seas of change; a world of our own making.](/website/images/nijousatsujikenriron-mock-up.png)
|
||||||
|
|
||||||
|
**Nijousatsujikenriron** is a murder-mystery dating-sim set in an
|
||||||
|
elevator. As Detective Monaghan, you just had the worst, and probably
|
||||||
|
last, day of your career. As you enter the elevator, you feel things
|
||||||
|
are not going to get better. Can you solve the mystery? Can you find
|
||||||
|
yourself? Can you move on?
|
||||||
|
|
||||||
|
Made in cooperation with _[Sketchwhale](http://takunomi.space)_
|
||||||
|
and _[Mikko "Mishicu" Aaltio](https://twitter.com/mishicumusic)_
|
||||||
|
|
||||||
|
Download on [itch.io](https://jmaa.itch.io/nijousatsujikenriron).
|
||||||
|
|
||||||
|
## Introduction ##
|
||||||
|
|
||||||
|
Last weekend, 13-15th April 2018, I participated in [Nordic Game
|
||||||
|
Jam](https://nordicgamejam.org/), a yearly gamejam set in Copenhagen.
|
||||||
|
I did not enjoy the trip at all, but was very satisfied with the
|
||||||
|
resulting game.
|
||||||
|
|
||||||
|
Most of this post is a rant about trains, the jam, implementation
|
||||||
|
details, etc.
|
||||||
|
|
||||||
|
## Transport Purgatory ##
|
||||||
|
|
||||||
|
I had planned to see [Robert Yang](https://twitter.com/radiatoryang)'s
|
||||||
|
presentation on sex in video games, and had planned my train journey to
|
||||||
|
Copenhagen with time to spare. When stopped at some random small-town
|
||||||
|
station, we're informed that a tree fell on the tracks, and thrown out
|
||||||
|
of the train. Together with hundreds of other confused people, I
|
||||||
|
waited 3 hours for a [train-replacement
|
||||||
|
bus](https://en.wikipedia.org/wiki/Rail_replacement_bus_service) that
|
||||||
|
never came. The tracks were cleared, and trains were running again
|
||||||
|
before a bus towards Copenhagen came. Good job [DSB](https://www.dsb.dk/).
|
||||||
|
|
||||||
|
The remaining journey to Copenhagen was spent in a stuffed train,
|
||||||
|
where even first-class passengers were standing. After arriving in
|
||||||
|
Copenhagen, I still had to walk an hour to get to TAP1, the game jam location.
|
||||||
|
|
||||||
|
## Friday ##
|
||||||
|
|
||||||
|
Similar to in [2016](/website/doki-doki-densha-sekai), my friend
|
||||||
|
[Sketchwhale](http://takunomi.space) and I had already talked about
|
||||||
|
some game ideas before the jam, and just like last time, we ignored
|
||||||
|
the theme completely.
|
||||||
|
|
||||||
|
The idea we settled on was _murder-mystery dating-sim, set in an
|
||||||
|
elevator_, which Sketchwhale had called _"This- This is awful- It's not
|
||||||
|
even a real mystery"_. We would focus on the dialog between the main
|
||||||
|
character, detective _Dave Monaghan_, and the other characters. The joke was
|
||||||
|
that the murderer was obvious, but the real game lie in becoming
|
||||||
|
friends with the characters. We used a pretty awful custom built 3d engine,
|
||||||
|
I'd made earlier in the year (2018).
|
||||||
|
|
||||||
|
![A lightly-clothed girl, with pink ponytail stands in front of a blue
|
||||||
|
and black background.](/website/images/nijousatsujikenriron-day-1.png)
|
||||||
|
|
||||||
|
The jam started late, somewhere around `21:30`, and so the progress
|
||||||
|
after day one was pretty rough, as can be seen above. We had a
|
||||||
|
sprite for one character, _Miko_ and some very colorful
|
||||||
|
walls. The dialog options on-screen was baked in, and there was no
|
||||||
|
interaction beyond rotating between different clones of Miko.
|
||||||
|
|
||||||
|
## Saturday ##
|
||||||
|
|
||||||
|
Since 2017 _Nordic Game Jam_ has been a vegetarian event. I have no
|
||||||
|
issue with vegetarian food, I can live fine without meat. What I don't
|
||||||
|
care for, is being served [skyr](https://en.wikipedia.org/wiki/Skyr)
|
||||||
|
natural for breakfast, when a bowl of cornflakes or havregryn would
|
||||||
|
have done just fine. Why go for extreme variety, when something so
|
||||||
|
normal and cheap is already vegetarian?
|
||||||
|
|
||||||
|
![The same girl as before, standing in the corner of two walls,
|
||||||
|
colored in triangles. The girl is saying "...Yes?". On the left side,
|
||||||
|
the player can choose a question to
|
||||||
|
ask.](/website/images/nijousatsujikenriron-day-2.png)
|
||||||
|
|
||||||
|
Most of the game was implemented on the second day, Saturday.
|
||||||
|
Sketchwhale drew the remaining characters, and wrote the dialog for
|
||||||
|
_Miko_ and the dog. I implemented the dialog system, including all of
|
||||||
|
the _Miko_ dialog.
|
||||||
|
|
||||||
|
The 3d engine is, as previously asserted, a bit rough. It calculates
|
||||||
|
texture coordinates wrong, so the act of looking around will change
|
||||||
|
how a texture is draw, when the texture fills a large amount of the
|
||||||
|
screen.
|
||||||
|
This is obviously incorrect, but I couldn't be bothered
|
||||||
|
with fixing it before the jam, and didn't have time under the jam.
|
||||||
|
|
||||||
|
![The picture of a guy patting his head with a towel, projected onto a
|
||||||
|
surface in 3d space. The camera is looking at the picture from an
|
||||||
|
angle. The projection is weird and
|
||||||
|
distorted.](/website/images/3d-engine-stretching-issue.png)
|
||||||
|
|
||||||
|
Above is an example of the stretching bug. Compare it with [original
|
||||||
|
image](/website/images/sweat-guy.jpg). Notice how large his head is on
|
||||||
|
the projected surface, compared to how large it is on the original.
|
||||||
|
|
||||||
|
One way to avoid extreme stretching of the texture, is to split one
|
||||||
|
triangle into several. The distortion is limited, as each triangle
|
||||||
|
fills less of the screen. Unfortunately the entire engine is such a
|
||||||
|
mess, that all my attempts failed with weird warping textures.
|
||||||
|
|
||||||
|
Sketchwhale had drawn a great wall texture, but due to the stretching
|
||||||
|
bug, we could not get it to work properly. Instead we made the walls
|
||||||
|
randomly colored triangles, which looks alright.
|
||||||
|
|
||||||
|
Sketchwhale knew a musician at the jam, [Mikko "Mishicu"
|
||||||
|
Aaltio](https://twitter.com/mishicumusic). Although Mishicu were
|
||||||
|
already working with another team, he was convinced to make some music
|
||||||
|
for us, based on [that one scene from
|
||||||
|
Drive](https://youtu.be/Kq2a7MWbmJU?t=1m28s). Mishicu did a great job,
|
||||||
|
and I encourage you to play the game through, if only to listen to the music.
|
||||||
|
|
||||||
|
## Sunday ##
|
||||||
|
|
||||||
|
The third day started with incredible pressure to get the game
|
||||||
|
finished. We started work around `10:00`, with a deadline of `13:00`.
|
||||||
|
Sketchwhale mainly worked on a bit of promotional material, like a
|
||||||
|
video, while I implemented the dog dialog, and implemented an
|
||||||
|
introductory scene. A fun change was to shorten the dialog options
|
||||||
|
when not selected. This was to accommodate some long dialog options
|
||||||
|
pushing other options off of the screen.
|
||||||
|
|
||||||
|
![A cybernetically enhanced dog sitting in a corner of the elevator.
|
||||||
|
The player has several options when talking to it, some of which are
|
||||||
|
cut off, to save screen space.](/website/images/nijousatsujikenriron-day-3.png)
|
||||||
|
|
||||||
|
We didn't have time to finish the following, during the jam:
|
||||||
|
|
||||||
|
- The timer mechanic never went anywhere, as we forgot to add an
|
||||||
|
ending.
|
||||||
|
- The score mechanic was incomplete, due to a bug in the dialog
|
||||||
|
system, where some points weren't given correctly.
|
||||||
|
- One of the characters has no dialog.
|
||||||
|
- The player was supposed to have a gun, and be able to shoot
|
||||||
|
characters.
|
||||||
|
- A wireframe minimap was supposed to help the player when they
|
||||||
|
felt lost.
|
||||||
|
|
||||||
|
## The presentations ##
|
||||||
|
|
||||||
|
After the jam, every group had to present their game, in front of 30 other groups,
|
||||||
|
before voting on everybody's favorite. My favorite games from our
|
||||||
|
presentation scene was:
|
||||||
|
|
||||||
|
- [Rage Against the Cuisine](https://d-lo.itch.io/rage-against-the-cuisine)
|
||||||
|
- [Puppet Improv Theatre](https://saracecilia.itch.io/puppet-improv-theatre)
|
||||||
|
- [On-line](https://mrjwolf.itch.io/on-line)
|
||||||
|
|
||||||
|
All three groups were great at presenting, and displayed the charm of
|
||||||
|
their games very well.
|
||||||
|
|
||||||
|
I didn't get to see the final presentation, or know who won, as I left
|
||||||
|
early. I was incredibly tired, and just wanted to get home.
|
||||||
|
|
||||||
|
## Post-jam ##
|
||||||
|
|
||||||
|
After the jam, I decided to fix some of the bugs and missing features. I
|
||||||
|
added an ending, and fixed the score bugs. Furthermore a proper title
|
||||||
|
screen was added.
|
||||||
|
|
||||||
|
The introduction sequence was heavily modified, to make it more
|
||||||
|
intuitive. The doors were made actual 3d objects, and the light
|
||||||
|
flickers in a more realistic manner. A fun change was for each
|
||||||
|
character's name to only appear once the player has spoken with them.
|
||||||
|
|
||||||
|
![Elevator doors are open to an unusually large elevator. Each of the
|
||||||
|
four characters are standing in their respective corner of the
|
||||||
|
elevator.](/website/images/nijousatsujikenriron-post-jam.png)
|
||||||
|
|
||||||
|
Please do try the game; it is entirely free, and can be
|
||||||
|
[downloaded above](#download).
|
86
website/2020-07-06-suggest-require.md
Normal file
86
website/2020-07-06-suggest-require.md
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
# Suggest-require
|
||||||
|
|
||||||
|
**Suggest-require** is a tiny Lua library, for discovering importable
|
||||||
|
modules for Lua's `require` function. The intended purpose is
|
||||||
|
as a part of an auto-complete system for Lua written in Lua. The
|
||||||
|
script can, when run as a standalone program, list all of the
|
||||||
|
available modules in the current environment.
|
||||||
|
|
||||||
|
The library has been tested with LuaJIT and Lua 5.1 under Linux.
|
||||||
|
Compatibility with Windows, MacOS and other Lua versions is possible,
|
||||||
|
but not assured.
|
||||||
|
|
||||||
|
Source code on [Gitfub](https://gitfub.space/Jmaa/suggest-require). Usage and examples are available in the source file itself. License is Beerware.
|
||||||
|
|
||||||
|
## Why suggest-require? ##
|
||||||
|
|
||||||
|
I have been writing a debugging shell in LÖVE for a while now. The
|
||||||
|
shell itself, called Xenoterm, is pretty powerful at this point, with complex
|
||||||
|
interactions and autocompletions, inspired by [Fish shell](https://fishshell.com/).
|
||||||
|
One of Xenoterm most powerful features is argument auto-completion,
|
||||||
|
where the shell detects which function is being tab-completed on, and
|
||||||
|
suggests several possible arguments. This is similar to when Fish
|
||||||
|
provides suggestions for command-line options, listing files in the
|
||||||
|
local directory, or password files for
|
||||||
|
[pass](https://www.passwordstore.org/). This allows the user to
|
||||||
|
offload the need to remember specific names or files, and allows them
|
||||||
|
to focus on more important things, like writing code.
|
||||||
|
|
||||||
|
![Using suggest-require within Xenoterm to autocomplete the Posix
|
||||||
|
module.](/website/images/suggest-require-2.png)
|
||||||
|
|
||||||
|
Argument completion <abbr title="reason for being" lang="fr">raison d'être</abbr>
|
||||||
|
was to make life easier for me and
|
||||||
|
[Sketchwhale](http://takunomi.space) while working on our games, as we
|
||||||
|
had a habit of forgetting the ids of items and enemies.
|
||||||
|
|
||||||
|
For obvious reasons, argument autocompletion makes most sense for
|
||||||
|
functions with a single string argument, and a limited number of
|
||||||
|
inputs. Giving autocompletions for `string.lower` would not make any
|
||||||
|
sense. A prime candidate from Lua's standard library was `require`,
|
||||||
|
Lua's module importing functionality, which is why I wrote the
|
||||||
|
suggest-require library written back in 2017.
|
||||||
|
|
||||||
|
## How is suggest-require implemented? ##
|
||||||
|
|
||||||
|
A curious thing about Lua is that it aims to be [POSIX
|
||||||
|
compatible](https://en.wikipedia.org/wiki/POSIX) in order to be as
|
||||||
|
portable as possible. This means pretty much no built-in knowledge of
|
||||||
|
filesystems. Instead, Lua stores any information about the file system
|
||||||
|
configuration in the `package` global: Directory separators, library
|
||||||
|
locations, and so on. Depending upon which platform your Lua is
|
||||||
|
compiled for the proper values are fitted in, but all of this can be
|
||||||
|
inspected and modified at runtime. `require` will update its behaviour
|
||||||
|
based upon the values in the table. So if you wanted to figure out the
|
||||||
|
importable modules, you have all the information you want.
|
||||||
|
|
||||||
|
Unfortunately, Lua is __very__ filesystem agnostic, to the point of
|
||||||
|
having no API for looking up files in a directory. The
|
||||||
|
[Lua Filesystem Module](https://keplerproject.github.io/luafilesystem/)
|
||||||
|
exists for filesystem lookup, but I don't like dependencies for a
|
||||||
|
simple script. Lua does have the `io.popen` function for
|
||||||
|
interacting with the system's shell, and this can be used to query the
|
||||||
|
filesystem. On Unixes, we use the `find` program to find files, and
|
||||||
|
its builtin pattern matching allowed a bit of a speedup.
|
||||||
|
|
||||||
|
![Using suggest-require along with grep to find all importable posix
|
||||||
|
modules](/website/images/suggest-require-1.png)
|
||||||
|
|
||||||
|
So the entire process is roughly:
|
||||||
|
|
||||||
|
1. Produce glob patterns, based on information in the global `package` table.
|
||||||
|
2. Use `find` to execute those globs, retrieving a list of possible
|
||||||
|
libraries.
|
||||||
|
3. The library paths in the `package` table may contain multiple
|
||||||
|
wildcards (marked as `?` in the path), which, when using `require`
|
||||||
|
is replaced with the requested module. Thus our glob approach finds
|
||||||
|
too many files, and we need to prune some of them, (so `./?/?.lua`
|
||||||
|
matches `./a/a.lua`, but not `./a/b/.lua`.)
|
||||||
|
4. Add the names of the already loaded libraries into the mix; these
|
||||||
|
are easily found by looking in the global `package.loaded` table.
|
||||||
|
|
||||||
|
Sugggest-require will thus most likely only work on desktop computers,
|
||||||
|
and other full featured environments. These are also the environments
|
||||||
|
where I could see the script being used; a script deep in a game
|
||||||
|
engine or on an embedded device will probably know exactly which
|
||||||
|
modules to import.
|
Loading…
Reference in New Issue
Block a user