Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Whispers

Pages: [1]
OXCE Builds & Ports / OXCE Lua
« on: June 07, 2024, 03:23:35 pm »

That's right, I've started it.

How it works

I've modified Game and Mod so that they take in a ModFile class which contains a list of all the mods active and are in the correct loading order. Once Mod has finished loading, then I load up LuaMod which goes through each metadata.yml and checks to see if there is a tag for a lua file in there. The metadata should look like this:

Code: [Select]
# metadata.yml for Lua Test

name: "Lua_Test"
version: 1.0
description: "Verifying the callback mechanism works"
author: Whispers
master: xcom2
lua: bootstrap.lua

Once it sees the "lua: bootstrap.lua", then it knows this is a mod which uses the new Lua stuff. Once that is detected, it uses the path to the mod, then appends the lua filename, then loads the Lua file. A couple of things to note here is that I don't think this will work for zipped up files in its current state, but that may come later. In fact, I'll post a bug on the repo so I know I will catch it at some point. The other thing to note is that I've overriden the Lua print and redirected it to log, so anything you print, or any Lua errors, will get output to the game log.

Once loaded, it is executed once, and only once. It's up to the mod to register events.

Code: [Select]
function onLoad(doc)
print("the above 'doc' contains the entire save state converted from YAML to Lua Tables")))


There will be more hooks, but I had to start somewhere. Once the game is loaded, then things become more interesting. "game.base" becomes available, which I'm currently working on. On the C++ side, I've been working on how to simplify the registration of events and callbacks, as well as how best to expose the data. I've come up with a mechanism which allows a programmer to register a container and the LuaApi does the rest, but it's still very early at the moment.

And that brings me to the current status. All the Lua stuff does at the moment is likely to change. For instance, 2 days ago I was designing the api to use getters and setters, but that's not necessary Lua. Want to change a soldiers name? Just set it in Lua and then you're done. Err, at least that's the idea anyway. Want to send a message to another mod? Sure, I'll get to that eventually. Cross mod communication is definitely on my agenda. My first priority is setting up the API and exposing as much as I can.

So, there are two types of callbacks, at the moment. Events and Accumulators. Events fire off just like you would expect them to. Things like onLoad and onSave or, when I get around to it, onTick are all events. They fire off with parameters that be be read by the Lua state. Most events fire off for every mod that registers a callback, but a handful of events can be consumed. When an event is consumed by the callback, it does not fire off for the next mod and it could also stop the default behavior in C++. Accumulators are a bit different. The first parameter for an accumulator callback is the result of the previous accumulator(or the default value). The accumulator must return a value which is passed to the next one or sent to the game.

The framework for Lua is mostly there. The Api has started to take shape. I'm very hopeful that this time around it will be an official release.

Big changes

This does introduce some changes that I feel are necessary.

1) YAML is no longer required in the binary dependencies. I would also like to get SDL removed, therefore removing all binary dependencies altogether, but... time...
2) I've dropped support for the old MSVC Project, Makefile and I will not be supporting any other build system other than CMake. Reason why is because in order to grab the YAML and (in the future) SDL stuff and build it, I use CMake for that. There's also a strong argument that if you are developing on something that is shared, then you should all be using the same process that is used to trigger the nightly builds.
3) I've squashed over 800 warnings from build the x64 version, but more are coming. I basically squash them as I'm building.
4) I've been slowly but steadily removing the "auto" from the variable declarations. In the process, I've found a TON of potential bugs and issues and fixed them as I went along. Far too many to list here.
5) I've exposed a getGame function callable from anywhere. I hate singletons, but in order to get the hooks where I needed them to be I need to get the Game*. Now, singletons are evil, but there is an alternative called Thread Local Storage. Not that it matters, due to how many other globals are floating around, but theoretically, you could fire off different Game objects on different threads. This keeps things nice and tidy for the future.
6) You need to have a C++20 compiler now

Backstory: A long time ago I started on working with integrating Lua into OpenXcom. At the time, I was basically told the change was not wanted by the authors of OXCE, so I abandoned it. This time around, *I* wanted the change so I could implement some custom logic without having to touch the source. It's taken me the last two weeks to get it up and running again, but this time it's far more powerful than before.

Next Steps

Continue implementing more events, exposing more data and fleshing out the API. Specifically, the next API I am working on is for UI.

I haven't even defined what a release looks like. I'd love to get your feedback and thoughts.

Programming / Local Llama3 Integration
« on: May 25, 2024, 04:21:52 pm »

A while back(several years ago) I wrote some stuff for OXCE which enabled some Lua modding, but it wasn't well received so I abandoned it.

Lately I've been toying with the idea of using a local Llama3:8b LLM model for some limited scope stuff within Xcom. The first, and most obvious one, is the council notices at the end of the month. Instead of it being some bland text which is always the same, I was thinking it would be cool if it could reference what happened during the month, and the results of those actions. Not everything, of course, but just the highlights. Even cooler, imagine if it would read it to you with a similar voice of the Spokesman in Firaxis Xcom, but maybe attenuated and made in 8 bit audio.

Unlike the Lua stuff, where I just went off and did it, then was told it wasn't going to make it into mainline, I wanted to ask before beginning work on something like this.

So the way it would work is fairly straightforward. If you have the option enabled and the address and port to the Llama instance set, then it would work. Otherwise it would fall back to using the same bland text we have seen for decades now. If it is enabled, then it would feed all actions you have performed over the past month, how those actions have changed your political standing within governments, and some very simple prompt engineering to make the report sound like it is coming from the Spokesman, then viola! You have a custom report at the end of every month detailing your progress and standing within the governments. It's possible to take this a step further and enable a conversation with the Spokesman, but I kinda feel as though that would diminish the feeling of finality of the end of the month report.

To do the voice encoding, it's possible to train up something with Piper( Once again, making it optional. If you have piper installed, then we could provide it with a model and text to read, and that's it. You'd have in game text to speech that would sound similar to the Spokesman.

What are your thoughts?

OXCE Builds & Ports / [OXCE+] Lua Integration
« on: September 15, 2018, 04:55:31 pm »
I started work on extending OXCE+ to include LUA hooks and so far the results are promising.

I wanted to start this thread to discuss the progress and also address any design considerations with how the OXCE+ LUA API is constructed.

First up, the progress.

I've set up a new rule which allows you to specify a script to load. The rule syntax is fairly straightforward.

Code: [Select]
  script: scripts/game.lua

This will simply tell the engine that you have a script in <mod root>/scripts/game.lua. When a game is loaded or a new game is started, it then executes the script for the first time. When the script is executed, it is responsible for registering the hooks that it requires in the engine. Currently, it's implemented in such a way that you can only have one hook per script per callback, so you can call xcom.geoscape.register1HourCallback(function) multiple times, but it will only execute the last function you pass to it on every hour.

In the current version on github, there is one callback at the moment. I'll be refactoring the code a bit to make it more generic so other callbacks will be quicker to implement, however, start small and work your way up :D

With that working, the next steps are to add in a ton of global callbacks and hooks.

I set up the github repo. The repo with the Lua additions is here:

Why Lua? Well, to be honest, it's a widely known language that I have familiarity with implementing and developing with. That's literally the only reason why. Oh, and functions are data, which allows you to overwrite other functions to extend functionality in ways that are limited only to your imagination(and coding skills).

From a design perspective, I want to be clear that the idea is not to replace or port any of the existing code over to Lua. I don't want to port OXCE+ over to Lua. Instead, the goal is merely to provide the ability to get/set data internally without having to modify the engine code for new features.

With that said, there are things I do have in mind to allow you to extend certain features already built into the engine. For instance, one of my goals is to allow you to write your own terrain generation algorithms and hook into the existing terrain generation to allow you to overwrite or skip certain terrain passes. Another thing I want to allow you to do is customise almost every screen in the game by exposing the active UI elements and allow you to move/add/remove all UI bits around as you see fit. Then there's the obvious stuff, like being able to change soldier stats, add new fields, and completely new game mechanics(soldier mana stat anyone?)

Future plans:

* Have the ability to set/get existing base information such as stores, tiles, crafts, soldiers, etc.
* Add more triggers like onEnemyCraftDetected, onEnemyLanded, onEnemyBaseDiscovered, etc
* Have custom terrain generation scripts
* Have battlescape scripted events
* Hook into save/load game to allow mods to save their stuff.

Questions for modders:

* Should there be scoped/privileged Lua calls that are only accessible to certain mods?
* Any special requests for features? ( I have a feeling I may regret asking this :P )

So I'd really like to get your thoughts on this. Any questions, please feel free to give me a shout! I will be back here to post new updates as they come, so stay tuned!

Pages: [1]