|
|
|
@ -21,199 +21,52 @@ Currently AcediaCore...
|
|
|
|
|
would require us breaking compatibility, we will break it |
|
|
|
|
(until version `1.0` is released). |
|
|
|
|
|
|
|
|
|
AcediaCore is currently in the alpha with a goal is to gather some feedback from |
|
|
|
|
other people while finishing some yet incomplete features and writing |
|
|
|
|
documentation. |
|
|
|
|
|
|
|
|
|
## Why should I use it? |
|
|
|
|
|
|
|
|
|
TODO: |
|
|
|
|
|
|
|
|
|
* Talk about how the proper documentation is still in development, link whatever |
|
|
|
|
will be available for Friday. |
|
|
|
|
* Add section about gameplay API, why it exists, how complete it is and how it |
|
|
|
|
is not mandatory to use. |
|
|
|
|
* Short installation/using instructions. |
|
|
|
|
|
|
|
|
|
### Aliases |
|
|
|
|
|
|
|
|
|
Aliases are basically alternative (more human-readable) names for pretty much |
|
|
|
|
anything. |
|
|
|
|
For example, inventory class of Killing Floor's AK47 is |
|
|
|
|
`KFMod.AK47AssaultRifle`, which is a handful. |
|
|
|
|
AcediaCore allows server admins to define their own aliases for such |
|
|
|
|
values, that can later be used by other mods: |
|
|
|
|
[Futility](https://www.insultplayers.ru/git/dkanus/Futility) |
|
|
|
|
allows to add AK47 to a player with a chat command like |
|
|
|
|
`!inventory SomeGuy add $ak47`, where `$ak47` will be resolved like an alias. |
|
|
|
|
|
|
|
|
|
There more aliases type than |
|
|
|
|
[weapon aliases](https://www.insultplayers.ru/git/dkanus/AcediaCore/src/branch/master/config/AcediaAliases_Colors.ini). |
|
|
|
|
Like [color aliases](https://www.insultplayers.ru/git/dkanus/AcediaCore/src/branch/master/config/AcediaAliases_Colors.ini), |
|
|
|
|
[entity aliases](https://www.insultplayers.ru/git/dkanus/AcediaCore/src/branch/master/config/AcediaAliases_Entities.ini). |
|
|
|
|
Or you can even add a custom alias source, if you need aliases for something |
|
|
|
|
completely different. |
|
|
|
|
|
|
|
|
|
### Commands |
|
|
|
|
|
|
|
|
|
> **NOTE:** AcediaCore's commands are fully functional, but there are still some |
|
|
|
|
> changes planned for them during the alpha. |
|
|
|
|
|
|
|
|
|
AcediaCore provides a unified command system. |
|
|
|
|
Instead of the usual way of manually handling `mutate` input to detect your |
|
|
|
|
command and its parameters, you can simply specify command's name and types of |
|
|
|
|
the parameters it should take, register this command with AcediaCore and let it |
|
|
|
|
handle the rest. |
|
|
|
|
Most prominent features of AcediaCore's commands are: |
|
|
|
|
|
|
|
|
|
* Supported parameters range from simple `int` or `string` to complex |
|
|
|
|
JSON values. Some parameters can be marked as optional. |
|
|
|
|
* Ability to specify targeted players with advanced selector system |
|
|
|
|
(e.g. `@`/`@self` refers to the caller player, `@all` to every player and |
|
|
|
|
`[@all, !@self, !Dude]` to every player except you and someone called |
|
|
|
|
"Dude"). |
|
|
|
|
* Ability to specify *options*: additional modifiers that start with either `--` |
|
|
|
|
or `-`. |
|
|
|
|
|
|
|
|
|
Nice example is [Futility](https://www.insultplayers.ru/git/dkanus/Futility)'s |
|
|
|
|
command that allows you to give yourself all available weapons: |
|
|
|
|
`inventory@ add --list all --force`. |
|
|
|
|
Same command also be written as `inventory@ add -lf all`, where `-lf` specifies |
|
|
|
|
both `--force` and `--list` options. |
|
|
|
|
This command is defined |
|
|
|
|
[here](https://www.insultplayers.ru/git/dkanus/Futility/src/branch/master/sources/Commands/ACommandInventory.uc). |
|
|
|
|
|
|
|
|
|
### Text and colors |
|
|
|
|
|
|
|
|
|
AcediaCore provides its own text types as alternative to `string`: |
|
|
|
|
`Text` and `MutableText`. |
|
|
|
|
They are less efficient than `string`, but provide a richer set of methods and |
|
|
|
|
a better formatting support - instead of the usual way of coloring `string`s |
|
|
|
|
with embedded 4-byte escape sequences, it stores meta information about color |
|
|
|
|
for each character. |
|
|
|
|
With custom text types comes a new way to define color, *colored strings*. |
|
|
|
|
Just as an example of one: |
|
|
|
|
"This is a string with {\$red red}, {rgb(0,255,0) green} and {#0000ff blue} |
|
|
|
|
colors! There is also {\$pink pink with {\$gold embedded gold} color}!". |
|
|
|
|
|
|
|
|
|
In the future our custom text types also have a potential to offer a better |
|
|
|
|
Unicode support. |
|
|
|
|
|
|
|
|
|
#### Parsing |
|
|
|
|
|
|
|
|
|
As a part of the text API, AcediaCore provides convenient parsing tools. |
|
|
|
|
As a simple example, here is a code that parses rgb color definition into 3 |
|
|
|
|
integer components: |
|
|
|
|
|
|
|
|
|
```unrealscript |
|
|
|
|
local Parser parser; |
|
|
|
|
local int redComponent, greenComponent, blueComponent; |
|
|
|
|
... |
|
|
|
|
parser = _.text.ParseS("rgb(0,255,0)"); |
|
|
|
|
parser.Match(P("rgb("), SCASE_INSENSITIVE) |
|
|
|
|
.MInteger(redComponent).Match(P(",")) |
|
|
|
|
.MInteger(greenComponent).Match(P(",")) |
|
|
|
|
.MInteger(blueComponent).Match(P(")")); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
`P()` here simply creates AcediaCore's `Text` instance from `string`. |
|
|
|
|
|
|
|
|
|
### `Signal`s and `Slot`s |
|
|
|
|
|
|
|
|
|
The usual way to listen to events in UnrealScript was to use some sort of |
|
|
|
|
listener object: `Mutator` can listen to events like `CheckReplacement()`, |
|
|
|
|
`GameRules` is made to listen to a variety of events like `OnNetDamage()` |
|
|
|
|
or `OnOverridePickupQuery()`. |
|
|
|
|
AcediaCore's `Signal`s and `Slot`s allow to provide mod makers with even simpler |
|
|
|
|
access to certain events. As an example, to listen to `OnNetDamage()` event |
|
|
|
|
[friendly fire fix](https://www.insultplayers.ru/git/dkanus/AcediaFixes/src/branch/master/sources/FixFFHack/FixFFHack_Feature.uc) |
|
|
|
|
simply does `_server.unreal.gameRules.OnNetDamage(self).connect = NetDamage;` |
|
|
|
|
and `_server.unreal.gameRules.OnNetDamage(self).Disconnect();` |
|
|
|
|
to stop listening. |
|
|
|
|
Here `NetDamage` is simply a function with a proper signature. |
|
|
|
|
|
|
|
|
|
### Collections |
|
|
|
|
|
|
|
|
|
Acedia provides two collection types `ArrayList` for dynamic array and |
|
|
|
|
`HashTable` for... hash tables. |
|
|
|
|
Both of them can store acedia's object values and any simple type values like |
|
|
|
|
`bool`, `byte`, `int`, `float`, `string`, `Vector` |
|
|
|
|
(and this list can be extended further via boxing!). |
|
|
|
|
`ArrayList` simply stores them as an array, by their numeric index, while |
|
|
|
|
`HashTable` stores its values by *keys*, most notably text keys: |
|
|
|
|
|
|
|
|
|
```unrealscript |
|
|
|
|
local HashTable table; |
|
|
|
|
table = _.collections.EmptyhashTable(); |
|
|
|
|
table.SetInt(P("My cool int!"), 7); |
|
|
|
|
table.SetFloat(P("Just a float..."), 1.25); |
|
|
|
|
Log("Int:" @ table.GetInt(P("My cool int!"))); |
|
|
|
|
Log("Float:" @ table.GetFloat(P("Just a float..."))); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
They can even store each other, allowing them together to store anything |
|
|
|
|
that JSON can by using `HashTable` to represent JSON object and |
|
|
|
|
`ArrayList` to represent JSON array. |
|
|
|
|
AcediaCore makes use of that and comes, among other things, with two-way |
|
|
|
|
conversion between its these collections and text JSON representation. |
|
|
|
|
Example of JSON to AcediaCore's collections conversion: |
|
|
|
|
|
|
|
|
|
```unrealscript |
|
|
|
|
local HashTable result; |
|
|
|
|
result = _.json.ParseHashTableWith(_.text.ParseString( |
|
|
|
|
"{\"value\": 7, \"arr\": [11, -39, 5067, true, []]}")); |
|
|
|
|
// Get int: |
|
|
|
|
Log("Int #1:" @ result.GetArrayList(P("arr")).Get(1)); // Int #1: -39 |
|
|
|
|
// Or directly |
|
|
|
|
Log("Int #2:" @ result.GetIntBy(P("/arr/1"))); // Int #2: -39 |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
### Features |
|
|
|
|
|
|
|
|
|
Features are server-side replacement for `Mutator`s with more requirements for |
|
|
|
|
them. |
|
|
|
|
Currently they are more annoying to make for a modder, but when done correctly |
|
|
|
|
provide more benefits for the user: |
|
|
|
|
|
|
|
|
|
1. Ability to have different configs for different game modes; |
|
|
|
|
2. Ability to serialize their configs into JSON, potentially editable (WIP) |
|
|
|
|
by users right during the gameplay; |
|
|
|
|
3. Potential ability to swap configs or start/shutdown `Feature`s on the fly. |
|
|
|
|
|
|
|
|
|
For now these still need to be manually implemented by modder and AcediaCore |
|
|
|
|
simply provides a common interface through which admins and other modders access |
|
|
|
|
these capabilities, but we have plans to automate implementation of at least |
|
|
|
|
the first two way later down the line. |
|
|
|
|
For now we will settle on providing these capabilities to all mods that we make |
|
|
|
|
with AcediaCore. |
|
|
|
|
|
|
|
|
|
### Console output |
|
|
|
|
|
|
|
|
|
When sending long messages to client one can encounter an issue with these |
|
|
|
|
messages wrapping to the next line and being displayed on top of the next |
|
|
|
|
message. |
|
|
|
|
AcediaCore introduces `ConsoleWriter` class that can automatically break lines |
|
|
|
|
when they get too long (what is "too long" defined by the config). |
|
|
|
|
Thanks to that, we don't have to think about whether out output gets too big. |
|
|
|
|
`ConsoleWriter` also provides auxiliary methods to make writing into |
|
|
|
|
the console easier. |
|
|
|
|
|
|
|
|
|
### [WIP] JSON local and remote databases and AvariceLink |
|
|
|
|
|
|
|
|
|
We bring them up last, because they aren't yet complete. |
|
|
|
|
To be precise, AcediaCore right now provides working support for local databases |
|
|
|
|
that can store arbitrary JSON values with following limitations: |
|
|
|
|
|
|
|
|
|
* Reading JSON data that is too large can lead to a crash; |
|
|
|
|
* Bit integers (with arbitrary beyond what `int` is capable of) aren't yet able |
|
|
|
|
to be saved/loaded from it. |
|
|
|
|
|
|
|
|
|
We also plan to make use of Acedia's JSON parsing capabilities to allow |
|
|
|
|
interaction with remote JSON database via something called *AvariceLink*. |
|
|
|
|
Work on that has already started (although it was postponed for about a year |
|
|
|
|
due to the need to develop other Acedia's areas) and there is a working |
|
|
|
|
prototype, that is able to overcome some of the UnrealScript's network quirks. |
|
|
|
|
*AvariceLink* itself is supposed to allow a simple JSOPN message exchange with |
|
|
|
|
outside applications. |
|
|
|
|
|
|
|
|
|
This is sure to be completed during the duration of this alpha. |
|
|
|
|
AcediaCore is currently in the alpha with a goal to expose it to slightly wider |
|
|
|
|
circle of people, while finishing some yet incomplete features. |
|
|
|
|
|
|
|
|
|
So far there's very little documentation to go by: |
|
|
|
|
|
|
|
|
|
* For reference documentation you can check the source code: it is rather |
|
|
|
|
heavily documented; |
|
|
|
|
* For basic usage examples you can refer to |
|
|
|
|
[this document](https://insultplayers.ru/killingfloor/acedia/howto/); |
|
|
|
|
* For information about how it works internally and justifications for why |
|
|
|
|
things were made the way they are, read |
|
|
|
|
[this document](https://insultplayers.ru/killingfloor/acedia/docs/). |
|
|
|
|
|
|
|
|
|
## Why should I be interested in it? |
|
|
|
|
|
|
|
|
|
Currently AcediaCore doesn't offer much in terms of gameplay-altering features, |
|
|
|
|
focusing mostly on utility APIs: |
|
|
|
|
|
|
|
|
|
* **Aliases** Write `$ak47` instead of `KFMod.AK47AssaultRifle`; |
|
|
|
|
* **Commands** Don't worry about parsing your `mutate` commands' input, |
|
|
|
|
AcediaCore will handle it for you; |
|
|
|
|
* **Text** Slower, but more functional text types. Define colored `string`s like |
|
|
|
|
this: |
|
|
|
|
`This is a string with {\$red red}, {rgb(0,255,0) green} and {#0000ff blue} colors! There is also {\$pink pink with {\$gold embedded gold} color}!`; |
|
|
|
|
* **Parsing** Additional tools for making parsing whatever you want easier; |
|
|
|
|
* **Signals and Slots** Want to handle user's `mutate` commands? |
|
|
|
|
Just do this: |
|
|
|
|
`_server.unreal.mutator.OnMutate(self).connect = HandleMutate;`; |
|
|
|
|
* **Collections** Generic collections that can be converted into JSON and back; |
|
|
|
|
* **Features** More of a pain in the ass to make than `Mutator`s, but should |
|
|
|
|
provide better UX (I hope); |
|
|
|
|
* **Console output** No more ugly-wrapped lines from `ClientMessage`, |
|
|
|
|
AcediaCore's `ConsoleWriter` will auto-wrap long lines for you; |
|
|
|
|
* **Local databases** Working local databases that can store arbitrary |
|
|
|
|
JSON values, still require a bit of polish; |
|
|
|
|
* **Unit testing** Built-in support for unit testing of things that can be |
|
|
|
|
tested within one tick; |
|
|
|
|
* **[WIP] External applications** Exchange JSON messages with external |
|
|
|
|
applications, including remote JSON databases. Passed proof-of-concept |
|
|
|
|
stage, but still unfinished; |
|
|
|
|
|
|
|
|
|
## Installation |
|
|
|
|
|
|
|
|
|
There is no need for installation besides copying the mod file into your |
|
|
|
|
server's `System/` directory, but to actually make use of AcediaCore you need |
|
|
|
|
to install |
|
|
|
|
[AcediaLanucher](https://www.insultplayers.ru/git/AcediaFramework/AcediaLauncher). |
|
|
|
|
There is a way to use AcediaCore without launcher or any other package, but we |
|
|
|
|
will document it later, after polishing a few things. |
|
|
|
|