Droofus Assembly Language plugin for Godot Development Update #1 (With Demos)

Hi Everyone, after weeks of work, and far too much caffeine, we’ve finally moved into the in-house release phase for Droofus, our assembly language engine and language plugin for Godot. The engine is feature complete, and we’ve started using, (the two separated versions, yes two), for actual game development. I’ve just posted the first development update video to our website and YouTube.

It’s a pretty in-depth deep dive into the project along with demos of actual assembly code running within Godot, including the first demo of an in-house game we’re writing entirely in assembly.

Many thanks have to be given to the Godot community for all the help we’ve received when stuck. Couldn’t have done some of it without you.

Enjoy.

2 Likes

That was very interesting. You may have addressed this and I missed, it, but can we use Droofus to create specific Assembly functions? Basically use it to improve just the sections of code we need to for performance?

2 Likes

Hi there, yes certainly, you can’t put the assembly code directly inline with your GDScript or C# code but what you can do is the following. Though possible this was never really our intent. We designed the system to run the entire program in assembly to take advantage of script queueing and such. Also running a script in this fashion does not necessarily mean it will run immediately. There may be other scripts is the queue waiting to run ahead of it.

func isTheWorldFlat ( radius: float ) -> bool:
	DroofusCore.execute_asm_with_value( "worldFlatnessCalculator.asm",  radius  )
	if DroofusCore.get_value_by_name("curve") > 0:
		return false
	return true
 

Running a script in this fashion sets the following engine flag .sharedData to true. When true all values remain in memory after a script exits.

You have to realise thought that in assembly all variables (we’ll call them that for sanity sake) are global. If we were to run the following script multiple times that would be fine, with .sharedData turned on script names are added to the prior scripts list so the compiler skips repeated variable creation for those scripts. But if we were to run another script which defined the variable “curve” we’d get a compile error.

With .sharedData turned on if your code expects a variable value to be as originally created, you’d need to set it back to the original value in code before use if run repeatedly.

.sharedData is one of the only engine flags not reset back to default after a script finishes, so for all scripts after this one .sharedData would be on unless you explicitly set it back to false in code.

There is also a .clearData directive you can use to reset everything if you wanted. The .sharedData flag though, would still remain in it current state..

Dot directives are compiler switches and are only evaluated at compile time and stripped from the final opCode. There’s no point putting one in the middle of a loop expecting it to be repeatedly called. It’ll still be evaluated at compile time, but gone at runtime.

In our early game demo you saw at the end of the video we’ve edited the droofus_defaults file to have shareData on by default.

Sorry for the longwinded explanation.

.debug false
.sharedData true
.optimiseLoops true

_start:
	lda #0 #reset the variable
	sta curve

	pop a #get the passed value off the stack

	# Some calculations

	sta curve

	brk

.dd curve, 0
1 Like

What versions of assembly does this allow for? Could one perhaps make an NES or SNES game with this plugin?

*sorry, had to ask

2 Likes

At the moment, we have Intel X86-64Bit, AMD X86-64Bit and ARM-64 Bit, patterns in our database, we could certainly add others assuming we could find the complete instruction set somewhere and the Linker requirements, but that’s not the big issue.

Godot itself needs to support the target platform as well and there is no way we’re going to be recompiling Godot to targets it doesn’t support, nor would I expect something like a NES would even have the memory or capabilities of running just Godot itself even without our additions.

It’s would be great, but I don’t think really achievable, at least not in any short time frame.

2 Likes

All it would require is a library for the version and the capability to put all of that into a .asm file, actually had a discussion similar recently or so, Actual retro game development with godot?, it is doable if you are interested in that sort of thing—either way this is a really cool project, good luck as well :slightly_smiling_face:

Like (ran out of likes for a while sorry)

1 Like

Thanks I’ll check that out..

1 Like

Huge quality of use upgrade, now we’ve got it working properly. Line numbers on our compiler or runtime errors. Also added a signal for when the splash screen disappears so I can start the ASM for the first scene without worrying about timing issues.

Even shaved an extra 100+ milliseconds of our, stupid :slight_smile: speed test program, even without .optimiseLoops turned on, just by going through the code, optimising and reducing unnecessary conditional checks. Now working on predictive branch testing, I think this one is going to do me in though…

3 Likes

Another big update today. We took a long look at our instruction set in mind with the instructions that would be used in modern game creation (We know ironic), in total we removed 21 versions of instructions from the Droofus’s core. Mostly old style instructions you might have used in old school 8-Bit days. That’s what our ‘Viro’ project was for. It’s also meant we could remove the binary_tools plugin as it’s no longer required.

Droofus’s core is lightyears ahead of Viro’s which was our proof of concept to see if this was even possible. Even after removing all these instructions, our puzzle game worked perfectly with no modifications what so ever. It’s even running at the default performance setting of 1000 instructions between yields and there’s no noticeable performance issues.

We didn’t see any speed boost, expectedly. Our new compiler is again far more advanced and compiles the code into instruction opcodes and creates a list of callable’s for each line of compiled code so we don’t have an ‘IF’ or a ‘MATCH’ statement in sight within the main core engine loop.

We’ve also updated the Syntax Highlighter to now handle, numbers and registers. Which really helps in coding.

Still can figure out how to expose the colours in the highlighter plugin even using ‘@export’, so that devs can set them to their preference. Even if we could I have no idea when to look for them in Godot’s editor. Would love some help with that. It would help in the development of other plugins.

Additionally we’ve added a couple of Droofus core flags, such as execution time display in minutes or seconds and also if the assembly is stored with the scene, rather than in the Droofus code directory. The only exclusion being the startup script which will always be looked for in the Droofus_Code directory.

Hi Everyone, I’ve just uploaded the first in our ‘Quick Flicks’ series, which we hope to be regular, short, unscripted videos highlighting updates to the game project and our in-house tooling. Been some nice updates to the game project this week. Thanks for all your help as always. This community is invaluable.