Codea Modern API Extension Library - Manage Craft/Legacy backwards compatibility and customise almost any Lua APIs including userdata

I posted some of this code previously in another thread “can quats do anything?” to give a solution for some missing operations that can be available by default in other engines for quaternion multiplication and matrix conversions mathematics.

For quaternion multiplication/conversion in Codea currently, a few mathematical functions need to be implemented depending on what’s wanted/needed. Which can be a bit tricky to remember or get your head around to begin with, if you haven’t encountered this sort of maths much before. For myself I find having multiplication operator support easier than not when it comes to rotations. So I worked out a technique similar to this originally in craft, to support quaternion multiplication by overriding the quat userdata’s lua metatable.

Since the Modern Codea API was released into beta I have been working on a little library, mainly just to make my development workflow a little bit easier when experimenting with Modern. Mostly based upon older Craft projects implemented with the Legacy API.

As the extensions classes were part of this library I thought I’d post the full version of the library here too which has a couple of other useful bits of generic functionality for any game and coding generally with the Modern API. Plus also ports of FirstPersonViewer and OrbitViewer for Modern from the Craft Cameras example/library. It can be used as a more or less drop in replacement for this Craft dependency, while the Touches example/library appears to work still as-is. So Touches is also included as a dependency automatically. I use this library as a base dependency for starting any 3D Modern Codea project. Everything that it contains is meant to be for more or less any game / project.

I’ll give an overview and discuss some of the code in a bit more depth too, a zip of ModernLibrary as a Codea project is at the end of the post.

ModernLibrary Overview/Features

  • Extensible class based API extensions mechanism, added as initial setup call, which are also per-project configurable, if desired.
  • Adds a generic type detection function type.is(var, type) for determining userdata, classes and instances within inheritance hierarchies.
  • Adds a couple of basic math functions math.round(value), for a mid-point rounding shortcut for doubles/floats, and math.sign(value, sign)to copy signs, which is required for one of the quaternion conversions.
  • Adds some extra string manipulation and comparison shortcuts, string.contains, string.startswith, string.endswith, string.replace and string.insert
  • Adds full quaternion multiplication operator support to quat, for vec3, mat3 and mat4.
  • Adds bi-directional quaternion to matrix conversion functions, quat.mat3, quat.mat4, mat3.quat and mat4.quat
  • Overrides scene.entity (scene:enity) to allow creation from a class scene.entity(MyEntityClass, args …), expecting a class init function like function MyEnitity:init(entity, args …). Returning then the class instance the same way a Craft/Legacy entity component is returned from entity:add.
  • Overrides entity.add to allow adding components Craft/Legacy style enitity:add(MyComponent, … args), expecting a class init function like, function MyComponent:init(entity, args …)
  • Minimal changes ports of Crafts OrbitViewerand FirstPersonViewer for Modern. An important note is coordinates orientation/handedness is different between Craft and Modern which isn’t necessarily accounted for (to keep them as close as possible to the Craft example/library as reference).

Usage/Examples

Firstly to get started, download the ModernLibrary zip and import it to Codea. Add it as a dependency to your project, then add a require for ModernLibrary and call extensions.setup from setup.

require(asset.documents.ModernLibrary)

function setup()
    extensions.setup()
    scene.main = scene.default3d()
end

Combined entity, components and quaternion multiplication extensions example.

Making multi-part buildings from multiple assets positioned by a single parent entity.

For this example there are a few Component classes needed to put it together. Firstly, we need to represent a Building as an entity, containing multiple BuildingPart instances. Which are the individual assets positioned based on the overall Building entities position and rotation as the parent entity.

Building = class()
function Building:init(entity, parent, parts)
    self.entity = entity
    self.entity.parent = parent
    self.parts = parts or {}
end

function Building:add(assetKey,...)
    local part = scene.entity(BuildingPart,self,assetKey,...)
    table.insert(self.parts,part)
end

BuildingPart = class()
function BuildingPart:init(entity, building, assetKey, pos, rot)
    self.entity = entity
    self.building = building
    self.entity.parent = building.entity
    self.mesh = mesh.read(assetKey)
    self.bounds = self.mesh.bounds
    self.size = self.mesh.bounds.size
    self.halfSize = self.size / 2
    self.entity:add(self.mesh)
    self.pos = pos or vec3(0.5,0,0.5)
    self.entity.position = self.pos * self.size
    if rot then
        if type.is(rot, vec3) then
            rot = quat.eulerAngles(rot:unpack())
        end
        self.entity.rotation = rot
        self.entity.position = ((self.pos * self.size) - self.halfSize) * rot + self.halfSize
    end
    
end


You may note that these classes use the extensions to quat multiplication and type.is. They are designed as components classes, similar to how they would be for craft except using the Modern API functions. It’s common in games that components can represent both full entities / types of entity, specific entities and also partial pieces of functionality or more abstract behaviours. Generally as individual/reusable units within the game they are designed.

To help make a more specific building now from these classes and introduce some assets, we create another component class and add a Building component and BuildingPart components with the Building:add shortcut function. The assets here are just from the built in SpaceKit asset pack.

HomeBase = class()
function HomeBase:init(entity)
    self.entity = entity

    self.hq = scene.entity(Building, self.entity)
    self.hq:add(asset.builtin.SpaceKit.buildingOpen_obj, vec3(1,0,1), vec3(0,0,0))
    self.hq:add(asset.builtin.SpaceKit.buildingOpen_obj, vec3(1,0,2))
    self.hq:add(asset.builtin.SpaceKit.metalStructureBottom_obj, vec3(3,0,1.5))
    self.hq:add(asset.builtin.SpaceKit.metalStructure_obj, vec3(3,1,1.5))
    self.hq:add(asset.builtin.SpaceKit.metalStructureCross_obj, vec3(3,2,1.5))
end

The arguments are Building:add(assetKey, position, rotation), which adds a BuildingPart entity and sets the parent to buildingComponent.entity where assetKey is any project model asset, position is a vec3 position relative to the Building and rotation may be a quat or vec3 x,y, Euler angles (as if passed to quat.eulerAngles).

We also need a Player component so we can have a view with a camera we can control to look around our more complex building. Adding the ported orbit viewer to the scenes camera component we obtain through the entity.

Player = class()
function Player:init(entity)
    self.entity = entity
    self.scene = entity.scene
    self.viewer = self.scene.camera:add(OrbitViewer, vec3(0,0,0), 100, 2, 200)
    self.viewer.rx = 30
end

Then finally to show a HomeBase entity on screen that we can see, we simply create one as follows in setup also adding with our quick Player as another entity.

function setup()
    extensions.setup()
    scene.main = scene.default3d()
    
    player = scene.entity(Player)
    home = scene.entity(HomeBase)
end

Thescene.entity function here simply creates a new entity and the component instances, then adds the component and returns back the new component instance. Just like entity:add both with these extensions and in Craft.

It is important to note that it is not the entity that is returned with this scene.entity variant. The standard Modern API is otherwise left alone and works as documented otherwise. I made this as a trade off for convenience when typing to create entities and access functionality from a primary component in a single line. As I mainly prod at an iPad screen generally. So I felt for my typical use I can make the entity available from ComponentClass.entity or another name provided its set it in the component initialiser as above.

However this whole library is really just designed as a starting point and to be hacked about and extended too. So you can just modify the scene.entity extension function in the Extensions tab in ModernLibrary’s code. Rename it as you like and add more tools as you make them and discover things. Or find you feel you would like to have more instance functions on userdata, lua types, Codea APIs or extend almost anything in Codea fairly unobtrusively then this library can help and be adjusted to your needs.

A note on the philosophy is it’s not meant to be huge library, rather just a collection of some extra basic fundamentals that can simplify some development. To then be able to focus more on making games and experimenting mechanics. Then be tinkering with the more of the supporting/underlying ‘software’ functionality.

Most of the functionality works by either just declaring new code or extending with direct replacements approaches such as function hooking or metatable manipulation and _G.

A entensions.hook function is provided so you may hook functions yourself. To do this you just need to write a wrapper like:

some.func = extensions.hook(function(base, …)
  -- your custom behaviour
  return base(…) -- (optional call base)
end

An extensions.replace_global(name, value) is also provided for manipulating and recording changes to _G . Technically these could be undone later too from this although it isn’t implemented.

To create new extensions a specific extensions.extension function shortcut is provided to automatically register class based extensions with extendions.setup. Otherwise classes and functions can be added manually with extensions.register.

An extension class should look as follows for example MathExtensions. Initialisers / initis not used, instead ExtensionInstance:setup is called if the extension is a class. Otherwise function extensions added with extensions.register are simply called once.

MathExtensions = extensions.extension()
function MathExtensions:setup()
    math.round = function(value)
        local v = math.floor(value)
        local d = value - v
        if d < 0.5 then
            return v
        end
        return math.ceil(value)
    end
    math.sign = function(value, sign)
        if (sign < 0 and value > 0) or (sign > 0 and value < 0) then
            return -value
        end
        return value
    end
end

Finally specific extensions can be included or excluded with a table or parameter list passed to extensions.setup (default is include, for exclude use table with an config.exclude table member).

In any case without further waffling, here’s the library. I would love to hear thoughts if you try it and also see what games you may create in Codea 4 beta / Modern API whether it’s with or without this!

ModernLibrary.zip (9.3 KB)

Not to be a noodge but you’ve reversed left-right scrolling. :wink:

So like this seems like it could be an awesome thing to me but I admit I barely understand it lol.

If I’m committing to Project Night Cobra :rofl::rofl::rofl: then I need to try to make something with this but I honestly don’t know what I’d make.

Were I to put aside my hesitance to make Modern projects while there’s no Xcode compatibility, would this be helpful porting my spaceship demo to Modern?

Ah glad you mentioned this as it shows the ‘handedness’ of the two different coordinates systems between Craft and Modern. I’ve tidied up a diff of the original OrbitViewer from Craft and my port and screenshotted each of the significant changes/ differences. There are a few extra differences if you do this yourself which are redundant changes where I’ve not tidied up the code from implementing fixes to make it run.

You can see from the differences it’s all just accounting for minor changes to Codeas API in 4, mostly time.delta. Besides a bit of parameters cleaning / sanitising in the init function/ constructor.

It should certainly give you a starting point for porting over from Craft alongside the 4.0 update guide in the Codea docs. It helps with certain things like it should let you just use most of your existing entity:addcalls from any Craft components you’ve made before in projects. In Modern there’s a lot of similarities in 4 with Legacy, it effectively moves craft into a unified API with the older Legacy functions while updating some things. Though some things have moved about and been renamed. The library doesn’t do anything for voxels, and definitely isn’t a fix all for legacy projects.

It’s just something which helps with making projects in Modern, taken from a point of view of if you’re already familiar with Craft and adds some extra bits of API for Modern. Such as quaternion multiplication which you find in other game engines like Unity or Unreal. So it could possibly help with porting your spaceship demo to Modern, and it should also let you extend it with more complex transformations in terms of rotations too. That for example if you have planetary bodies, can be relevant for calculating orbits / trajectories of asteroids etc.

Entities and Components are a primary concept in Modern and somewhat in Craft too. They are a little bit of a different way of thinking of things in comparison to just regular classes. The Unity engines documentation has a fairly good Entity component systems concepts overview, which might help explain this way of working, that can then be applied to Codea in Craft and Modern.

I took a look at that link and felt the same as I felt when I learned about the Craft entity:add() system: it seems like there’s an easier way to do that.

I’m fairly positive I’m wrong because I’m speaking from ignorance here.

And maybe it’s way more useful for large projects and I’ve just never made anything large enough to need it. In legacy you can add functions directly to entities using dot notation and I’ve yet to find fault with that. Maybe I would if I had to manage tons of different entities though? I’m not sure. Components seem to give entities abilities and that’s what functions do too, with a lot less work.

Again, this sure seems like an established and widely used design pattern, so I know I’m getting something wrong here.

Yeah it’s definitely a bit different and this is also designed for working with the entity:add way of doing things too. You’re not wrong either that there might be easier annd other ways of doing things.

Entity component systems are a trade off and a change of focus to ‘composition’ instead of ‘inheritance’. Composition with components is generally better at solving a problem that inheritance is not so good at. Which is, when you try to make classes based on inheritance hierarchies that need to use lots of different bits of functionality like in games. They can become very complicated.

Take an example of Player and Enemy entity with health that you add as entity functions with dot notation.

player = scene.entity()
player.health = 100
player.damage = function(self, amount) self.health = self.health - amount end

enemy = scene.entity()
enemy.health = 100
enemy.damage = function(self, amount) self.health = self.health - amount end

This works and you can also share the function definitions of course. Or you can do the same/similar with classes:

EntityBase = class()
function EntityBase:init()
  self.health = 100
end
function EntityBase:damage(amount)
  self.health = self.health - amount
end

Player = class(EntityBase)
Enemy = class(EntityBase)

This becomes problematic however when you start getting entities which don’t fit the base ‘mould’ and start needing to add classes into the hierarchy. Which can make it tall and convoluted to reason. Although technically mixins are also valid in Lua these require something custom. Codea on the other hand supports components as lua classes on entities out of the box.

So I can make a component to make a universal concept of health for any entity. Then give that to any entity I choose. Regardless of whether it fits a particular entities other logical definitions/representations. A component for health as above looks like as follows in Craft and Modern.

Health = class()
function Health:init(e, value)
  self.entity = e
  self.value = value or 100
end

function Health:damage(amount)
  self.value = self.value - amount
end


-- usage (craft or modern with extensions)
player = scene.entity()
ph = player:add(Health, 100)

enemy = scene.entity()
eh = enemy:add(Health, 50)

-- somewhere else
ph_get = player:get(Health)
eh_get = enemy:get(Health)
-- note you can operate selectively with this

component = entity:get(ComponentClass)
if component <> nil then
  -- do something with ComponentClass interface
else
  -- isn’t an entity with a ComponentClass component
end

Components can also have an update and touched functions defined on them by attaching to the entity, which then be called automatically by Codea in Modern too. For example to remove ‘dead’ entities from the scene immediately:

Health = class()
function Health:init(e, value)
    self.entity = e
    self.value = value or 100
    self.entity.update = function(e,dt)
        self:update(dt)
    end
end

function Health:damage(amount)
    self.value = self.value - amount
end

function Health:update(dt)
    if self.value <= 0 then
        self.entity:destroy() -- remove entity from scene
    end
end

Note care is needed with this technique replacing the entity update method as this is shared between components. A simple work around is using extensions.hook to keep adding update hooks wrapping the last, although this may have call stack implications if excessively used.

Another approach is simply making another component to manage entity components updates / touches from somewhere else. Or handle custom components more universally over a determined set of current entities, narrowed for performance with a quad-tree or oct-tree and iterate all entities. There are multiple ways, you can keep things simple to start with, then just extend and expand as you find you need them. Most things start with making a component class that’s either more specific or more generic depending on what it does. Like Building and BuildingPart represent a more complex in game part you can use as an entity, which can be built up from multiple individual model assets.

Okay so like if, say, someone of sufficient ambition were to add some kind of critters to the Voxel Worlds project, you’re saying this might be a good candidate for differentiating them and their behavior? Just for example?

@M4nw3l I’m very interested to learn more about your use of the Modern API and what would make things easier for you.

  • Do you need more quat operations? Like mat3/mat4 ↔ quat? Maybe also inverse, dot, angle/axis, lerp, and scalar multiply
  • You mention “entity update method as this is shared between components” — not sure if this is the case? Define function MyComponent:update(dt) on the class and each
    component should get its own update. Same for touched, draw, created, destroyed
  • Your override of entity:add, is this because the entity is not passed to the component’s initialiser and is instead passed in the created method in Modern? Modern calls init() with no args, then sets self.entity, then passes args to created(...). We could pass the
    entity and args to init too for better Craft compatibility
  • Should OrbitViewer / FirstPersonViewer just ship with the scene API? Anything else in your library you’d say belongs in the API rather than a dependency?
1 Like

@UberGoober Yeah absolutely, it means you can create many different types of critters all with both shared and distinct behaviour, functionality that is unique to some or also the same and shared with others. You can just build up different types of critters from different components with entity:add. I chose health as an example as it’s typically a very common element between players, enemy’s, npcs etc.

While you can define differently what happens say when health reaches zero for each type, player, enemy or npc based on another component. For example you can check if there’s a Player, Enemy or Npc component also in the entity when handling health reaching zero or handle each one’s concept of Health from Player, Enemy and Npc components separately. It’s very flexible and you can use inheritance / hierarchy within it too, with care.

@sim Thank you so much, sure I’m more than happy to explain in further detail. The inspiration has come from my playing around with multiple game dev tools / engines on and off over the years including Codea and the usual suspects at the moment, Unity, Unreal, Godot. Among also doing some more hacky and modding types of things with some other engines and games…

So I’ll preface with that I’m often using quite a lot of random references for game dev that are not necessarily Codea specific. Then I’m trying to adapt them from the references I’m using into similar concepts / implementations for Codea.

  • Quaternion operations have definitely been one of the more challenging things to work out in Codea. I have a similar implementation of this library for the Legacy/Craft runtime too. Which iirc was harder to work out / has problems possibly due to the coordinate systems handedness. Information from other engines involving more complex rotations is typically expressed with combining quaternions with multiplications and can certainly use other operations too which generally need to be adapted/implemented for Codea too. A few experiments I’ve done have ended up like ‘well I thought I implemented it right’ but the visual effects on screen say otherwise. So definitely more quaternion operations out of the box would make life a lot easier I suspect from the point of view of making some things more easily / comprehensively in Codea. Where otherwise you might need quite a bit of medium to advanced mathematical knowledge to implement some of the operations suitably/be able to debug the equations applying them. Where these equations are generally from more or less books/papers/proofs/sparse online c/c++ tutorials/walkthroughs from years ago or discussions on math.stackexchange etc that then need to be ported into Lua for Codea.

  • The Health:update function here is in my Health component class. What I’m wanting here really is to be able to attach to the entity update from the component class like it’s an ‘event’ handler, where I can add multiple delegates. Two components both setting entity.update in a component:init overwrite one another unless this is handled somehow currently. For example:

    Health = class()
    function Health:init(e, value)
        self.entity = e
        self.value = value or 100
        self.entity.update = function(e,dt)
           self:update(dt)
        end
    end
    
    function Health:update(dt)
        print("health update")
    end
    
    Health2 = class()
    function Health2:init(e, value)
        self.entity = e
        self.value = value or 100
        self.entity.update = function(e,dt)
            self:update(dt)
        end
    end
    
    function Health2:update(dt)
        print("health2 update")
    end
    
    
    function setup()
        extensions.setup()
        scene.main = scene.default3d()
        
        player = scene.entity(Health)
        player.entity:add(Health2)
    end
    

    Which prints just “health2 update” on every entity.update.

  • For entity:add yes this is based on Craft being different/incompatible with the new API’s approach with the created entity handler. This hacks it back handling args earlier back in init functions. Similarly for my scene.entity override, in Craft I’d often group an entities components definition under a representative ’parent’ component, as an editor where you just add components to entities and save them was not available. So being able to create an entity from a more specific component class is handy e.g. player = scene.entity(Player), player:init can setup the player entity with sub-components like Health with code like self.health = entity:add(Health), where entity is passed as the first argument (or set pre init) so it can be accessed from component init functions, and can also get to the scene too through the entity. I’m still following some semi object oriented techniques at the same time as an entity component system approach like in other engines. While my adaption is to port/keep the ‘factory’ creation like behaviour of entity:add and then expand this slightly to entity creation too.

    My Building, BuildingPart and HomeBase components/example show this to some degree, although HomeBase is cut down to just its components/assets/child entities to show the in game building constructed from more than one asset and stuck together. The idea here is partly thinking about making something with an in game ‘builder’, where the player can construct their own designs, an example could be a game like Kerbal Space Programme.

  • The OrbitViewer and FirstPersonViewer components are more difficult in a way as these are more just in the library for convenience. They’re handy components so from this perspective yeah might not be unhelpful. However they are more in the realms of a ‘rig’ for a player, which can be more specific depending on the game. Which I can see more advantages with coming as more like a default/example/sample dependency. Similar possibly to how Unity releases base player rig assets on their asset store. Overall I think your approach with shipping examples come dependencies with Codea and Craft was a really good way to do this.

  • To answer your question about if there’s anything else missing in the Codea API this is not an easy question to answer in a way. Having done a fair bit of the kind of pondering needed to develop APis myself, I know how incredibly challenging it is because everything you add has to be justified almost as if it will be there forever, once you’ve put it in there and implemented something. Some things can tie your hands in order to not to break things. My approach here has been as I come across difficulties in making things or from finding I wish to approach things in a certain way that I might do from experience or working in another environment. Lua’s flexibility allows for a lot of possibilities, the hook function I use for example is something I have used a lot before in hacking/modding games with Lua based scripting somewhere.

  • I think certainly the documentation of Codea Legacy is strong point, in Modern at the moment I have found myself more discovering the API with code like for k,v in pairs(getmetatable(something)) do, alongside deeper digging through _G etc …(I like reverse engineering too among other things :sweat_smile:). The current API docs that are there aren’t unhelpful, and I can generally track down the info I need at the moment through various means. However it would be awesome to be able to reference and look up everything in Modern too from the docs, although I know this can take a great deal of time too. So really I’d say I would like to understand the Modern API more overall. Then from this it would possibly lead me to being able to find more little difficulties/opportunities to shorten my having to be typing from an on screen keyboard haha. (This is deliberate though so I don’t feel like I’m on a pc/laptop all the time :joy:)

I have also attached a couple of my older projects, CraftExtensions is ModernLibrary’s earlier iteration from Craft and EverLancer is a project which uses it based on John’s planet generator. The goal here was to try to make parts/expand it towards games like Freelancer or No Mans Sky, applying Codea’s voxel generation for ‘planetary landings’, although this isn’t realised at this point. Also incidentally this project can generate a crash or two from my adaption of Codea+’s threading code and my own knowledge of messing around with coroutine before from various other experiments / earlier projects. Alongside it can seem to take over one of Codeas threads on setup but then behaves differently pressing the ‘generate’ button. I have not really been able to get to the bottom of exactly why, although I suspect it’s something to do with main thread vs background thread vs how setup is called vs parameter callbacks and attempting to do fire and forget / “Tasks” / “Units of work” defined as arbitrary lambdas/ anonymous functions etc type threading code. Sort of like what you might see in runtimes like .Net / C# for example, which the threading in CraftExtensions is somewhat based on trying to replicate.

EverLancer.zip (2.1 MB)

CraftExtensions.zip (4.6 KB)

EverLancer won’t run for me in either legacy or modern.

Yes I got the dependency set up. It would be good if you got the require statement in the code so I don’t have to open the dependency editor as long as I have both projects.

In modern I get this error:

##readImage is deprecated. Use image.read instead

Error loading lua string:
Documents/Atmosphere/Shader.lua:1: unexpected symbol near '{'

And in legacy I get this error:

setup

invalid option '%2' to 'lua_pushfstring'
stack traceback:
	[C]: in method 'add'
	Documents/EverLancer:%20FreeSpace/Main.lua:89: in function 'setup
  • Found the problem
  • It’s the same problem I had with that UAP project you did: you put “_obj” at the end of the model names and that is an invalid way to refer to them for me. To get both of your projects to run I had to globally delete “_obj”
  • This baffles my mind a little: how could these projects even run for you with invalid asset references
  • Still: is this is supposed to be an alteration of the planet generator? I don’t see any planet, even when I tap the ‘generate’ button. A still spaceship that doesn’t respond to the Dpad and a sun.
  • Unrelated: is the UAP project supposed to be in color? For me it’s black and white, or rather, all gray.

Hmmm strange, yeah these run on my iPad which is iOS 18 and Codea beta. Here’s along the lines of what you should see for EverLancer:

The dpad doesn’t work as it was about the planet generator and voxels initially. The planet generator has been bumped to generate the planet asynchronously in the background, which for me seems to work from the setup function. The generate button is on the border of broken mostly. It’s possibly something about the way Codea is exporting the projects that’s going wrong, as they all only use default / built in assets from Codea.

The UAPGame which HomeBase is from should look like:

@UberGoober EverLancer is also meant to be run in the Legacy runtime because it’s based on Craft. I switched over to trying out more of Modern as the new docs for 4 came out in amongst this project.

This generation code for the planet and moon is what I was primarily working on:

function generate()
    Task.run(function()
        generators.seed = Seed
        Task.yield()
        if planet then
            planet:generate(planets.earth)
            Task.yield()
        end
        if moon then
            moon:generate(planets.moon)
            Task.yield()
        end
    end)
end

Where Task.run is intended to run in the background via a coroutine, so it appears to run asynchronously without interrupting rendering at the same time. Allowing planets to be built / loaded / generated in the background, different level of details etc, while the player still being able to ‘fly’ about without lagging from the fairly hefty work of generation. My Tasks code in CraftExtensions is definitely not quite right somewhere and I was debugging it last time I worked on it. I’ve just exported these projects to zips from my Codea projects list, the _obj on assets I think might be being added by the exporter somehow?

Here’s a video of how EverLancer is meant to look starting up as well (compressed heavily to a gif :sweat_smile:)

image


This is how those projects look to me. iPhone 16e, iOS 26.2.1, latest Codea.

Ohhh interesting, somethings definitely gone weird in the exporting there I’d guess, although the UAP game scene looks quite cool I think there, like it’s Noir and moody. I wonder if it’s something to do with the materials / shaders they are using. Although they’re still all built ins / basic materials and shaders, only assets from standard asset packs that come with Codea and/or can be downloaded from the assets editor.

Edit: For @sim I’ve exported these from an iPad Pro with iOS 18.6.2 , Codea beta 3.18 builds 617 and 619.

1 Like
  • This baffles my mind a little: how could these projects even run for you with invalid asset references

This is one of the tricky parts of the asset system. If there are two files in the same directory with different extensions, the asset system makes you write the extension with an underscore (_png / _obj)

It seems like the textures may be missing — Codea exported the .obj with @M4nw3l’s project, but failed to export the texture with the same name. That meant when you referenced the asset there was only one file with the given extension, so you didn’t need the _ext syntax

That probably explains why the objects look untextured when you run the project too. It’s a bug that Codea is not figuring out there is an obj file with associated texture and exporting both…

Just a quick response to the entity update issue, you don’t have to assign anything to the entity’s update slot — your component update methods get called automatically, e.g:

Health = class()
function Health:init(e, value)
    self.entity = e
    self.value = value or 100
end

function Health:update(dt)
    print("health update")
end

Health2 = class()
function Health2:init(e, value)
    self.entity = e
    self.value = value or 100
end

function Health2:update(dt)
    print("health2 update")
end


function setup()
    scene.main = scene.default3d()
    
    player = scene.main:entity()
    player:add(Health)
    player:add(Health2)
end

As far as I can tell, he’s using standard assets and standard textures so they are all there. The situation is a little weirder than I think you’re describing.

When I type in the asset name I can see in the auto complete that there are different kinds of files with that name and the one with the _ and OBJ is there. But if I tap the _obj from the autocomplete bar it autocompletes without the extension and indeed it gives an error if I use the extension as “_obj” even though that’s what it says in the autocomplete bar. So yes I can have the editor showing me a red error bar at an asset typed in with an “obj” suffix at the exact same time as the autocomplete is showing me that asset with an “_obj” suffix.

Yeah that is weird, I’ll give the projects a try and see if I can fix the bug

Oh :man_facepalming: I didn’t think I could do this, not sure how I came to that conclusion though. I’m possibly working from earlier knowledge or I misunderstood the documentation perhaps :sweat_smile: I feel I tried it at some point and it didn’t work but I’m questioning that now too haha.

1 Like