You are reading: Fun64 dev blog
Chatdown

Chatdown is a markdown like text format for describing chat trees, the idea is to have all the logic somewhere else and just use this for describing the relationship and hierarchy of the text.

The bad news is this means you have to label each part of the chat with reasonable ids so the code can find it. Naming things is hard and has to be done.

Mostly the file is interpreted as paragraphs similar to markdowns paragraphs separated by empty lines, between these paragraphs lines beginning with one of the special characters #<>= switch the mode, and assign where the next set of paragraphs will be stored.

Following immediately on from these special characters with no white space in between are the id labels, these are used to name each set of paragraphs and allow references between them. This is the most complex part of the chatdown format.

A chat is started by beginning a line with a # this can be thought of as the talky part of an NPCs brain and a chatdown file contains multiple chats. These chats can reference each other, for example one NPC can check what you have told another NPC.

The first paragraph of a #chat is the display name of the NPC, the rest of the paragraphs are a longer description. More data can also be associated with the NPC here but I will go into that another time.

Responses are started with a < and they belong to the current chat, these are the things that an NPC says, for instance, <welcome is the first thing an NPC says when you talk to them.

Decisions are your choices that can be made after an NPC talks, started with a > these are stored in the current response and are primarily links to another response.

With decisions the first paragraph is displayed and the remaining paragraphs can be used as the spoken out loud dialogue. Some styles of dialogue writing use this form, others only need the first paragraph.

Proxies are variables associated with this chat, they are assigned by lines beginning with an = and all paragraphs following are given to this proxy. Proxies way be set inside any of the other states and the change will happen as you progress through the chat. This allows us to track decisions by changing a proxy inside the decision.

Proxies may be expanded inside paragraphs or even option names by using squiggly brackets like so {proxyname}, more complicated expansions will be added later if needed.

This is just an overview and its best we explain with some code, so take a look at the following chatdown example which you will find embedded at the top of this fun64 file. The code to parse and display this format is included, probably best you do not look too closely at that bit :)

Since chatdown took some time to formalise, it is also going to take more than one short post to explain, expect a follow up with a more complex example.

~ xriss 2017-03-19
Hello World!

Apparently if your hello world example is longer than a couple of lines then you are open to ridicule.

I suspect people who say this are blissfully unaware exactly what _main gets up to before your code runs and lets not even think about C++.

Still it helps to remove as much gubbins as possible so the code that's running becomes obvious. Fun64 is built around the idea that you should define the hardware before the program runs so lets hide all that away inside a builtin function that will set you up a basic looking screen to work with.

Introducing the configurator, this function will provide various setups depending on the mode requested and also provide a main function that will allow you to provide a single update function rather than dealing with more complexities. A single update function is less optimal but a perfectly reasonable way to write short bits of test code.

So far the only mode we have is "fun64" which will get you a 60fps 320x240 screen with three layers and the Swanky32 palette. The three layers gives us a copper background, a tile+sprite foreground and finally a text overlay on the very top. For graphical memory we have a 64x64 area of 8x8 tiles (4096 in total) and we auto upload the 4x8 fun64 font to the very first line for use by the text layer.

NB: If you clobber this top line all your text will go funny, just like on real hardware.

The main point of the layers is so we can have drop shadows between them, the text layer on top gives us some very cheap 80s looking text menus when used with solid blocks of background color.

~ xriss 2017-02-12
Comic test.

Lets see if we can build 4lfa.com style comics using just fun64 :)

~ xriss 2017-01-27
Basic fun!

A cut down and basic fun example, we do not make many assumptions so you are free to configure and setup your code to your own tastes.

There are only two parts that you must provide for fun to work. The first is a table describing the virtual hardware component setup, eg the resolution of screen and tilemaps and sprite layers to display.

hardware={
    {
        component="screen",
        size={424,240}, -- lowrez with a 1920x1080 aspect
        scale=3, -- draw in a window at 3 times scale
        fps=60, -- 60 fps please
    },
    ...
}

This requests the virtual hardware that will be setup before main is called. system is a global table that will be created according to your requested hardware and can then be referenced when the main function is called.

The second is a main function which will be called as a yield-able co-routine with a table that should be treated as an incoming message. Use the basic skeleton below to receive need.setup/update/draw requests. As you can see it is possible to have multiple needs at once and this call structure allows for a setup, repeat update/draw then cleanup flow of code within this co-routine.

function main(need)
    if not need.setup then need=coroutine.yield() end -- wait for setup request

    -- perform setup

    local done=false while not done do
        need=coroutine.yield()

        if need.update then

            -- perform update

        end

        if need.draw then

            -- perform draw

        end            

        if need.clean then done=true end -- cleanup requested
    end

    -- perform cleanup

end
~ xriss 2017-01-20