akevitt

package module
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2024 License: EUPL-1.2 Imports: 13 Imported by: 1

README

Akevitt

Akevitt is a MUD engine designed to be as modular, but powerfully minimal, as possible. This means that there are no "plugins" or "add-ons" that have narrow functionality. You get the infrastructure, information persistence, accounts, and other essentials done for you, while the rest is up to you. Strongly inspired by Evennia. What you can do with Akevitt is only limited by your imagination and technical skill in Go.

Features

  • Runs on an SSH server, meaning that, just like with Telnet, you can connect to an Akevitt game from almost any device available in the world.
  • Automatic database, meaning any game object (GObject) you create is tracked and survives reboots. You do not need to think about the database, ever.
  • Modularity. Use straight-forward API to create your objects, NPCs, rooms, or anything with, and place them all in one file or organised across as many files as you need.

How does Akevitt work?

The engine runs on a simple SSH server, which means that anybody with an SSH client installed on their computer can connect to the game and play in their terminal. Data is then stored in a small database that requires no external libraries or programs. It is all built into Akevitt. The server is entirely self-sufficient: nothing like SQLite is required.

What does Akevitt use to work?

The SSH server is implemented with ssh by Glider Labs. Database is Bolt, a simple non-relational key-value database, which is really all that is needed for a MUD. UI elements are implemented with tview. Basically, whatever challenges Akevitt meets, they are solved with the latest, mature libraries that the Go ecosystem has to offer. This leads to a robust infrastructure with the worst bugs eliminated before a single line of Akevitt's source was written.

Why this over Evennia?

Although Evennia is ambitious, and it certainly delivers in its rich feature set, it is quite bloated for what it is: over 350 MB of source just to get a simple MUD going? We can do better. Additionally, Python is very difficult to actually develop large projects in. pip is a nightmare. Maintainers of Python frequently introduce breaking changes in what are supposed to be minor versions of Python 3. Python virtual environments offer mixed results, most often not really solving the issue they are allegedly addressing. We can go on.

For end-users, it probably will not make a lick of difference whether their MUD runs on Akevitt or Evennia. However, for developers like us it makes a huge difference, and Akevitt is here to bring joy to developing MUDs, while retaining the ease of deploying complete games. If functional programming is more your speed, Akevitt is what you are looking for.

Licence & Attribution

Programming and design

Ivan Korchmit (c) 2023

Design and presentation

Maxwell Jensen (c) 2023

Licensed under European Union Public Licence 1.2. For more information, view LICENCE.

Documentation

Overview

Program written by Ivan Korchmit (c) 2023 Licensed under European Union Public Licence 1.2. For more information, view LICENCE or README

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendText

func AppendText(message string, chatlog io.Writer)

func BindRooms

func BindRooms(room *Room, exit *Exit, otherRooms ...*Room)

Binds room with an exit.

func ErrorBox

func ErrorBox(message string, app *tview.Application, back tview.Primitive)

func FetchPlugin

func FetchPlugin[T Plugin](engine *Akevitt) (*T, error)

func FetchPluginUnsafe

func FetchPluginUnsafe[T Plugin](engine *Akevitt) T

func FilterByType

func FilterByType[T any, TCollection any](collection []TCollection) []T

func Find

func Find[T comparable](collection []T, value T) bool

Finds `T` value of []T.

func FindByKey

func FindByKey[TCollection, T comparable](collection []TCollection, selector func(key TCollection) T, value T) *TCollection

func FindNeighboringRoomByName

func FindNeighboringRoomByName(currentRoom *Room, name string) (*Room, *Exit, error)

func LogError

func LogError(message string)

func LogInfo

func LogInfo(message string)

func LogWarn

func LogWarn(message string)

func LookupOfType

func LookupOfType[T Object](room *Room) []T

func MapSlice

func MapSlice[T any, TResult any](l []T, callback func(v T) TResult) []TResult

Maps slice, similar to JavaScript's map method.

func NewEngine

func NewEngine() *akevittBuilder

Engine default constructor

func PurgeDeadSessions

func PurgeDeadSessions(engine *Akevitt, callback DeadSessionFunc)

func RemoveItem

func RemoveItem[T comparable](l []T, item T) []T

Removes item from collection and returns it.

func RemoveItemByIndex

func RemoveItemByIndex[T any](l []T, i int) []T

Types

type Account

type Account struct {
	Username       string
	Password       string
	PersistentData map[string]any
}

Basic structure for storing credential information. After registering an account, the password is hashed in a proper way To create one you would need to invoke `engine.Register(username, password, session)`

func (*Account) GetName

func (account *Account) GetName() string

func (*Account) Save

func (account *Account) Save(engine *Akevitt) error

Save account into a database

type ActiveSession

type ActiveSession struct {
	Account     *Account
	Application *tview.Application
	Data        map[string]any
}

type Akevitt

type Akevitt struct {
	// contains filtered or unexported fields
}

func (*Akevitt) AddCommand

func (engine *Akevitt) AddCommand(command string, function CommandFunc)

Register command with an alias and function

func (*Akevitt) AddInit

func (engine *Akevitt) AddInit(fn func(*Akevitt, *ActiveSession))

func (*Akevitt) ExecuteCommand

func (engine *Akevitt) ExecuteCommand(command string, session *ActiveSession) error

Execute the command specified in a `command`. The command can be registered using the useRegisterCommand method. Returns an error if the given command not found or the result of associated function returns an error.

func (*Akevitt) GetCommands

func (engine *Akevitt) GetCommands() []string

Gets currently registered commands. This is useful if your game implements auto-completion.

func (*Akevitt) GetOnDeadSession

func (engine *Akevitt) GetOnDeadSession() DeadSessionFunc

func (*Akevitt) GetRoom

func (engine *Akevitt) GetRoom(key uint64) (*Room, error)

Obtains currently loaded rooms by key. It will return an error if room not found.

func (*Akevitt) GetSessions

func (engine *Akevitt) GetSessions() Sessions

func (*Akevitt) GetSpawnRoom

func (engine *Akevitt) GetSpawnRoom() *Room

Get sspawn room if specified. Useful for setting character's initial room during its creation.

func (*Akevitt) GlobalLookup

func (engine *Akevitt) GlobalLookup(room *Room, name string) []Object

func (*Akevitt) Run

func (engine *Akevitt) Run() error

Run the given instance of engine. You should pass your own implementation of ActiveSession, so it can be controlled of how your game would behave

func (*Akevitt) SaveObject

func (engine *Akevitt) SaveObject(object Object) error

Saves object into a database.

type CommandFunc

type CommandFunc = func(engine *Akevitt, session *ActiveSession, arguments string) error

type DatabasePlugin

type DatabasePlugin[T Object] interface {
	Plugin

	Save(T) error
	LoadAll() ([]T, error)
}

type DeadSessionFunc

type DeadSessionFunc = func(deadSession *ActiveSession, liveSessions []*ActiveSession, engine *Akevitt)

type Exit

type Exit struct {
	Room       *Room
	OnPreEnter func(*Akevitt, *ActiveSession) error
}

func IsRoomReachable

func IsRoomReachable[T Room](engine *Akevitt, session *ActiveSession, name string, currentRoomKey uint64) (*Exit, error)

Checks if current room specified reachable to another room.

type Object

type Object interface {
	GetName() string
}

type Pair

type Pair[TFirst any, TSecond any] struct {
	L TFirst
	R TSecond
}

type Plugin

type Plugin interface {
	Build(*Akevitt) error
}

type Room

type Room struct {
	Name       string
	Exits      []*Exit
	Objects    []Object
	OnPreEnter func(*Akevitt, *ActiveSession, *Exit) error
}

func (*Room) Enter added in v0.3.5

func (room *Room) Enter(engine *Akevitt, session *ActiveSession, targetExit *Exit) error

func (*Room) GetKey

func (room *Room) GetKey() uint64

type Sessions

type Sessions = map[ssh.Session]*ActiveSession

type UIFunc

type UIFunc = func(engine *Akevitt, session *ActiveSession) tview.Primitive

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL