Jump to content

Lua in Leadwerks 5 is Solved

Josh

1,275 views

When considering the script system in Leadwerks 5, I looked at alternatives including Squirrel, which is used by Valve in many games, but these gave me a deeper appreciation for the simplicity of Lua. There are only a handful of rules you need to learn to use the language, it’s fun to use, yet somehow it does everything you could ever need.

These were three big issues I had to solve. First, the Leadwerks 5 API makes extensive use of smart pointers, which our binding library tolua++ does not support. Second, I wanted better auto completion and a better user experience in the IDE in general. Third, if an external IDE is going to be used it needs to be able to interface with the Leadwerks debugging system.

To support smart pointers, I found a new library called sol2 that does everything we need. @Rick and I discussed the idea at great length and I am happy to say we’ve come up with a design that is simple to use and quite a bit easier than Leadwerks 4.x even. The binding code is nowhere near done but at this point I can see that everything will work.

@AggrorJorn suggested using Visual Studio Code as our official script IDE in Leadwerks 5, and after investigating I think it’s a great idea. The auto completion is quite good and the IDE feels more natural then anything I could come up with using a custom text editor made with Scintilla. In fact eliminating the built-in script editor in Leadwerks 5 relieves me of a lot of uncertainty and potential issues when this is written.

Finally, VS Code has support for custom debuggers. I wrote an example command line debugger for Leadwerks and I will use this to show another programmer how to interface with Leadwerks. (I don’t plan on writing the debugger myself.)

With your feedback and ideas are shaping up to make Leadwerks 5 a huge leap forward over our previous designs. The improved simplicity of the new script system is a big cognitive relief. Having fewer things to worry about makes life better in a subtle but definite way.

There’s something else that consumes a lot of mental attention. Social media and the internet have grown and changed over the years and become more efficient at consuming our attention. (Many features of this site are designed the same way.)

The scary thing is that normal non-technical people seem to be more vulnerable than nerds. We’ll fire up the Witcher and play for an hour, but regular people are checking their phones 24/7 for feedback and validation. It’s much much worse than any accusation we got as kids of being “Nintendo zombies” because we spent an afternoon playing games instead of staring passively at broadcast TV. People who play games generally don’t care about posting photographs of their food or collecting followers.

Somewhere along the line the internet went from being a weird thing on your computer to the collective consciousness of humanity. Reality is online and the physical world around us is just a mirage, one possible instance of a million possible individual experiences. Maybe it was around the time they started using AI to optimize clickbait that things got out of hand.

Although my career and the way I live my life are only possible through the internet, I am old enough to remember life before the web, and in many ways it was better. Things were more focused. Even the early web before clickbait ads and online echo chambers was pretty nice. You could go to a record store and hang out talking to people about new music. Printed paper magazines were a thing.

I already removed the link to our Google+ page in the website footer and no one noticed. I think about deleting our Facebook and twitter accounts, or at least not linking to them on our site. Why must every website pay homage to these monopolies? What are they doing for me, besides a limited flow of hits that pale in comparison to what my own email list brings in? I have written about this before but now that it is fashionable to criticize social media I might act on it. I don’t know, we’ll see.

Please like, share, and retweet.

  • Like 8


11 Comments


Recommended Comments

I woke up with a sore throat so I am going to stay home today and hopefully prevent this from becoming a full-blown cold.

What I’m saying about social media is also a function of where we’re at right now. Everyone here has enough experience with Leadwerks 4 that we can discuss how to make the next version have the absolute best user experience ever. Plus I made quite a lot of money on Steam and I can afford to spend some on artwork and other things for version 5 (which will not be called Leadwerks anymore). I want to focus on you guys and give you something really amazing. and not spend any time yelling into the wind on Facebook.

I’ve also been thinking a lot about the need to establish something independent from Steam, which is why I started the $5 subscription service on our site.

The only social network I care about is you guys, right here.

Share this comment


Link to comment

I had some worries about the lua bindings with the new pointer system myself, but glad a new library does the job. I might look into Sol for my personal projects.

The VSCode implementation seems really neat. My only criticism is that it ruins the "All in one package" model you have created for the current version if you decide to not do your own script editor. Regardless, VS Code is really nice, I use it all the time. I just wish it opened as fast as notepad or notepad++. 

I haven't had the time to really play with Leadwerks at all as of late. But I'm always looking forward to what's new in the engine.

Oh yeah, as a kid I got called anti social because I liked to be on the computer a lot while being in the comfort of my home. I went to roller skating at a place last weekend and noticed that mostly everyone there was on their phones most of the time. I on the other hand left my phone in the car so it wouldn't get broken.

The idea that people paid money for admission for a social event, to be on their phone is disgusting.

Anyway, glad everything is working out.

Share this comment


Link to comment
7 hours ago, Josh said:

version 5 (which will not be called Leadwerks anymore)

Really?  I assume you'll want to wait before announcing it but do you already have a name in mind?

Share this comment


Link to comment

surprising you would want to walk away from your brand recognition that you have built up for over a decade by abandoning the Leadwerks name... :huh:

Share this comment


Link to comment

Branding is a difficult thing to achieve.  Companies re-brand themselves many times over the course of company solvency.  The only input I can give on this subject is when there is a core shift in the cultural ideas of said company.  This isn't to Josh, whom is more business oriented actually running one while I still work for one, this is to anybody reading in general.  Successful companies know when they evolve so does its culture and its ideas and that is where re-branding comes in.

Regarding pointers and Lua.  Lua is so highly underrated for a scripting language.  Of all scripting languages it's the closest to C in simplicity.  Combine that with C++, which as an aside by the time C++23 comes out raw pointers are *OUT*.  C++ was always meant to lean towards references but that backward compatibility with C made it what it was; although now you don't hear about pedantic conversations of C/C++ being interchanged.  They are two different languages now and continue to diverge.  

Hate to sound like I am ranting or rambling but I will say this:  Leadwerks is the only proprietary piece of software I am not only willing to shell out my own money for, I actually do with every opportunity...pitching ideas in unrelated circles to Steam or the wanna be game programmer and that whole "speaking with your money" part in the States where I reside this means something.  I have seen many pro's and con's with Josh, Leadwerks, etc. on social media that it made me a late comer to this product and community.  Some things I have not liked but in the end the actual product speaks for itself which is what matters most; even if I disagreed with Josh.

I believe, and I may be wrong, but it is my belief Josh wants a successful business while still having a loyal customer base not because of his company or his product but both and that is something I have subscribed myself to supporting as a customer.

Apologies if this sounds like some pointless rant but I am juggling a family, a successful Principal Engineer/Manager, and ready to work for myself instead of someone else.  I have to finish cooking dinner, get the kids to bed, and then get back to my side project with LeadWerks.  After 25+ years doing this I see a way to break the cycle without being beholden to the hamster wheel.

 

Share this comment


Link to comment

I would not consider a name change unless the new one was very good at making the brand spread faster and telling people what the product does. The name will be revealed when the Kickstarter campaign launches, which will be near the end of development. The point of the Kickstarter campaign is to launch the larger marketing campaign. GDC will come next, with a booth and maybe a lecture.

My first speaking gig at GDC was a nightmare. I had spent threee years writing my first C++ program. Unity had just announced a free mobile version the day before. There was a bad echo in the sound system so all my words were bouncing back to my after a short delay, making it extremely difficult to speak. And there were 600 people in the audience, from Apple, EA, Microsoft, etc., and everyone hated me, thought I was crazy, or didn’t know who I was. But I did it and I am proud of myself for that.

That happened before Leadwerks had any success. It was just an idea and I was an unproven nobody, with no track record of success. This was before Steam and before our first Kickstarter campaign. When Leadwerks 3 was launched I did not have all the contacts in the game industry that I have now. I did not know a dozen people at Valve. I was also broke. There’s a lot more I can do with the launch of 5 but at the core of that has to be a great, not good product.

The feedback I get from you guys is going to make this great, so I am definitely listening.

  • Like 2

Share this comment


Link to comment

It was really interesting to follow along with the lua/C++ discussion with Josh and Rick. I feel like I learned a lot by just reading the comments. 

My money is on Gearhead Engine (a person who pursues mechanical or technological interests (as in automobiles or computers). Fits with the gear logo too. But seriously surprised about the name change.

Either way, I like how you are open to the feedback of the community.

Share this comment


Link to comment
4 hours ago, Josh said:

I would not consider a name change unless the new one was very good at making the brand spread faster and telling people what the product does. The name will be revealed when the Kickstarter campaign launches, which will be near the end of development. The point of the Kickstarter campaign is to launch the larger marketing campaign. GDC will come next, with a booth and maybe a lecture.

My first speaking gig at GDC was a nightmare. I had spent threee years writing my first C++ program. Unity had just announced a free mobile version the day before. There was a bad echo in the sound system so all my words were bouncing back to my after a short delay, making it extremely difficult to speak. And there were 600 people in the audience, from Apple, EA, Microsoft, etc., and everyone hated me, thought I was crazy, or didn’t know who I was. But I did it and I am proud of myself for that.

That happened before Leadwerks had any success. It was just an idea and I was an unproven nobody, with no track record of success. This was before Steam and before our first Kickstarter campaign. When Leadwerks 3 was launched I did not have all the contacts in the game industry that I have now. I did not know a dozen people at Valve. I was also broke. There’s a lot more I can do with the launch of 5 but at the core of that has to be a great, not good product.

The feedback I get from you guys is going to make this great, so I am definitely listening.

Wow I didn’t know those details. Much respect as that took massive courage to do!

Share this comment


Link to comment

@Rick Yep, I was pretty shaky but when I showed them a deferred renderer running on an iPad 2 they **** their pants.

Anyways, my point is that I have enough contacts in the industry that if the product is great it will get a fair chance and won't be ignored. We just need to make sure it's great.

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Blog Entries

    • By reepblue in reepblue's Blog 2
      Loading sounds in Leadwerks has always been straight forward. A sound file is loaded from the disk, and with the Source class emits the sound in 3D space. The sound entity also has a play function, but it's only really good for UI sounds. There is also Entity::EmitSound() which will play the sound at the entity's location. (You can also throw in a Source, but it'll auto release the object when it's done.)
      While this is OK for small games, larger games in which sounds may change might mean you have to open your class, and adjust the sounds accordingly. What if you use the sound in multiple places and you're happy with the volume and pitch settings from an earlier implementation? You could just redefine the source in a different actor, but why should you?
      A solution I came up with comes from SoundScripts from the Source Engine. With that engine, you had to define each sound as a SoundScript entry. This allowed you to define a sound once, and it allowed for other sound settings such as multiple sounds per entry. I thought this over, and with JSON, we can easily create a similar system for Leadwerks 4 and the new engine.
      I first started with a dummy script so I can figure out how I wanted the end result to be.
      { "soundData": { "Error": { "file": "Sound/error.wav", "volume": 1.0, "pitch": 1.0, "range": 0.25 }, "RandomSound": { "files": { "file1": "Sound/Test/tone1.wav", "file2": "Sound/Test/tone2.wav", "file3": "Sound/Test/tone3.wav" }, "volume": 1.0, "pitch": 1.0, "range": 0.25 } } } In this script, we have two sound entries. We have an error sound (Which is suppose to be the fall back sound for an invalid sound entry) and we have a sound entry that holds multiple files. We want a simple, straight forward. entry like "Error" to work, while also supporting something "RandomSound" which can be used for something like footstep sounds.
      The script is streamed and stored into multiple structs in a std::map at the application start. We use the key for the name, and the value is the struct.
      typedef struct { std::string files[128]; char filecount; float volume; float pitch; float range; bool loopmode; } sounddata_t; std::map<std::string, sounddata_t> scriptedsounds; Also notice that we don't store any pointers, just information. To do the next bit, I decided to derive off of the engine's Source class and call it "Speaker". The Speaker class allows us to load sounds via the script entry, and support multiple sounds.
      You create one like this, and you have all the functionalities with the Source as before, but a few differences.
      // Speaker: auto speaker = CreateSpeaker("RandomSound"); When you use Play() with the speaker class and if the sound entry has a "files" table array, it'll pick a sound at random. You can also use PlayIndex() to play the sound entry in the array. I also added a SetSourceEntity() function which will create a pivot, parent to the target entity. From there, the Play function will always play from the pivot's position. This is a good alternative to Entity::EmitSound(), as you don't need to Copy/Instance the Source before calling the function as that function releases the Source as mentioned earlier. Just play the speaker, and you'll be fine! You can also change the sound entry at anytime by calling SetSoundEntry(const std::string pSoundEntryName); The creation of the Speaker class will start the JSON phrasing. If it has already been done, it will not do it again.
      Having sounds being loaded and stored like this opens up a lot of possibles. One thing I plan on implementing is a volume modifier which will adjust the volume based on the games volume setting.Right now, it uses the defined volume setting. It's also a part of another system I have in the works.
    • By Josh in Josh's Dev Blog 7
      An update for Leadwerks 5 is now available.
      The Vulkan data transfer system has been revised and is now simpler but uses more memory. Data is likely to be quadruple-buffered, but it's a fairly small amount of data and this isn't a big concern. 
      I fixed a bad bug where multiple threads were accessing a global variable in the Mat4::GetQuaternion function. This fixes the object flashing glitch that was visible in previous builds.
      The engine is updated to the latest version of Newton Dynamics and kinematic joints work correctly now. The upvector joint is removed and a plane joint has been added for 2D physics, but I don't think it will work yet. Object picking up is implemented in the player controller script.
      I switched out the default scene with a new one using some of @TWahl 's materials.
      Added an FPSWeapon script that loads a gun and makes it sway.
      Entity::AddScript() can now be called in the Start() function of another script with no problems.
      Fullscreen windows are now working.
      The window / display system is changed a bit. New display commands:
      std::vector<shared_ptr<Display> > ListDisplays() std::vector<iVec2> Display::GraphicsModes() You must pass a display object in the window creation command now. Here's how I do it in Lua:
      --Get the primary display local displaylist = ListDisplays() local display = displaylist[1]; --Get the display's highest resolution graphics mode gfxmodes = display:GraphicsModes() gfx = gfxmodes[#gfxmodes] --Create a window local fullscreenmode = false local window if fullscreenmode then window = CreateWindow(display, "My Game", 0, 0, gfx.x, gfx.y, WINDOW_FULLSCREEN) else window = CreateWindow(display, "My Game", 0, 0, 1280 * display.scale.x, 720 * display.scale.y, WINDOW_CENTER + WINDOW_TITLEBAR) end And in C++:
      const bool fullscreenmode = false; //Get the primary display auto displays = ListDisplays(); auto display = displays[0]; //Create a window shared_ptr<Window> window; if (fullscreenmode) { auto gfxmodes = display->GraphicsModes(); auto gfx = gfxmodes[gfxmodes.size() - 1]; window = CreateWindow(display, L"My Game", 0, 0, gfx.x, gfx.y, WINDOW_FULLSCREEN); } else { Vec2 displayscale = display->GetScale(); window = CreateWindow(display, L"My Game", 0, 0, 1280 * displayscale.x, 720 * displayscale.y, WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CENTER); } The speed of the point light shadow updating is unbelievably fast. Point light shadows in Leadwerks 4 are very expensive to update because they require six different render passes for each of the six cubemap faces, but in Leadwerks 5 beta with Vulkan they are basically free. I'm sure it will slow down if I add enough points lights and have them all constantly updating, but I don't see any difference at all in the framerate right now when shadows are active. If you are having any trouble with their appearance you can set the global variable MULTIPASS_CUBEMAP to false in C++ at the very beginning of your program.

      This script can be used to display performance statistics. At this time it only shows the framerate but I can expand on this in the future.
      function Script:Start() self.statsEnabled = true self.textcache = {} self.font = LoadFont("Fonts/arial.ttf") self.fontsize = 16 self.textalignment = TEXT_LEFT self.world:EnableStats(self.statsEnabled) self:BindKey(KEY_F11, self.ToggleStats) end function Script:ToggleStats() self.statsEnabled = not self.statsEnabled self.world:EnableStats(self.statsEnabled) end function Script:Update() --Return if disabled or font missing if self.statsEnabled == false or self.font == nil then return end --Hide previously used sprite if self.displayfps ~= nil then self.displayfps:Hide() end --Retrieve the framerate and convert to string --Convert to integer to limit the amount of different string values local fps = tostring(math.ceil(self.world.renderstats.framerate - 0.5)).." FPS" --Check for cached version and create it if it doesn't exist if self.textcache[fps] == nil then self.textcache[fps] = CreateText(self.world, self.font, fps, self.fontsize, self.textalignment, 1) self.textcache[fps]:SetPosition(4,4) self.textcache[fps]:SetColor(0,1,0,0.75) end --Set current sprite and show self.displayfps = self.textcache[fps] self.displayfps:Show() end It may seem like a lot of code just to draw a bit of text onscreen, but the benefit is extreme performance. Instead of drawing one character at a time like the Leadwerks renderer does, this creates persistent text objects and reuses them when needed. That cuts the performance cost of displaying text down to basically zero, making it great for complex GUIs and game interfaces.
    • By Josh in Josh's Dev Blog 10
      Leadwerks 3 / 4 was aimed at beginners who were completely new to game development. Since we were the first game engine on Steam, this made a lot of sense at the time, and the decision resulted in a successful outcome. However, in the next engine we are taking a different approach. (This is a direct result of Steam Direct.)
      Enterprise is a new market I am pursuing, and we have a lot of interest from aerospace and defense VR developers. The fact that I am American also helps here. There are special features these customers need that aren't necessarily needed by game developers, but I think you will like some of the possibilities this unlocks.
      For game developers, I have been moving back to an approach more like Leadwerks 2 where we focus on extreme high-end PC game technology, so that comes down to graphical quality and performance. I think most people here will be pretty happy with that direction. We're going to sell on Steam, Humble Store, Amazon, Microsoft store, Mac App Store, and direct from our website. Less importance will be attached to Steam, as they are just one more storefront we sell through. We're not going to use Steam Workshop.
      For pricing of the non-enterprise version, I am thinking $59.99 / $99.99 standard / pro with a monthly subscription option at $4.99 / $9.99. This is actually cheaper than the pricing of Leadwerks, but I think keeping things under $100 is better for the consumer market.
      The paid beta subscription is going to end before the end of the year, and it will be replaced with an open beta. The reason I did this was because I wanted a very small group of people testing the early betas (really more of an alpha), and I wanted to test out our subscriptions system. During that time we found and fixed a couple of small issues, so this was a good idea. A big thanks to all who participated and bought me many espressos.  ☕
      Finally, we are not going to call Leadwerks 5 "Turbo Game Engine". The name just isn't sticking for me, and I don't think we can get rid of the :"retro" connotations it has. My new technology has developed quite a lot since then, and speed is not the only advantage it brings to the table. I do have a new name in mind, but I am not ready to announce it yet. Until then, I will refer to the new engine as "Leadwerks 5 beta".
×
×
  • Create New...