Jump to content

Rick

Members
  • Posts

    7,936
  • Joined

  • Last visited

Everything posted by Rick

  1. Rick

    Fun with Stateless API

    For 2, in the C++ realm isn't it kind of "ugly" to have straggler C functions?
  2. Rick

    Fun with Stateless API

    Just to play devils advocate, instead of having global functions like CreateBox() CreateCamera() and passing in the world, what about functions tied to the world itself like world->CreateCamera(), world->CreateBox()?
  3. Why are you thinking you need to do C++ to do those 2 things? You should be able to do that in lua itself. Nevermind I guess achievement code is only in C++
  4. "My goal is place some boxes at the position of some pre-placed pivots" You stated a goal but I wonder if this is the entire goal really? Why do you want to great a global variable to store these in? To reach your goal just make a Box script and attach it to the pivots and inside it's Start() it makes a box at self.entity position. That would reach your goal.
  5. Attach the entire script. It'll be easier to see what's wrong.
  6. I agree with tip. I always thought escape room would be good. From a programming perspective it's easy (just tedious setting things up).However it requires a fair amount of art.
  7. User driven content is the answer and it's what more and more games are moving to. Let your users create the content. Just provide them with terrain and veg. The ability for users to build in game has really taken off and it's only getting stronger. I always thought it was odd how physics is always taking up cycles on objects that can't possibly be hit by anything just by existing. Seems you'd only want a small moving section around something that is moving to check things directly around it. If you gridded out the terrain, a player walking around would only need to check collisions with a 3x3 grid around it with it in the center grid at all times. Dynamically load the 3 grids and unload the other 3 grids as the player moves around. I would think the same ideas of a 3x3 gird could be done for actual terrain chunks. Loading/unloading as they player moves around. There is no need for things to happen in unloaded terrain chunks in real-time. When one gets loaded it just may needs to know about some state variables so things inside of it can adjust accordingly. Push a button in 1 grid that should cause x to happen in an unloaded grid? That state variable is set (and stays with the player) and when grid x is loaded whatever entity is on it checks that state variable and puts itself in whatever state it needs to show the effect. So terrain state variables become special and whenever a terrain chunk is loaded all entities on it have a method called which has all state variables available to it so they can do what they need to do based on the value of the state variable.
  8. That's why I'm confused as to why you said generated script. No lua script needs to be generated for visual coding really. That's all just configuration of what hooks to what. Code generation adds another layer into the mix.
  9. I'm not following why you want to programmatically generate a script to do this specific game requirement. With the idea of connecting functions to 'events' that's just configuration information between generic/reusable user created scripts that is ran when the starting 'event' is triggered. If you're thinking about a per-entity flowgraph, all you need is the information of the entity, attached scripts, and the connecting information. After all that is loaded, read a text file that stores the config of what hooks to what and since lua is so flexible that string information in the text file should be able to be setup since everything in lua can be accessed with it's string name. So let's imagine entity1 has a health script, sound script, postprocessing script attached to it. The per entity flowgraph could just be a text file config file I would think. When saving you're saving the 'event' variable name and what script it belongs to and the called function and what script that belongs to. All that information can be stored as a string and read back as a string and then you can get all the actual lua objects from their string names. So not following the idea of generating a script to do this functionality.
  10. Because that script has properties like the current noise does. So you need a way to capture those and combine it with the functionality. The noise script can emit events as well like onFinishedPlaying, onHalfWayThrough whatever. A script is just a class to hold all that information, then you make instances of it by attaching it to entities. It's not engine commands. We have our own scripts that do a lot of gameplay specific events and functions that we would want to hook up as well. OnScorePoint, OnFoundTreasure, etc etc. Stuff that you can't make common commands for but are useful for our games scripts. Now, once you've attached a bunch of scripts to an entity then yes you need a place to connect everything between those scripts and a per entity flowgraph is a good idea on how to do that actually. One could do another script that is specific to that entity and do it all by typing the code if they wanted to do that but a flowgraph for each entity would be a really cool way to do that. If you could save the entity as a prefab and it has all that information (scripts, flowgraph, model, etc) that would be cool too!
  11. You would never have/want health information inside a sound script. That script has stopped being generic enough for reuse at that point and it's now very "leaky". Other responsibility is leaking into that script. If you want 3 instances of that script all playing sound on different events you either bloat the 1 script to handle all use cases (which no reuseable script will know all possible use cases) or you create 3 different scripts. Both are bad options. There are all sorts of different events that you want to play a sound and trying to build in common functions or sharing information directly inside another script is just a mess waiting to happen and again kills reuse. Being able to link the event to a function in the editor is the way to go. Those other ways you're showing can't really be done via the editor unless you start doing code generation inside the scripts themselves which leads to a whole other mess. I think your StartThePain()/StopThePain() is the right idea as long as the idea is that I can connect (in another script or via editor) my sound scripts Play() and Stop() function to those functions (events). That way the 2 scripts are unaware of each other on the inside of themselves. The sound script has no knowledge internally of the health script and vice versa. A much cleaner and reusable situation.
  12. Just to put a more concrete example with this. Let's say the goal is to have a heartbeat sound play when health is < 25% and to also add pulsing red post process effect around the edges of the screen. A reusable way to do something like this so that others can modify it to their needs would be to: Create a Noise.lua script. This would have a property of what sound to play and a function Play() (some other properties as well). Create a HurtPostProcessing.lua script. It will do the pulsating red boarder when you call it's TurnOn() function and you can turn it off by calling it's TurnOff(). It can have properties as well to control certain aspects like how fast the pulsating is. Create a Health.lua script that has a Hurt() function and an onHealthBelowTwentyFivePercent event. It also has properties like max health and such. All 3 of these scripts are separate and were created by 3 different people and put in the shop. I come along and add all 3 scripts to my player entity. I set the noise.lua wav file property to some heavy breathing sound and I connect it's Play() function to the Health scripts onHealthBelowTwentyFivePercent. I do the same for the HurtPostProcessing script. I now have 3 scripts that knew nothing about each other working together help me reach my goal effect. This is the benefit of "events" and event programming. If we used the polling and shared variable way of doing things this wouldn't be ideal. My reusable Noise script should never know or care about a Health script. Inside it's Update() method it shouldn't be checking if self.health is < 25% because self.health has nothing to do with Noises. It couldn't possible know all the use cases for playing noises. The main benefit of attaching multiple scripts is the reusability and cleanliness of code. Put a nice user interface on top of hooking all this up and you have a very friendly system to make complex functionality without much coding by the user. This gives the coders a framework to create reusable scripts, and down the line a revenue stream by selling those scripts.
  13. You do that for the reason my blog post talks about. When making reusable scripts for others to use, you create events for things that happen inside that script. Users connect whatever they want to that scripts events (I wouldn't know what they want to do at the time of writing my reusable script) and when I fire them inside my reusable script their custom code is called. If a health script wanted to tell the outside world when the health dropped below 50% then inside it's Hurt() function when health is < 50% is would raise or call an event. Since these are functions in your example it can just call the function onHealthBelowFiftyPercent() I guess but internally that function would be empty and only exists for others to connect to it so they can call their functions. So in that regard it acts more like an event since it's sole purpose is for others to just connect to it and it's body is empty.
  14. So :Connect() is an entity function. Can we have our own event? In the example above "Collision" can be thought of as an event. When it's called/raised you call the connected functions. Can we have our own lua defined event that we can call and it'll call all the connected functions? -- treating this more as an event that I can call and it'll in turn raise all the connected functions function Script:MyScriptsEvent() end self:Connect("MyScriptsEvent", target, "Foo") So when inside self I "raise" or call MyScriptsEvent function it'll call Foo() from target? Why do you do the AddArg()? Is that for the C++ side of things? Lua can do variable number of arguments so you could capture all arguments after the 3rd one and pack them off in a table and then unpack them when you make the call and they'll fall in the right order.
  15. Update is the "event". In all the stuff you're saying you are linking functions to "events". Then when that "event" is fired/called it's actually calling the function we assigned to it. Being able to assign multiple functions would be nice. In your example your 2nd param is basically a script in itself as it's getting executed, but before you were assigning things to straight functions to be called and so I was wondering if you could assign to multiple functions and when Update is called it'll loop through and make the call to all functions attached. If you changed the name of Update to onUpdate then it becomes clearer that it's basically an event that the engine is raising every frame. There are other events like onCollision. Same idea. You're simply allowing users to have their functions called when these events are raised (when those engine functions are called). That's the premise of my blog post. Raising and event is just like calling a function, except the event can have N number of functions that the user assigned to be called when the event was raised. It allows one to make events when they don't know what a user wants to do with said event. It gives them the flexibility to do whatever they want when an event is raised. It's easier to think about a GUI button. When it's pressed the UI library "should" raise and event and the user would have attached a function (or more than 1) to that event that gets called. This is opposed to the polling that you use in your GUI system. So you either poll or use events.
  16. Do you have it so we can connect multiple functions to an "event"?
  17. I just want to note that the high level concept you are doing in that example is basically connecting event(s) to functions. A great way to program :). I have multiple blogs on that from Roland and me back a year or so ago. It handles arguments and other things like criteria to call the function or not (returns a boolean to call or not. comes in handy).
  18. I'm well aware of the benefits of adding multiple scripts to entities. Some have been asking for it and simulating it in LE for a long time :). That's not the question. The question really is the best way to do it. Giving the ability while not pigeonholing you into a style is generally what I think is best/safest for the core part of the engine. Then you can add something like this on top of that. The value attaching thing is a great idea for sure!
  19. I hope my post didn't come off as it was a bad idea. I said there are pluses to doing it this way and just needs to be promoted and supported by Josh (he can't just tell people to name their functions this way he needs to built them into entity scripts just like UpdateWorld() and others are). I mentioned that this is completely different from what Josh has wanted in the past. Josh was always more of a library vs framework guy. LE was always a library. it gave you generic ways to create games and/or multimedia apps. What he's saying now is way more specific and funnels people towards a common way of creating these apps/games. A library is more like a bunch of baking tools and ingredients. You have everything you need to bake something but it's 100% up to you on how to use those tools and ingredients to do it. A framework is more like following directions on how to bake something. It gives detailed guidelines on how to do it, but still has a little room for you to add your own special mix to set it apart. Josh was always a library guy with LE and with this blog we can see the shift which is surprising to us who have been around awhile.
  20. I'm very shocked I'm hearing you say this. This is a complete 180 from your normal style. There are pluses to doing this but it would have to be built in and promoted by you, the creator, to work. You're basically making more game specific UpdateWorld() type script functions. I never thought I'd see the day.
  21. It currently does cause issues with script variables being overwritten. You can't have independent script variables with the same name as they'll just merge into 1 variable that all scripts share. So people have to be careful with their script variable names especially if using a script someone else wrote as it could cause unforeseen and hard to track issues. What you just said is the main reason to just create a table on the entity for each script attached to store the instance of that script and then reference any function or variable by using that scripts instance because it's the most flexible way that satisfies the most use cases, which is not what this system is doing. Surprisingly, since josh usually hates forcing convention, this system forces convention even if you don't want it. ie. if 2 scripts have the same function name calling one anywhere will automatically call both every time no matter what. To get around that is a naming convention that you hope other scripts from other programmers don't have a collision with your function names. I'm assuming a very specific use case for the NASA stuff Josh is working on caused this.
  22. In practice I don't think you will get this smooth interaction. If you look at the examples in this blog you'll see that 3 different people named a function with similar functionality differently. ReduceHealth()/TakeDamage()/HurtEnemy(). The chances that different programmers all name their functions the same in order to add different functionality is pretty slim. There will just be little cohesion to make this act as the bridge for adding different scripts from different programmers who weren't working together. While this helped your situation, which unless you had 25+ different scripts attached I don't see why calling the specific scripts reset is that huge of a deal, this is a pretty specialized situation for the NASA stuff you're working on. I think you'd be better off using an event system to get what you want so things are more explicit. Define an event in one master script on the entity and in it's Start() get references to all the scripts attached and add their Reset() methods to the event. Then raise the event and it'll chain call all those methods. While for your specific case it may seem like more work, for a more generic case, like our games, it gives more flexibility in chaining functions with different names by raising 1 event, it gives explicit intent which makes debugging easier, and it makes it so the community isn't trying to come up with consistent naming conventions which will never happen.
×
×
  • Create New...