Jump to content

NQ-Deckard

Staff
  • Posts

    239
  • Joined

  • Last visited

Reputation Activity

  1. Like
    NQ-Deckard got a reaction from SpacemanSpiff in DEVBLOG: REVISITING CONSTRUCT SLOT CHANGES   
    Following the discussion around yesterday’s devblog, the community asked us to look over our figures to see what we can reliably sustain in terms of construct limits. In this communication we want to take the opportunity to outline what we have decided to change from the previous devblog as well as to explain some decisions such as the mechanics of construct abandonment and our reasons for arriving at our previous figures. These proposed changes are still being developed by our design team and we welcome your continued feedback on this major update.
     
    Organization Constructs Slots versus Personal Construct Slots
     
    There appeared to be some confusion in yesterday’s devblog between organization and personal construct slots. Personal construct slots are always independent of organization construct slots. 
     
    Before outlining the details of the construct slots, it’s important to note that our position on excess construct abandoning mechanics. For the avoidance of doubt, when this change is implemented in the Panacea release. No construct will be subject to abandonment through the following mechanics for at least the first month after release.
     
    This is to ensure as smooth a release as possible, and to allow our players who want to specialize in the architectural gameplay loop or the collecting of wonderful constructs, some time to accrue talent points and to adapt.
     
    Personal construct slots:
     
    Can only be used for constructs in the player’s ownership. Can not be assigned to organizations. Are non-transferable to other players. Are gained through talents independently of organization construct slots.  
    Organization construct slots:
     
    Can be assigned to any organization, regardless of membership. Can not be assigned to players. Once assigned to an organization, can not be repealed from that organization for 30 days. Once repealed, the organization will have until the next bi-weekly construct check to ensure that it meets its construct slot requirements. If that bi-weekly construct check determines that the organization has more constructs than it has slots, the organization will receive a warning and be required to ensure the constructs count is brought down to its capacity. If the next bi-weekly construct check following that warning determines that the organization still has more constructs than it has slots, random constructs from that organization will be abandoned until the organization is back in compliance with its slot capacity. All this means that even if you go over the available slot count, you have at the very minimum 14 days to correct it.  
    We are keeping the random nature of selection for construct abandonment. This is because as game developers we know that if there exists a way for a game system to be broken, our players will find it. In this particular instance, given the gravity of the impact, we feel that it’s important to protect the game and our community from abuse, and the randomization is an effort to do that.
     
    We hope this clears up some of the lingering questions that were remaining yesterday.
     
    Player allocated slot amounts, why so low?
     
    Following internal research, we determined that currently per active player there are approximately 25 constructs in the game at the present time.
     
    Therefore we believed that having a total of 42 slots per player would have been enough to provide an overhead for the community to be able to distribute the available slots amongst each other and support each other's projects.
     
    We do value our players and recognise that some of you own considerably more constructs than that average, and though we want to encourage collaboration and community, we don’t want to constrain those players that prefer to go it alone.
     
    And, we’ve heard you. 
     
    We are looking into an alternative approach that we feel will meet the majority of the community needs while also meeting our requirements for the long term sustainability and balancing of Dual Universe.
     
    Talent Changes
     
    We are going to increase the core allowances. In yesterday's devblog we proposed a figure of 42 total constructs. We are going to increase that through the introduction of talent changes that will require considerable time investment but keep the door open to players that wish to own many constructs.
     
    The new talents are separated into three tiers, increasing in expense significantly per tier.
     
    The new figures are (subject to change)

    For personal construct slots:
     
    The base personal construct slots will be increased from 2 to 10 slots without any talents. The first tier personal construct talent will grant 3 slots per level (up from 2), for a total of 15. The second tier personal construct talent will grant 5 slots per level (up from 1), for a total of 25. The new third tier personal construct talent will grant 10 slots per level, for a total of 50.  
    This will allow for a maximum personal construct limit of 100, once all the talents are fully acquired.
     
    For organization construct slots:
     
    The base organization construct slots will grant 10 slots without any talents. The new first tier organization construct talent will grant 3 slots per level, for a total of 15. The new second tier organization construct talent will grant 5 slots per level, for a total of 25. The new third tier organization construct talent will grant 10 slots per level, for a total of 50.  
    This will allow for a maximum organization construct limit of 100, once all the talents are fully acquired.
     
    The combination of the two will allow a determined player to reach the maximum number of construct slots that we can reasonably maintain. This will take substantial time investment in order to be a specialization within the game. 
     
    We will still be refunding the following Legate based talents:
     
    Organization Construct Management Organization Construct Management Specialization Advanced Organization Construct Management Specialization  
    These talents will be buffed to collectively increase the maximum ceiling for the organization's construct limit to 1625.
     
    If you have already trained Advanced Organization Construct Management Specialization to level 5, by reinvesting the refunded talent points, we estimate that you will be able to reach at least a construct slot capacity total of 80. Further, given the grace period of at least 1 month following the Panacea release, we hope that those amongst our players who value their construct capacity can increase it to a comfortable level of approximately 125 construct slots before needing to make decisions on which constructs to keep.
     
    We want to thank you all for your feedback and take this opportunity to recognize the passion you our community have for the future of this game. We would love to hear how you feel about the new changes outlined above in this forum.
     
  2. Like
    NQ-Deckard got a reaction from Shaman in DEVBLOG: REVISITING CONSTRUCT SLOT CHANGES   
    Following the discussion around yesterday’s devblog, the community asked us to look over our figures to see what we can reliably sustain in terms of construct limits. In this communication we want to take the opportunity to outline what we have decided to change from the previous devblog as well as to explain some decisions such as the mechanics of construct abandonment and our reasons for arriving at our previous figures. These proposed changes are still being developed by our design team and we welcome your continued feedback on this major update.
     
    Organization Constructs Slots versus Personal Construct Slots
     
    There appeared to be some confusion in yesterday’s devblog between organization and personal construct slots. Personal construct slots are always independent of organization construct slots. 
     
    Before outlining the details of the construct slots, it’s important to note that our position on excess construct abandoning mechanics. For the avoidance of doubt, when this change is implemented in the Panacea release. No construct will be subject to abandonment through the following mechanics for at least the first month after release.
     
    This is to ensure as smooth a release as possible, and to allow our players who want to specialize in the architectural gameplay loop or the collecting of wonderful constructs, some time to accrue talent points and to adapt.
     
    Personal construct slots:
     
    Can only be used for constructs in the player’s ownership. Can not be assigned to organizations. Are non-transferable to other players. Are gained through talents independently of organization construct slots.  
    Organization construct slots:
     
    Can be assigned to any organization, regardless of membership. Can not be assigned to players. Once assigned to an organization, can not be repealed from that organization for 30 days. Once repealed, the organization will have until the next bi-weekly construct check to ensure that it meets its construct slot requirements. If that bi-weekly construct check determines that the organization has more constructs than it has slots, the organization will receive a warning and be required to ensure the constructs count is brought down to its capacity. If the next bi-weekly construct check following that warning determines that the organization still has more constructs than it has slots, random constructs from that organization will be abandoned until the organization is back in compliance with its slot capacity. All this means that even if you go over the available slot count, you have at the very minimum 14 days to correct it.  
    We are keeping the random nature of selection for construct abandonment. This is because as game developers we know that if there exists a way for a game system to be broken, our players will find it. In this particular instance, given the gravity of the impact, we feel that it’s important to protect the game and our community from abuse, and the randomization is an effort to do that.
     
    We hope this clears up some of the lingering questions that were remaining yesterday.
     
    Player allocated slot amounts, why so low?
     
    Following internal research, we determined that currently per active player there are approximately 25 constructs in the game at the present time.
     
    Therefore we believed that having a total of 42 slots per player would have been enough to provide an overhead for the community to be able to distribute the available slots amongst each other and support each other's projects.
     
    We do value our players and recognise that some of you own considerably more constructs than that average, and though we want to encourage collaboration and community, we don’t want to constrain those players that prefer to go it alone.
     
    And, we’ve heard you. 
     
    We are looking into an alternative approach that we feel will meet the majority of the community needs while also meeting our requirements for the long term sustainability and balancing of Dual Universe.
     
    Talent Changes
     
    We are going to increase the core allowances. In yesterday's devblog we proposed a figure of 42 total constructs. We are going to increase that through the introduction of talent changes that will require considerable time investment but keep the door open to players that wish to own many constructs.
     
    The new talents are separated into three tiers, increasing in expense significantly per tier.
     
    The new figures are (subject to change)

    For personal construct slots:
     
    The base personal construct slots will be increased from 2 to 10 slots without any talents. The first tier personal construct talent will grant 3 slots per level (up from 2), for a total of 15. The second tier personal construct talent will grant 5 slots per level (up from 1), for a total of 25. The new third tier personal construct talent will grant 10 slots per level, for a total of 50.  
    This will allow for a maximum personal construct limit of 100, once all the talents are fully acquired.
     
    For organization construct slots:
     
    The base organization construct slots will grant 10 slots without any talents. The new first tier organization construct talent will grant 3 slots per level, for a total of 15. The new second tier organization construct talent will grant 5 slots per level, for a total of 25. The new third tier organization construct talent will grant 10 slots per level, for a total of 50.  
    This will allow for a maximum organization construct limit of 100, once all the talents are fully acquired.
     
    The combination of the two will allow a determined player to reach the maximum number of construct slots that we can reasonably maintain. This will take substantial time investment in order to be a specialization within the game. 
     
    We will still be refunding the following Legate based talents:
     
    Organization Construct Management Organization Construct Management Specialization Advanced Organization Construct Management Specialization  
    These talents will be buffed to collectively increase the maximum ceiling for the organization's construct limit to 1625.
     
    If you have already trained Advanced Organization Construct Management Specialization to level 5, by reinvesting the refunded talent points, we estimate that you will be able to reach at least a construct slot capacity total of 80. Further, given the grace period of at least 1 month following the Panacea release, we hope that those amongst our players who value their construct capacity can increase it to a comfortable level of approximately 125 construct slots before needing to make decisions on which constructs to keep.
     
    We want to thank you all for your feedback and take this opportunity to recognize the passion you our community have for the future of this game. We would love to hear how you feel about the new changes outlined above in this forum.
     
  3. Like
    NQ-Deckard got a reaction from Zeddrick in DEVBLOG: CONSTRUCTION SLOTS AND STACKED ELEMENTS - discussion thread   
    Hello everyone, thank you for all the feedback so far.

    We will be reviewing the feedback tomorrow and there will likely be some adjustments. However that will have to be seen tomorrow.

    Keep it constructive so its useful to us and it will be seen. 
     
    We will have more news on todays article for you soon.
  4. Like
    NQ-Deckard got a reaction from Tional in DEVBLOG: CONSTRUCTION SLOTS AND STACKED ELEMENTS - discussion thread   
    Hello everyone, thank you for all the feedback so far.

    We will be reviewing the feedback tomorrow and there will likely be some adjustments. However that will have to be seen tomorrow.

    Keep it constructive so its useful to us and it will be seen. 
     
    We will have more news on todays article for you soon.
  5. Like
    NQ-Deckard got a reaction from DJSlicer in DEVBLOG: CONSTRUCTION SLOTS AND STACKED ELEMENTS - discussion thread   
    Hello everyone, thank you for all the feedback so far.

    We will be reviewing the feedback tomorrow and there will likely be some adjustments. However that will have to be seen tomorrow.

    Keep it constructive so its useful to us and it will be seen. 
     
    We will have more news on todays article for you soon.
  6. Like
    NQ-Deckard got a reaction from Serula in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  7. Like
    NQ-Deckard got a reaction from JayleBreak in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  8. Like
    NQ-Deckard got a reaction from huschhusch in DEVBLOG: CONSTRUCTION SLOTS AND STACKED ELEMENTS - discussion thread   
    A few clarifications:
     
    Your personal slots have nothing to do with this.

    Each player gets a base amount of 15 organization construct slots assigned to their account.
    Plus a new talent that can add 10 more organization construct slots to reach a total of 25.

    Any amount of these slots can be assigned to any organization of your choosing.
  9. Like
    NQ-Deckard got a reaction from antanox in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  10. Like
    NQ-Deckard got a reaction from DJSlicer in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  11. Like
    NQ-Deckard got a reaction from UnCheat in PANACEA UPDATE ADDED TO ROADMAP - discussion thread   
    In short, I suppose this is possible. The chances of that happening however are very very small. 
    How often have you accidentally collided with asteroids so far?

     
     
    Zarcata hit this nail on the head.
     
    We still have no intention to reset everything at this time, and will avoid doing so if we can.
     
     
    Quite a few of those are still out there undiscovered!
     
     
    All these questions will be answered in a later devblog when we have more information to share with you. Many of the listed features and systems are still undergoing a lot of change. As such it's to early for us to go into specifics at this time.
     
     
    The Camera Lua API will provide a way for control units to retrieve the view direction of the player. Allowing for improved tracking and overlaying in player made Lua scripts such as some of the already very impressive "Alternate Reality" overlays some of our players have been making. It will not however introduce new camera views.
     
     
    Sure, it needs to happen during a maintenance. The materials for the maintenance are not ready, and rather than introducing new bugs and issues to the game it was postponed by one day.
     
    - NQ-Deckard
  12. Like
    NQ-Deckard got a reaction from Atmosph3rik in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  13. Like
    NQ-Deckard got a reaction from Warlander in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  14. Like
    NQ-Deckard got a reaction from Knight-Sevy in DEVBLOG: PRECISION IN BUILDING - discussion thread   
    So this is an interesting question which I will attempt to answer to the best of my ability...
     
    I'm really fighting the urge to make the "It never was" meme here, but I'm sure one of you will do that for me soon enough.
    The reality here is that you never actually were making 1/8th or 1/16th slopes, you've been creating what is the closest approximation of that.
     
    In the old system, we used 253 points. In the new system, we use 252 points. This means that in the old system, a single voxel was: 84.3333333333333 (recurring) points.
    84.333 also does not divide by 8, 16, 32, or 64.

    In fact, in the old system you couldn't really reliably cut a voxel in half to an exact precision, and even a single voxel was not precise. As for example:
    84.333 / 2 = 42.166 (in reality this would have been 42 because we don't store decimals) 84.333 / 4 = 21.083 (in reality this would have been 21 because we don't store decimals) 84.333 / 8 = 10.541 (in reality this would have been 11 because we don't store decimals) 84.333 / 16 = 5.270 (in reality this would have been 5 because we don't store decimals) 84.333 / 32 = 2.635 (in reality this would have been 3 because we don't store decimals) 84.333 / 64 = 1.317 (in reality this would have been 1 because we don't store decimals) Sure, the difference is so negligible that you can't see it by eye. But that's essentially the same in the new system as the new pattern looks like this:
    84 / 2 = 42 exactly 84 / 4 = 21 exactly 84 / 8 = 10.5 (in reality this would be either 10 or 11 again because we don't store decimals) 84 / 16 = 5.25 (in reality this would be 5 again because we don't store decimals) 84 / 32 = 2.625 (in reality this would be 3 again because we don't store decimals) 84 / 64 = 1.315 (in reality this would be 1 again because we don't store decimals) Now, if we had changed the division to 64 instead of 84.333 you could expect the following to happen to all currently existing constructs:
    A loss of precision around 25% Every existing voxel would have lost around 25% of its available detail. You would see huge changes in your designs and most existing designs would likely loose a lot of their detail. Curves would be less curvy, more blocky. But you would have access to a 1/8 slope. With the new division of 84 instead of 84.333, you can expect the following:
    The precision loss is only 0.395% Every voxel will look near enough exactly the same, except for a few edge case ones. You likely not see any noticeable change in your existing designs. Curves are still curvy. But your 1/8 slope might be a bit wonky, and its probably better to adjust to 1/7.  In short, the precision cost of changing to 1/64 is not worth it. It really isn't. Trust me, we've looked. It's ugly.

    I can already see the new question brewing in your minds: Why didn't you increase it to 128 per voxel?
    Sure, this could increase the detail and be more divisible, however it also doesn't fit inside a single byte. So now we are talking about every single construct in the game taking up twice as much in terms of data. And if you feel your cache is big now, you really don't want to know what its like with double the resolution of voxels.  

    We could perhaps consider introducing a pseudo 1/64 grid mode further down the road, which would give you a 1/64 grid. However it will still not actually place a vertex at a 1/8, 1/16, 1/32, 1/64 position. It would place it at its closest available position.

    Also, to answer the question about the scale at which the tool works. No, it will always be 1.5vx in each direction from the vertices point of origin.
    I thought maximum adjustment range on this image made that quite clear, but perhaps that was an error on my part:


    I highly recommend you try it before you cast to much judgement on it, as someone who's tinkered with voxels for a long time. I absolutely love using the tool.
    I find myself mostly using Grid 2 and Grid 7, using the control key to make bigger jumps.
     
    I hope this answers some of the burning questions you all have.
    I wish you all a wonderful day, and look forward to seeing what you will all create with it.
    - Deckard
  15. Like
    NQ-Deckard got a reaction from Yezar in Why DU needs BIGGER cores, not less cores...   
    But let's face it, there would just be 17 XL cores instead of the 17 L cores that are there currently with an even larger multi-core build placed there.
    And in the process your performance would be worse off.

    I'm sorry to say we unfortunately won't be introducing larger cores any time soon. For a number of reasons, most of which are technical related to performance and data.
     
    Multiple smaller cores actually have a number of performance benefits as the load limits apply better that way. 
     
    - Deckard
  16. Like
    NQ-Deckard got a reaction from Koriandah in Why DU needs BIGGER cores, not less cores...   
    But let's face it, there would just be 17 XL cores instead of the 17 L cores that are there currently with an even larger multi-core build placed there.
    And in the process your performance would be worse off.

    I'm sorry to say we unfortunately won't be introducing larger cores any time soon. For a number of reasons, most of which are technical related to performance and data.
     
    Multiple smaller cores actually have a number of performance benefits as the load limits apply better that way. 
     
    - Deckard
  17. Like
    NQ-Deckard got a reaction from Endstar in New obstruction is too extreme   
    Hello everyone,
     
    Just to let you all know that we are looking into possibilities to make the element overlap detection a little less aggressive.
    More news on that will follow soon.
     
    - Deckard
  18. Like
    NQ-Deckard got a reaction from Atmosph3rik in New obstruction is too extreme   
    Hello everyone,
     
    Just to let you all know that we are looking into possibilities to make the element overlap detection a little less aggressive.
    More news on that will follow soon.
     
    - Deckard
  19. Like
    NQ-Deckard got a reaction from Zeddrick in New obstruction is too extreme   
    Hello everyone,
     
    Just to let you all know that we are looking into possibilities to make the element overlap detection a little less aggressive.
    More news on that will follow soon.
     
    - Deckard
  20. Like
    NQ-Deckard got a reaction from CptLoRes in New obstruction is too extreme   
    Hello everyone,
     
    Just to let you all know that we are looking into possibilities to make the element overlap detection a little less aggressive.
    More news on that will follow soon.
     
    - Deckard
  21. Like
    NQ-Deckard got a reaction from enjeyy in DEVBLOG: PANACEA LUA CHANGES - discussion thread   
    I do understand your concerns, but I'd like to reaffirm that we've been very clear about the logs not being a feature and these options potentially being removed at a later date.
     
    We are not opposed to players creating wonderful digital creations that work wonders with the game, however backchanneling that data through the games logs using in some cases closed source third party created software to then transfer that to databases stored online with who-knows-what data its collecting is not the right way to create this and that concerns us.
     
    None of this means that we don't see the use cases of an API or similar data export options, and we don't know when or how yet. But it's something we can look into in the future.
     
    For now however, data exportation will in most cases need to be done via screen units on demand if desired.
     
    - Deckard
  22. Like
    NQ-Deckard got a reaction from Merzie in DEVBLOG: PANACEA LUA CHANGES - discussion thread   
    We are never out to hurt anyone, however we do have to protect the security of the game. On top of which, what you're describing above is very much not in accordance with the EULA and will see you get into trouble for it. Reading the log files alone however, does not. There are a number of other concerns, such as the ability to write directly to a players hard drive through the logs. Which is one of the primary concerns about the logging functions.
     
    We have also been very clear about this from day one when players found this function. We were not enforcing it, but it was never a "feature", and never included in the codex. I have mentioned on multiple occasions in multiple locations that the logging functions would likely one day be redacted but we would observe what came from them in the meantime.
     
    As such, the audio feature is being developed to provide a suitable replacement for the community created audio framework.
     
     
    To be clear, this was also very clearly stated in the patch notes. If you read them carefully you'll notice that the VR capable talents that are mentioned are the ones that count towards the generation of Calibrations. Not the ones that consume them.
     
     
    The camera Lua feature set does not permit a Lua script to take control of your camera. It grants the Lua the ability to read orientation of the camera. Allowing for such things as accurate "Alternate reality" HUD designs, that move with the background and allow you to have virtual "panels" around you. It does not however allow a Lua script to force your camera to look at something.
  23. Like
    NQ-Deckard got a reaction from Thomsult in Lua Screen Units API and Instructions (Updated: 19/07/2021)   
    Sample Scripts (Control Unit Interaction)
    These scripts show some simple examples of Control Units interacting with screen units.
     
    Light Control (Screen to Programming Board) This example demonstrates clickable buttons on a screen unit, that set the screens output to a value, the programming board reads that value and then clears it and toggles lights based on that data. (See the top section for the programming board code)
    --[[---------------------------------------------------------------------------- -- Add the following section to a programming boards System.Update() -- Link the screen unit and three lights to the programming board -- Name the slots in the programming board respectively: screen, light0, light1, light2 local handlers = {} handlers['Light 0'] = function() light0.toggle() end handlers['Light 1'] = function() light1.toggle() end handlers['Light 2'] = function() light2.toggle() end local output = screen.getScriptOutput() if #output > 0 then screen.clearScriptOutput() if handlers[output] then handlers[output]() end end --]]---------------------------------------------------------------------------- -- Screen render script below -------------------------------------------------------------------------------- font = loadFont('Play-Bold', 32) rx, ry = getResolution() cx, cy = getCursor() layer = createLayer() click = getCursorPressed() -------------------------------------------------------------------------------- if not Button then local mt = {} mt.__index = mt function Button (text, x, y) return setmetatable({ text = text, x = x, y = y, }, mt) end function mt:draw () local sx, sy = self:getSize() local x0 = self.x - sx/2 local y0 = self.y - sy/2 local x1 = x0 + sx local y1 = y0 + sy local r, g, b = 0.3, 0.7, 1.0 if cx >= x0 and cx <= x1 and cy >= y0 and cy <= y1 then r, g, b = 1.0, 0.0, 0.4 if click then setOutput(self.text) end end setNextShadow(layer, 64, r, g, b, 0.3) setNextFillColor(layer, 0.1, 0.1, 0.1, 1) setNextStrokeColor(layer, r, g, b, 1) setNextStrokeWidth(layer, 2) addBoxRounded(layer, self.x - sx/2, self.y - sy/2, sx, sy, 4) setNextFillColor(layer, 1, 1, 1, 1) setNextTextAlign(layer, AlignH_Center, AlignV_Middle) addText(layer, font, self.text, self.x, self.y) end function mt:getSize () local sx, sy = getTextBounds(font, self.text) return sx + 32, sy + 16 end function mt:setPos (x, y) self.x, self.y = x, y end end function drawFree (elems) for i, v in ipairs(elems) do v:draw() end end function drawListV (elems, x, y) for i, v in ipairs(elems) do local sx, sy = v:getSize() v:setPos(x, y) v:draw() y = y + sy + 4 end end function drawUsage () local font = loadFont('FiraMono', 16) setNextTextAlign(layer, AlignH_Center, AlignV_Top) addText(layer, font, "Activate board to enable buttons!", rx/2, ry - 32) end function drawCursor () if cx < 0 then return end addLine(layer, cx - 12, cy - 12, cx + 12, cy + 12) addLine(layer, cx + 12, cy - 12, cx - 12, cy + 12) end -------------------------------------------------------------------------------- local buttons = { Button('Light 0', 128, 90), Button('Light 1', 128, 290), Button('Light 2', 128, 490), } drawFree(buttons) drawUsage() drawCursor() requestAnimationFrame(5)  

     
     
    Light Control (Screen to Programming Board) This allows you to create and use toggle buttons for boolean values, the examples flip not only their own state, but also the horizontally neighbouring toggle.
    --[[---------------------------------------------------------------------------- -- Add to programming board's unit.start() and connect it to this screen. local messages = { "Hi, I am a message!", "Yes hello this is Lua Screen.", "We love Pops the Hamster!", "WARNING: No warnings found.", "I am a screen unit.", "Are you enjoying this?", "Pending Screen Operations", "Lua Screen Units o/", "It is NOT NQ-Node\'s fault.", "Knock knock...", "Who's there?", "Ran out of Knock knock jokes.", "It is all NQ-Deckard\'s fault." } local message = messages[math.random(1, #messages)] local params = { message = message, testNumber = 1.337, testStr = 'hello I am a string', testTable = {x = 1, y = 0, k = {1, 2, 3, 4}}, } screen.setScriptInput(json.encode(params)) unit.exit() --]]---------------------------------------------------------------------------- -- Screen render script below -------------------------------------------------------------------------------- local json = require('dkjson') local params = json.decode(getInput()) or {} message = params.message or '[ no message ]' fontSize = params.fontSize or 64 color = params.color or {r=1.0,g=0,b=0.3} -------------------------------------------------------------------------------- local font = loadFont('Play-Bold', fontSize) local rx, ry = getResolution() local layer = createLayer() local cx, cy = getCursor() local sx, sy = getTextBounds(font, message) setDefaultStrokeColor(layer, Shape_Line, 1, 1, 1, 0.5) setNextShadow(layer, 64, color.r, color.g, color.b, 0.4) setNextFillColor(layer, color.r, color.g, color.b, 1.0) addBoxRounded(layer, (rx-sx-16)/2, (ry-sy-16)/2, sx+16, sy+16, 8) setNextFillColor(layer, 0, 0, 0, 1) setNextTextAlign(layer, AlignH_Center, AlignV_Middle) addText(layer, font, message, rx/2,ry/2) -------------------------------------------------------------------------------- local fontCache = {} function getFont (font, size) local k = font .. '_' .. tostring(size) if not fontCache[k] then fontCache[k] = loadFont(font, size) end return fontCache[k] end function drawUsage () local font = getFont('FiraMono', 16) setNextTextAlign(layer, AlignH_Center, AlignV_Top) addText(layer, font, "Activate for an exciting new message!", rx/2, ry - 32) end function drawCursor () if cx < 0 then return end if getCursorDown() then setDefaultShadow(layer, Shape_Line, 32, color.r, color.g, color.b, 0.5) end addLine(layer, cx - 12, cy - 12, cx + 12, cy + 12) addLine(layer, cx + 12, cy - 12, cx - 12, cy + 12) end function prettyStr (x) if type(x) == 'table' then local elems = {} for k, v in pairs(x) do table.insert(elems, string.format('%s = %s', prettyStr(k), prettyStr(v))) end return string.format('{%s}', table.concat(elems, ', ')) else return tostring(x) end end function drawParams () local font = getFont('RobotoMono', 11) setNextTextAlign(layer, AlignH_Left, AlignV_Bottom) addText(layer, font, "Script Parameters", 16, 16) local y = 32 for k, v in pairs(params) do setNextTextAlign(layer, AlignH_Left, AlignV_Bottom) addText(layer, font, k .. ' = ' .. prettyStr(v), 24, y) y = y + 12 end end -------------------------------------------------------------------------------- drawUsage() drawCursor() drawParams() requestAnimationFrame(1)  

  24. Like
    NQ-Deckard got a reaction from Kurock in Lua Screen Units API and Instructions (Updated: 19/07/2021)   
    Sample Scripts (Widget Objects)
    These widget scripts show some examples of interactive UI elements created using the new Lua Screen Units.
     
    Sliders This allows you to create and use sliders for number values, the example handles change the color properties of background square.
    ------------------------------------ -- Slider widget example -- Usage: -- Creates a slider style widget with a minimum and maximum value. -- -- Init: -- widget = Slider(x,y,width,length,minValue,maxValue,defaultValue,label) -- Return fractional value of the slider position: -- widget:getFraction() -- Force set the value of the slider: -- widget:setValue(value) -- Draw the slider: -- widget:draw(layer) -- Return the value of slider: -- widget.value ------------------------------------ if not Slider then -- Object definition: Lets start by creating a meta table with some properties local slider = {} slider.__index = slider function Slider(x, y, width, length, min, max, defaultValue, label) self = {} self.x = x or 0 self.y = y or 0 self.l = length or 100 self.w = width or 20 self.min = min or 0 self.max = max or 1 self.value = math.max(self.min, math.min(self.max, defaultValue)) or self.min self.label = label or "" self.doDrag = false return setmetatable(self, slider) end -- example helper method that returns the position of the slider between a value of 0 and 1 function slider:getFraction() return (self.value - self.min) / (self.max - self.min) end -- example set method that allows us to set the value of the slider function slider:setValue(val) self.value = math.max(self.min, math.min(self.max, val)) end -- example draw method that draws the slider on the screen using the given layer and stored properties function slider:draw(layer) -- Collect some cursor data local cx, cy = getCursor() local cPressed = getCursorPressed() local cReleased = getCursorReleased() -- Determine if the handle for this slider was just clicked or released if cPressed and cx >= self.x and cx <= (self.x + self.w) and cy >= self.y + self.l - (self:getFraction() * self.l) and cy <= self.y + (self.w / 5) + self.l - (self:getFraction() * self.l) + (2 * self.w / 5) then self.doDrag = true elseif cReleased == true or cx == -1 then self.doDrag = false end -- If we are currently dragging the handle we should update the position and value of the slider. if self.doDrag then local vy = 1 - ((cy - self.y - self.w / 5) / self.l) self.value = math.max(self.min, math.min(self.max, self.min + ((self.max - self.min) * vy))) end -- Finaly lets draw the entire slider on the screen -- Draw the background vertical bar (You could change the color below this line, or make a property for it) setNextFillColor(layer, 0.5, 0.5, 1, 1) addBoxRounded(layer, self.x + (self.w / 2.5), self.y + self.w / 5, self.w / 5, self.l, math.min(self.w / 10, self.l / 10)) -- Draw the handle (You could change the color below this line, or make a property for it) setNextFillColor(layer, 0.7, 0.7, 1, 1) addBoxRounded(layer, self.x, self.y + self.l - (self:getFraction() * self.l), self.w, self.w / 2.5, self.w / 10) -- Lets load a font for this slider, if you want lots of sliders, you may want to load the font outside this object to avoid to many fonts. local font = loadFont("Montserrat", self.w / 5) -- Fetch the dimensions of the label and value we are about to draw local lw,lh = getTextBounds(font, self.label) local vw,vh = getTextBounds(font, math.floor(self.value * 100) * 0.01) -- draw the label above the slider addText(layer, font, self.label, self.x + (self.w / 2) - (lw / 2), self.y - (lh * 0.5)) -- draw the value on the handle setNextFillColor(layer, 0.1, 0.1, 0.1, 1) addText(layer, font, math.floor(self.value * 100) * 0.01, self.x + (self.w / 2) - (vw / 2), self.y + self.l - (self:getFraction() * self.l) + (self.w / 5) + (vh / 2)) end end ------------------------------------ -- Display ------------------------------------ -- Collect the screen resolution for positioning local rx, ry = getResolution() -- Create two layers, one for the background square, the other for the sliders local backgroundLayer = createLayer() local sliderLayer = createLayer() -- Run this portion only once on screen startup, this creates the slider objects if not init then init = true sliderRed = Slider(rx/5-25, ry/8,50, ry/8*6, 0, 1, 0.2, "Red") sliderGreen = Slider(rx/5*2-25, ry/8,50, ry/8*6, 0, 1, 0.4, "Green") sliderBlue = Slider(rx/5*3-25, ry/8,50, ry/8*6, 0, 1, 0.6, "Blue") sliderAlpha = Slider(rx/5*4-25, ry/8,50, ry/8*6, 0, 1, 0.8, "Alpha") end -- every frame, draw the 4 slider sliderRed:draw(sliderLayer) sliderGreen:draw(sliderLayer) sliderBlue:draw(sliderLayer) sliderAlpha:draw(sliderLayer) -- every frame, draw the background square using the slider values as colour properties for the fill setNextFillColor(backgroundLayer, sliderRed.value, sliderGreen.value, sliderBlue.value, sliderAlpha.value) addBoxRounded(backgroundLayer,25,25,rx-50,ry-50,20) -- render cost profiler if true then local layer = createLayer() local font = loadFont('Play-Bold', 14) setNextFillColor(layer, 1, 1, 1, 1) addText(layer, font, string.format('render cost : %d / %d', getRenderCost(), getRenderCostMax()), 8, 16) end -- refresh the screen at a high rate to keep the slider elements responsive requestAnimationFrame(1)  

     
     
    Toggle buttons This allows you to create and use toggle buttons for boolean values, the examples flip not only their own state, but also the horizontally neighbouring toggle.
    ------------------------------------ -- Toggle widget example -- Usage: -- Creates a toggle button style widget with a true or false state. -- -- Init: -- widget = Toggle(x, y, width, height, defaultState, label, font, onClick) -- onClick can be a function that is executed when the button is clicked. -- Draw the slider: -- widget:draw(layer) -- Return the value of slider: -- widget:getState() -- or -- widget.state -- Set the state of the toggle: -- widget:setState(boolean) -- Switch the state of the toggle: -- widget:switch() -- Also returns the new state of the widget ------------------------------------ if not Toggle then -- Object definition: Lets start by creating a meta table with some properties local toggle = {} toggle.__index = toggle function Toggle(x, y, width, height, defaultState, label, font, onClick) self = {} self.x = x or 0 self.y = y or 0 self.h = height or 20 self.w = width or 20 self.state = defaultState or false self.label = label or "" self.onClick = onClick self.font = font or function() return loadFont("Montserrat",self.h * 5.5) end return setmetatable(self, toggle) end -- create a function that creates a new font if required, otherwise returns the font identifier from the properties local function getFont() local font = self.font if type(font) == "function" then font = self.font() end return font end -- draw method that draws the toggle on the screen unit function toggle:draw(layer) -- Collect cursor coordinates local cx, cy = getCursor() -- check if the mouse is over the button if cx >= self.x and cx <= self.x + self.w and cy >= self.y and cy <= self.y + self.h then -- handle the click action if getCursorReleased() then self.state = not self.state if self.onClick ~= nil then self.onClick() end end -- set the mouseover colors if self.state and getCursorDown() then setNextFillColor(layer, 1, 0.6, 0.8, 1) elseif getCursorDown() then setNextFillColor(layer, 0.6, 1, 0.8, 1) elseif self.state then setNextFillColor(layer, 1, 0.2, 0.2, 1) else setNextFillColor(layer, 0.2, 0.8, 0.2, 1) end elseif self.state then -- set color if toggle is true setNextFillColor(layer, 0.2, 0.2, 0.6, 1) else -- set color if toggle is false setNextFillColor(layer, 0.2, 0.2, 0.2, 1) end -- draw the button toggle local w, h = self:getBounds() addBox(layer, self.x, self.y + (h / 2 - self.h / 2), self.w, self.h) setNextTextAlign(layer, AlignH_Left, AlignV_Middle) addText(layer, getFont(), self.label, self.x + self.w + (self.w / 5), self.y + (h / 2)) end -- simple example helper method that returns the current state of the toggle function toggle:getState() return self.state end -- simple example helper method that sets the state of the toggle function toggle:setState(newState) if type(newState) == "boolean" then self.state = newState end end -- simple example helper method that changes and returns the new state of the toggle function toggle:switch() self.state = not self.state return self.state end -- helper method that returns the width and height of toggle function toggle:getBounds() local tx, ty = getTextBounds(getFont(),self.label) return self.x + self.w + (self.w / 5) + tx, math.max(self.h, ty) end end ---------------------------------------------------- -- Display ---------------------------------------------------- -- Collect the screen resolution for positioning local rx,ry = getResolution() -- Create a layer to draw the toggles local exampleLayer = createLayer() -- Create a font for all the toggles local font = loadFont("Montserrat", 20) -- Run this portion only once on screen startup, this creates the toggle objects if not init then init = true example1 = Toggle(rx / 7, ry / 5 - rx / 40, rx / 20, rx / 20, true, "Example Toggle 1 (Linked)", font) example2 = Toggle(rx / 7, ry / 5 * 2 - rx / 40, rx / 20, rx / 20, false, "Example Toggle 2 (Linked)", font) example3 = Toggle(rx / 7, ry / 5 * 3 - rx / 40, rx / 20, rx / 20, true, "Example Toggle 3", font) example4 = Toggle(rx / 7, ry / 5 * 4 - rx / 40, rx / 20, rx / 20, false, "Example Toggle 4", font) exampleA = Toggle(rx / 7 * 4, ry / 5 - rx / 40, rx / 20, rx / 20, false, "Example Toggle A (Linked)", font) exampleB = Toggle(rx / 7 * 4, ry / 5 * 2 - rx / 40, rx / 20, rx / 20, true, "Example Toggle B (Linked)", font) exampleC = Toggle(rx / 7 * 4, ry / 5 * 3 - rx / 40, rx / 20, rx / 20, false, "Example Toggle C", font) exampleD = Toggle(rx / 7 * 4, ry / 5 * 4 - rx / 40, rx / 20, rx / 20, true, "Example Toggle D", font) end -- for toggle, make the toggle next to it always the opposite and then draw the toggle example1:setState(not exampleA:getState()) example1:draw(exampleLayer) example2:setState(not exampleB:getState()) example2:draw(exampleLayer) example3:draw(exampleLayer) example4:draw(exampleLayer) exampleA:setState(not example1:getState()) exampleA:draw(exampleLayer) exampleB:setState(not example2:getState()) exampleB:draw(exampleLayer) exampleC:draw(exampleLayer) exampleD:draw(exampleLayer) -- render cost profiler if true then local layer = createLayer() local font = loadFont('Play-Bold', 14) setNextFillColor(layer, 1, 1, 1, 1) addText(layer, font, string.format('render cost : %d / %d', getRenderCost(), getRenderCostMax()), 8, 16) end -- Refresh the screen requestAnimationFrame(1)  

  25. Like
    NQ-Deckard got a reaction from Kurock in Lua Screen Units API and Instructions (Updated: 19/07/2021)   
    Sample Scripts (Advanced)
    These more advanced scripts demonstrate what can ultimately be achieved with this API. Perhaps they will inspire you a bit!
     
    Entropy Like the bouncy ball example, but fancier!
    local ballCount = 5000 local speed = 20 local rx, ry = getResolution() --[[ init ]]-------------------------------------------------------------------- if not init then init = true function randF (a, b) return a + (b - a) * math.random() end function randExp () return -math.log(1.0 - math.random()) end balls = {} for i = 1, ballCount do local e = {} e.x = randF(0, rx) e.y = randF(0, ry) e.r = 1 + 1.0 * math.log(1.0 - math.random()) ^ 2.0 e.vx = randF(-1, 1) * randExp() e.vy = randF(-1, 1) * randExp() e.cx = 1.0 * math.random() e.cy = 0.1 * math.random() e.cz = 0.4 * math.random() e.ca = math.random() table.insert(balls, e) end end --[[ simulation ]]-------------------------------------------------------------- local dt = speed * getDeltaTime() for _, v in ipairs(balls) do v.x = v.x + dt * v.vx v.y = v.y + dt * v.vy if v.x < 0 or v.x > rx then v.x = v.x - dt * v.vx v.vx = -v.vx end if v.y < 0 or v.y > ry then v.y = v.y - dt * v.vy v.vy = -v.vy end end --[[ rendering ]]--------------------------------------------------------------- local l = createLayer() -- render balls for _, e in ipairs(balls) do setNextFillColor(l, e.cx, e.cy, e.cz, e.ca) addCircle(l, e.x, e.y, e.r) end -- render title local font = loadFont('Play-Bold', 64) addText(l, font, '{{ E N T R O P Y }}', 32, ry - 32) requestAnimationFrame(1) --------------------------------------------------------------------------------  
     
    Radial Menu Practical example of how responsive UI elements could be designed, creates 3 radial menu's using the same function.
    Left: Example with transparency on the circle layer to demonstrate layering and the use of math to define the circle stroke.
    Top right: Example without transparency, drawn to a different scale.
    Bottom right: Example of a collapsible version saving screen real-estate and reducing rending costs while collapsed. (Only a dot is drawn while collapsed)
    -- Get screen resolution and center coordinates local resolutionX,resolutionY = getResolution() local centerX,centerY = resolutionX/2, resolutionY/2 -- Draw radial menu layers local triLayer = createLayer() local circleLayer = createLayer() local textLayer = createLayer() -- Define some helpers to convert degrees to radians local d2r = math.pi/180 -- Helper function to get distance of cursor from coordinates function getCursorDistance(x,y) local curX,curY = getCursor() curX = curX - x curY = curY - y return math.sqrt(curX^2+curY^2) end -- Helper function to check if cursor is inside a radial menu section function isCursorInside(radialCenterX,radialCenterY,radiusMin,radiusMax,degMin,degMax) local curX,curY = getCursor() curX = curX - radialCenterX curY = curY - radialCenterY local magnitude = getCursorDistance(radialCenterX,radialCenterY) local deg = math.atan(curY/curX)/d2r if curX < 0 then deg = deg + 180 end if curX > 0 and curY < 0 then deg = deg + 360 end if magnitude <= radiusMax and magnitude >= radiusMin and deg > degMin and deg < degMax then return true end end -- Define function that can draw a radial menu on demand function drawRadialMenu(posX,posY,radius,steps,hide,strokeAndCenterAlpha) -- Define default variables local posX = posX or centerX local posY = posY or centerY local radius = radius or 200 local steps = steps or 15 if hide ~= nil then hide = hide else hide = true end local strokeAndCenterAlpha = strokeAndCenterAlpha or 1 -- minimum of 4 segments steps = math.max(steps,4) -- work out the depth of the triangular facets along the circumferance and use it to determine the outer circle stroke width local aX,aY = radius*math.cos(0) , radius*math.sin(0) local bX,bY = radius*math.cos(((360/steps)*1)*d2r) , radius*math.sin(((360/steps)*1)*d2r) local stroke = math.min(-(radius-math.sqrt(((aX+bX)/2)^2+((aY+bY)/2)^2)),-3) if not hide or (hide and getCursorDistance(posX,posY) < (radius)) then -- Draw triangular segments local alpha = 0.5 for step=1,steps,1 do -- calculate the corners of the triangles on the radius local aX,aY = posX + (radius*math.cos(((360/steps)*(step-1))*d2r)) , posY + (radius*math.sin(((360/steps)*(step-1))*d2r)) local bX,bY = posX + (radius*math.cos(((360/steps)*step)*d2r)) , posY + (radius*math.sin(((360/steps)*step)*d2r)) -- call helper function to determine if cursor is inside the segment and change color if true if isCursorInside(posX,posY,radius/3,radius,((360/steps)*(step-1)),(360/steps)*step) then setNextFillColor(triLayer,1,1,1,1) -- create center number while the cursor is over a selection local font = loadFont('Montserrat', math.floor(radius/4)) setNextFillColor(textLayer, 1, 1, 1, 1) addText(textLayer, font,step, posX-((radius/12)*#tostring(step)), posY+math.floor(radius/12)) else setNextFillColor(triLayer,1,0,0,alpha + 0.5) end -- Draw the triangle based on pre-calculated coordinates and with the color now preset addTriangle(triLayer,posX,posY,aX,aY,bX,bY) -- flip the alpha between 1 and 0 for the next segment alpha = 0.5 - alpha end -- Create the outer stroke which should be a negative value so it overlaps the triangle facets setNextStrokeColor(circleLayer,0.5,0.5,1,strokeAndCenterAlpha) setNextFillColor(circleLayer,0,0,0,0) setNextStrokeWidth(circleLayer,stroke) addCircle(circleLayer,posX,posY,radius) -- Create the inner stroke and fill to create the "hole" in the center at 1/4th of the radius. setNextStrokeColor(circleLayer,0.5,0.5,1,strokeAndCenterAlpha) setNextFillColor(circleLayer,0,0,0,strokeAndCenterAlpha) setNextStrokeWidth(circleLayer,stroke) addCircle(circleLayer,posX,posY,radius/4) else -- Create a transparent dot to indicate its position while its hidden. setNextFillColor(circleLayer,0.5,0.5,1,0.2) addCircle(circleLayer,posX,posY,radius/4) end end -- Draw three examples -- Example 1 (large one on left) with transparency to demonstrate how the circular shape was achieved with the triangles. drawRadialMenu(resolutionX/3,centerY,200,6,false,0.5) -- Example 2 (Top right) Does not hide, shows the result without transparency drawRadialMenu((resolutionX/3)*2,resolutionY/3,100,8,false) -- Example 3 (Bottom right) Remains hidden and un-rendered until the cursor enters its area, reducing render cost by ~120000 while hidden. drawRadialMenu((resolutionX/3)*2,(resolutionY/3)*2,80,36) -- render cost profiler if true then local layer = createLayer() local font = loadFont('Play-Bold', 14) setNextFillColor(layer, 1, 1, 1, 1) addText(layer, font, string.format('render cost : %d / %d', getRenderCost(), getRenderCostMax()), 8, 16) end -- Request a refresh requestAnimationFrame(1)  
     
    Text positioning Demonstration example of the various alignment points for text using Font Metrics and Text Align.
    local fontName = 'Play' local fontSize = 32 local font = loadFont(fontName, fontSize) local fontDebug = loadFont('FiraMono', 12) local back = createLayer() local layer = createLayer() local rx, ry = getResolution() local ascender, descender = getFontMetrics(font) local text = "??" frame = (frame or 0) + 1 setDefaultFillColor(layer, Shape_Text, 1, 1, 1, 1) setDefaultFillColor(layer, Shape_Circle, 1, 0, 0, 1) function drawTextBox (x, y, alignH, alignV) local w, h, ascent, descent = getTextBounds(font, text) if alignH == AlignH_Left then x = x elseif alignH == AlignH_Center then x = x - w/2 elseif alignH == AlignH_Right then x = x - w end if alignV == AlignV_Ascender then y = y h = ascender - descender elseif alignV == AlignV_Top then y = y elseif alignV == AlignV_Middle then h = ascender - descender y = y - h/2 elseif alignV == AlignV_Baseline then y = y - ascent elseif alignV == AlignV_Bottom then y = y - h elseif alignV == AlignV_Descender then h = ascender - descender y = y - h end setNextFillColor(back, 0.1, 0.5, 1.0, 1.0) setNextStrokeWidth(back, 1) addBox(back, x, y, w, h) end function main () if frame % 2 == 0 then text = "acemnor " else text = "aCjÅkö[]|!r " end -- display debug info about font if true then local infoLines = { string.format(" font : %s", fontName), string.format(" size : %d", fontSize), string.format(" ascender : %d", ascender), string.format("descender : %d", descender), } for i, line in ipairs(infoLines) do setNextTextAlign(layer, AlignH_Left, AlignV_Top) addText(layer, fontDebug, line, 16, 16 + (i - 1) * 12) end end local alignHs = { 'AlignH_Left', 'AlignH_Center', 'AlignH_Right', } local alignVs = { 'AlignV_Ascender', 'AlignV_Top', 'AlignV_Middle', 'AlignV_Baseline', 'AlignV_Bottom', 'AlignV_Descender', } -- draw text boxes with various alignments local sx = 300 local sy = 80 local x0 = rx/2 - sx * (#alignHs-1)/2 local y0 = ry/2 - sy * (#alignVs-1)/2 for y, alignVName in ipairs(alignVs) do for x, alignHName in ipairs(alignHs) do local px = x0 + sx * (x - 1) local py = y0 + sy * (y - 1) local alignV = _ENV[alignVName] local alignH = _ENV[alignHName] drawTextBox(px, py, alignH, alignV) setNextTextAlign(layer, alignH, alignV) addText(layer, font, text, px, py) addCircle(layer, px, py, 3) end end -- draw AlignH labels for x, alignH in ipairs(alignHs) do setNextTextAlign(layer, _ENV[alignH], AlignV_Descender) setNextFillColor(layer, 0.5, 0.5, 0.5, 1) addText(layer, fontDebug, alignH, x0 + (x - 1)*sx, y0 - 16) end -- draw AlignV labels for y, alignV in ipairs(alignVs) do setNextTextAlign(layer, AlignH_Right, _ENV[alignV]) setNextFillColor(layer, 0.5, 0.5, 0.5, 1) addText(layer, fontDebug, alignV, x0 - 16, y0 + (y - 1)*sy) end end if not isFontLoaded(font) then requestAnimationFrame(10) else main() requestAnimationFrame(120) end  

×
×
  • Create New...